@calimero-network/mero-js 12.1.0 → 13.1.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/dist/admin-api/admin-types.d.ts +12 -6
- package/dist/ephemeral/codec.d.ts +4 -0
- package/dist/ephemeral/codec.js +12 -0
- package/dist/ephemeral/index.d.ts +51 -0
- package/dist/ephemeral/index.js +81 -0
- package/dist/ephemeral/types.d.ts +22 -0
- package/dist/ephemeral/types.js +1 -0
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +4 -4
- package/dist/index.cjs +104 -23
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.mjs +104 -23
- package/dist/index.mjs.map +3 -3
- package/dist/mero-js.d.ts +9 -0
- package/dist/mero-js.js +16 -0
- package/dist/rpc/index.d.ts +8 -0
- package/dist/rpc/index.js +28 -20
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -25,6 +25,7 @@ __export(index_exports, {
|
|
|
25
25
|
CAPABILITIES: () => CAPABILITIES,
|
|
26
26
|
CloudClient: () => CloudClient,
|
|
27
27
|
DEFAULT_LOCAL_NODE_PORTS: () => DEFAULT_LOCAL_NODE_PORTS,
|
|
28
|
+
EphemeralClient: () => EphemeralClient,
|
|
28
29
|
HTTPError: () => HTTPError,
|
|
29
30
|
LocalStorageTokenStore: () => LocalStorageTokenStore,
|
|
30
31
|
MemoryTokenStore: () => MemoryTokenStore,
|
|
@@ -54,6 +55,7 @@ __export(index_exports, {
|
|
|
54
55
|
createUniversalHttpClient: () => createUniversalHttpClient,
|
|
55
56
|
discoverLocalNodes: () => discoverLocalNodes,
|
|
56
57
|
hasCap: () => hasCap,
|
|
58
|
+
jsonCodec: () => jsonCodec,
|
|
57
59
|
localNodeUrl: () => localNodeUrl,
|
|
58
60
|
nodeEndpoint: () => nodeEndpoint,
|
|
59
61
|
parseAuthCallback: () => parseAuthCallback,
|
|
@@ -1538,35 +1540,33 @@ var RpcError = class extends Error {
|
|
|
1538
1540
|
this.type = type;
|
|
1539
1541
|
}
|
|
1540
1542
|
};
|
|
1543
|
+
async function jsonRpcCall(httpClient, method, params) {
|
|
1544
|
+
const response = await httpClient.post("/jsonrpc", {
|
|
1545
|
+
jsonrpc: "2.0",
|
|
1546
|
+
id: 1,
|
|
1547
|
+
method,
|
|
1548
|
+
params
|
|
1549
|
+
});
|
|
1550
|
+
if (response.error) {
|
|
1551
|
+
const err = response.error;
|
|
1552
|
+
throw new RpcError(err.code ?? -1, err.message ?? err.type ?? "RPC error", err.data, err.type);
|
|
1553
|
+
}
|
|
1554
|
+
return response.result;
|
|
1555
|
+
}
|
|
1541
1556
|
var RpcClient = class {
|
|
1542
1557
|
constructor(opts) {
|
|
1543
1558
|
this.httpClient = opts.httpClient;
|
|
1544
1559
|
}
|
|
1545
1560
|
async execute(params) {
|
|
1546
|
-
const
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
argsJson: params.argsJson ?? {}
|
|
1554
|
-
}
|
|
1555
|
-
};
|
|
1556
|
-
const response = await this.httpClient.post(
|
|
1557
|
-
"/jsonrpc",
|
|
1558
|
-
body
|
|
1559
|
-
);
|
|
1560
|
-
if (response.error) {
|
|
1561
|
-
const err = response.error;
|
|
1562
|
-
const code = err.code ?? -1;
|
|
1563
|
-
const message = err.message ?? err.type ?? "RPC error";
|
|
1564
|
-
throw new RpcError(code, message, err.data, err.type);
|
|
1565
|
-
}
|
|
1566
|
-
if (response.result && "output" in response.result) {
|
|
1567
|
-
return response.result.output;
|
|
1561
|
+
const result = await jsonRpcCall(this.httpClient, "execute", {
|
|
1562
|
+
contextId: params.contextId,
|
|
1563
|
+
method: params.method,
|
|
1564
|
+
argsJson: params.argsJson ?? {}
|
|
1565
|
+
});
|
|
1566
|
+
if (result && "output" in result) {
|
|
1567
|
+
return result.output;
|
|
1568
1568
|
}
|
|
1569
|
-
return
|
|
1569
|
+
return result;
|
|
1570
1570
|
}
|
|
1571
1571
|
/**
|
|
1572
1572
|
* One-tap owner-driven convert: re-signs the caller's identity-gated entries
|
|
@@ -2057,6 +2057,72 @@ var _WsClient = class _WsClient {
|
|
|
2057
2057
|
_WsClient.MAX_BACKOFF_MS = 3e4;
|
|
2058
2058
|
var WsClient = _WsClient;
|
|
2059
2059
|
|
|
2060
|
+
// src/ephemeral/codec.ts
|
|
2061
|
+
function jsonCodec() {
|
|
2062
|
+
return {
|
|
2063
|
+
encode(value) {
|
|
2064
|
+
return Array.from(new TextEncoder().encode(JSON.stringify(value)));
|
|
2065
|
+
},
|
|
2066
|
+
decode(bytes) {
|
|
2067
|
+
return JSON.parse(new TextDecoder().decode(new Uint8Array(bytes)));
|
|
2068
|
+
}
|
|
2069
|
+
};
|
|
2070
|
+
}
|
|
2071
|
+
|
|
2072
|
+
// src/ephemeral/index.ts
|
|
2073
|
+
var EphemeralClient = class {
|
|
2074
|
+
constructor(opts) {
|
|
2075
|
+
this.httpClient = opts.httpClient;
|
|
2076
|
+
this.sse = opts.sse;
|
|
2077
|
+
}
|
|
2078
|
+
/**
|
|
2079
|
+
* Publish your own presence slice, replacing it wholesale.
|
|
2080
|
+
*
|
|
2081
|
+
* Rejects with an `RpcError` (not a bare `Error`), so a typed failure such as
|
|
2082
|
+
* an oversized slice keeps its `type` and `data` — e.g. `SliceTooLarge` with
|
|
2083
|
+
* the offending size — and is `instanceof RpcError` like every other RPC in
|
|
2084
|
+
* this SDK.
|
|
2085
|
+
*/
|
|
2086
|
+
async set(contextId, state, codec = jsonCodec()) {
|
|
2087
|
+
await jsonRpcCall(this.httpClient, "set_ephemeral", {
|
|
2088
|
+
contextId,
|
|
2089
|
+
state: codec.encode(state)
|
|
2090
|
+
});
|
|
2091
|
+
}
|
|
2092
|
+
/**
|
|
2093
|
+
* Observe presence changes for a context.
|
|
2094
|
+
*
|
|
2095
|
+
* This adds NO transport — it is a typed filter over the existing SSE event
|
|
2096
|
+
* stream, which already carries `{ contextId, type, data }`. On subscribing,
|
|
2097
|
+
* the node replays that context's current presence to this connection as
|
|
2098
|
+
* ordinary `Ephemeral` events before any live deltas; a replayed entry
|
|
2099
|
+
* carries `ageMs`, a live delta does not (never synthesized as `0` — absent
|
|
2100
|
+
* and zero mean different things). Returns an unsubscribe function.
|
|
2101
|
+
*/
|
|
2102
|
+
subscribe(contextId, handler, codec = jsonCodec()) {
|
|
2103
|
+
const listener = (event) => {
|
|
2104
|
+
const e = event;
|
|
2105
|
+
if (e.type !== "Ephemeral" || e.contextId !== contextId) return;
|
|
2106
|
+
const data = e.data;
|
|
2107
|
+
if (!data?.author) return;
|
|
2108
|
+
const removed = Boolean(data.removed);
|
|
2109
|
+
const entry = {
|
|
2110
|
+
author: data.author,
|
|
2111
|
+
state: removed || data.state === void 0 ? void 0 : codec.decode(data.state),
|
|
2112
|
+
removed
|
|
2113
|
+
};
|
|
2114
|
+
if (data.ageMs !== void 0) entry.ageMs = data.ageMs;
|
|
2115
|
+
handler(entry);
|
|
2116
|
+
};
|
|
2117
|
+
this.sse.on("event", listener);
|
|
2118
|
+
void this.sse.connect().catch(() => void 0);
|
|
2119
|
+
void this.sse.subscribe([contextId]).catch(() => void 0);
|
|
2120
|
+
return () => {
|
|
2121
|
+
this.sse.off("event", listener);
|
|
2122
|
+
};
|
|
2123
|
+
}
|
|
2124
|
+
};
|
|
2125
|
+
|
|
2060
2126
|
// src/mero-js.ts
|
|
2061
2127
|
var REFRESH_LOCK_NAME = "mero-js:token-refresh";
|
|
2062
2128
|
function getLockManager() {
|
|
@@ -2175,6 +2241,21 @@ var MeroJs = class {
|
|
|
2175
2241
|
}
|
|
2176
2242
|
return this.sseClient;
|
|
2177
2243
|
}
|
|
2244
|
+
/**
|
|
2245
|
+
* Get the ephemeral-presence client (lazy initialized).
|
|
2246
|
+
*
|
|
2247
|
+
* Shares this instance's SSE client, so `subscribe` reuses the one event
|
|
2248
|
+
* stream rather than opening a second connection.
|
|
2249
|
+
*/
|
|
2250
|
+
get ephemeral() {
|
|
2251
|
+
if (!this.ephemeralClient) {
|
|
2252
|
+
this.ephemeralClient = new EphemeralClient({
|
|
2253
|
+
httpClient: this.httpClient,
|
|
2254
|
+
sse: this.events
|
|
2255
|
+
});
|
|
2256
|
+
}
|
|
2257
|
+
return this.ephemeralClient;
|
|
2258
|
+
}
|
|
2178
2259
|
/**
|
|
2179
2260
|
* Get the WebSocket event client (lazy initialized).
|
|
2180
2261
|
* @experimental Use `events` (SSE) for production. WsClient is experimental.
|