@orqenix/mesh-router 0.6.0-phase-6

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/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ Copyright 2026 Milo Nguyen and Orqenix contributors
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License");
8
+ you may not use this file except in compliance with the License.
9
+ You may obtain a copy of the License at
10
+
11
+ http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing, software
14
+ distributed under the License is distributed on an "AS IS" BASIS,
15
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ See the License for the specific language governing permissions and
17
+ limitations under the License.
18
+
19
+ [Full Apache 2.0 text: include verbatim from https://www.apache.org/licenses/LICENSE-2.0.txt]
@@ -0,0 +1,28 @@
1
+ import type { ObservabilityHooks } from '@orqenix/mesh-observability';
2
+ import type { ScopeId, TransportRegistry } from '@orqenix/mesh-transport-core';
3
+ import { MeshRouter, type AddressResolver } from './router.js';
4
+ import { type CircuitBreakerOptions } from './circuit-breaker.js';
5
+ import { type CrossTransportDedupOptions } from './dedup.js';
6
+ import type { AppHandler, StructuralCapabilityVerifier } from './inbound.js';
7
+ export declare class MeshRouterBuilder {
8
+ private localScopeId?;
9
+ private registry?;
10
+ private verifier?;
11
+ private addressResolver?;
12
+ private priority;
13
+ private breakerOpts?;
14
+ private dedupOpts?;
15
+ private hooks?;
16
+ private handler?;
17
+ withLocalScope(id: ScopeId): this;
18
+ withRegistry(r: TransportRegistry): this;
19
+ withVerifier(v: StructuralCapabilityVerifier): this;
20
+ withAddressResolver(fn: AddressResolver): this;
21
+ withPriority(order: ReadonlyArray<string>): this;
22
+ withBreaker(opts: CircuitBreakerOptions): this;
23
+ withDedup(opts: CrossTransportDedupOptions): this;
24
+ withHooks(h: ObservabilityHooks): this;
25
+ withHandler(h: AppHandler): this;
26
+ build(): MeshRouter;
27
+ }
28
+ //# sourceMappingURL=builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAA0B,MAAM,aAAa,CAAC;AACvF,OAAO,EAAkB,KAAK,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,EAAuB,KAAK,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAElF,OAAO,KAAK,EAAE,UAAU,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AAE7E,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,YAAY,CAAC,CAAU;IAC/B,OAAO,CAAC,QAAQ,CAAC,CAAoB;IACrC,OAAO,CAAC,QAAQ,CAAC,CAA+B;IAChD,OAAO,CAAC,eAAe,CAAC,CAAkB;IAC1C,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,WAAW,CAAC,CAAwB;IAC5C,OAAO,CAAC,SAAS,CAAC,CAA6B;IAC/C,OAAO,CAAC,KAAK,CAAC,CAAqB;IACnC,OAAO,CAAC,OAAO,CAAC,CAAa;IAE7B,cAAc,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI;IACjC,YAAY,CAAC,CAAC,EAAE,iBAAiB,GAAG,IAAI;IACxC,YAAY,CAAC,CAAC,EAAE,4BAA4B,GAAG,IAAI;IACnD,mBAAmB,CAAC,EAAE,EAAE,eAAe,GAAG,IAAI;IAC9C,YAAY,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,IAAI;IAChD,WAAW,CAAC,IAAI,EAAE,qBAAqB,GAAG,IAAI;IAC9C,SAAS,CAAC,IAAI,EAAE,0BAA0B,GAAG,IAAI;IACjD,SAAS,CAAC,CAAC,EAAE,kBAAkB,GAAG,IAAI;IACtC,WAAW,CAAC,CAAC,EAAE,UAAU,GAAG,IAAI;IAEhC,KAAK,IAAI,UAAU;CA4BpB"}
@@ -0,0 +1,56 @@
1
+ import { MeshRouter } from './router.js';
2
+ import { CircuitBreaker } from './circuit-breaker.js';
3
+ import { CrossTransportDedup } from './dedup.js';
4
+ import { DEFAULT_PRIORITY, priorityList } from './priority.js';
5
+ export class MeshRouterBuilder {
6
+ localScopeId;
7
+ registry;
8
+ verifier;
9
+ addressResolver;
10
+ priority = DEFAULT_PRIORITY;
11
+ breakerOpts;
12
+ dedupOpts;
13
+ hooks;
14
+ handler;
15
+ withLocalScope(id) { this.localScopeId = id; return this; }
16
+ withRegistry(r) { this.registry = r; return this; }
17
+ withVerifier(v) { this.verifier = v; return this; }
18
+ withAddressResolver(fn) { this.addressResolver = fn; return this; }
19
+ withPriority(order) { this.priority = priorityList(order); return this; }
20
+ withBreaker(opts) { this.breakerOpts = opts; return this; }
21
+ withDedup(opts) { this.dedupOpts = opts; return this; }
22
+ withHooks(h) { this.hooks = h; return this; }
23
+ withHandler(h) { this.handler = h; return this; }
24
+ build() {
25
+ if (!this.localScopeId)
26
+ throw new Error('MeshRouterBuilder: localScopeId required');
27
+ if (!this.registry)
28
+ throw new Error('MeshRouterBuilder: registry required');
29
+ if (!this.verifier)
30
+ throw new Error('MeshRouterBuilder: verifier required');
31
+ if (!this.addressResolver)
32
+ throw new Error('MeshRouterBuilder: addressResolver required');
33
+ const breaker = new CircuitBreaker({
34
+ ...(this.breakerOpts ?? {}),
35
+ scopeId: this.localScopeId,
36
+ hooks: this.hooks,
37
+ });
38
+ const dedup = new CrossTransportDedup(this.dedupOpts);
39
+ const opts = {
40
+ localScopeId: this.localScopeId,
41
+ registry: this.registry,
42
+ verifier: this.verifier,
43
+ addressResolver: this.addressResolver,
44
+ priority: this.priority,
45
+ breaker,
46
+ dedup,
47
+ hooks: this.hooks,
48
+ handler: this.handler,
49
+ };
50
+ const router = new MeshRouter(opts);
51
+ if (this.handler)
52
+ router.bindInboundToAllTransports();
53
+ return router;
54
+ }
55
+ }
56
+ //# sourceMappingURL=builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.js","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { ObservabilityHooks } from '@orqenix/mesh-observability';
2
+ import type { ScopeId } from '@orqenix/mesh-transport-core';
3
+ export type BreakerState = 'Closed' | 'Open' | 'HalfOpen';
4
+ export interface CircuitBreakerOptions {
5
+ failureThreshold?: number;
6
+ cooldownMs?: number;
7
+ now?: () => number;
8
+ scopeId?: ScopeId;
9
+ hooks?: ObservabilityHooks;
10
+ }
11
+ export declare class CircuitBreaker {
12
+ private readonly failureThreshold;
13
+ private readonly cooldownMs;
14
+ private readonly now;
15
+ private readonly scopeId;
16
+ private readonly hooks?;
17
+ private readonly byKind;
18
+ constructor(opts?: CircuitBreakerOptions);
19
+ canAttempt(kind: string): boolean;
20
+ recordSuccess(kind: string): void;
21
+ recordFailure(kind: string): void;
22
+ stateOf(kind: string): BreakerState;
23
+ consecutiveFailures(kind: string): number;
24
+ private ensure;
25
+ private transition;
26
+ }
27
+ //# sourceMappingURL=circuit-breaker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuit-breaker.d.ts","sourceRoot":"","sources":["../src/circuit-breaker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEtE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAE5D,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAE1D,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,kBAAkB,CAAC;CAC5B;AASD,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmC;gBAE9C,IAAI,GAAE,qBAA0B;IAQ5C,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAkBjC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IASjC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAejC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY;IAInC,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIzC,OAAO,CAAC,MAAM;IASd,OAAO,CAAC,UAAU;CAgBnB"}
@@ -0,0 +1,93 @@
1
+ import { onCircuitClose, onCircuitHalfOpen, onCircuitOpen } from '@orqenix/mesh-observability';
2
+ export class CircuitBreaker {
3
+ failureThreshold;
4
+ cooldownMs;
5
+ now;
6
+ scopeId;
7
+ hooks;
8
+ byKind = new Map();
9
+ constructor(opts = {}) {
10
+ this.failureThreshold = opts.failureThreshold ?? 3;
11
+ this.cooldownMs = opts.cooldownMs ?? 30_000;
12
+ this.now = opts.now ?? Date.now;
13
+ this.scopeId = opts.scopeId ?? 'unknown';
14
+ this.hooks = opts.hooks;
15
+ }
16
+ canAttempt(kind) {
17
+ const s = this.ensure(kind);
18
+ if (s.state === 'Closed')
19
+ return true;
20
+ if (s.state === 'Open') {
21
+ if (this.now() - s.openedAt >= this.cooldownMs) {
22
+ this.transition(kind, 'HalfOpen');
23
+ s.inFlightProbes++;
24
+ return true;
25
+ }
26
+ return false;
27
+ }
28
+ if (s.inFlightProbes < 1) {
29
+ s.inFlightProbes++;
30
+ return true;
31
+ }
32
+ return false;
33
+ }
34
+ recordSuccess(kind) {
35
+ const s = this.ensure(kind);
36
+ if (s.state === 'HalfOpen') {
37
+ s.inFlightProbes = Math.max(0, s.inFlightProbes - 1);
38
+ this.transition(kind, 'Closed');
39
+ }
40
+ s.consecutiveFailures = 0;
41
+ }
42
+ recordFailure(kind) {
43
+ const s = this.ensure(kind);
44
+ if (s.state === 'HalfOpen') {
45
+ s.inFlightProbes = Math.max(0, s.inFlightProbes - 1);
46
+ this.transition(kind, 'Open');
47
+ return;
48
+ }
49
+ if (s.state === 'Closed') {
50
+ s.consecutiveFailures++;
51
+ if (s.consecutiveFailures >= this.failureThreshold) {
52
+ this.transition(kind, 'Open');
53
+ }
54
+ }
55
+ }
56
+ stateOf(kind) {
57
+ return this.ensure(kind).state;
58
+ }
59
+ consecutiveFailures(kind) {
60
+ return this.ensure(kind).consecutiveFailures;
61
+ }
62
+ ensure(kind) {
63
+ let s = this.byKind.get(kind);
64
+ if (!s) {
65
+ s = { state: 'Closed', consecutiveFailures: 0, openedAt: 0, inFlightProbes: 0 };
66
+ this.byKind.set(kind, s);
67
+ }
68
+ return s;
69
+ }
70
+ transition(kind, next) {
71
+ const s = this.ensure(kind);
72
+ if (s.state === next)
73
+ return;
74
+ s.state = next;
75
+ if (next === 'Open') {
76
+ s.openedAt = this.now();
77
+ s.consecutiveFailures = 0;
78
+ if (this.hooks)
79
+ onCircuitOpen(this.hooks, { scopeId: this.scopeId, transport: kind });
80
+ }
81
+ else if (next === 'HalfOpen') {
82
+ s.inFlightProbes = 0;
83
+ if (this.hooks)
84
+ onCircuitHalfOpen(this.hooks, { scopeId: this.scopeId, transport: kind });
85
+ }
86
+ else {
87
+ s.consecutiveFailures = 0;
88
+ if (this.hooks)
89
+ onCircuitClose(this.hooks, { scopeId: this.scopeId, transport: kind });
90
+ }
91
+ }
92
+ }
93
+ //# sourceMappingURL=circuit-breaker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuit-breaker.js","sourceRoot":"","sources":["../src/circuit-breaker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { MeshResponse } from '@orqenix/mesh-transport-core';
2
+ export interface CrossTransportDedupOptions {
3
+ maxEntries?: number;
4
+ now?: () => number;
5
+ }
6
+ export declare class CrossTransportDedup {
7
+ private readonly map;
8
+ private readonly maxEntries;
9
+ private readonly now;
10
+ constructor(opts?: CrossTransportDedupOptions);
11
+ get(id: string): MeshResponse | undefined;
12
+ set(id: string, resp: MeshResponse, ttlMs: number): void;
13
+ size(): number;
14
+ hasUnexpired(id: string): boolean;
15
+ }
16
+ //# sourceMappingURL=dedup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dedup.d.ts","sourceRoot":"","sources":["../src/dedup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAOjE,MAAM,WAAW,0BAA0B;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA4B;IAChD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAEvB,IAAI,GAAE,0BAA+B;IAKjD,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAYzC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAUxD,IAAI,IAAI,MAAM;IAId,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;CAIlC"}
package/dist/dedup.js ADDED
@@ -0,0 +1,40 @@
1
+ export class CrossTransportDedup {
2
+ map = new Map();
3
+ maxEntries;
4
+ now;
5
+ constructor(opts = {}) {
6
+ this.maxEntries = opts.maxEntries ?? 4_096;
7
+ this.now = opts.now ?? Date.now;
8
+ }
9
+ get(id) {
10
+ const e = this.map.get(id);
11
+ if (!e)
12
+ return undefined;
13
+ if (this.now() >= e.expiresAt) {
14
+ this.map.delete(id);
15
+ return undefined;
16
+ }
17
+ this.map.delete(id);
18
+ this.map.set(id, e);
19
+ return e.resp;
20
+ }
21
+ set(id, resp, ttlMs) {
22
+ if (this.map.has(id))
23
+ this.map.delete(id);
24
+ this.map.set(id, { resp, expiresAt: this.now() + Math.max(0, ttlMs) });
25
+ while (this.map.size > this.maxEntries) {
26
+ const oldest = this.map.keys().next().value;
27
+ if (oldest === undefined)
28
+ break;
29
+ this.map.delete(oldest);
30
+ }
31
+ }
32
+ size() {
33
+ return this.map.size;
34
+ }
35
+ hasUnexpired(id) {
36
+ const e = this.map.get(id);
37
+ return !!(e && this.now() < e.expiresAt);
38
+ }
39
+ }
40
+ //# sourceMappingURL=dedup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dedup.js","sourceRoot":"","sources":["../src/dedup.ts"],"names":[],"mappings":"AAYA,MAAM,OAAO,mBAAmB;IACb,GAAG,GAAG,IAAI,GAAG,EAAiB,CAAC;IAC/B,UAAU,CAAS;IACnB,GAAG,CAAe;IAEnC,YAAY,OAAmC,EAAE;QAC/C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,KAAK,CAAC;QAC3C,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IAClC,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC3B,IAAI,CAAC,CAAC;YAAE,OAAO,SAAS,CAAC;QACzB,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;YAC9B,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACpB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACpB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACpB,OAAO,CAAC,CAAC,IAAI,CAAC;IAChB,CAAC;IAED,GAAG,CAAC,EAAU,EAAE,IAAkB,EAAE,KAAa;QAC/C,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;QACvE,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;YACvC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;YAC5C,IAAI,MAAM,KAAK,SAAS;gBAAE,MAAM;YAChC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;IACvB,CAAC;IAED,YAAY,CAAC,EAAU;QACrB,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC3B,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC;IAC3C,CAAC;CACF"}
@@ -0,0 +1,28 @@
1
+ import { type MeshRequest, type MeshResponse, type ScopeId, type TransportCtx } from '@orqenix/mesh-transport-core';
2
+ import type { ObservabilityHooks } from '@orqenix/mesh-observability';
3
+ import { CrossTransportDedup } from './dedup.js';
4
+ export interface StructuralCapabilityVerifier {
5
+ verify(input: {
6
+ capability: string;
7
+ fromScope: ScopeId;
8
+ toScope: ScopeId;
9
+ method: string;
10
+ }): Promise<{
11
+ ok: true;
12
+ token: unknown;
13
+ } | {
14
+ ok: false;
15
+ code: string;
16
+ message: string;
17
+ }>;
18
+ }
19
+ export type AppHandler = (req: MeshRequest, ctx: TransportCtx) => Promise<MeshResponse>;
20
+ export interface InboundDispatchOptions {
21
+ localScopeId: ScopeId;
22
+ verifier: StructuralCapabilityVerifier;
23
+ hooks?: ObservabilityHooks;
24
+ dedup: CrossTransportDedup;
25
+ handler: AppHandler;
26
+ }
27
+ export declare function makeInboundDispatch(opts: InboundDispatchOptions): (req: MeshRequest, ctx: TransportCtx) => Promise<MeshResponse>;
28
+ //# sourceMappingURL=inbound.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbound.d.ts","sourceRoot":"","sources":["../src/inbound.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,OAAO,EACZ,KAAK,YAAY,EAClB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,4BAA4B;IAC3C,MAAM,CAAC,KAAK,EAAE;QACZ,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,OAAO,CAAC;QACnB,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CACP;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,GAC5B;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAC/C,CAAC;CACH;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,YAAY,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;AAExF,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,4BAA4B,CAAC;IACvC,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,KAAK,EAAE,mBAAmB,CAAC;IAC3B,OAAO,EAAE,UAAU,CAAC;CACrB;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,sBAAsB,IAG/B,KAAK,WAAW,EAAE,KAAK,YAAY,KAAG,OAAO,CAAC,YAAY,CAAC,CAuD3F"}
@@ -0,0 +1,64 @@
1
+ import { toMeshResponse, CapabilityError, } from '@orqenix/mesh-transport-core';
2
+ import { onRpcDenied, onRpcIn, onRpcOut } from '@orqenix/mesh-observability';
3
+ export function makeInboundDispatch(opts) {
4
+ const { localScopeId, verifier, hooks, dedup, handler } = opts;
5
+ return async function dispatch(req, ctx) {
6
+ const transportLabel = ctx.peerId ? guessTransport(ctx) : 'unknown';
7
+ const commonCtx = { scopeId: localScopeId, transport: transportLabel, peerId: ctx.peerId };
8
+ if (hooks)
9
+ onRpcIn(hooks, commonCtx, req);
10
+ const cached = dedup.get(req.id);
11
+ if (cached) {
12
+ if (hooks)
13
+ onRpcOut(hooks, commonCtx, req, cached, 0);
14
+ return cached;
15
+ }
16
+ let verifyResult;
17
+ try {
18
+ verifyResult = await verifier.verify({
19
+ capability: String(req.capability),
20
+ fromScope: req.fromScope,
21
+ toScope: req.toScope,
22
+ method: req.method,
23
+ });
24
+ }
25
+ catch (e) {
26
+ const denied = toMeshResponse(req.id, new CapabilityError('verify threw', 'E_CAP_INVALID'));
27
+ if (hooks)
28
+ onRpcDenied(hooks, commonCtx, { id: req.id, method: req.method }, denied.error?.code ?? 'E_CAP_INVALID');
29
+ return denied;
30
+ }
31
+ if (!verifyResult.ok) {
32
+ const denied = {
33
+ id: req.id,
34
+ status: 'denied',
35
+ error: { code: verifyResult.code, message: verifyResult.message },
36
+ };
37
+ if (hooks)
38
+ onRpcDenied(hooks, commonCtx, { id: req.id, method: req.method }, verifyResult.code);
39
+ dedup.set(req.id, denied, Math.max(0, req.deadlineMs - Date.now()));
40
+ return denied;
41
+ }
42
+ const t0 = Date.now();
43
+ let response;
44
+ try {
45
+ response = await handler(req, ctx);
46
+ }
47
+ catch (e) {
48
+ response = toMeshResponse(req.id, e);
49
+ }
50
+ const durationMs = Date.now() - t0;
51
+ if (hooks)
52
+ onRpcOut(hooks, commonCtx, req, response, durationMs);
53
+ dedup.set(req.id, response, Math.max(0, req.deadlineMs - Date.now()));
54
+ return response;
55
+ };
56
+ }
57
+ function guessTransport(ctx) {
58
+ if (ctx.remoteAddr && ctx.remoteAddr.startsWith('inproc'))
59
+ return 'loopback';
60
+ if (ctx.peerId && ctx.peerId.startsWith('12D3KooW'))
61
+ return 'libp2p';
62
+ return 'http';
63
+ }
64
+ //# sourceMappingURL=inbound.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbound.js","sourceRoot":"","sources":["../src/inbound.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,eAAe,GAMhB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAyB7E,MAAM,UAAU,mBAAmB,CAAC,IAA4B;IAC9D,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAE/D,OAAO,KAAK,UAAU,QAAQ,CAAC,GAAgB,EAAE,GAAiB;QAChE,MAAM,cAAc,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACpE,MAAM,SAAS,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;QAE3F,IAAI,KAAK;YAAE,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;QAE1C,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACjC,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,KAAK;gBAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;YACtD,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,IAAI,YAAyE,CAAC;QAC9E,IAAI,CAAC;YACH,YAAY,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;gBACnC,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC;gBAClC,SAAS,EAAE,GAAG,CAAC,SAAS;gBACxB,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,MAAM,EAAE,GAAG,CAAC,MAAM;aACnB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,MAAM,GAAG,cAAc,CAC3B,GAAG,CAAC,EAAE,EACN,IAAI,eAAe,CAAC,cAAc,EAAE,eAAiC,CAAC,CACvE,CAAC;YACF,IAAI,KAAK;gBAAE,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,IAAI,eAAe,CAAC,CAAC;YACpH,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;YACrB,MAAM,MAAM,GAAiB;gBAC3B,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,YAAY,CAAC,OAAO,EAAE;aAClE,CAAC;YACF,IAAI,KAAK;gBAAE,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC;YAChG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACpE,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACtB,IAAI,QAAsB,CAAC;QAC3B,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACrC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACvC,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;QAEnC,IAAI,KAAK;YAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QAEjE,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAEtE,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,GAAiB;IACvC,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,UAAU,CAAC;IAC7E,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,QAAQ,CAAC;IACrE,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,7 @@
1
+ export * from './priority.js';
2
+ export * from './circuit-breaker.js';
3
+ export * from './dedup.js';
4
+ export * from './inbound.js';
5
+ export * from './router.js';
6
+ export * from './builder.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export * from './priority.js';
2
+ export * from './circuit-breaker.js';
3
+ export * from './dedup.js';
4
+ export * from './inbound.js';
5
+ export * from './router.js';
6
+ export * from './builder.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { MeshTransport } from '@orqenix/mesh-transport-core';
2
+ export interface PriorityList {
3
+ readonly order: ReadonlyArray<string>;
4
+ }
5
+ export declare const DEFAULT_PRIORITY: PriorityList;
6
+ export declare function priorityList(order: ReadonlyArray<string>): PriorityList;
7
+ export declare function sortByPriority(transports: ReadonlyArray<MeshTransport>, priority: PriorityList): MeshTransport[];
8
+ //# sourceMappingURL=priority.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"priority.d.ts","sourceRoot":"","sources":["../src/priority.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACvC;AAED,eAAO,MAAM,gBAAgB,EAAE,YAA4C,CAAC;AAE5E,wBAAgB,YAAY,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,YAAY,CAQvE;AAED,wBAAgB,cAAc,CAC5B,UAAU,EAAE,aAAa,CAAC,aAAa,CAAC,EACxC,QAAQ,EAAE,YAAY,GACrB,aAAa,EAAE,CAWjB"}
@@ -0,0 +1,26 @@
1
+ export const DEFAULT_PRIORITY = { order: ['libp2p', 'http'] };
2
+ export function priorityList(order) {
3
+ if (order.length === 0)
4
+ throw new Error('priorityList: must contain at least one transport kind');
5
+ const seen = new Set();
6
+ for (const k of order) {
7
+ if (seen.has(k))
8
+ throw new Error(`priorityList: duplicate kind ${k}`);
9
+ seen.add(k);
10
+ }
11
+ return { order: [...order] };
12
+ }
13
+ export function sortByPriority(transports, priority) {
14
+ const rank = new Map();
15
+ priority.order.forEach((k, i) => rank.set(k, i));
16
+ const indexed = transports.map((t, i) => ({ t, i }));
17
+ indexed.sort((a, b) => {
18
+ const ra = rank.has(a.t.kind) ? rank.get(a.t.kind) : Number.MAX_SAFE_INTEGER;
19
+ const rb = rank.has(b.t.kind) ? rank.get(b.t.kind) : Number.MAX_SAFE_INTEGER;
20
+ if (ra !== rb)
21
+ return ra - rb;
22
+ return a.i - b.i;
23
+ });
24
+ return indexed.map((x) => x.t);
25
+ }
26
+ //# sourceMappingURL=priority.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"priority.js","sourceRoot":"","sources":["../src/priority.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,gBAAgB,GAAiB,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC;AAE5E,MAAM,UAAU,YAAY,CAAC,KAA4B;IACvD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAClG,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,EAAE,CAAC,CAAC;QACtE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACd,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,UAAwC,EACxC,QAAsB;IAEtB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;IACvC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACpB,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAY,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC;QACzF,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAY,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC;QACzF,IAAI,EAAE,KAAK,EAAE;YAAE,OAAO,EAAE,GAAG,EAAE,CAAC;QAC9B,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,37 @@
1
+ import { type MeshAddress, type MeshRequest, type MeshResponse, type ScopeId, type SendOpts, type TransportRegistry } from '@orqenix/mesh-transport-core';
2
+ import type { ObservabilityHooks } from '@orqenix/mesh-observability';
3
+ import { CircuitBreaker } from './circuit-breaker.js';
4
+ import { CrossTransportDedup } from './dedup.js';
5
+ import { type PriorityList } from './priority.js';
6
+ import { type AppHandler, type StructuralCapabilityVerifier } from './inbound.js';
7
+ export type AddressResolver = (kind: string, scopeId: ScopeId) => MeshAddress | undefined;
8
+ export interface MeshRouterOptions {
9
+ localScopeId: ScopeId;
10
+ registry: TransportRegistry;
11
+ verifier: StructuralCapabilityVerifier;
12
+ addressResolver: AddressResolver;
13
+ priority?: PriorityList;
14
+ breaker?: CircuitBreaker;
15
+ dedup?: CrossTransportDedup;
16
+ hooks?: ObservabilityHooks;
17
+ handler?: AppHandler;
18
+ }
19
+ export declare class MeshRouter {
20
+ readonly localScopeId: ScopeId;
21
+ private readonly registry;
22
+ private readonly verifier;
23
+ private readonly addressResolver;
24
+ private readonly priority;
25
+ private readonly breaker;
26
+ private readonly dedup;
27
+ private readonly hooks?;
28
+ private handler?;
29
+ constructor(opts: MeshRouterOptions);
30
+ attachHandler(handler: AppHandler): void;
31
+ bindInboundToAllTransports(): void;
32
+ send(req: MeshRequest, opts?: SendOpts): Promise<MeshResponse>;
33
+ private sendOne;
34
+ breakerStateOf(kind: string): ReturnType<CircuitBreaker['stateOf']>;
35
+ dedupHas(id: string): boolean;
36
+ }
37
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,YAAY,EAEjB,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,KAAK,iBAAiB,EACvB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEtE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AACpF,OAAO,EAAuB,KAAK,UAAU,EAAE,KAAK,4BAA4B,EAAE,MAAM,cAAc,CAAC;AAEvG,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,WAAW,GAAG,SAAS,CAAC;AAE1F,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,QAAQ,EAAE,4BAA4B,CAAC;IACvC,eAAe,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,KAAK,CAAC,EAAE,mBAAmB,CAAC;IAC5B,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAED,qBAAa,UAAU;IACrB,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+B;IACxD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAsB;IAC5C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAqB;IAC5C,OAAO,CAAC,OAAO,CAAC,CAAa;gBAEjB,IAAI,EAAE,iBAAiB;IAYnC,aAAa,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;IAKxC,0BAA0B,IAAI,IAAI;IAc5B,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC;YAiDtD,OAAO;IAarB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;IAInE,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;CAG9B"}
package/dist/router.js ADDED
@@ -0,0 +1,101 @@
1
+ import { toMeshResponse, } from '@orqenix/mesh-transport-core';
2
+ import { onFailover } from '@orqenix/mesh-observability';
3
+ import { CircuitBreaker } from './circuit-breaker.js';
4
+ import { CrossTransportDedup } from './dedup.js';
5
+ import { DEFAULT_PRIORITY, sortByPriority } from './priority.js';
6
+ import { makeInboundDispatch } from './inbound.js';
7
+ export class MeshRouter {
8
+ localScopeId;
9
+ registry;
10
+ verifier;
11
+ addressResolver;
12
+ priority;
13
+ breaker;
14
+ dedup;
15
+ hooks;
16
+ handler;
17
+ constructor(opts) {
18
+ this.localScopeId = opts.localScopeId;
19
+ this.registry = opts.registry;
20
+ this.verifier = opts.verifier;
21
+ this.addressResolver = opts.addressResolver;
22
+ this.priority = opts.priority ?? DEFAULT_PRIORITY;
23
+ this.breaker = opts.breaker ?? new CircuitBreaker({ hooks: opts.hooks, scopeId: opts.localScopeId });
24
+ this.dedup = opts.dedup ?? new CrossTransportDedup();
25
+ this.hooks = opts.hooks;
26
+ this.handler = opts.handler;
27
+ }
28
+ attachHandler(handler) {
29
+ this.handler = handler;
30
+ this.bindInboundToAllTransports();
31
+ }
32
+ bindInboundToAllTransports() {
33
+ if (!this.handler)
34
+ return;
35
+ const dispatch = makeInboundDispatch({
36
+ localScopeId: this.localScopeId,
37
+ verifier: this.verifier,
38
+ hooks: this.hooks,
39
+ dedup: this.dedup,
40
+ handler: this.handler,
41
+ });
42
+ for (const t of this.registry.all()) {
43
+ t.onRequest(dispatch);
44
+ }
45
+ }
46
+ async send(req, opts) {
47
+ const all = this.registry.reachable(req.toScope);
48
+ const ordered = sortByPriority(all, this.priority);
49
+ if (ordered.length === 0) {
50
+ return toMeshResponse(req.id, new Error('no transports reachable for target scope'));
51
+ }
52
+ const candidates = ordered.filter((t) => this.breaker.canAttempt(t.kind));
53
+ if (candidates.length === 0) {
54
+ return toMeshResponse(req.id, new Error('all transports open by circuit breaker'));
55
+ }
56
+ let lastResponse;
57
+ for (let i = 0; i < candidates.length; i++) {
58
+ const t = candidates[i];
59
+ const remaining = Math.max(0, req.deadlineMs - Date.now());
60
+ if (remaining <= 0)
61
+ break;
62
+ const candidatesLeft = candidates.length - i;
63
+ const perAttempt = Math.max(1, Math.floor(remaining / Math.max(1, candidatesLeft)));
64
+ const addr = this.addressResolver(t.kind, req.toScope);
65
+ if (!addr) {
66
+ this.breaker.recordFailure(t.kind);
67
+ continue;
68
+ }
69
+ const attempt = await this.sendOne(t, addr, req, { ...opts, timeoutMs: perAttempt });
70
+ lastResponse = attempt;
71
+ if (attempt.status === 'denied' || attempt.status === 'ok') {
72
+ this.breaker.recordSuccess(t.kind);
73
+ return attempt;
74
+ }
75
+ this.breaker.recordFailure(t.kind);
76
+ const next = candidates[i + 1];
77
+ if (next && Date.now() < req.deadlineMs) {
78
+ if (this.hooks)
79
+ onFailover(this.hooks, { scopeId: this.localScopeId, from: t.kind, to: next.kind });
80
+ continue;
81
+ }
82
+ break;
83
+ }
84
+ return lastResponse ?? { id: req.id, status: 'timeout' };
85
+ }
86
+ async sendOne(t, addr, req, opts) {
87
+ try {
88
+ return await t.send(addr, req, opts);
89
+ }
90
+ catch (e) {
91
+ return toMeshResponse(req.id, e);
92
+ }
93
+ }
94
+ breakerStateOf(kind) {
95
+ return this.breaker.stateOf(kind);
96
+ }
97
+ dedupHas(id) {
98
+ return this.dedup.hasUnexpired(id);
99
+ }
100
+ }
101
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@orqenix/mesh-router",
3
+ "version": "0.6.0-phase-6",
4
+ "description": "Cross-transport mesh router for Orqenix Phase 6: priority-based selection, circuit breaker, sequential failover within deadline, cross-transport dedup, capability-gated inbound dispatch.",
5
+ "type": "module",
6
+ "license": "Apache-2.0",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "default": "./dist/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "README.md",
19
+ "LICENSE",
20
+ "CHANGELOG.md"
21
+ ],
22
+ "dependencies": {
23
+ "@orqenix/mesh-transport-core": "0.6.0-phase-6",
24
+ "@orqenix/mesh-observability": "0.6.0-phase-6"
25
+ },
26
+ "devDependencies": {
27
+ "@types/node": "^22.7.0",
28
+ "@vitest/coverage-v8": "^2.1.0",
29
+ "tsx": "^4.19.0",
30
+ "typescript": "^5.6.0",
31
+ "vitest": "^2.1.0"
32
+ },
33
+ "publishConfig": {
34
+ "access": "public",
35
+ "provenance": false
36
+ },
37
+ "engines": {
38
+ "node": ">=22.0.0"
39
+ },
40
+ "scripts": {
41
+ "build": "tsc -p tsconfig.json",
42
+ "test": "vitest run --coverage",
43
+ "gate:G43": "vitest run test/G43-gate-wrapper.test.ts --reporter verbose"
44
+ }
45
+ }