meridian-sdk 0.2.1 → 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.
Files changed (84) hide show
  1. package/biome.json +4 -0
  2. package/dist/auth/token.d.ts +0 -19
  3. package/dist/auth/token.d.ts.map +1 -1
  4. package/dist/auth/token.js +6 -31
  5. package/dist/auth/token.js.map +1 -1
  6. package/dist/client.d.ts +139 -23
  7. package/dist/client.d.ts.map +1 -1
  8. package/dist/client.js +165 -52
  9. package/dist/client.js.map +1 -1
  10. package/dist/codec.d.ts +7 -35
  11. package/dist/codec.d.ts.map +1 -1
  12. package/dist/codec.js +13 -65
  13. package/dist/codec.js.map +1 -1
  14. package/dist/constants.d.ts +7 -0
  15. package/dist/constants.d.ts.map +1 -0
  16. package/dist/constants.js +7 -0
  17. package/dist/constants.js.map +1 -0
  18. package/dist/crdt/gcounter.d.ts +18 -9
  19. package/dist/crdt/gcounter.d.ts.map +1 -1
  20. package/dist/crdt/gcounter.js +16 -13
  21. package/dist/crdt/gcounter.js.map +1 -1
  22. package/dist/crdt/lwwregister.d.ts +24 -11
  23. package/dist/crdt/lwwregister.d.ts.map +1 -1
  24. package/dist/crdt/lwwregister.js +25 -19
  25. package/dist/crdt/lwwregister.js.map +1 -1
  26. package/dist/crdt/orset.d.ts +25 -13
  27. package/dist/crdt/orset.d.ts.map +1 -1
  28. package/dist/crdt/orset.js +31 -23
  29. package/dist/crdt/orset.js.map +1 -1
  30. package/dist/crdt/pncounter.d.ts +22 -4
  31. package/dist/crdt/pncounter.d.ts.map +1 -1
  32. package/dist/crdt/pncounter.js +28 -14
  33. package/dist/crdt/pncounter.js.map +1 -1
  34. package/dist/crdt/presence.d.ts +33 -13
  35. package/dist/crdt/presence.d.ts.map +1 -1
  36. package/dist/crdt/presence.js +36 -20
  37. package/dist/crdt/presence.js.map +1 -1
  38. package/dist/errors.d.ts +0 -4
  39. package/dist/errors.d.ts.map +1 -1
  40. package/dist/errors.js +0 -16
  41. package/dist/errors.js.map +1 -1
  42. package/dist/schema.d.ts +3 -9
  43. package/dist/schema.d.ts.map +1 -1
  44. package/dist/schema.js +3 -34
  45. package/dist/schema.js.map +1 -1
  46. package/dist/sync/clock.d.ts +1 -20
  47. package/dist/sync/clock.d.ts.map +1 -1
  48. package/dist/sync/clock.js +20 -46
  49. package/dist/sync/clock.js.map +1 -1
  50. package/dist/sync/delta.d.ts +5 -22
  51. package/dist/sync/delta.d.ts.map +1 -1
  52. package/dist/sync/delta.js +18 -26
  53. package/dist/sync/delta.js.map +1 -1
  54. package/dist/transport/http.d.ts +1 -14
  55. package/dist/transport/http.d.ts.map +1 -1
  56. package/dist/transport/http.js +3 -21
  57. package/dist/transport/http.js.map +1 -1
  58. package/dist/transport/websocket.d.ts +0 -27
  59. package/dist/transport/websocket.d.ts.map +1 -1
  60. package/dist/transport/websocket.js +9 -37
  61. package/dist/transport/websocket.js.map +1 -1
  62. package/dist/utils/to-hex.d.ts +2 -0
  63. package/dist/utils/to-hex.d.ts.map +1 -0
  64. package/dist/utils/to-hex.js +2 -0
  65. package/dist/utils/to-hex.js.map +1 -0
  66. package/package.json +6 -3
  67. package/src/auth/token.ts +6 -34
  68. package/src/client.ts +165 -65
  69. package/src/codec.ts +13 -71
  70. package/src/constants.ts +6 -0
  71. package/src/crdt/gcounter.ts +18 -20
  72. package/src/crdt/lwwregister.ts +27 -26
  73. package/src/crdt/orset.ts +32 -29
  74. package/src/crdt/pncounter.ts +30 -21
  75. package/src/crdt/presence.ts +37 -26
  76. package/src/errors.ts +0 -21
  77. package/src/schema.ts +3 -44
  78. package/src/sync/clock.ts +18 -50
  79. package/src/sync/delta.ts +20 -58
  80. package/src/transport/http.ts +3 -33
  81. package/src/transport/websocket.ts +15 -52
  82. package/src/utils/to-hex.ts +1 -0
  83. package/test/integration.test.ts +2 -3
  84. package/test/sync.test.ts +1 -2
