@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.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export type { MigrateMyEntriesSummary } from './rpc/index.js';
|
|
|
12
12
|
export type { ExecuteParams } from './rpc/index.js';
|
|
13
13
|
export { SseClient, WsClient } from './events/index.js';
|
|
14
14
|
export type { SseEventData, WsEventData, AppVersionChangedEvent, GroupMembershipEventData, GroupMigrationEventData, MigrationStartedData, MigrationProgressData, CascadeProgressData, MigrationCompletedData, } from './events/index.js';
|
|
15
|
+
export { EphemeralClient, jsonCodec } from './ephemeral/index.js';
|
|
16
|
+
export type { Codec, EphemeralEntry } from './ephemeral/index.js';
|
|
15
17
|
export * from './cloud/index.js';
|
|
16
18
|
export * from './capabilities.js';
|
|
17
19
|
export { DEFAULT_LOCAL_NODE_PORTS, localNodeUrl, nodeEndpoint, probeNodeHealth, discoverLocalNodes, } from './nodeDiscovery.js';
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,8 @@ export { MemoryTokenStore, LocalStorageTokenStore } from './token-store/index.js
|
|
|
16
16
|
export { RpcClient, RpcError } from './rpc/index.js';
|
|
17
17
|
// Events (SSE / WebSocket)
|
|
18
18
|
export { SseClient, WsClient } from './events/index.js';
|
|
19
|
+
// Ephemeral presence (cursors / typing / online)
|
|
20
|
+
export { EphemeralClient, jsonCodec } from './ephemeral/index.js';
|
|
19
21
|
// Cloud client (enable-HA, disable-HA)
|
|
20
22
|
export * from './cloud/index.js';
|
|
21
23
|
// Member capability bitmask constants & helpers
|
package/dist/index.mjs
CHANGED
|
@@ -1472,35 +1472,33 @@ var RpcError = class extends Error {
|
|
|
1472
1472
|
this.type = type;
|
|
1473
1473
|
}
|
|
1474
1474
|
};
|
|
1475
|
+
async function jsonRpcCall(httpClient, method, params) {
|
|
1476
|
+
const response = await httpClient.post("/jsonrpc", {
|
|
1477
|
+
jsonrpc: "2.0",
|
|
1478
|
+
id: 1,
|
|
1479
|
+
method,
|
|
1480
|
+
params
|
|
1481
|
+
});
|
|
1482
|
+
if (response.error) {
|
|
1483
|
+
const err = response.error;
|
|
1484
|
+
throw new RpcError(err.code ?? -1, err.message ?? err.type ?? "RPC error", err.data, err.type);
|
|
1485
|
+
}
|
|
1486
|
+
return response.result;
|
|
1487
|
+
}
|
|
1475
1488
|
var RpcClient = class {
|
|
1476
1489
|
constructor(opts) {
|
|
1477
1490
|
this.httpClient = opts.httpClient;
|
|
1478
1491
|
}
|
|
1479
1492
|
async execute(params) {
|
|
1480
|
-
const
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
argsJson: params.argsJson ?? {}
|
|
1488
|
-
}
|
|
1489
|
-
};
|
|
1490
|
-
const response = await this.httpClient.post(
|
|
1491
|
-
"/jsonrpc",
|
|
1492
|
-
body
|
|
1493
|
-
);
|
|
1494
|
-
if (response.error) {
|
|
1495
|
-
const err = response.error;
|
|
1496
|
-
const code = err.code ?? -1;
|
|
1497
|
-
const message = err.message ?? err.type ?? "RPC error";
|
|
1498
|
-
throw new RpcError(code, message, err.data, err.type);
|
|
1499
|
-
}
|
|
1500
|
-
if (response.result && "output" in response.result) {
|
|
1501
|
-
return response.result.output;
|
|
1493
|
+
const result = await jsonRpcCall(this.httpClient, "execute", {
|
|
1494
|
+
contextId: params.contextId,
|
|
1495
|
+
method: params.method,
|
|
1496
|
+
argsJson: params.argsJson ?? {}
|
|
1497
|
+
});
|
|
1498
|
+
if (result && "output" in result) {
|
|
1499
|
+
return result.output;
|
|
1502
1500
|
}
|
|
1503
|
-
return
|
|
1501
|
+
return result;
|
|
1504
1502
|
}
|
|
1505
1503
|
/**
|
|
1506
1504
|
* One-tap owner-driven convert: re-signs the caller's identity-gated entries
|
|
@@ -1991,6 +1989,72 @@ var _WsClient = class _WsClient {
|
|
|
1991
1989
|
_WsClient.MAX_BACKOFF_MS = 3e4;
|
|
1992
1990
|
var WsClient = _WsClient;
|
|
1993
1991
|
|
|
1992
|
+
// src/ephemeral/codec.ts
|
|
1993
|
+
function jsonCodec() {
|
|
1994
|
+
return {
|
|
1995
|
+
encode(value) {
|
|
1996
|
+
return Array.from(new TextEncoder().encode(JSON.stringify(value)));
|
|
1997
|
+
},
|
|
1998
|
+
decode(bytes) {
|
|
1999
|
+
return JSON.parse(new TextDecoder().decode(new Uint8Array(bytes)));
|
|
2000
|
+
}
|
|
2001
|
+
};
|
|
2002
|
+
}
|
|
2003
|
+
|
|
2004
|
+
// src/ephemeral/index.ts
|
|
2005
|
+
var EphemeralClient = class {
|
|
2006
|
+
constructor(opts) {
|
|
2007
|
+
this.httpClient = opts.httpClient;
|
|
2008
|
+
this.sse = opts.sse;
|
|
2009
|
+
}
|
|
2010
|
+
/**
|
|
2011
|
+
* Publish your own presence slice, replacing it wholesale.
|
|
2012
|
+
*
|
|
2013
|
+
* Rejects with an `RpcError` (not a bare `Error`), so a typed failure such as
|
|
2014
|
+
* an oversized slice keeps its `type` and `data` — e.g. `SliceTooLarge` with
|
|
2015
|
+
* the offending size — and is `instanceof RpcError` like every other RPC in
|
|
2016
|
+
* this SDK.
|
|
2017
|
+
*/
|
|
2018
|
+
async set(contextId, state, codec = jsonCodec()) {
|
|
2019
|
+
await jsonRpcCall(this.httpClient, "set_ephemeral", {
|
|
2020
|
+
contextId,
|
|
2021
|
+
state: codec.encode(state)
|
|
2022
|
+
});
|
|
2023
|
+
}
|
|
2024
|
+
/**
|
|
2025
|
+
* Observe presence changes for a context.
|
|
2026
|
+
*
|
|
2027
|
+
* This adds NO transport — it is a typed filter over the existing SSE event
|
|
2028
|
+
* stream, which already carries `{ contextId, type, data }`. On subscribing,
|
|
2029
|
+
* the node replays that context's current presence to this connection as
|
|
2030
|
+
* ordinary `Ephemeral` events before any live deltas; a replayed entry
|
|
2031
|
+
* carries `ageMs`, a live delta does not (never synthesized as `0` — absent
|
|
2032
|
+
* and zero mean different things). Returns an unsubscribe function.
|
|
2033
|
+
*/
|
|
2034
|
+
subscribe(contextId, handler, codec = jsonCodec()) {
|
|
2035
|
+
const listener = (event) => {
|
|
2036
|
+
const e = event;
|
|
2037
|
+
if (e.type !== "Ephemeral" || e.contextId !== contextId) return;
|
|
2038
|
+
const data = e.data;
|
|
2039
|
+
if (!data?.author) return;
|
|
2040
|
+
const removed = Boolean(data.removed);
|
|
2041
|
+
const entry = {
|
|
2042
|
+
author: data.author,
|
|
2043
|
+
state: removed || data.state === void 0 ? void 0 : codec.decode(data.state),
|
|
2044
|
+
removed
|
|
2045
|
+
};
|
|
2046
|
+
if (data.ageMs !== void 0) entry.ageMs = data.ageMs;
|
|
2047
|
+
handler(entry);
|
|
2048
|
+
};
|
|
2049
|
+
this.sse.on("event", listener);
|
|
2050
|
+
void this.sse.connect().catch(() => void 0);
|
|
2051
|
+
void this.sse.subscribe([contextId]).catch(() => void 0);
|
|
2052
|
+
return () => {
|
|
2053
|
+
this.sse.off("event", listener);
|
|
2054
|
+
};
|
|
2055
|
+
}
|
|
2056
|
+
};
|
|
2057
|
+
|
|
1994
2058
|
// src/mero-js.ts
|
|
1995
2059
|
var REFRESH_LOCK_NAME = "mero-js:token-refresh";
|
|
1996
2060
|
function getLockManager() {
|
|
@@ -2109,6 +2173,21 @@ var MeroJs = class {
|
|
|
2109
2173
|
}
|
|
2110
2174
|
return this.sseClient;
|
|
2111
2175
|
}
|
|
2176
|
+
/**
|
|
2177
|
+
* Get the ephemeral-presence client (lazy initialized).
|
|
2178
|
+
*
|
|
2179
|
+
* Shares this instance's SSE client, so `subscribe` reuses the one event
|
|
2180
|
+
* stream rather than opening a second connection.
|
|
2181
|
+
*/
|
|
2182
|
+
get ephemeral() {
|
|
2183
|
+
if (!this.ephemeralClient) {
|
|
2184
|
+
this.ephemeralClient = new EphemeralClient({
|
|
2185
|
+
httpClient: this.httpClient,
|
|
2186
|
+
sse: this.events
|
|
2187
|
+
});
|
|
2188
|
+
}
|
|
2189
|
+
return this.ephemeralClient;
|
|
2190
|
+
}
|
|
2112
2191
|
/**
|
|
2113
2192
|
* Get the WebSocket event client (lazy initialized).
|
|
2114
2193
|
* @experimental Use `events` (SSE) for production. WsClient is experimental.
|
|
@@ -2462,6 +2541,7 @@ export {
|
|
|
2462
2541
|
CAPABILITIES,
|
|
2463
2542
|
CloudClient,
|
|
2464
2543
|
DEFAULT_LOCAL_NODE_PORTS,
|
|
2544
|
+
EphemeralClient,
|
|
2465
2545
|
HTTPError,
|
|
2466
2546
|
LocalStorageTokenStore,
|
|
2467
2547
|
MemoryTokenStore,
|
|
@@ -2491,6 +2571,7 @@ export {
|
|
|
2491
2571
|
createUniversalHttpClient,
|
|
2492
2572
|
discoverLocalNodes,
|
|
2493
2573
|
hasCap,
|
|
2574
|
+
jsonCodec,
|
|
2494
2575
|
localNodeUrl,
|
|
2495
2576
|
nodeEndpoint,
|
|
2496
2577
|
parseAuthCallback,
|