@furystack/cross-node-bus 1.0.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 +78 -0
- package/README.md +49 -0
- package/esm/cross-node-bus-telemetry.d.ts +74 -0
- package/esm/cross-node-bus-telemetry.d.ts.map +1 -0
- package/esm/cross-node-bus-telemetry.js +28 -0
- package/esm/cross-node-bus-telemetry.js.map +1 -0
- package/esm/cross-node-bus-telemetry.spec.d.ts +2 -0
- package/esm/cross-node-bus-telemetry.spec.d.ts.map +1 -0
- package/esm/cross-node-bus-telemetry.spec.js +115 -0
- package/esm/cross-node-bus-telemetry.spec.js.map +1 -0
- package/esm/cross-node-bus.d.ts +78 -0
- package/esm/cross-node-bus.d.ts.map +1 -0
- package/esm/cross-node-bus.js +18 -0
- package/esm/cross-node-bus.js.map +1 -0
- package/esm/cross-node-bus.spec.d.ts +2 -0
- package/esm/cross-node-bus.spec.d.ts.map +1 -0
- package/esm/cross-node-bus.spec.js +123 -0
- package/esm/cross-node-bus.spec.js.map +1 -0
- package/esm/define-in-process-cross-node-bus.d.ts +26 -0
- package/esm/define-in-process-cross-node-bus.d.ts.map +1 -0
- package/esm/define-in-process-cross-node-bus.js +27 -0
- package/esm/define-in-process-cross-node-bus.js.map +1 -0
- package/esm/errors.d.ts +21 -0
- package/esm/errors.d.ts.map +1 -0
- package/esm/errors.js +30 -0
- package/esm/errors.js.map +1 -0
- package/esm/errors.spec.d.ts +2 -0
- package/esm/errors.spec.d.ts.map +1 -0
- package/esm/errors.spec.js +30 -0
- package/esm/errors.spec.js.map +1 -0
- package/esm/in-process-cross-node-bus.d.ts +58 -0
- package/esm/in-process-cross-node-bus.d.ts.map +1 -0
- package/esm/in-process-cross-node-bus.js +196 -0
- package/esm/in-process-cross-node-bus.js.map +1 -0
- package/esm/in-process-cross-node-bus.spec.d.ts +2 -0
- package/esm/in-process-cross-node-bus.spec.d.ts.map +1 -0
- package/esm/in-process-cross-node-bus.spec.js +737 -0
- package/esm/in-process-cross-node-bus.spec.js.map +1 -0
- package/esm/index.d.ts +8 -0
- package/esm/index.d.ts.map +1 -0
- package/esm/index.js +7 -0
- package/esm/index.js.map +1 -0
- package/esm/memory-broker.d.ts +74 -0
- package/esm/memory-broker.d.ts.map +1 -0
- package/esm/memory-broker.js +156 -0
- package/esm/memory-broker.js.map +1 -0
- package/esm/memory-broker.spec.d.ts +2 -0
- package/esm/memory-broker.spec.d.ts.map +1 -0
- package/esm/memory-broker.spec.js +497 -0
- package/esm/memory-broker.spec.js.map +1 -0
- package/esm/testing/create-in-process-bus-network.d.ts +49 -0
- package/esm/testing/create-in-process-bus-network.d.ts.map +1 -0
- package/esm/testing/create-in-process-bus-network.js +54 -0
- package/esm/testing/create-in-process-bus-network.js.map +1 -0
- package/esm/testing/create-in-process-bus-network.spec.d.ts +2 -0
- package/esm/testing/create-in-process-bus-network.spec.d.ts.map +1 -0
- package/esm/testing/create-in-process-bus-network.spec.js +142 -0
- package/esm/testing/create-in-process-bus-network.spec.js.map +1 -0
- package/esm/testing/index.d.ts +2 -0
- package/esm/testing/index.d.ts.map +1 -0
- package/esm/testing/index.js +2 -0
- package/esm/testing/index.js.map +1 -0
- package/esm/types.d.ts +35 -0
- package/esm/types.d.ts.map +1 -0
- package/esm/types.js +2 -0
- package/esm/types.js.map +1 -0
- package/package.json +56 -0
- package/src/cross-node-bus-telemetry.spec.ts +44 -0
- package/src/cross-node-bus-telemetry.ts +69 -0
- package/src/cross-node-bus.spec.ts +41 -0
- package/src/cross-node-bus.ts +92 -0
- package/src/define-in-process-cross-node-bus.ts +38 -0
- package/src/errors.spec.ts +32 -0
- package/src/errors.ts +38 -0
- package/src/in-process-cross-node-bus.spec.ts +428 -0
- package/src/in-process-cross-node-bus.ts +248 -0
- package/src/index.ts +7 -0
- package/src/memory-broker.spec.ts +282 -0
- package/src/memory-broker.ts +199 -0
- package/src/testing/create-in-process-bus-network.spec.ts +73 -0
- package/src/testing/create-in-process-bus-network.ts +87 -0
- package/src/testing/index.ts +1 -0
- package/src/types.ts +35 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { CrossNodeBusTelemetryToken } from './cross-node-bus-telemetry.js';
|
|
2
|
+
import { InProcessCrossNodeBus } from './in-process-cross-node-bus.js';
|
|
3
|
+
/**
|
|
4
|
+
* Returns a {@link ServiceFactory} bound to {@link CrossNodeBus}. Use it to
|
|
5
|
+
* override the default factory at boot:
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* injector.bind(
|
|
9
|
+
* CrossNodeBus,
|
|
10
|
+
* defineInProcessCrossNodeBus({ topicPrefix: 'svc-a/' }),
|
|
11
|
+
* )
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* Mirrors the `defineXxxCrossNodeBusAdapter` shape future transport
|
|
15
|
+
* adapters expose. Wires telemetry and disposal into the surrounding
|
|
16
|
+
* injector scope.
|
|
17
|
+
*/
|
|
18
|
+
export const defineInProcessCrossNodeBus = (options = {}) => {
|
|
19
|
+
return ({ inject, onDispose }) => {
|
|
20
|
+
const telemetry = inject(CrossNodeBusTelemetryToken);
|
|
21
|
+
const bus = new InProcessCrossNodeBus({ ...options, telemetry });
|
|
22
|
+
// eslint-disable-next-line furystack/prefer-using-wrapper -- delegated to onDispose
|
|
23
|
+
onDispose(() => bus[Symbol.dispose]());
|
|
24
|
+
return bus;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=define-in-process-cross-node-bus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-in-process-cross-node-bus.js","sourceRoot":"","sources":["../src/define-in-process-cross-node-bus.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAA;AAC1E,OAAO,EAAE,qBAAqB,EAAqC,MAAM,gCAAgC,CAAA;AAUzG;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CACzC,UAA8C,EAAE,EAClB,EAAE;IAChC,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE;QAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,0BAA0B,CAAC,CAAA;QACpD,MAAM,GAAG,GAAG,IAAI,qBAAqB,CAAC,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,CAAC,CAAA;QAChE,oFAAoF;QACpF,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACtC,OAAO,GAAG,CAAA;IACZ,CAAC,CAAA;AACH,CAAC,CAAA"}
|
package/esm/errors.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CrossNodeBusCapabilities } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Thrown synchronously by {@link CrossNodeBus.replay} when `fromSeq` falls
|
|
4
|
+
* outside the adapter's retained window. Facades catch this and fall back
|
|
5
|
+
* to a full-snapshot path.
|
|
6
|
+
*/
|
|
7
|
+
export declare class ReplayWindowExceededError extends Error {
|
|
8
|
+
readonly topic: string;
|
|
9
|
+
readonly fromSeq: string;
|
|
10
|
+
readonly oldestRetainedSeq: string | undefined;
|
|
11
|
+
constructor(topic: string, fromSeq: string, oldestRetainedSeq: string | undefined);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Thrown synchronously by an adapter when a caller invokes a method that
|
|
15
|
+
* requires a capability the adapter does not advertise.
|
|
16
|
+
*/
|
|
17
|
+
export declare class UnsupportedCapabilityError extends Error {
|
|
18
|
+
readonly capability: keyof CrossNodeBusCapabilities;
|
|
19
|
+
constructor(capability: keyof CrossNodeBusCapabilities);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAA;AAE1D;;;;GAIG;AACH,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,SAAgB,KAAK,EAAE,MAAM,CAAA;IAC7B,SAAgB,OAAO,EAAE,MAAM,CAAA;IAC/B,SAAgB,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAA;gBAEzC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,SAAS;CAWlF;AAED;;;GAGG;AACH,qBAAa,0BAA2B,SAAQ,KAAK;IACnD,SAAgB,UAAU,EAAE,MAAM,wBAAwB,CAAA;gBAE9C,UAAU,EAAE,MAAM,wBAAwB;CAKvD"}
|
package/esm/errors.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thrown synchronously by {@link CrossNodeBus.replay} when `fromSeq` falls
|
|
3
|
+
* outside the adapter's retained window. Facades catch this and fall back
|
|
4
|
+
* to a full-snapshot path.
|
|
5
|
+
*/
|
|
6
|
+
export class ReplayWindowExceededError extends Error {
|
|
7
|
+
topic;
|
|
8
|
+
fromSeq;
|
|
9
|
+
oldestRetainedSeq;
|
|
10
|
+
constructor(topic, fromSeq, oldestRetainedSeq) {
|
|
11
|
+
super(`Replay window exceeded for topic "${topic}": requested fromSeq=${fromSeq}, oldest retained=${oldestRetainedSeq ?? 'none'}`);
|
|
12
|
+
this.name = 'ReplayWindowExceededError';
|
|
13
|
+
this.topic = topic;
|
|
14
|
+
this.fromSeq = fromSeq;
|
|
15
|
+
this.oldestRetainedSeq = oldestRetainedSeq;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Thrown synchronously by an adapter when a caller invokes a method that
|
|
20
|
+
* requires a capability the adapter does not advertise.
|
|
21
|
+
*/
|
|
22
|
+
export class UnsupportedCapabilityError extends Error {
|
|
23
|
+
capability;
|
|
24
|
+
constructor(capability) {
|
|
25
|
+
super(`Adapter does not support capability: ${capability}`);
|
|
26
|
+
this.name = 'UnsupportedCapabilityError';
|
|
27
|
+
this.capability = capability;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,OAAO,yBAA0B,SAAQ,KAAK;IAClC,KAAK,CAAQ;IACb,OAAO,CAAQ;IACf,iBAAiB,CAAoB;IAErD,YAAY,KAAa,EAAE,OAAe,EAAE,iBAAqC;QAC/E,KAAK,CACH,qCAAqC,KAAK,wBAAwB,OAAO,qBACvE,iBAAiB,IAAI,MACvB,EAAE,CACH,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAA;QACvC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAA;IAC5C,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IACnC,UAAU,CAAgC;IAE1D,YAAY,UAA0C;QACpD,KAAK,CAAC,wCAAwC,UAAU,EAAE,CAAC,CAAA;QAC3D,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAA;QACxC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;IAC9B,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.spec.d.ts","sourceRoot":"","sources":["../src/errors.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { ReplayWindowExceededError, UnsupportedCapabilityError } from './errors.js';
|
|
3
|
+
describe('errors', () => {
|
|
4
|
+
describe('ReplayWindowExceededError', () => {
|
|
5
|
+
it('captures the topic, fromSeq and oldestRetainedSeq', () => {
|
|
6
|
+
const error = new ReplayWindowExceededError('topic', '5', '7');
|
|
7
|
+
expect(error.name).toBe('ReplayWindowExceededError');
|
|
8
|
+
expect(error.topic).toBe('topic');
|
|
9
|
+
expect(error.fromSeq).toBe('5');
|
|
10
|
+
expect(error.oldestRetainedSeq).toBe('7');
|
|
11
|
+
expect(error.message).toContain('topic');
|
|
12
|
+
expect(error.message).toContain('5');
|
|
13
|
+
expect(error.message).toContain('7');
|
|
14
|
+
});
|
|
15
|
+
it('reports "none" when no messages are retained', () => {
|
|
16
|
+
const error = new ReplayWindowExceededError('topic', '5', undefined);
|
|
17
|
+
expect(error.oldestRetainedSeq).toBeUndefined();
|
|
18
|
+
expect(error.message).toContain('none');
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
describe('UnsupportedCapabilityError', () => {
|
|
22
|
+
it('captures the missing capability name', () => {
|
|
23
|
+
const error = new UnsupportedCapabilityError('replay');
|
|
24
|
+
expect(error.name).toBe('UnsupportedCapabilityError');
|
|
25
|
+
expect(error.capability).toBe('replay');
|
|
26
|
+
expect(error.message).toContain('replay');
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
//# sourceMappingURL=errors.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.spec.js","sourceRoot":"","sources":["../src/errors.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAA;AAEnF,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;IACtB,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACzC,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;YAC3D,MAAM,KAAK,GAAG,IAAI,yBAAyB,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;YAC9D,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAA;YACpD,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACjC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAC/B,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YACzC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;YACxC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;YACpC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QACtC,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACtD,MAAM,KAAK,GAAG,IAAI,yBAAyB,CAAC,OAAO,EAAE,GAAG,EAAE,SAAS,CAAC,CAAA;YACpE,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,aAAa,EAAE,CAAA;YAC/C,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;QACzC,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;QAC1C,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;YAC9C,MAAM,KAAK,GAAG,IAAI,0BAA0B,CAAC,QAAQ,CAAC,CAAA;YACtD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAA;YACrD,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YACvC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;QAC3C,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { CrossNodeBusTelemetry } from './cross-node-bus-telemetry.js';
|
|
2
|
+
import { MemoryBroker } from './memory-broker.js';
|
|
3
|
+
import type { CrossNodeBus } from './cross-node-bus.js';
|
|
4
|
+
import type { BusMessage, CrossNodeBusCapabilities } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Options accepted by {@link InProcessCrossNodeBus}.
|
|
7
|
+
*/
|
|
8
|
+
export type InProcessCrossNodeBusOptions = {
|
|
9
|
+
/**
|
|
10
|
+
* Shared {@link MemoryBroker}. When omitted a private broker is minted —
|
|
11
|
+
* single-instance behavior matches an isolated EventHub. The testing
|
|
12
|
+
* harness passes the same broker to N buses so they can observe each
|
|
13
|
+
* other's publishes without an external transport.
|
|
14
|
+
*/
|
|
15
|
+
broker?: MemoryBroker;
|
|
16
|
+
/** Stable, per-process identifier. Defaults to `local-${crypto.randomUUID()}`. */
|
|
17
|
+
nodeId?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Wire-level prefix applied to every topic on `publish` / `subscribe`.
|
|
20
|
+
* Defaults to `''` (no prefix). Multi-service simulations pick distinct
|
|
21
|
+
* prefixes per bus so cross-service eavesdrop can be exercised against a
|
|
22
|
+
* single shared broker.
|
|
23
|
+
*/
|
|
24
|
+
topicPrefix?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Convenience for the common case of "one bus, fresh private broker, this
|
|
27
|
+
* many retained messages per topic". Ignored when `broker` is provided.
|
|
28
|
+
*/
|
|
29
|
+
replayWindow?: number;
|
|
30
|
+
/** Sink for `onCrossNodePublished` / `onCrossNodeReceived` / `onCrossNodeError`. */
|
|
31
|
+
telemetry?: CrossNodeBusTelemetry;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* In-process default {@link CrossNodeBus} adapter. Backs single-node
|
|
35
|
+
* deployments out of the box and powers the multi-instance testing harness
|
|
36
|
+
* exposed at `@furystack/cross-node-bus/testing`.
|
|
37
|
+
*
|
|
38
|
+
* Local fan-out is multiplexed: regardless of how many handlers subscribe
|
|
39
|
+
* to a single wire topic, the bus opens exactly one broker subscription and
|
|
40
|
+
* dispatches arrivals to its own handler set. This keeps `onCrossNodeReceived`
|
|
41
|
+
* counting one event per arrival rather than per handler invocation, and
|
|
42
|
+
* mirrors the consumer-group shape future network adapters will use.
|
|
43
|
+
*/
|
|
44
|
+
export declare class InProcessCrossNodeBus implements CrossNodeBus {
|
|
45
|
+
#private;
|
|
46
|
+
readonly nodeId: string;
|
|
47
|
+
readonly capabilities: CrossNodeBusCapabilities;
|
|
48
|
+
constructor(options?: InProcessCrossNodeBusOptions);
|
|
49
|
+
publish(topic: string, payload: unknown): Promise<void>;
|
|
50
|
+
subscribe(topic: string, handler: (message: BusMessage) => void): Disposable;
|
|
51
|
+
subscribeRemoteOnly(topic: string, handler: (message: BusMessage) => void): Disposable;
|
|
52
|
+
subscribeForeign(prefix: string, topic: string, handler: (message: BusMessage) => void): Disposable;
|
|
53
|
+
replay(topic: string, fromSeq: string): AsyncIterable<BusMessage>;
|
|
54
|
+
compareSeq(a: string, b: string): number;
|
|
55
|
+
oldestSeq(topic: string): string | undefined;
|
|
56
|
+
[Symbol.dispose](): void;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=in-process-cross-node-bus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-process-cross-node-bus.d.ts","sourceRoot":"","sources":["../src/in-process-cross-node-bus.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAA;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAA;AAEtE;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC;;;;;OAKG;IACH,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,oFAAoF;IACpF,SAAS,CAAC,EAAE,qBAAqB,CAAA;CAClC,CAAA;AAcD;;;;;;;;;;GAUG;AACH,qBAAa,qBAAsB,YAAW,YAAY;;IACxD,SAAgB,MAAM,EAAE,MAAM,CAAA;IAC9B,SAAgB,YAAY,EAAE,wBAAwB,CAAe;gBAczD,OAAO,GAAE,4BAAiC;IAkBzC,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB7D,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,IAAI,GAAG,UAAU;IAK5E,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,IAAI,GAAG,UAAU;IAMtF,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,IAAI,GAAG,UAAU;IAKnG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,CAAC,UAAU,CAAC;IAUjE,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM;IAIxC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAK5C,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI;CAkGhC"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { MemoryBroker } from './memory-broker.js';
|
|
3
|
+
const CAPABILITIES = Object.freeze({
|
|
4
|
+
persistent: false,
|
|
5
|
+
replay: true,
|
|
6
|
+
assignsSequence: true,
|
|
7
|
+
});
|
|
8
|
+
/**
|
|
9
|
+
* In-process default {@link CrossNodeBus} adapter. Backs single-node
|
|
10
|
+
* deployments out of the box and powers the multi-instance testing harness
|
|
11
|
+
* exposed at `@furystack/cross-node-bus/testing`.
|
|
12
|
+
*
|
|
13
|
+
* Local fan-out is multiplexed: regardless of how many handlers subscribe
|
|
14
|
+
* to a single wire topic, the bus opens exactly one broker subscription and
|
|
15
|
+
* dispatches arrivals to its own handler set. This keeps `onCrossNodeReceived`
|
|
16
|
+
* counting one event per arrival rather than per handler invocation, and
|
|
17
|
+
* mirrors the consumer-group shape future network adapters will use.
|
|
18
|
+
*/
|
|
19
|
+
export class InProcessCrossNodeBus {
|
|
20
|
+
nodeId;
|
|
21
|
+
capabilities = CAPABILITIES;
|
|
22
|
+
#broker;
|
|
23
|
+
#ownsBroker;
|
|
24
|
+
#topicPrefix;
|
|
25
|
+
#telemetry;
|
|
26
|
+
/** displayTopic per wire topic — keyed by wire string for O(1) routing. */
|
|
27
|
+
#localHandlers = new Map();
|
|
28
|
+
/** Live broker subscription per wire topic, opened on first local handler. */
|
|
29
|
+
#brokerHandles = new Map();
|
|
30
|
+
#disposed = false;
|
|
31
|
+
constructor(options = {}) {
|
|
32
|
+
this.#ownsBroker = options.broker === undefined;
|
|
33
|
+
this.nodeId = options.nodeId ?? `local-${randomUUID()}`;
|
|
34
|
+
this.#topicPrefix = options.topicPrefix ?? '';
|
|
35
|
+
this.#telemetry = options.telemetry;
|
|
36
|
+
this.#broker =
|
|
37
|
+
options.broker ??
|
|
38
|
+
new MemoryBroker({
|
|
39
|
+
replayWindow: options.replayWindow,
|
|
40
|
+
onEviction: (wire, evictedSeq, retainedCount) => this.#telemetry?.emit('onCrossNodeWindowEvicted', {
|
|
41
|
+
topic: this.#displayTopicFor(wire),
|
|
42
|
+
evictedSeq,
|
|
43
|
+
retainedCount,
|
|
44
|
+
}),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
async publish(topic, payload) {
|
|
48
|
+
this.#ensureLive();
|
|
49
|
+
const wire = this.#wireTopic(topic);
|
|
50
|
+
let byteLength = 0;
|
|
51
|
+
if (this.#telemetry) {
|
|
52
|
+
try {
|
|
53
|
+
byteLength = Buffer.byteLength(JSON.stringify(payload) ?? '');
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
this.#telemetry.emit('onCrossNodeError', { topic, error, phase: 'serialize' });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
this.#broker.publish(wire, this.nodeId, payload, (error) => {
|
|
61
|
+
this.#telemetry?.emit('onCrossNodeError', { topic, error, phase: 'subscribe' });
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
this.#telemetry?.emit('onCrossNodeError', { topic, error, phase: 'publish' });
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
this.#telemetry?.emit('onCrossNodePublished', { topic, originId: this.nodeId, byteLength });
|
|
69
|
+
}
|
|
70
|
+
subscribe(topic, handler) {
|
|
71
|
+
this.#ensureLive();
|
|
72
|
+
return this.#subscribeWire(this.#wireTopic(topic), topic, handler, 'subscribe');
|
|
73
|
+
}
|
|
74
|
+
subscribeRemoteOnly(topic, handler) {
|
|
75
|
+
return this.subscribe(topic, (message) => {
|
|
76
|
+
if (message.originId !== this.nodeId)
|
|
77
|
+
handler(message);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
subscribeForeign(prefix, topic, handler) {
|
|
81
|
+
this.#ensureLive();
|
|
82
|
+
return this.#subscribeWire(`${prefix}${topic}`, topic, handler, 'subscribeForeign');
|
|
83
|
+
}
|
|
84
|
+
replay(topic, fromSeq) {
|
|
85
|
+
this.#ensureLive();
|
|
86
|
+
try {
|
|
87
|
+
return this.#broker.replay(this.#wireTopic(topic), fromSeq);
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
this.#telemetry?.emit('onCrossNodeError', { topic, error, phase: 'replay' });
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
compareSeq(a, b) {
|
|
95
|
+
return Number(a) - Number(b);
|
|
96
|
+
}
|
|
97
|
+
oldestSeq(topic) {
|
|
98
|
+
this.#ensureLive();
|
|
99
|
+
return this.#broker.oldestSeq(this.#wireTopic(topic));
|
|
100
|
+
}
|
|
101
|
+
[Symbol.dispose]() {
|
|
102
|
+
if (this.#disposed)
|
|
103
|
+
return;
|
|
104
|
+
this.#disposed = true;
|
|
105
|
+
for (const handle of this.#brokerHandles.values()) {
|
|
106
|
+
handle[Symbol.dispose]();
|
|
107
|
+
}
|
|
108
|
+
this.#brokerHandles.clear();
|
|
109
|
+
this.#localHandlers.clear();
|
|
110
|
+
if (this.#ownsBroker) {
|
|
111
|
+
this.#broker[Symbol.dispose]();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
#wireTopic(topic) {
|
|
115
|
+
return `${this.#topicPrefix}${topic}`;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Reverse-resolve the caller-facing display topic for a wire topic. When
|
|
119
|
+
* local handlers exist their displayTopic is authoritative — `subscribe`
|
|
120
|
+
* always yields `prefix+t` and `subscribeForeign` always yields `p+t`, so
|
|
121
|
+
* the first entry is representative. Falls back to the wire string when no
|
|
122
|
+
* subscriber on this bus has registered (publish-only buses never need to
|
|
123
|
+
* round-trip a display name; the wire is the most accurate label).
|
|
124
|
+
*/
|
|
125
|
+
#displayTopicFor(wire) {
|
|
126
|
+
const handlers = this.#localHandlers.get(wire);
|
|
127
|
+
if (!handlers)
|
|
128
|
+
return wire;
|
|
129
|
+
const first = handlers.values().next().value;
|
|
130
|
+
return first ? first.displayTopic : wire;
|
|
131
|
+
}
|
|
132
|
+
#subscribeWire(wire, displayTopic, handler, phase) {
|
|
133
|
+
const entry = { handler, displayTopic };
|
|
134
|
+
let handlers = this.#localHandlers.get(wire);
|
|
135
|
+
if (!handlers) {
|
|
136
|
+
handlers = new Set();
|
|
137
|
+
this.#localHandlers.set(wire, handlers);
|
|
138
|
+
try {
|
|
139
|
+
const brokerHandle = this.#broker.subscribe(wire, (message) => this.#deliver(wire, message));
|
|
140
|
+
this.#brokerHandles.set(wire, brokerHandle);
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
this.#localHandlers.delete(wire);
|
|
144
|
+
this.#telemetry?.emit('onCrossNodeError', { topic: displayTopic, error, phase });
|
|
145
|
+
throw error;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
handlers.add(entry);
|
|
149
|
+
return {
|
|
150
|
+
[Symbol.dispose]: () => {
|
|
151
|
+
const current = this.#localHandlers.get(wire);
|
|
152
|
+
if (!current)
|
|
153
|
+
return;
|
|
154
|
+
current.delete(entry);
|
|
155
|
+
if (current.size === 0) {
|
|
156
|
+
this.#localHandlers.delete(wire);
|
|
157
|
+
this.#brokerHandles.get(wire)?.[Symbol.dispose]();
|
|
158
|
+
this.#brokerHandles.delete(wire);
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
#deliver(wire, message) {
|
|
164
|
+
const handlers = this.#localHandlers.get(wire);
|
|
165
|
+
if (!handlers || handlers.size === 0)
|
|
166
|
+
return;
|
|
167
|
+
if (this.#telemetry) {
|
|
168
|
+
// Multiple subscribers on the same wire share a displayTopic that maps
|
|
169
|
+
// 1:1 to the wire string: `subscribe(t)` always yields prefix+t and
|
|
170
|
+
// `subscribeForeign(p, t)` always yields p+t. The first entry's
|
|
171
|
+
// displayTopic is therefore representative.
|
|
172
|
+
const first = handlers.values().next().value;
|
|
173
|
+
if (first) {
|
|
174
|
+
this.#telemetry.emit('onCrossNodeReceived', {
|
|
175
|
+
topic: first.displayTopic,
|
|
176
|
+
originId: message.originId,
|
|
177
|
+
lagMs: Date.now() - Date.parse(message.emittedAt),
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
for (const entry of handlers) {
|
|
182
|
+
try {
|
|
183
|
+
entry.handler(message);
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
this.#telemetry?.emit('onCrossNodeError', { topic: entry.displayTopic, error, phase: 'subscribe' });
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
#ensureLive() {
|
|
191
|
+
if (this.#disposed) {
|
|
192
|
+
throw new Error('InProcessCrossNodeBus has been disposed');
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=in-process-cross-node-bus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-process-cross-node-bus.js","sourceRoot":"","sources":["../src/in-process-cross-node-bus.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-process-cross-node-bus.spec.d.ts","sourceRoot":"","sources":["../src/in-process-cross-node-bus.spec.ts"],"names":[],"mappings":""}
|