meridian-sdk 0.2.0 → 0.2.2
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/biome.json +4 -0
- package/dist/auth/token.d.ts +0 -19
- package/dist/auth/token.d.ts.map +1 -1
- package/dist/auth/token.js +6 -31
- package/dist/auth/token.js.map +1 -1
- package/dist/client.d.ts +139 -23
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +165 -52
- package/dist/client.js.map +1 -1
- package/dist/codec.d.ts +7 -35
- package/dist/codec.d.ts.map +1 -1
- package/dist/codec.js +13 -65
- package/dist/codec.js.map +1 -1
- package/dist/constants.d.ts +7 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +7 -0
- package/dist/constants.js.map +1 -0
- package/dist/crdt/gcounter.d.ts +18 -9
- package/dist/crdt/gcounter.d.ts.map +1 -1
- package/dist/crdt/gcounter.js +16 -13
- package/dist/crdt/gcounter.js.map +1 -1
- package/dist/crdt/lwwregister.d.ts +24 -11
- package/dist/crdt/lwwregister.d.ts.map +1 -1
- package/dist/crdt/lwwregister.js +25 -19
- package/dist/crdt/lwwregister.js.map +1 -1
- package/dist/crdt/orset.d.ts +25 -13
- package/dist/crdt/orset.d.ts.map +1 -1
- package/dist/crdt/orset.js +31 -23
- package/dist/crdt/orset.js.map +1 -1
- package/dist/crdt/pncounter.d.ts +22 -4
- package/dist/crdt/pncounter.d.ts.map +1 -1
- package/dist/crdt/pncounter.js +28 -14
- package/dist/crdt/pncounter.js.map +1 -1
- package/dist/crdt/presence.d.ts +33 -13
- package/dist/crdt/presence.d.ts.map +1 -1
- package/dist/crdt/presence.js +36 -20
- package/dist/crdt/presence.js.map +1 -1
- package/dist/errors.d.ts +0 -4
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +0 -16
- package/dist/errors.js.map +1 -1
- package/dist/schema.d.ts +3 -9
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +3 -34
- package/dist/schema.js.map +1 -1
- package/dist/sync/clock.d.ts +1 -20
- package/dist/sync/clock.d.ts.map +1 -1
- package/dist/sync/clock.js +20 -46
- package/dist/sync/clock.js.map +1 -1
- package/dist/sync/delta.d.ts +5 -22
- package/dist/sync/delta.d.ts.map +1 -1
- package/dist/sync/delta.js +18 -26
- package/dist/sync/delta.js.map +1 -1
- package/dist/transport/http.d.ts +1 -14
- package/dist/transport/http.d.ts.map +1 -1
- package/dist/transport/http.js +3 -21
- package/dist/transport/http.js.map +1 -1
- package/dist/transport/websocket.d.ts +0 -27
- package/dist/transport/websocket.d.ts.map +1 -1
- package/dist/transport/websocket.js +9 -37
- package/dist/transport/websocket.js.map +1 -1
- package/dist/utils/to-hex.d.ts +2 -0
- package/dist/utils/to-hex.d.ts.map +1 -0
- package/dist/utils/to-hex.js +2 -0
- package/dist/utils/to-hex.js.map +1 -0
- package/package.json +6 -3
- package/src/auth/token.ts +6 -34
- package/src/client.ts +165 -65
- package/src/codec.ts +13 -71
- package/src/constants.ts +6 -0
- package/src/crdt/gcounter.ts +18 -20
- package/src/crdt/lwwregister.ts +27 -26
- package/src/crdt/orset.ts +32 -29
- package/src/crdt/pncounter.ts +30 -21
- package/src/crdt/presence.ts +37 -26
- package/src/errors.ts +0 -21
- package/src/schema.ts +3 -44
- package/src/sync/clock.ts +18 -50
- package/src/sync/delta.ts +20 -58
- package/src/transport/http.ts +3 -33
- package/src/transport/websocket.ts +15 -52
- package/src/utils/to-hex.ts +1 -0
- package/test/integration.test.ts +2 -3
- package/test/sync.test.ts +1 -2
- package/tsconfig.json +2 -15
package/biome.json
ADDED
package/dist/auth/token.d.ts
CHANGED
|
@@ -1,27 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Token parsing and expiry check (client-side only — no signature verification).
|
|
3
|
-
*
|
|
4
|
-
* Wire format: `base64url_no_pad(msgpack(TokenClaims)) + "." + base64url_no_pad(sig[64B])`
|
|
5
|
-
*/
|
|
6
1
|
import { Effect } from "effect";
|
|
7
2
|
import { TokenParseError, TokenExpiredError } from "../errors.js";
|
|
8
3
|
import { TokenClaims } from "../schema.js";
|
|
9
|
-
/**
|
|
10
|
-
* Parse a Meridian token string and return the decoded claims.
|
|
11
|
-
* Returns Effect<TokenClaims, TokenParseError>.
|
|
12
|
-
* Does NOT verify the ed25519 signature — the server enforces that.
|
|
13
|
-
*/
|
|
14
4
|
export declare const parseToken: (token: string) => Effect.Effect<TokenClaims, TokenParseError>;
|
|
15
|
-
/**
|
|
16
|
-
* Check token expiry. Returns Effect<TokenClaims, TokenExpiredError>.
|
|
17
|
-
* Clock-skew tolerance: ±5s.
|
|
18
|
-
*/
|
|
19
5
|
export declare const checkTokenExpiry: (claims: TokenClaims, nowMs?: number) => Effect.Effect<TokenClaims, TokenExpiredError>;
|
|
20
|
-
/**
|
|
21
|
-
* Parse and check expiry in one step.
|
|
22
|
-
* Returns Effect<TokenClaims, TokenParseError | TokenExpiredError>.
|
|
23
|
-
*/
|
|
24
6
|
export declare const parseAndValidateToken: (token: string) => Effect.Effect<TokenClaims, TokenParseError | TokenExpiredError>;
|
|
25
|
-
/** Returns milliseconds until the token expires (negative if already expired). */
|
|
26
7
|
export declare const tokenTtlMs: (claims: TokenClaims, nowMs?: number) => number;
|
|
27
8
|
//# sourceMappingURL=token.d.ts.map
|
package/dist/auth/token.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/auth/token.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/auth/token.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG3C,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,eAAe,CA+BjF,CAAC;AAEL,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,WAAW,EACnB,cAAkB,KACjB,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,iBAAiB,CAK9C,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,OAAO,MAAM,KACZ,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,eAAe,GAAG,iBAAiB,CACP,CAAC;AAE3D,eAAO,MAAM,UAAU,GAAI,QAAQ,WAAW,EAAE,cAAkB,KAAG,MAC1C,CAAC"}
|
package/dist/auth/token.js
CHANGED
|
@@ -1,20 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
* Token parsing and expiry check (client-side only — no signature verification).
|
|
3
|
-
*
|
|
4
|
-
* Wire format: `base64url_no_pad(msgpack(TokenClaims)) + "." + base64url_no_pad(sig[64B])`
|
|
5
|
-
*/
|
|
6
|
-
import { unpack } from "msgpackr";
|
|
1
|
+
import { decode } from "@msgpack/msgpack";
|
|
7
2
|
import { Effect, Schema } from "effect";
|
|
8
3
|
import { TokenParseError, TokenExpiredError } from "../errors.js";
|
|
9
4
|
import { TokenClaims } from "../schema.js";
|
|
10
|
-
|
|
11
|
-
// Parse
|
|
12
|
-
// ---------------------------------------------------------------------------
|
|
13
|
-
/**
|
|
14
|
-
* Parse a Meridian token string and return the decoded claims.
|
|
15
|
-
* Returns Effect<TokenClaims, TokenParseError>.
|
|
16
|
-
* Does NOT verify the ed25519 signature — the server enforces that.
|
|
17
|
-
*/
|
|
5
|
+
import { TOKEN_SKEW_MS } from "../constants.js";
|
|
18
6
|
export const parseToken = (token) => Effect.gen(function* () {
|
|
19
7
|
const dotIndex = token.indexOf(".");
|
|
20
8
|
if (dotIndex === -1) {
|
|
@@ -32,7 +20,7 @@ export const parseToken = (token) => Effect.gen(function* () {
|
|
|
32
20
|
}
|
|
33
21
|
let raw;
|
|
34
22
|
try {
|
|
35
|
-
raw =
|
|
23
|
+
raw = decode(bytes);
|
|
36
24
|
}
|
|
37
25
|
catch {
|
|
38
26
|
yield* Effect.fail(new TokenParseError({ message: "Invalid token format: msgpack decode failed" }));
|
|
@@ -40,28 +28,15 @@ export const parseToken = (token) => Effect.gen(function* () {
|
|
|
40
28
|
}
|
|
41
29
|
return yield* Schema.decodeUnknown(TokenClaims)(raw).pipe(Effect.mapError((e) => new TokenParseError({ message: `Invalid token format: ${e.message}` })));
|
|
42
30
|
});
|
|
43
|
-
/**
|
|
44
|
-
* Check token expiry. Returns Effect<TokenClaims, TokenExpiredError>.
|
|
45
|
-
* Clock-skew tolerance: ±5s.
|
|
46
|
-
*/
|
|
47
31
|
export const checkTokenExpiry = (claims, nowMs = Date.now()) => {
|
|
48
|
-
|
|
49
|
-
if (nowMs >= claims.expires_at + SKEW_MS) {
|
|
32
|
+
if (nowMs >= claims.expires_at + TOKEN_SKEW_MS) {
|
|
50
33
|
return Effect.fail(new TokenExpiredError({ expiredAt: claims.expires_at }));
|
|
51
34
|
}
|
|
52
35
|
return Effect.succeed(claims);
|
|
53
36
|
};
|
|
54
|
-
/**
|
|
55
|
-
* Parse and check expiry in one step.
|
|
56
|
-
* Returns Effect<TokenClaims, TokenParseError | TokenExpiredError>.
|
|
57
|
-
*/
|
|
58
37
|
export const parseAndValidateToken = (token) => parseToken(token).pipe(Effect.flatMap(checkTokenExpiry));
|
|
59
|
-
/** Returns milliseconds until the token expires (negative if already expired). */
|
|
60
38
|
export const tokenTtlMs = (claims, nowMs = Date.now()) => claims.expires_at - nowMs;
|
|
61
|
-
|
|
62
|
-
// Base64url (no-padding) decoder — no external dep
|
|
63
|
-
// ---------------------------------------------------------------------------
|
|
64
|
-
function base64urlDecode(input) {
|
|
39
|
+
const base64urlDecode = (input) => {
|
|
65
40
|
const padded = input.replace(/-/g, "+").replace(/_/g, "/");
|
|
66
41
|
const padLen = (4 - (padded.length % 4)) % 4;
|
|
67
42
|
const b64 = padded + "=".repeat(padLen);
|
|
@@ -71,5 +46,5 @@ function base64urlDecode(input) {
|
|
|
71
46
|
bytes[i] = binary.charCodeAt(i);
|
|
72
47
|
}
|
|
73
48
|
return bytes;
|
|
74
|
-
}
|
|
49
|
+
};
|
|
75
50
|
//# sourceMappingURL=token.js.map
|
package/dist/auth/token.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/auth/token.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/auth/token.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,19 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* MeridianClient — top-level SDK entry point.
|
|
3
|
-
*
|
|
4
|
-
* Use `MeridianClient.create(config)` (returns Effect) to parse the token
|
|
5
|
-
* and validate it before connecting.
|
|
6
|
-
*
|
|
7
|
-
* ```ts
|
|
8
|
-
* const client = await Effect.runPromise(
|
|
9
|
-
* MeridianClient.create({ url: "ws://localhost:3000", namespace: "room", token })
|
|
10
|
-
* );
|
|
11
|
-
* const counter = client.gcounter("gc:page-views");
|
|
12
|
-
* counter.increment();
|
|
13
|
-
* counter.onChange(v => console.log("views:", v));
|
|
14
|
-
* ```
|
|
15
|
-
*/
|
|
16
|
-
import { Effect, Schema } from "effect";
|
|
1
|
+
import { Effect, type Schema } from "effect";
|
|
17
2
|
import { HttpClient } from "./transport/http.js";
|
|
18
3
|
import { GCounterHandle } from "./crdt/gcounter.js";
|
|
19
4
|
import { PNCounterHandle } from "./crdt/pncounter.js";
|
|
@@ -23,15 +8,37 @@ import { PresenceHandle } from "./crdt/presence.js";
|
|
|
23
8
|
import type { TokenClaims } from "./schema.js";
|
|
24
9
|
import type { TokenParseError, TokenExpiredError } from "./errors.js";
|
|
25
10
|
export interface MeridianClientConfig {
|
|
26
|
-
/** Base URL of the Meridian server, e.g. "http://localhost:3000" */
|
|
27
11
|
url: string;
|
|
28
|
-
/** Namespace to connect to. */
|
|
29
12
|
namespace: string;
|
|
30
|
-
/** Meridian token for this namespace. */
|
|
31
13
|
token: string;
|
|
32
|
-
/** If true, open the WebSocket immediately. Default: true */
|
|
33
14
|
autoConnect?: boolean;
|
|
34
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* The main entry point for the Meridian real-time CRDT SDK.
|
|
18
|
+
*
|
|
19
|
+
* Create an instance with the static `MeridianClient.create()` factory, then
|
|
20
|
+
* use the handle methods to obtain typed CRDT handles that sync automatically
|
|
21
|
+
* over WebSocket.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* import { Effect } from 'effect';
|
|
26
|
+
* import { MeridianClient } from 'meridian-sdk';
|
|
27
|
+
*
|
|
28
|
+
* const client = await Effect.runPromise(
|
|
29
|
+
* MeridianClient.create({
|
|
30
|
+
* url: 'wss://example.com',
|
|
31
|
+
* namespace: 'my-app',
|
|
32
|
+
* token: '<JWT>',
|
|
33
|
+
* })
|
|
34
|
+
* );
|
|
35
|
+
*
|
|
36
|
+
* const counter = client.gcounter('visitors');
|
|
37
|
+
* counter.increment();
|
|
38
|
+
*
|
|
39
|
+
* client.close();
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
35
42
|
export declare class MeridianClient {
|
|
36
43
|
readonly namespace: string;
|
|
37
44
|
readonly clientId: number;
|
|
@@ -45,17 +52,126 @@ export declare class MeridianClient {
|
|
|
45
52
|
private readonly prHandles;
|
|
46
53
|
private constructor();
|
|
47
54
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
55
|
+
* Creates and validates a new `MeridianClient` from the supplied configuration.
|
|
56
|
+
*
|
|
57
|
+
* The JWT `token` is parsed and validated synchronously inside the Effect; the
|
|
58
|
+
* Effect fails with `TokenParseError` or `TokenExpiredError` if the token is
|
|
59
|
+
* malformed or expired. The WebSocket connection is opened immediately unless
|
|
60
|
+
* `autoConnect` is set to `false`.
|
|
61
|
+
*
|
|
62
|
+
* @param config - Connection configuration including the server `url`,
|
|
63
|
+
* `namespace`, and a signed `token`.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```ts
|
|
67
|
+
* import { Effect } from 'effect';
|
|
68
|
+
* import { MeridianClient } from 'meridian-sdk';
|
|
69
|
+
*
|
|
70
|
+
* const client = await Effect.runPromise(
|
|
71
|
+
* MeridianClient.create({ url: 'ws://localhost:8080', namespace: 'demo', token: myToken })
|
|
72
|
+
* );
|
|
73
|
+
* ```
|
|
50
74
|
*/
|
|
51
75
|
static create(config: MeridianClientConfig): Effect.Effect<MeridianClient, TokenParseError | TokenExpiredError>;
|
|
76
|
+
/**
|
|
77
|
+
* Returns a handle for a grow-only counter (GCounter) CRDT.
|
|
78
|
+
*
|
|
79
|
+
* Handles are cached by `crdtId`; calling this method multiple times with the
|
|
80
|
+
* same id returns the same handle instance and creates only one subscription.
|
|
81
|
+
*
|
|
82
|
+
* @param crdtId - Unique identifier for the CRDT within this namespace.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* const counter = client.gcounter('page-views');
|
|
87
|
+
* counter.increment(5);
|
|
88
|
+
* console.log(counter.value()); // 5
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
52
91
|
gcounter(crdtId: string): GCounterHandle;
|
|
92
|
+
/**
|
|
93
|
+
* Returns a handle for a positive-negative counter (PNCounter) CRDT.
|
|
94
|
+
*
|
|
95
|
+
* Handles are cached by `crdtId`; calling this method multiple times with the
|
|
96
|
+
* same id returns the same handle instance and creates only one subscription.
|
|
97
|
+
*
|
|
98
|
+
* @param crdtId - Unique identifier for the CRDT within this namespace.
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```ts
|
|
102
|
+
* const score = client.pncounter('game-score');
|
|
103
|
+
* score.increment(10);
|
|
104
|
+
* score.decrement(3);
|
|
105
|
+
* console.log(score.value()); // 7
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
53
108
|
pncounter(crdtId: string): PNCounterHandle;
|
|
109
|
+
/**
|
|
110
|
+
* Returns a handle for an Observed-Remove Set (OR-Set) CRDT.
|
|
111
|
+
*
|
|
112
|
+
* Handles are cached by `crdtId`; calling this method multiple times with the
|
|
113
|
+
* same id returns the same handle instance and creates only one subscription.
|
|
114
|
+
*
|
|
115
|
+
* @param crdtId - Unique identifier for the CRDT within this namespace.
|
|
116
|
+
* @param schema - Optional Effect schema used to decode elements from the wire format.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```ts
|
|
120
|
+
* import { Schema } from 'effect';
|
|
121
|
+
*
|
|
122
|
+
* const tags = client.orset('article-tags', Schema.String);
|
|
123
|
+
* tags.add('typescript');
|
|
124
|
+
* tags.remove('typescript');
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
54
127
|
orset<T>(crdtId: string, schema?: Schema.Schema<T>): ORSetHandle<T>;
|
|
128
|
+
/**
|
|
129
|
+
* Returns a handle for a Last-Write-Wins register (LWW-Register) CRDT.
|
|
130
|
+
*
|
|
131
|
+
* Handles are cached by `crdtId`; calling this method multiple times with the
|
|
132
|
+
* same id returns the same handle instance and creates only one subscription.
|
|
133
|
+
*
|
|
134
|
+
* @param crdtId - Unique identifier for the CRDT within this namespace.
|
|
135
|
+
* @param schema - Optional Effect schema used to decode the value from the wire format.
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* ```ts
|
|
139
|
+
* import { Schema } from 'effect';
|
|
140
|
+
*
|
|
141
|
+
* const theme = client.lwwregister('ui-theme', Schema.Literal('light', 'dark'));
|
|
142
|
+
* theme.set('dark');
|
|
143
|
+
* console.log(theme.value()); // 'dark'
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
55
146
|
lwwregister<T>(crdtId: string, schema?: Schema.Schema<T>): LwwRegisterHandle<T>;
|
|
147
|
+
/**
|
|
148
|
+
* Returns a handle for a presence channel CRDT.
|
|
149
|
+
*
|
|
150
|
+
* Handles are cached by `crdtId`; calling this method multiple times with the
|
|
151
|
+
* same id returns the same handle instance and creates only one subscription.
|
|
152
|
+
*
|
|
153
|
+
* @param crdtId - Unique identifier for the presence channel within this namespace.
|
|
154
|
+
* @param schema - Optional Effect schema used to decode peer data from the wire format.
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```ts
|
|
158
|
+
* import { Schema } from 'effect';
|
|
159
|
+
*
|
|
160
|
+
* const room = client.presence('room-1', Schema.Struct({ name: Schema.String }));
|
|
161
|
+
* room.heartbeat({ name: 'Alice' }, 10_000);
|
|
162
|
+
* console.log(room.online()); // [{ clientId: 1, data: { name: 'Alice' }, expiresAtMs: ... }]
|
|
163
|
+
* room.leave();
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
56
166
|
presence<T>(crdtId: string, schema?: Schema.Schema<T>): PresenceHandle<T>;
|
|
57
|
-
/** Resolves when the WebSocket is connected and ready. */
|
|
58
167
|
waitForConnected(timeoutMs?: number): Promise<void>;
|
|
168
|
+
/**
|
|
169
|
+
* Closes the underlying WebSocket connection.
|
|
170
|
+
*
|
|
171
|
+
* Call this when the client is no longer needed to free resources. If you are
|
|
172
|
+
* using `<MeridianProvider>` in React, the provider calls this automatically
|
|
173
|
+
* on unmount.
|
|
174
|
+
*/
|
|
59
175
|
close(): void;
|
|
60
176
|
private handleServerMsg;
|
|
61
177
|
}
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE7C,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AASpD,OAAO,KAAK,EAAa,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEtE,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBAAa,cAAc;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAE7B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IACxC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAG1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqC;IAC/D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsC;IAChE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA2C;IACrE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiD;IAC3E,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8C;IAExE,OAAO;IAsBP;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,MAAM,CAAC,MAAM,CACX,MAAM,EAAE,oBAAoB,GAC3B,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,eAAe,GAAG,iBAAiB,CAAC;IAMrE;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc;IAUxC;;;;;;;;;;;;;;;OAeG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe;IAU1C;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC;IAWnE;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC;IAW/E;;;;;;;;;;;;;;;;;;OAkBG;IACH,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC;IAWzE,gBAAgB,CAAC,SAAS,SAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlD;;;;;;OAMG;IACH,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,eAAe;CA6BxB"}
|
package/dist/client.js
CHANGED
|
@@ -1,19 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* MeridianClient — top-level SDK entry point.
|
|
3
|
-
*
|
|
4
|
-
* Use `MeridianClient.create(config)` (returns Effect) to parse the token
|
|
5
|
-
* and validate it before connecting.
|
|
6
|
-
*
|
|
7
|
-
* ```ts
|
|
8
|
-
* const client = await Effect.runPromise(
|
|
9
|
-
* MeridianClient.create({ url: "ws://localhost:3000", namespace: "room", token })
|
|
10
|
-
* );
|
|
11
|
-
* const counter = client.gcounter("gc:page-views");
|
|
12
|
-
* counter.increment();
|
|
13
|
-
* counter.onChange(v => console.log("views:", v));
|
|
14
|
-
* ```
|
|
15
|
-
*/
|
|
16
|
-
import { Effect, Schema } from "effect";
|
|
1
|
+
import { Effect } from "effect";
|
|
17
2
|
import { WsTransport } from "./transport/websocket.js";
|
|
18
3
|
import { HttpClient } from "./transport/http.js";
|
|
19
4
|
import { GCounterHandle } from "./crdt/gcounter.js";
|
|
@@ -23,17 +8,39 @@ import { LwwRegisterHandle } from "./crdt/lwwregister.js";
|
|
|
23
8
|
import { PresenceHandle } from "./crdt/presence.js";
|
|
24
9
|
import { decodeGCounterDelta, decodePNCounterDelta, decodeORSetDelta, decodeLwwDelta, decodePresenceDelta, } from "./sync/delta.js";
|
|
25
10
|
import { parseAndValidateToken } from "./auth/token.js";
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
11
|
+
/**
|
|
12
|
+
* The main entry point for the Meridian real-time CRDT SDK.
|
|
13
|
+
*
|
|
14
|
+
* Create an instance with the static `MeridianClient.create()` factory, then
|
|
15
|
+
* use the handle methods to obtain typed CRDT handles that sync automatically
|
|
16
|
+
* over WebSocket.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { Effect } from 'effect';
|
|
21
|
+
* import { MeridianClient } from 'meridian-sdk';
|
|
22
|
+
*
|
|
23
|
+
* const client = await Effect.runPromise(
|
|
24
|
+
* MeridianClient.create({
|
|
25
|
+
* url: 'wss://example.com',
|
|
26
|
+
* namespace: 'my-app',
|
|
27
|
+
* token: '<JWT>',
|
|
28
|
+
* })
|
|
29
|
+
* );
|
|
30
|
+
*
|
|
31
|
+
* const counter = client.gcounter('visitors');
|
|
32
|
+
* counter.increment();
|
|
33
|
+
*
|
|
34
|
+
* client.close();
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
29
37
|
export class MeridianClient {
|
|
30
38
|
namespace;
|
|
31
39
|
clientId;
|
|
32
40
|
claims;
|
|
33
41
|
transport;
|
|
34
42
|
http;
|
|
35
|
-
//
|
|
36
|
-
// factories restore them via typed get+cast on retrieval.
|
|
43
|
+
// HACK: Generic params are erased at storage level; factories restore them via typed get+cast on retrieval.
|
|
37
44
|
gcHandles = new Map();
|
|
38
45
|
pnHandles = new Map();
|
|
39
46
|
orHandles = new Map();
|
|
@@ -58,70 +65,176 @@ export class MeridianClient {
|
|
|
58
65
|
}
|
|
59
66
|
}
|
|
60
67
|
/**
|
|
61
|
-
*
|
|
62
|
-
*
|
|
68
|
+
* Creates and validates a new `MeridianClient` from the supplied configuration.
|
|
69
|
+
*
|
|
70
|
+
* The JWT `token` is parsed and validated synchronously inside the Effect; the
|
|
71
|
+
* Effect fails with `TokenParseError` or `TokenExpiredError` if the token is
|
|
72
|
+
* malformed or expired. The WebSocket connection is opened immediately unless
|
|
73
|
+
* `autoConnect` is set to `false`.
|
|
74
|
+
*
|
|
75
|
+
* @param config - Connection configuration including the server `url`,
|
|
76
|
+
* `namespace`, and a signed `token`.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```ts
|
|
80
|
+
* import { Effect } from 'effect';
|
|
81
|
+
* import { MeridianClient } from 'meridian-sdk';
|
|
82
|
+
*
|
|
83
|
+
* const client = await Effect.runPromise(
|
|
84
|
+
* MeridianClient.create({ url: 'ws://localhost:8080', namespace: 'demo', token: myToken })
|
|
85
|
+
* );
|
|
86
|
+
* ```
|
|
63
87
|
*/
|
|
64
88
|
static create(config) {
|
|
65
89
|
return parseAndValidateToken(config.token).pipe(Effect.map((claims) => new MeridianClient(config, claims)));
|
|
66
90
|
}
|
|
67
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Returns a handle for a grow-only counter (GCounter) CRDT.
|
|
93
|
+
*
|
|
94
|
+
* Handles are cached by `crdtId`; calling this method multiple times with the
|
|
95
|
+
* same id returns the same handle instance and creates only one subscription.
|
|
96
|
+
*
|
|
97
|
+
* @param crdtId - Unique identifier for the CRDT within this namespace.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* const counter = client.gcounter('page-views');
|
|
102
|
+
* counter.increment(5);
|
|
103
|
+
* console.log(counter.value()); // 5
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
68
106
|
gcounter(crdtId) {
|
|
69
|
-
let
|
|
70
|
-
if (!
|
|
71
|
-
|
|
72
|
-
this.gcHandles.set(crdtId,
|
|
107
|
+
let handle = this.gcHandles.get(crdtId);
|
|
108
|
+
if (!handle) {
|
|
109
|
+
handle = new GCounterHandle({ ns: this.namespace, crdtId, clientId: this.clientId, transport: this.transport });
|
|
110
|
+
this.gcHandles.set(crdtId, handle);
|
|
73
111
|
this.transport.subscribe(crdtId);
|
|
74
112
|
}
|
|
75
|
-
return
|
|
113
|
+
return handle;
|
|
76
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* Returns a handle for a positive-negative counter (PNCounter) CRDT.
|
|
117
|
+
*
|
|
118
|
+
* Handles are cached by `crdtId`; calling this method multiple times with the
|
|
119
|
+
* same id returns the same handle instance and creates only one subscription.
|
|
120
|
+
*
|
|
121
|
+
* @param crdtId - Unique identifier for the CRDT within this namespace.
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```ts
|
|
125
|
+
* const score = client.pncounter('game-score');
|
|
126
|
+
* score.increment(10);
|
|
127
|
+
* score.decrement(3);
|
|
128
|
+
* console.log(score.value()); // 7
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
77
131
|
pncounter(crdtId) {
|
|
78
|
-
let
|
|
79
|
-
if (!
|
|
80
|
-
|
|
81
|
-
this.pnHandles.set(crdtId,
|
|
132
|
+
let handle = this.pnHandles.get(crdtId);
|
|
133
|
+
if (!handle) {
|
|
134
|
+
handle = new PNCounterHandle({ ns: this.namespace, crdtId, clientId: this.clientId, transport: this.transport });
|
|
135
|
+
this.pnHandles.set(crdtId, handle);
|
|
82
136
|
this.transport.subscribe(crdtId);
|
|
83
137
|
}
|
|
84
|
-
return
|
|
138
|
+
return handle;
|
|
85
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Returns a handle for an Observed-Remove Set (OR-Set) CRDT.
|
|
142
|
+
*
|
|
143
|
+
* Handles are cached by `crdtId`; calling this method multiple times with the
|
|
144
|
+
* same id returns the same handle instance and creates only one subscription.
|
|
145
|
+
*
|
|
146
|
+
* @param crdtId - Unique identifier for the CRDT within this namespace.
|
|
147
|
+
* @param schema - Optional Effect schema used to decode elements from the wire format.
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```ts
|
|
151
|
+
* import { Schema } from 'effect';
|
|
152
|
+
*
|
|
153
|
+
* const tags = client.orset('article-tags', Schema.String);
|
|
154
|
+
* tags.add('typescript');
|
|
155
|
+
* tags.remove('typescript');
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
86
158
|
orset(crdtId, schema) {
|
|
87
|
-
let
|
|
88
|
-
if (!
|
|
159
|
+
let handle = this.orHandles.get(crdtId);
|
|
160
|
+
if (!handle) {
|
|
89
161
|
const base = { ns: this.namespace, crdtId, clientId: this.clientId, transport: this.transport };
|
|
90
|
-
|
|
91
|
-
this.orHandles.set(crdtId,
|
|
162
|
+
handle = schema ? new ORSetHandle({ ...base, schema }) : new ORSetHandle(base);
|
|
163
|
+
this.orHandles.set(crdtId, handle);
|
|
92
164
|
this.transport.subscribe(crdtId);
|
|
93
165
|
}
|
|
94
|
-
return
|
|
166
|
+
return handle;
|
|
95
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Returns a handle for a Last-Write-Wins register (LWW-Register) CRDT.
|
|
170
|
+
*
|
|
171
|
+
* Handles are cached by `crdtId`; calling this method multiple times with the
|
|
172
|
+
* same id returns the same handle instance and creates only one subscription.
|
|
173
|
+
*
|
|
174
|
+
* @param crdtId - Unique identifier for the CRDT within this namespace.
|
|
175
|
+
* @param schema - Optional Effect schema used to decode the value from the wire format.
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* ```ts
|
|
179
|
+
* import { Schema } from 'effect';
|
|
180
|
+
*
|
|
181
|
+
* const theme = client.lwwregister('ui-theme', Schema.Literal('light', 'dark'));
|
|
182
|
+
* theme.set('dark');
|
|
183
|
+
* console.log(theme.value()); // 'dark'
|
|
184
|
+
* ```
|
|
185
|
+
*/
|
|
96
186
|
lwwregister(crdtId, schema) {
|
|
97
|
-
let
|
|
98
|
-
if (!
|
|
187
|
+
let handle = this.lwHandles.get(crdtId);
|
|
188
|
+
if (!handle) {
|
|
99
189
|
const base = { ns: this.namespace, crdtId, clientId: this.clientId, transport: this.transport };
|
|
100
|
-
|
|
101
|
-
this.lwHandles.set(crdtId,
|
|
190
|
+
handle = schema ? new LwwRegisterHandle({ ...base, schema }) : new LwwRegisterHandle(base);
|
|
191
|
+
this.lwHandles.set(crdtId, handle);
|
|
102
192
|
this.transport.subscribe(crdtId);
|
|
103
193
|
}
|
|
104
|
-
return
|
|
194
|
+
return handle;
|
|
105
195
|
}
|
|
196
|
+
/**
|
|
197
|
+
* Returns a handle for a presence channel CRDT.
|
|
198
|
+
*
|
|
199
|
+
* Handles are cached by `crdtId`; calling this method multiple times with the
|
|
200
|
+
* same id returns the same handle instance and creates only one subscription.
|
|
201
|
+
*
|
|
202
|
+
* @param crdtId - Unique identifier for the presence channel within this namespace.
|
|
203
|
+
* @param schema - Optional Effect schema used to decode peer data from the wire format.
|
|
204
|
+
*
|
|
205
|
+
* @example
|
|
206
|
+
* ```ts
|
|
207
|
+
* import { Schema } from 'effect';
|
|
208
|
+
*
|
|
209
|
+
* const room = client.presence('room-1', Schema.Struct({ name: Schema.String }));
|
|
210
|
+
* room.heartbeat({ name: 'Alice' }, 10_000);
|
|
211
|
+
* console.log(room.online()); // [{ clientId: 1, data: { name: 'Alice' }, expiresAtMs: ... }]
|
|
212
|
+
* room.leave();
|
|
213
|
+
* ```
|
|
214
|
+
*/
|
|
106
215
|
presence(crdtId, schema) {
|
|
107
|
-
let
|
|
108
|
-
if (!
|
|
216
|
+
let handle = this.prHandles.get(crdtId);
|
|
217
|
+
if (!handle) {
|
|
109
218
|
const base = { ns: this.namespace, crdtId, clientId: this.clientId, transport: this.transport };
|
|
110
|
-
|
|
111
|
-
this.prHandles.set(crdtId,
|
|
219
|
+
handle = schema ? new PresenceHandle({ ...base, schema }) : new PresenceHandle(base);
|
|
220
|
+
this.prHandles.set(crdtId, handle);
|
|
112
221
|
this.transport.subscribe(crdtId);
|
|
113
222
|
}
|
|
114
|
-
return
|
|
223
|
+
return handle;
|
|
115
224
|
}
|
|
116
|
-
// ---- Lifecycle ----
|
|
117
|
-
/** Resolves when the WebSocket is connected and ready. */
|
|
118
225
|
waitForConnected(timeoutMs = 5_000) {
|
|
119
226
|
return this.transport.waitForConnected(timeoutMs);
|
|
120
227
|
}
|
|
228
|
+
/**
|
|
229
|
+
* Closes the underlying WebSocket connection.
|
|
230
|
+
*
|
|
231
|
+
* Call this when the client is no longer needed to free resources. If you are
|
|
232
|
+
* using `<MeridianProvider>` in React, the provider calls this automatically
|
|
233
|
+
* on unmount.
|
|
234
|
+
*/
|
|
121
235
|
close() {
|
|
122
236
|
this.transport.close();
|
|
123
237
|
}
|
|
124
|
-
// ---- Internal: route ServerMsg.Delta to the right handle ----
|
|
125
238
|
handleServerMsg(msg) {
|
|
126
239
|
if (!("Delta" in msg))
|
|
127
240
|
return;
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|