@net-mesh/core 0.21.0 → 0.23.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.
@@ -0,0 +1,56 @@
1
+ export type RegistryErrorKind = 'transport' | 'codec' | 'unknown-template' | 'duplicate-group-name' | 'spawn-rejected' | 'spawn-not-supported' | 'invalid-args';
2
+ export type FoldQueryErrorKind = 'transport' | 'codec' | 'unknown-kind' | 'invalid-args';
3
+ export declare class RegistryClientError extends Error {
4
+ readonly kind: RegistryErrorKind;
5
+ readonly serverDetail?: string;
6
+ constructor(kind: RegistryErrorKind, detail: string);
7
+ }
8
+ export declare class FoldQueryClientError extends Error {
9
+ readonly kind: FoldQueryErrorKind;
10
+ readonly serverDetail?: string;
11
+ constructor(kind: FoldQueryErrorKind, detail: string);
12
+ }
13
+ /**
14
+ * Inspect an error message for the `agg:` prefix and return the
15
+ * structured `{kind, detail}` if it matches. Returns `null` when
16
+ * the message is missing the prefix or is malformed.
17
+ */
18
+ export declare function parseAggregatorError(e: unknown): {
19
+ kind: string;
20
+ detail: string;
21
+ } | null;
22
+ /**
23
+ * Re-throw a typed error for the given raw error if it carries the
24
+ * `agg:` prefix. Non-matching errors pass through unchanged so
25
+ * `throw classifyAggregatorError(e)` is safe at any catch site.
26
+ *
27
+ * Routes to `RegistryClientError` for registry-shaped kinds and
28
+ * `FoldQueryClientError` for fold-query-shaped kinds. Both surfaces
29
+ * share `transport` / `codec` / `invalid-args`; we route by the
30
+ * caller's typing — pass an explicit `surface` if you know which
31
+ * client raised it, otherwise the default routing biases to
32
+ * `RegistryClientError` for shared kinds (the substrate's primary
33
+ * surface).
34
+ */
35
+ export declare function classifyAggregatorError(e: unknown, surface?: 'registry' | 'fold-query'): unknown;
36
+ export interface RegistryReplicaRow {
37
+ generation: bigint;
38
+ healthy: boolean;
39
+ diagnostic?: string;
40
+ placementNodeId?: bigint;
41
+ }
42
+ export interface RegistryGroupSummary {
43
+ name: string;
44
+ groupSeedHex: string;
45
+ replicas: RegistryReplicaRow[];
46
+ }
47
+ export interface SummaryBucket {
48
+ name: string;
49
+ count: bigint;
50
+ }
51
+ export interface SummaryAnnouncement {
52
+ foldKind: number;
53
+ sourceSubnet: string;
54
+ generation: bigint;
55
+ buckets: SummaryBucket[];
56
+ }
package/aggregator.js ADDED
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ // Typed error classes + classifier for the `aggregator.registry`
3
+ // / `fold.query` RPC clients.
4
+ //
5
+ // The napi binding throws plain Error with the stable `agg:`
6
+ // prefix (`agg:<kind>: <detail>`); `classifyAggregatorError`
7
+ // re-throws as a typed `RegistryClientError` /
8
+ // `FoldQueryClientError`. Prefix locked against
9
+ // `ERR_AGG_PREFIX` in `bindings/node/src/aggregator.rs`;
10
+ // `tests/error_kind_mirror.rs` is the cross-language pin.
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.FoldQueryClientError = exports.RegistryClientError = void 0;
13
+ exports.parseAggregatorError = parseAggregatorError;
14
+ exports.classifyAggregatorError = classifyAggregatorError;
15
+ const ERR_AGG_PREFIX = 'agg:';
16
+ class RegistryClientError extends Error {
17
+ kind;
18
+ serverDetail;
19
+ constructor(kind, detail) {
20
+ super(`${kind}: ${detail}`);
21
+ this.name = 'RegistryClientError';
22
+ this.kind = kind;
23
+ this.serverDetail = detail;
24
+ Object.setPrototypeOf(this, RegistryClientError.prototype);
25
+ }
26
+ }
27
+ exports.RegistryClientError = RegistryClientError;
28
+ class FoldQueryClientError extends Error {
29
+ kind;
30
+ serverDetail;
31
+ constructor(kind, detail) {
32
+ super(`${kind}: ${detail}`);
33
+ this.name = 'FoldQueryClientError';
34
+ this.kind = kind;
35
+ this.serverDetail = detail;
36
+ Object.setPrototypeOf(this, FoldQueryClientError.prototype);
37
+ }
38
+ }
39
+ exports.FoldQueryClientError = FoldQueryClientError;
40
+ const REGISTRY_KINDS = new Set([
41
+ 'transport',
42
+ 'codec',
43
+ 'unknown-template',
44
+ 'duplicate-group-name',
45
+ 'spawn-rejected',
46
+ 'spawn-not-supported',
47
+ 'invalid-args',
48
+ ]);
49
+ const FOLD_KINDS = new Set([
50
+ 'transport',
51
+ 'codec',
52
+ 'unknown-kind',
53
+ 'invalid-args',
54
+ ]);
55
+ /**
56
+ * Inspect an error message for the `agg:` prefix and return the
57
+ * structured `{kind, detail}` if it matches. Returns `null` when
58
+ * the message is missing the prefix or is malformed.
59
+ */
60
+ function parseAggregatorError(e) {
61
+ const msg = extractMessage(e);
62
+ if (!msg.startsWith(ERR_AGG_PREFIX))
63
+ return null;
64
+ const after = msg.slice(ERR_AGG_PREFIX.length);
65
+ // Find the FIRST `: ` separator — kinds are stable kebab-case
66
+ // identifiers with no colons; the detail may contain colons.
67
+ const sepIdx = after.indexOf(': ');
68
+ if (sepIdx === -1) {
69
+ // No detail, just the kind (defensive — substrate always emits
70
+ // a detail string today).
71
+ return { kind: after, detail: '' };
72
+ }
73
+ return {
74
+ kind: after.slice(0, sepIdx),
75
+ detail: after.slice(sepIdx + 2),
76
+ };
77
+ }
78
+ /**
79
+ * Re-throw a typed error for the given raw error if it carries the
80
+ * `agg:` prefix. Non-matching errors pass through unchanged so
81
+ * `throw classifyAggregatorError(e)` is safe at any catch site.
82
+ *
83
+ * Routes to `RegistryClientError` for registry-shaped kinds and
84
+ * `FoldQueryClientError` for fold-query-shaped kinds. Both surfaces
85
+ * share `transport` / `codec` / `invalid-args`; we route by the
86
+ * caller's typing — pass an explicit `surface` if you know which
87
+ * client raised it, otherwise the default routing biases to
88
+ * `RegistryClientError` for shared kinds (the substrate's primary
89
+ * surface).
90
+ */
91
+ function classifyAggregatorError(e, surface) {
92
+ const parsed = parseAggregatorError(e);
93
+ if (!parsed)
94
+ return e;
95
+ // Surface-specific kinds take priority — they are unambiguous.
96
+ if (parsed.kind === 'unknown-kind') {
97
+ return new FoldQueryClientError('unknown-kind', parsed.detail);
98
+ }
99
+ if (parsed.kind === 'unknown-template' ||
100
+ parsed.kind === 'duplicate-group-name' ||
101
+ parsed.kind === 'spawn-rejected' ||
102
+ parsed.kind === 'spawn-not-supported') {
103
+ return new RegistryClientError(parsed.kind, parsed.detail);
104
+ }
105
+ // Shared kinds — route by caller hint, default to registry.
106
+ if (parsed.kind === 'transport' ||
107
+ parsed.kind === 'codec' ||
108
+ parsed.kind === 'invalid-args') {
109
+ if (surface === 'fold-query') {
110
+ return new FoldQueryClientError(parsed.kind, parsed.detail);
111
+ }
112
+ return new RegistryClientError(parsed.kind, parsed.detail);
113
+ }
114
+ // Unknown kind under the `agg:` umbrella — keep the original
115
+ // error so callers see the full string instead of a synthetic
116
+ // typed wrapper that drops information.
117
+ void REGISTRY_KINDS;
118
+ void FOLD_KINDS;
119
+ return e;
120
+ }
121
+ function extractMessage(e) {
122
+ if (e === null || e === undefined)
123
+ return '';
124
+ if (typeof e === 'string')
125
+ return e;
126
+ if (typeof e !== 'object')
127
+ return '';
128
+ const msg = e.message;
129
+ return typeof msg === 'string' ? msg : '';
130
+ }