package/biome.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/2.4.7/schema.json",
3
+ "extends": ["../../biome.json"]
4
+ }
@@ -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
@@ -1 +1 @@
1
- {"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/auth/token.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,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;AAM3C;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,eAAe,CA+BjF,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,WAAW,EACnB,cAAkB,KACjB,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,iBAAiB,CAM9C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAChC,OAAO,MAAM,KACZ,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,eAAe,GAAG,iBAAiB,CACP,CAAC;AAE3D,kFAAkF;AAClF,eAAO,MAAM,UAAU,GAAI,QAAQ,WAAW,EAAE,cAAkB,KAAG,MAC1C,CAAC"}
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"}
@@ -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 = unpack(bytes);
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
- const SKEW_MS = 5_000;
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
@@ -1 +1 @@
1
- {"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/auth/token.ts"],"names":[],"mappings":"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"}
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
- * Create a MeridianClient, parsing and validating the token.
49
- * Returns Effect<MeridianClient, TokenParseError | TokenExpiredError>.
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
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAExC,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;AAMtE,MAAM,WAAW,oBAAoB;IACnC,oEAAoE;IACpE,GAAG,EAAE,MAAM,CAAC;IACZ,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAMD,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;IAI1B,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;;;OAGG;IACH,MAAM,CAAC,MAAM,CACX,MAAM,EAAE,oBAAoB,GAC3B,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,eAAe,GAAG,iBAAiB,CAAC;IAQrE,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc;IAUxC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe;IAU1C,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC;IAWnE,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC;IAW/E,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC;IAazE,0DAA0D;IAC1D,gBAAgB,CAAC,SAAS,SAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlD,KAAK,IAAI,IAAI;IAMb,OAAO,CAAC,eAAe;CA6BxB"}
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
- // MeridianClient
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
- // Handle caches — keyed by crdt_id. Generic params erased at storage level;
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
- * Create a MeridianClient, parsing and validating the token.
62
- * Returns Effect<MeridianClient, TokenParseError | TokenExpiredError>.
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
- // ---- CRDT factory methods ----
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 h = this.gcHandles.get(crdtId);
70
- if (!h) {
71
- h = new GCounterHandle({ ns: this.namespace, crdtId, clientId: this.clientId, transport: this.transport });
72
- this.gcHandles.set(crdtId, h);
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 h;
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 h = this.pnHandles.get(crdtId);
79
- if (!h) {
80
- h = new PNCounterHandle({ ns: this.namespace, crdtId, clientId: this.clientId, transport: this.transport });
81
- this.pnHandles.set(crdtId, h);
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 h;
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 h = this.orHandles.get(crdtId);
88
- if (!h) {
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
- h = schema ? new ORSetHandle({ ...base, schema }) : new ORSetHandle(base);
91
- this.orHandles.set(crdtId, h);
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 h;
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 h = this.lwHandles.get(crdtId);
98
- if (!h) {
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
- h = schema ? new LwwRegisterHandle({ ...base, schema }) : new LwwRegisterHandle(base);
101
- this.lwHandles.set(crdtId, h);
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 h;
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 h = this.prHandles.get(crdtId);
108
- if (!h) {
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
- h = schema ? new PresenceHandle({ ...base, schema }) : new PresenceHandle(base);
111
- this.prHandles.set(crdtId, h);
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 h;
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;
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}