@adonis-agora/durable 0.1.0 → 0.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/CHANGELOG.md +15 -0
- package/dist/providers/durable_provider.d.ts.map +1 -1
- package/dist/providers/durable_provider.js +19 -1
- package/dist/providers/durable_provider.js.map +1 -1
- package/dist/src/control-plane-redis/index.d.ts +2 -0
- package/dist/src/control-plane-redis/index.d.ts.map +1 -0
- package/dist/src/control-plane-redis/index.js +2 -0
- package/dist/src/control-plane-redis/index.js.map +1 -0
- package/dist/src/control-plane-redis/redis-control-plane.d.ts +64 -0
- package/dist/src/control-plane-redis/redis-control-plane.d.ts.map +1 -0
- package/dist/src/control-plane-redis/redis-control-plane.js +57 -0
- package/dist/src/control-plane-redis/redis-control-plane.js.map +1 -0
- package/dist/src/control-planes/factory.d.ts +65 -0
- package/dist/src/control-planes/factory.d.ts.map +1 -0
- package/dist/src/control-planes/factory.js +37 -0
- package/dist/src/control-planes/factory.js.map +1 -0
- package/dist/src/define_config.d.ts +11 -4
- package/dist/src/define_config.d.ts.map +1 -1
- package/dist/src/define_config.js +2 -1
- package/dist/src/define_config.js.map +1 -1
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -0
- package/dist/src/index.js.map +1 -1
- package/package.json +13 -8
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# @adonis-agora/durable
|
|
2
|
+
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`6b47d1a`](https://github.com/DavideCarvalho/adonis-durable/commit/6b47d1a7d0bc6f76e5b6ebe704c3ea8cfe025d53) - Require AdonisJS v7 (bump @adonisjs/\* peers; Lucid 22, Queue 0.6)
|
|
8
|
+
|
|
9
|
+
## 0.2.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- [`2ecedd7`](https://github.com/DavideCarvalho/adonis-durable/commit/2ecedd7984641208ba59088535ed8c165b5992b5) - Redis control-plane driver for cross-pod cancellation + lifecycle-event fan-out (multi-replica).
|
|
14
|
+
|
|
15
|
+
Adds `controlPlanes.redis({ connection: 'main', prefix? })` and the `RedisControlPlane` class — a Redis pub/sub `ControlPlane` that broadcasts workflow lifecycle events and cancellation across every engine replica. Without it, a `cancel` issued on one pod never reaches the pod running the run and a dashboard pod can't live-tail runs executing elsewhere. The channel (`${prefix}-control`) and payload match the NestJS BullMQ transport, so an AdonisJS fleet interoperates with a NestJS fleet on the same Redis. `controlPlane` config now accepts a `ControlPlaneFactory` as well as a ready instance; `@adonisjs/redis` stays an optional, lazily-imported peer. Omit `controlPlane` and the engine remains local-only (single instance).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"durable_provider.d.ts","sourceRoot":"","sources":["../../providers/durable_provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"durable_provider.d.ts","sourceRoot":"","sources":["../../providers/durable_provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAkC/D;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,OAAO,OAAO,eAAe;;IAKtB,SAAS,CAAC,GAAG,EAAE,kBAAkB;gBAAvB,GAAG,EAAE,kBAAkB;IAE7C,QAAQ;IAkFR;;;;;;OAMG;IACG,KAAK;IAOL,QAAQ;CAUf"}
|
|
@@ -32,6 +32,7 @@ export default class DurableProvider {
|
|
|
32
32
|
app;
|
|
33
33
|
#detachDiagnostics = null;
|
|
34
34
|
#transport = null;
|
|
35
|
+
#controlPlane = null;
|
|
35
36
|
constructor(app) {
|
|
36
37
|
this.app = app;
|
|
37
38
|
}
|
|
@@ -45,10 +46,13 @@ export default class DurableProvider {
|
|
|
45
46
|
const transport = await this.#resolveTransport(config, ctx);
|
|
46
47
|
// Hold the transport so `shutdown()` can release broker workers/connections cleanly.
|
|
47
48
|
this.#transport = transport;
|
|
49
|
+
const controlPlane = await this.#resolveControlPlane(config, ctx);
|
|
50
|
+
// Hold the control plane so `shutdown()` can tear down its subscriber connection cleanly.
|
|
51
|
+
this.#controlPlane = controlPlane;
|
|
48
52
|
const deps = {
|
|
49
53
|
store,
|
|
50
54
|
transport,
|
|
51
|
-
...(
|
|
55
|
+
...(controlPlane ? { controlPlane } : {}),
|
|
52
56
|
...(config.leaseMs !== undefined ? { leaseMs: config.leaseMs } : {}),
|
|
53
57
|
...(config.instanceId ? { instanceId: config.instanceId } : {}),
|
|
54
58
|
...(config.maxRecoveryAttempts !== undefined
|
|
@@ -88,6 +92,17 @@ export default class DurableProvider {
|
|
|
88
92
|
}
|
|
89
93
|
return factory(ctx);
|
|
90
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Resolve the configured control plane. `config.controlPlane` may be a ready {@link ControlPlane}
|
|
97
|
+
* instance (used as-is) or a {@link ControlPlaneFactory} thunk (called at boot so its peer
|
|
98
|
+
* dependency loads lazily). Omitted → no control plane (the engine runs local-only).
|
|
99
|
+
*/
|
|
100
|
+
async #resolveControlPlane(config, ctx) {
|
|
101
|
+
const cp = config.controlPlane;
|
|
102
|
+
if (!cp)
|
|
103
|
+
return null;
|
|
104
|
+
return typeof cp === 'function' ? cp(ctx) : cp;
|
|
105
|
+
}
|
|
91
106
|
/**
|
|
92
107
|
* Once everything is booted, bridge engine lifecycle events onto the `@adonis-agora/diagnostics` bus —
|
|
93
108
|
* but only when diagnostics is actually installed (its emit slot is populated at module load).
|
|
@@ -108,6 +123,9 @@ export default class DurableProvider {
|
|
|
108
123
|
// Release the transport's broker workers / queues / connections so a deploy hands off cleanly.
|
|
109
124
|
await this.#transport?.close?.();
|
|
110
125
|
this.#transport = null;
|
|
126
|
+
// Tear down the control plane's subscriber connection (Redis pub/sub) on the way out.
|
|
127
|
+
await this.#controlPlane?.close?.();
|
|
128
|
+
this.#controlPlane = null;
|
|
111
129
|
}
|
|
112
130
|
}
|
|
113
131
|
//# sourceMappingURL=durable_provider.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"durable_provider.js","sourceRoot":"","sources":["../../providers/durable_provider.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"durable_provider.js","sourceRoot":"","sources":["../../providers/durable_provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/control-plane-redis/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,WAAW,GACjB,MAAM,0BAA0B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/control-plane-redis/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,GAGlB,MAAM,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { ControlMessage, ControlPlane } from '../index.js';
|
|
2
|
+
/**
|
|
3
|
+
* The minimal Redis pub/sub surface this control plane needs. BOTH a raw `ioredis` instance and an
|
|
4
|
+
* `@adonisjs/redis` connection satisfy it structurally, so we depend on the surface rather than a
|
|
5
|
+
* concrete type — keeping the peer coupling minimal and the driver testable.
|
|
6
|
+
*
|
|
7
|
+
* The two clients differ in how a subscriber is obtained:
|
|
8
|
+
* - **raw ioredis**: a subscriber connection can't run normal commands, so `duplicate()` a dedicated
|
|
9
|
+
* one, `subscribe(channel)` on it, and receive via `.on('message', (channel, message) => ...)`.
|
|
10
|
+
* - **`@adonisjs/redis` connection**: `subscribe(channel, (message) => ...)` manages its own
|
|
11
|
+
* subscriber connection internally — no duplicate needed; the handler receives the message directly.
|
|
12
|
+
*
|
|
13
|
+
* We detect which one we have by feature: a raw ioredis client exposes `duplicate()`; the
|
|
14
|
+
* `@adonisjs/redis` connection does not (it hides its `ioConnection`).
|
|
15
|
+
*/
|
|
16
|
+
export interface RedisPubSub {
|
|
17
|
+
/** Publish a message to a channel (both clients return a promise-ish here). */
|
|
18
|
+
publish(channel: string, message: string): unknown;
|
|
19
|
+
/**
|
|
20
|
+
* Subscribe to a channel. ioredis takes only the channel (messages arrive via `on('message')`);
|
|
21
|
+
* the `@adonisjs/redis` connection takes a channel + a per-message handler.
|
|
22
|
+
*/
|
|
23
|
+
subscribe(channel: string, handler?: (message: string, channel: string) => void): unknown;
|
|
24
|
+
/** ioredis-only: per-message event used when a dedicated subscriber connection is duplicated. */
|
|
25
|
+
on?(event: 'message', listener: (channel: string, message: string) => void): unknown;
|
|
26
|
+
/** ioredis-only: build a dedicated subscriber connection (pub/sub can't share a command client). */
|
|
27
|
+
duplicate?(): RedisPubSub;
|
|
28
|
+
/** ioredis-only: tear down the duplicated subscriber connection. */
|
|
29
|
+
disconnect?(): void;
|
|
30
|
+
}
|
|
31
|
+
export interface RedisControlPlaneOptions {
|
|
32
|
+
/** An ioredis instance or an `@adonisjs/redis` connection used for pub/sub. */
|
|
33
|
+
connection: RedisPubSub;
|
|
34
|
+
/**
|
|
35
|
+
* Key prefix namespacing the control channel. Defaults to `durable`. The channel is
|
|
36
|
+
* `` `${prefix}-control` `` — matched EXACTLY to the NestJS BullMQ transport so an AdonisJS fleet
|
|
37
|
+
* and a NestJS fleet sharing one Redis interoperate on the same control plane.
|
|
38
|
+
*/
|
|
39
|
+
prefix?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A {@link ControlPlane} backed by Redis pub/sub: the cross-pod broadcast channel for workflow
|
|
43
|
+
* **lifecycle events** (so a dashboard-only pod can live-tail a run executing on a worker pod) and
|
|
44
|
+
* **cancellation** (so the pod actually running a run learns it was cancelled elsewhere).
|
|
45
|
+
*
|
|
46
|
+
* This is purely out-of-band signalling — it carries NO replay/determinism weight; the engine
|
|
47
|
+
* already dedupes self-broadcasts by `msg.from`, so a publish Redis echoes back to its own subscriber
|
|
48
|
+
* is ignored. Omit a control plane entirely and the engine is local-only (single instance).
|
|
49
|
+
*
|
|
50
|
+
* The channel name (`` `${prefix}-control` ``) and the JSON payload match the NestJS BullMQ
|
|
51
|
+
* transport, so a mixed AdonisJS + NestJS fleet on one Redis fans out across both runtimes.
|
|
52
|
+
*/
|
|
53
|
+
export declare class RedisControlPlane implements ControlPlane {
|
|
54
|
+
private readonly connection;
|
|
55
|
+
private readonly channel;
|
|
56
|
+
private subscriber;
|
|
57
|
+
private subscribed;
|
|
58
|
+
constructor(options: RedisControlPlaneOptions);
|
|
59
|
+
publishControl(msg: ControlMessage): Promise<void>;
|
|
60
|
+
onControl(handler: (msg: ControlMessage) => void): void;
|
|
61
|
+
/** Tear down the dedicated subscriber connection, if one was duplicated (ioredis path). */
|
|
62
|
+
close(): Promise<void>;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=redis-control-plane.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-control-plane.d.ts","sourceRoot":"","sources":["../../../src/control-plane-redis/redis-control-plane.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhE;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,WAAW;IAC1B,+EAA+E;IAC/E,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IACnD;;;OAGG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC;IAC1F,iGAAiG;IACjG,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC;IACrF,oGAAoG;IACpG,SAAS,CAAC,IAAI,WAAW,CAAC;IAC1B,oEAAoE;IACpE,UAAU,CAAC,IAAI,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,+EAA+E;IAC/E,UAAU,EAAE,WAAW,CAAC;IACxB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,iBAAkB,YAAW,YAAY;IACpD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAc;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,UAAU,CAAS;gBAEf,OAAO,EAAE,wBAAwB;IAKvC,cAAc,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxD,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,IAAI;IA0BvD,2FAA2F;IACrF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A {@link ControlPlane} backed by Redis pub/sub: the cross-pod broadcast channel for workflow
|
|
3
|
+
* **lifecycle events** (so a dashboard-only pod can live-tail a run executing on a worker pod) and
|
|
4
|
+
* **cancellation** (so the pod actually running a run learns it was cancelled elsewhere).
|
|
5
|
+
*
|
|
6
|
+
* This is purely out-of-band signalling — it carries NO replay/determinism weight; the engine
|
|
7
|
+
* already dedupes self-broadcasts by `msg.from`, so a publish Redis echoes back to its own subscriber
|
|
8
|
+
* is ignored. Omit a control plane entirely and the engine is local-only (single instance).
|
|
9
|
+
*
|
|
10
|
+
* The channel name (`` `${prefix}-control` ``) and the JSON payload match the NestJS BullMQ
|
|
11
|
+
* transport, so a mixed AdonisJS + NestJS fleet on one Redis fans out across both runtimes.
|
|
12
|
+
*/
|
|
13
|
+
export class RedisControlPlane {
|
|
14
|
+
connection;
|
|
15
|
+
channel;
|
|
16
|
+
subscriber;
|
|
17
|
+
subscribed = false;
|
|
18
|
+
constructor(options) {
|
|
19
|
+
this.connection = options.connection;
|
|
20
|
+
this.channel = `${options.prefix ?? 'durable'}-control`;
|
|
21
|
+
}
|
|
22
|
+
async publishControl(msg) {
|
|
23
|
+
await this.connection.publish(this.channel, JSON.stringify(msg));
|
|
24
|
+
}
|
|
25
|
+
onControl(handler) {
|
|
26
|
+
if (this.subscribed)
|
|
27
|
+
return; // one subscription per control plane
|
|
28
|
+
this.subscribed = true;
|
|
29
|
+
const deliver = (payload) => {
|
|
30
|
+
let msg;
|
|
31
|
+
try {
|
|
32
|
+
msg = JSON.parse(payload);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return; // swallow malformed payloads — a control message must never crash the engine
|
|
36
|
+
}
|
|
37
|
+
handler(msg);
|
|
38
|
+
};
|
|
39
|
+
if (typeof this.connection.duplicate === 'function') {
|
|
40
|
+
// raw ioredis: a subscriber connection can't run normal commands → use a dedicated dup.
|
|
41
|
+
const sub = this.connection.duplicate();
|
|
42
|
+
this.subscriber = sub;
|
|
43
|
+
void sub.subscribe(this.channel);
|
|
44
|
+
sub.on?.('message', (_channel, payload) => deliver(payload));
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
// `@adonisjs/redis` connection: manages its own subscriber connection; handler gets the message.
|
|
48
|
+
void this.connection.subscribe(this.channel, (payload) => deliver(payload));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/** Tear down the dedicated subscriber connection, if one was duplicated (ioredis path). */
|
|
52
|
+
async close() {
|
|
53
|
+
this.subscriber?.disconnect?.();
|
|
54
|
+
this.subscriber = undefined;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=redis-control-plane.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-control-plane.js","sourceRoot":"","sources":["../../../src/control-plane-redis/redis-control-plane.ts"],"names":[],"mappings":"AA2CA;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,iBAAiB;IACX,UAAU,CAAc;IACxB,OAAO,CAAS;IACzB,UAAU,CAA0B;IACpC,UAAU,GAAG,KAAK,CAAC;IAE3B,YAAY,OAAiC;QAC3C,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACrC,IAAI,CAAC,OAAO,GAAG,GAAG,OAAO,CAAC,MAAM,IAAI,SAAS,UAAU,CAAC;IAC1D,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,GAAmB;QACtC,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,SAAS,CAAC,OAAsC;QAC9C,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO,CAAC,qCAAqC;QAClE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QAEvB,MAAM,OAAO,GAAG,CAAC,OAAe,EAAE,EAAE;YAClC,IAAI,GAAmB,CAAC;YACxB,IAAI,CAAC;gBACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAmB,CAAC;YAC9C,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,CAAC,6EAA6E;YACvF,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,CAAC;QACf,CAAC,CAAC;QAEF,IAAI,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,KAAK,UAAU,EAAE,CAAC;YACpD,wFAAwF;YACxF,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC;YACxC,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;YACtB,KAAK,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACjC,GAAG,CAAC,EAAE,EAAE,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QAC/D,CAAC;aAAM,CAAC;YACN,iGAAiG;YACjG,KAAK,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IAED,2FAA2F;IAC3F,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,UAAU,EAAE,UAAU,EAAE,EAAE,CAAC;QAChC,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;IAC9B,CAAC;CACF"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { ControlPlane } from '../interfaces.js';
|
|
2
|
+
/**
|
|
3
|
+
* The minimal application surface a {@link ControlPlaneFactory} thunk needs at boot to resolve an
|
|
4
|
+
* optional peer's service (an `@adonisjs/redis` connection). The durable provider passes the booted
|
|
5
|
+
* `ApplicationService`, which satisfies this structurally — typed here so core stays free of a hard
|
|
6
|
+
* `@adonisjs/core` dependency. Mirrors `TransportContext` / `StoreContext`.
|
|
7
|
+
*/
|
|
8
|
+
export interface ControlPlaneContext {
|
|
9
|
+
/** The booted application — used to resolve services/connections from the container. */
|
|
10
|
+
app: {
|
|
11
|
+
container: {
|
|
12
|
+
make(service: unknown): Promise<unknown>;
|
|
13
|
+
};
|
|
14
|
+
config: {
|
|
15
|
+
get<T>(key: string, defaultValue?: T): T;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A configured control plane: a thunk the durable provider calls at boot to build the
|
|
21
|
+
* {@link ControlPlane}. The factory lazily imports its peer dependency (`@adonisjs/redis`) inside the
|
|
22
|
+
* thunk, so the driver is only loaded when it is actually selected — keeping that package optional.
|
|
23
|
+
*/
|
|
24
|
+
export type ControlPlaneFactory = (ctx: ControlPlaneContext) => Promise<ControlPlane>;
|
|
25
|
+
/** Options for the Redis pub/sub control plane (`@adonisjs/redis`). */
|
|
26
|
+
export interface RedisControlPlaneConfig {
|
|
27
|
+
/**
|
|
28
|
+
* Name of the `@adonisjs/redis` connection — a key of the `connections` map in `config/redis.ts` —
|
|
29
|
+
* whose pub/sub this control plane broadcasts over. Defaults to `'main'`. You configure the host /
|
|
30
|
+
* credentials once in `config/redis.ts`; durable just references it by name.
|
|
31
|
+
*/
|
|
32
|
+
connection?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Channel prefix. Defaults to `durable`; the channel is `` `${prefix}-control` ``, matched exactly
|
|
35
|
+
* to the NestJS BullMQ transport so an AdonisJS fleet interoperates with a NestJS fleet on one Redis.
|
|
36
|
+
*/
|
|
37
|
+
prefix?: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The control-plane factory namespace used in `config/durable.ts`:
|
|
41
|
+
*
|
|
42
|
+
* ```ts
|
|
43
|
+
* import { defineConfig, transports, controlPlanes } from '@adonis-agora/durable'
|
|
44
|
+
*
|
|
45
|
+
* export default defineConfig({
|
|
46
|
+
* transport: 'queue',
|
|
47
|
+
* transports: { queue: transports.queue({ connection: 'redis', group: 'workers' }) },
|
|
48
|
+
* // Fan out lifecycle events + cancellation across every replica over Redis pub/sub.
|
|
49
|
+
* controlPlane: controlPlanes.redis({ connection: 'main' }),
|
|
50
|
+
* })
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* Each factory returns a {@link ControlPlaneFactory} — a lazy thunk. Calling it in the config file
|
|
54
|
+
* costs nothing; the peer dependency is only imported when the provider builds it at boot. Omit
|
|
55
|
+
* `controlPlane` entirely and the engine is local-only (single instance).
|
|
56
|
+
*/
|
|
57
|
+
export declare const controlPlanes: {
|
|
58
|
+
/**
|
|
59
|
+
* Broadcast lifecycle events + cancellation across every replica over `@adonisjs/redis` pub/sub,
|
|
60
|
+
* using a connection from `config/redis.ts`. Interoperates with a NestJS fleet on the same Redis
|
|
61
|
+
* via the shared `` `${prefix}-control` `` channel.
|
|
62
|
+
*/
|
|
63
|
+
redis(config?: RedisControlPlaneConfig): ControlPlaneFactory;
|
|
64
|
+
};
|
|
65
|
+
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/control-planes/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,wFAAwF;IACxF,GAAG,EAAE;QACH,SAAS,EAAE;YAAE,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;SAAE,CAAC;QACxD,MAAM,EAAE;YAAE,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;SAAE,CAAC;KACtD,CAAC;CACH;AAED;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,GAAG,EAAE,mBAAmB,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;AAEtF,uEAAuE;AACvE,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAOD;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,aAAa;IACxB;;;;OAIG;mBACW,uBAAuB,GAAQ,mBAAmB;CAWjE,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The control-plane factory namespace used in `config/durable.ts`:
|
|
3
|
+
*
|
|
4
|
+
* ```ts
|
|
5
|
+
* import { defineConfig, transports, controlPlanes } from '@adonis-agora/durable'
|
|
6
|
+
*
|
|
7
|
+
* export default defineConfig({
|
|
8
|
+
* transport: 'queue',
|
|
9
|
+
* transports: { queue: transports.queue({ connection: 'redis', group: 'workers' }) },
|
|
10
|
+
* // Fan out lifecycle events + cancellation across every replica over Redis pub/sub.
|
|
11
|
+
* controlPlane: controlPlanes.redis({ connection: 'main' }),
|
|
12
|
+
* })
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* Each factory returns a {@link ControlPlaneFactory} — a lazy thunk. Calling it in the config file
|
|
16
|
+
* costs nothing; the peer dependency is only imported when the provider builds it at boot. Omit
|
|
17
|
+
* `controlPlane` entirely and the engine is local-only (single instance).
|
|
18
|
+
*/
|
|
19
|
+
export const controlPlanes = {
|
|
20
|
+
/**
|
|
21
|
+
* Broadcast lifecycle events + cancellation across every replica over `@adonisjs/redis` pub/sub,
|
|
22
|
+
* using a connection from `config/redis.ts`. Interoperates with a NestJS fleet on the same Redis
|
|
23
|
+
* via the shared `` `${prefix}-control` `` channel.
|
|
24
|
+
*/
|
|
25
|
+
redis(config = {}) {
|
|
26
|
+
return async () => {
|
|
27
|
+
const { RedisControlPlane } = await import('../control-plane-redis/redis-control-plane.js');
|
|
28
|
+
const redis = (await import('@adonisjs/redis/services/main')).default;
|
|
29
|
+
const connection = redis.connection(config.connection ?? 'main');
|
|
30
|
+
return new RedisControlPlane({
|
|
31
|
+
connection,
|
|
32
|
+
...(config.prefix !== undefined ? { prefix: config.prefix } : {}),
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../src/control-planes/factory.ts"],"names":[],"mappings":"AA2CA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B;;;;OAIG;IACH,KAAK,CAAC,SAAkC,EAAE;QACxC,OAAO,KAAK,IAAI,EAAE;YAChB,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,+CAA+C,CAAC,CAAC;YAC5F,MAAM,KAAK,GAAG,CAAC,MAAM,MAAM,CAAC,+BAA+B,CAAC,CAAC,CAAC,OAA2B,CAAC;YAC1F,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,CAAU,CAAC;YAC1E,OAAO,IAAI,iBAAiB,CAAC;gBAC3B,UAAU;gBACV,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAClE,CAAC,CAAC;QACL,CAAC,CAAC;IACJ,CAAC;CACF,CAAC"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { controlPlanes } from './control-planes/factory.js';
|
|
2
|
+
import type { ControlPlaneContext, ControlPlaneFactory, RedisControlPlaneConfig } from './control-planes/factory.js';
|
|
1
3
|
import type { ControlPlane, RunDispatcher } from './interfaces.js';
|
|
2
4
|
import type { ScheduledWorkflow } from './scheduler.js';
|
|
3
5
|
import { stores } from './stores/factory.js';
|
|
@@ -44,8 +46,13 @@ export interface DurableConfig {
|
|
|
44
46
|
store?: string;
|
|
45
47
|
/** Named state stores, built with the {@link stores} factory. */
|
|
46
48
|
stores?: Record<string, StoreFactory>;
|
|
47
|
-
/**
|
|
48
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Cross-instance broadcast for lifecycle events + cancellation. Omit for single-instance. Either a
|
|
51
|
+
* ready {@link ControlPlane} instance, or a {@link ControlPlaneFactory} built with the
|
|
52
|
+
* {@link controlPlanes} factory (e.g. `controlPlanes.redis({ connection: 'main' })`) so the peer
|
|
53
|
+
* dependency (`@adonisjs/redis`) is imported lazily, only when selected.
|
|
54
|
+
*/
|
|
55
|
+
controlPlane?: ControlPlane | ControlPlaneFactory;
|
|
49
56
|
/** Recovery lease duration in ms. Default 30s. */
|
|
50
57
|
leaseMs?: number;
|
|
51
58
|
/** Unique id for this engine instance. Defaults to a random id. */
|
|
@@ -67,6 +74,6 @@ export interface DurableConfig {
|
|
|
67
74
|
}
|
|
68
75
|
/** Identity helper giving `config/durable.ts` full type-checking. */
|
|
69
76
|
export declare function defineConfig(config?: DurableConfig): DurableConfig;
|
|
70
|
-
export { transports, stores };
|
|
71
|
-
export type { TransportContext, TransportFactory, MemoryTransportConfig, QueueTransportConfig, DbTransportConfig, StoreContext, StoreFactory, LucidStoreConfig, };
|
|
77
|
+
export { transports, stores, controlPlanes };
|
|
78
|
+
export type { TransportContext, TransportFactory, MemoryTransportConfig, QueueTransportConfig, DbTransportConfig, StoreContext, StoreFactory, LucidStoreConfig, ControlPlaneContext, ControlPlaneFactory, RedisControlPlaneConfig, };
|
|
72
79
|
//# sourceMappingURL=define_config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define_config.d.ts","sourceRoot":"","sources":["../../src/define_config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,KAAK,EACV,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC9C;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACtC
|
|
1
|
+
{"version":3,"file":"define_config.d.ts","sourceRoot":"","sources":["../../src/define_config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,KAAK,EACV,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC9C;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACtC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,YAAY,GAAG,mBAAmB,CAAC;IAClD,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yFAAyF;IACzF,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,gEAAgE;IAChE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,gFAAgF;IAChF,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,iBAAiB,EAAE,CAAC;CACjC;AAED,qEAAqE;AACrE,wBAAgB,YAAY,CAAC,MAAM,GAAE,aAAkB,GAAG,aAAa,CAEtE;AAED,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;AAC7C,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,GACxB,CAAC"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { controlPlanes } from './control-planes/factory.js';
|
|
1
2
|
import { stores } from './stores/factory.js';
|
|
2
3
|
import { transports } from './transports/factory.js';
|
|
3
4
|
/** Identity helper giving `config/durable.ts` full type-checking. */
|
|
4
5
|
export function defineConfig(config = {}) {
|
|
5
6
|
return config;
|
|
6
7
|
}
|
|
7
|
-
export { transports, stores };
|
|
8
|
+
export { transports, stores, controlPlanes };
|
|
8
9
|
//# sourceMappingURL=define_config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define_config.js","sourceRoot":"","sources":["../../src/define_config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"define_config.js","sourceRoot":"","sources":["../../src/define_config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAQ5D,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AA4ErD,qEAAqE;AACrE,MAAM,UAAU,YAAY,CAAC,SAAwB,EAAE;IACrD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC"}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -31,6 +31,9 @@ export { stores } from './stores/factory.js';
|
|
|
31
31
|
export type { StoreContext, StoreFactory, LucidStoreConfig } from './stores/factory.js';
|
|
32
32
|
export { LucidStateStore, type LucidStateStoreOptions } from './stores/lucid.js';
|
|
33
33
|
export { DURABLE_TABLES, createDurableTables, dropDurableTables } from './stores/lucid-schema.js';
|
|
34
|
+
export { controlPlanes } from './control-planes/factory.js';
|
|
35
|
+
export type { ControlPlaneContext, ControlPlaneFactory, RedisControlPlaneConfig, } from './control-planes/factory.js';
|
|
36
|
+
export { RedisControlPlane, type RedisControlPlaneOptions, type RedisPubSub, } from './control-plane-redis/redis-control-plane.js';
|
|
34
37
|
export { defineConfig } from './define_config.js';
|
|
35
38
|
export type { DurableConfig } from './define_config.js';
|
|
36
39
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAGrE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EACL,gBAAgB,EAChB,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAGlG,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAGrE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EACL,gBAAgB,EAChB,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAGlG,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,YAAY,EACV,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,WAAW,GACjB,MAAM,8CAA8C,CAAC;AAGtD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/src/index.js
CHANGED
|
@@ -32,6 +32,9 @@ export { TRANSPORT_TABLES, createDurableTransportTables, dropDurableTransportTab
|
|
|
32
32
|
export { stores } from './stores/factory.js';
|
|
33
33
|
export { LucidStateStore } from './stores/lucid.js';
|
|
34
34
|
export { DURABLE_TABLES, createDurableTables, dropDurableTables } from './stores/lucid-schema.js';
|
|
35
|
+
// --- config-driven control-plane drivers ------------------------------------
|
|
36
|
+
export { controlPlanes } from './control-planes/factory.js';
|
|
37
|
+
export { RedisControlPlane, } from './control-plane-redis/redis-control-plane.js';
|
|
35
38
|
// --- AdonisJS integration ---------------------------------------------------
|
|
36
39
|
export { defineConfig } from './define_config.js';
|
|
37
40
|
//# sourceMappingURL=index.js.map
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,+EAA+E;AAC/E,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAErE,+EAA+E;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAQrD,OAAO,EAAE,cAAc,EAA8B,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,WAAW,EAA2B,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EACL,gBAAgB,EAChB,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,2BAA2B,CAAC;AAEnC,+EAA+E;AAC/E,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,OAAO,EAAE,eAAe,EAA+B,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElG,+EAA+E;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,+EAA+E;AAC/E,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAErE,+EAA+E;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAQrD,OAAO,EAAE,cAAc,EAA8B,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,WAAW,EAA2B,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EACL,gBAAgB,EAChB,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,2BAA2B,CAAC;AAEnC,+EAA+E;AAC/E,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,OAAO,EAAE,eAAe,EAA+B,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElG,+EAA+E;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAM5D,OAAO,EACL,iBAAiB,GAGlB,MAAM,8CAA8C,CAAC;AAEtD,+EAA+E;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adonis-agora/durable",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Durable cross-app workflows for AdonisJS — deterministic replay engine, AdonisJS binding, ace commands, dashboard, OpenTelemetry, Telescope, testing harness and Redis admission, all in one package. Part of the Agora ecosystem.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -58,6 +58,11 @@
|
|
|
58
58
|
"import": "./dist/src/admission-redis/index.js",
|
|
59
59
|
"default": "./dist/src/admission-redis/index.js"
|
|
60
60
|
},
|
|
61
|
+
"./control-plane-redis": {
|
|
62
|
+
"types": "./dist/src/control-plane-redis/index.d.ts",
|
|
63
|
+
"import": "./dist/src/control-plane-redis/index.js",
|
|
64
|
+
"default": "./dist/src/control-plane-redis/index.js"
|
|
65
|
+
},
|
|
61
66
|
"./commands": {
|
|
62
67
|
"types": "./dist/commands/main.d.ts",
|
|
63
68
|
"import": "./dist/commands/main.js",
|
|
@@ -79,10 +84,10 @@
|
|
|
79
84
|
"zod": "^3.23.0"
|
|
80
85
|
},
|
|
81
86
|
"peerDependencies": {
|
|
82
|
-
"@adonisjs/core": "^
|
|
83
|
-
"@adonisjs/lucid": "^
|
|
87
|
+
"@adonisjs/core": "^7.3.0",
|
|
88
|
+
"@adonisjs/lucid": "^22.4.0",
|
|
84
89
|
"@adonisjs/queue": "^0.6.0",
|
|
85
|
-
"@adonisjs/redis": "^9.
|
|
90
|
+
"@adonisjs/redis": "^9.2.0",
|
|
86
91
|
"@opentelemetry/api": "^1.0.0",
|
|
87
92
|
"cron-parser": "^4.0.0 || ^5.0.0",
|
|
88
93
|
"ioredis": "^5.0.0",
|
|
@@ -112,11 +117,11 @@
|
|
|
112
117
|
}
|
|
113
118
|
},
|
|
114
119
|
"devDependencies": {
|
|
115
|
-
"@adonisjs/assembler": "^
|
|
116
|
-
"@adonisjs/core": "^
|
|
117
|
-
"@adonisjs/lucid": "^
|
|
120
|
+
"@adonisjs/assembler": "^8.4.0",
|
|
121
|
+
"@adonisjs/core": "^7.3.0",
|
|
122
|
+
"@adonisjs/lucid": "^22.4.0",
|
|
118
123
|
"@adonisjs/queue": "^0.6.1",
|
|
119
|
-
"@adonisjs/redis": "^9.
|
|
124
|
+
"@adonisjs/redis": "^9.2.0",
|
|
120
125
|
"@opentelemetry/api": "^1.9.0",
|
|
121
126
|
"@opentelemetry/context-async-hooks": "^1.30.0",
|
|
122
127
|
"@opentelemetry/sdk-trace-base": "^1.30.0",
|