@net-mesh/core 0.21.0 → 0.22.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/aggregator.d.ts +56 -0
- package/aggregator.js +130 -0
- package/meshdb.d.ts +23 -0
- package/meshdb.js +101 -0
- package/net.darwin-arm64.node +0 -0
- package/net.darwin-x64.node +0 -0
- package/net.linux-arm64-gnu.node +0 -0
- package/net.linux-arm64-musl.node +0 -0
- package/net.linux-x64-gnu.node +0 -0
- package/net.linux-x64-musl.node +0 -0
- package/net.win32-arm64-msvc.node +0 -0
- package/net.win32-x64-msvc.node +0 -0
- package/package.json +20 -12
package/aggregator.d.ts
ADDED
|
@@ -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
|
+
}
|
package/meshdb.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Result of {@link parseMeshDbErrorKind}: extracted structured
|
|
3
|
+
* discriminator + the human-readable message stripped of the
|
|
4
|
+
* `<<meshdb-kind:...>>` prefix.
|
|
5
|
+
*/
|
|
6
|
+
export interface ParsedMeshDbError {
|
|
7
|
+
kind: string;
|
|
8
|
+
message: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Pull the structured error kind out of a MeshDB error message.
|
|
12
|
+
*
|
|
13
|
+
* The Rust binding embeds the kind discriminator (one of the
|
|
14
|
+
* `MeshError` variant tags such as `planner_error`,
|
|
15
|
+
* `executor_error`, `query_cancelled`, `historical_range_unavailable`,
|
|
16
|
+
* `ambiguous_discovery`, etc.) at the start of the error message
|
|
17
|
+
* as `<<meshdb-kind:KIND>>MSG`. This helper parses it back.
|
|
18
|
+
*
|
|
19
|
+
* Returns `null` for errors that don't carry a kind prefix
|
|
20
|
+
* (SDK-side validation failures, factory rejections) — those
|
|
21
|
+
* surface with the plain message intact.
|
|
22
|
+
*/
|
|
23
|
+
export declare function parseMeshDbErrorKind(err: unknown): ParsedMeshDbError | null;
|
package/meshdb.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// MeshDB AsyncIterable shim.
|
|
3
|
+
//
|
|
4
|
+
// Augments the napi-rs–generated `MeshQueryStream` class with
|
|
5
|
+
// `[Symbol.asyncIterator]` so callers can write `for await (const row
|
|
6
|
+
// of await runner.execute(query)) { ... }`. The locked Node SDK
|
|
7
|
+
// decision is `Promise<AsyncIterable<Row>>`; importing this module
|
|
8
|
+
// once at startup makes the shape land.
|
|
9
|
+
//
|
|
10
|
+
// Usage:
|
|
11
|
+
//
|
|
12
|
+
// import "@net-mesh/core/meshdb"; // augments MeshQueryStream
|
|
13
|
+
// import { MeshQuery, MeshQueryRunner } from "@net-mesh/core";
|
|
14
|
+
//
|
|
15
|
+
// const runner = new MeshQueryRunner(reader);
|
|
16
|
+
// const stream = await runner.execute(MeshQuery.latest(0xABn));
|
|
17
|
+
// for await (const row of stream) {
|
|
18
|
+
// console.log(row.seq, row.payload);
|
|
19
|
+
// }
|
|
20
|
+
//
|
|
21
|
+
// The shim is idempotent — re-imports are no-ops. It detaches
|
|
22
|
+
// cleanly under tree-shaking too (no top-level side effects beyond
|
|
23
|
+
// the prototype attach, which only fires when `MeshQueryStream` is
|
|
24
|
+
// part of the loaded native binding).
|
|
25
|
+
//
|
|
26
|
+
// Phase-F note: this shim is a wire-shape ergonomics layer; it
|
|
27
|
+
// doesn't change semantics. The underlying `next()` / `toArray()`
|
|
28
|
+
// methods stay available for callers that prefer manual iteration
|
|
29
|
+
// or batch drain.
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
exports.parseMeshDbErrorKind = parseMeshDbErrorKind;
|
|
32
|
+
// The napi-generated MeshQueryStream is a constructor function with a
|
|
33
|
+
// prototype, but the original cast typed it as a plain object — the
|
|
34
|
+
// later `typeof === "function"` narrowing then collapsed it to `never`
|
|
35
|
+
// and reading `.prototype` errored under `-D warnings`. Cast as a
|
|
36
|
+
// Function with a prototype so both type-guards line up.
|
|
37
|
+
const native = require("./index");
|
|
38
|
+
if (native.MeshQueryStream &&
|
|
39
|
+
typeof native.MeshQueryStream === "function" &&
|
|
40
|
+
!(Symbol.asyncIterator in native.MeshQueryStream.prototype)) {
|
|
41
|
+
Object.defineProperty(native.MeshQueryStream.prototype, Symbol.asyncIterator, {
|
|
42
|
+
value() {
|
|
43
|
+
const stream = this;
|
|
44
|
+
return {
|
|
45
|
+
async next() {
|
|
46
|
+
const row = await stream.next();
|
|
47
|
+
if (row === null || row === undefined) {
|
|
48
|
+
return { value: undefined, done: true };
|
|
49
|
+
}
|
|
50
|
+
return { value: row, done: false };
|
|
51
|
+
},
|
|
52
|
+
// `return(value)` is invoked when a `for await (...)` loop
|
|
53
|
+
// `break`s, `return`s from the enclosing function, or an
|
|
54
|
+
// exception unwinds out of the loop body. Without this,
|
|
55
|
+
// the backing row Vec stays pinned on the AsyncMutex
|
|
56
|
+
// until JS GC eventually drops the stream — for a 10k+
|
|
57
|
+
// row result that's a sizeable memory pin.
|
|
58
|
+
async return(value) {
|
|
59
|
+
if (typeof stream.release === "function") {
|
|
60
|
+
await stream.release();
|
|
61
|
+
}
|
|
62
|
+
return { value, done: true };
|
|
63
|
+
},
|
|
64
|
+
// `throw(err)` is the iteration-protocol's error path.
|
|
65
|
+
// Symmetric to `return()`: free the buffer, then
|
|
66
|
+
// re-surface the error to the caller.
|
|
67
|
+
async throw(err) {
|
|
68
|
+
if (typeof stream.release === "function") {
|
|
69
|
+
await stream.release();
|
|
70
|
+
}
|
|
71
|
+
throw err;
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
},
|
|
75
|
+
enumerable: false,
|
|
76
|
+
configurable: true,
|
|
77
|
+
writable: true,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Pull the structured error kind out of a MeshDB error message.
|
|
82
|
+
*
|
|
83
|
+
* The Rust binding embeds the kind discriminator (one of the
|
|
84
|
+
* `MeshError` variant tags such as `planner_error`,
|
|
85
|
+
* `executor_error`, `query_cancelled`, `historical_range_unavailable`,
|
|
86
|
+
* `ambiguous_discovery`, etc.) at the start of the error message
|
|
87
|
+
* as `<<meshdb-kind:KIND>>MSG`. This helper parses it back.
|
|
88
|
+
*
|
|
89
|
+
* Returns `null` for errors that don't carry a kind prefix
|
|
90
|
+
* (SDK-side validation failures, factory rejections) — those
|
|
91
|
+
* surface with the plain message intact.
|
|
92
|
+
*/
|
|
93
|
+
function parseMeshDbErrorKind(err) {
|
|
94
|
+
if (!(err instanceof Error))
|
|
95
|
+
return null;
|
|
96
|
+
// Accept digits too (`protocol_v2_mismatch`-style future kinds).
|
|
97
|
+
const m = err.message.match(/^<<meshdb-kind:([a-z0-9_]+)>>(.*)$/s);
|
|
98
|
+
if (!m)
|
|
99
|
+
return null;
|
|
100
|
+
return { kind: m[1], message: m[2] };
|
|
101
|
+
}
|
package/net.darwin-arm64.node
CHANGED
|
Binary file
|
package/net.darwin-x64.node
CHANGED
|
Binary file
|
package/net.linux-arm64-gnu.node
CHANGED
|
Binary file
|
|
Binary file
|
package/net.linux-x64-gnu.node
CHANGED
|
Binary file
|
package/net.linux-x64-musl.node
CHANGED
|
Binary file
|
|
Binary file
|
package/net.win32-x64-msvc.node
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@net-mesh/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "High-performance, schema-agnostic event bus for AI runtime workloads",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -20,6 +20,10 @@
|
|
|
20
20
|
"./meshdb": {
|
|
21
21
|
"types": "./meshdb.d.ts",
|
|
22
22
|
"default": "./meshdb.js"
|
|
23
|
+
},
|
|
24
|
+
"./aggregator": {
|
|
25
|
+
"types": "./aggregator.d.ts",
|
|
26
|
+
"default": "./aggregator.js"
|
|
23
27
|
}
|
|
24
28
|
},
|
|
25
29
|
"napi": {
|
|
@@ -56,6 +60,10 @@
|
|
|
56
60
|
"errors.d.ts",
|
|
57
61
|
"mesh_rpc.js",
|
|
58
62
|
"mesh_rpc.d.ts",
|
|
63
|
+
"meshdb.js",
|
|
64
|
+
"meshdb.d.ts",
|
|
65
|
+
"aggregator.js",
|
|
66
|
+
"aggregator.d.ts",
|
|
59
67
|
"*.node"
|
|
60
68
|
],
|
|
61
69
|
"devDependencies": {
|
|
@@ -66,9 +74,9 @@
|
|
|
66
74
|
},
|
|
67
75
|
"scripts": {
|
|
68
76
|
"artifacts": "napi artifacts",
|
|
69
|
-
"build": "napi build --platform --release --features redis,net,cortex,compute,groups,meshos,deck,meshdb",
|
|
70
|
-
"build:debug": "napi build --platform --features redis,net,cortex,compute,groups,meshos,deck,meshdb",
|
|
71
|
-
"build:test": "napi build --platform --features redis,net,cortex,compute,groups,meshos,deck,meshdb,test-helpers",
|
|
77
|
+
"build": "napi build --platform --release --features redis,net,cortex,compute,groups,meshos,deck,meshdb,aggregator",
|
|
78
|
+
"build:debug": "napi build --platform --features redis,net,cortex,compute,groups,meshos,deck,meshdb,aggregator",
|
|
79
|
+
"build:test": "napi build --platform --features redis,net,cortex,compute,groups,meshos,deck,meshdb,aggregator,test-helpers",
|
|
72
80
|
"build:ts": "tsc -p tsconfig.build.json",
|
|
73
81
|
"prepublishOnly": "npm run build:ts && napi prepublish -t npm",
|
|
74
82
|
"test": "vitest run",
|
|
@@ -83,13 +91,13 @@
|
|
|
83
91
|
"node": ">=20"
|
|
84
92
|
},
|
|
85
93
|
"optionalDependencies": {
|
|
86
|
-
"@net-mesh/core-win32-x64-msvc": "0.
|
|
87
|
-
"@net-mesh/core-win32-arm64-msvc": "0.
|
|
88
|
-
"@net-mesh/core-darwin-x64": "0.
|
|
89
|
-
"@net-mesh/core-darwin-arm64": "0.
|
|
90
|
-
"@net-mesh/core-linux-x64-gnu": "0.
|
|
91
|
-
"@net-mesh/core-linux-x64-musl": "0.
|
|
92
|
-
"@net-mesh/core-linux-arm64-gnu": "0.
|
|
93
|
-
"@net-mesh/core-linux-arm64-musl": "0.
|
|
94
|
+
"@net-mesh/core-win32-x64-msvc": "0.22.0",
|
|
95
|
+
"@net-mesh/core-win32-arm64-msvc": "0.22.0",
|
|
96
|
+
"@net-mesh/core-darwin-x64": "0.22.0",
|
|
97
|
+
"@net-mesh/core-darwin-arm64": "0.22.0",
|
|
98
|
+
"@net-mesh/core-linux-x64-gnu": "0.22.0",
|
|
99
|
+
"@net-mesh/core-linux-x64-musl": "0.22.0",
|
|
100
|
+
"@net-mesh/core-linux-arm64-gnu": "0.22.0",
|
|
101
|
+
"@net-mesh/core-linux-arm64-musl": "0.22.0"
|
|
94
102
|
}
|
|
95
103
|
}
|