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/dist/codec.d.ts CHANGED
@@ -1,40 +1,12 @@
1
- /**
2
- * Msgpack codec — wraps msgpackr with Meridian-specific conventions.
3
- *
4
- * The server uses rmp-serde with `to_vec_named` (named fields) so enum
5
- * variants are encoded as `{ "VariantName": { ...fields } }` maps.
6
- * msgpackr handles this transparently in JS land.
7
- */
8
1
  import { Effect } from "effect";
9
2
  import { CodecError } from "./errors.js";
10
3
  import { ServerMsg } from "./schema.js";
11
4
  import type { ClientMsg, VectorClock } from "./schema.js";
12
- /** Encode any value to msgpack bytes. */
13
- export declare function encode(value: unknown): Uint8Array<ArrayBuffer>;
14
- /** Decode msgpack bytes to a plain JS value (unsafe no schema validation). */
15
- export declare function decode(bytes: Uint8Array): unknown;
16
- /**
17
- * Encode a ClientMsg to a binary WebSocket frame.
18
- * The msgpack encoding matches rmp-serde's "named" enum format:
19
- * `{ Subscribe: { crdt_id: "foo" } }` → msgpack map with one key.
20
- */
21
- export declare function encodeClientMsg(msg: ClientMsg): Uint8Array;
22
- /**
23
- * Decode a binary WebSocket frame into a ServerMsg.
24
- * Returns Effect<ServerMsg, CodecError>.
25
- */
26
- export declare function decodeServerMsg(bytes: Uint8Array): Effect.Effect<ServerMsg, CodecError>;
27
- /**
28
- * Convert a UUID string ("xxxxxxxx-xxxx-...") to a 16-byte Uint8Array.
29
- * Rust's `uuid::Uuid` is serialized by rmp-serde as raw bytes (bin type).
30
- */
31
- export declare function uuidToBytes(uuid: string): Uint8Array;
32
- /**
33
- * Encode a wall-clock timestamp (ms) as BigInt for msgpack u64 encoding.
34
- * msgpackr encodes JS `number` as float64 for large values; Rust u64 fields
35
- * require an integer encoding — BigInt forces msgpackr to use uint64.
36
- */
37
- export declare function wallMsToBigInt(ms: number): bigint;
38
- export declare function encodeVectorClock(vc: VectorClock): Uint8Array;
39
- export declare function decodeVectorClock(bytes: Uint8Array): Effect.Effect<VectorClock, CodecError>;
5
+ export declare const encode: (value: unknown) => Uint8Array;
6
+ export declare const decode: (bytes: Uint8Array) => unknown;
7
+ export declare const encodeClientMsg: (msg: ClientMsg) => Uint8Array;
8
+ export declare const decodeServerMsg: (bytes: Uint8Array) => Effect.Effect<ServerMsg, CodecError>;
9
+ export declare const uuidToBytes: (uuid: string) => Uint8Array;
10
+ export declare const encodeVectorClock: (vc: VectorClock) => Uint8Array;
11
+ export declare const decodeVectorClock: (bytes: Uint8Array) => Effect.Effect<VectorClock, CodecError>;
40
12
  //# sourceMappingURL=codec.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../src/codec.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAM1D,yCAAyC;AACzC,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAAC,WAAW,CAAC,CAE9D;AAED,gFAAgF;AAChF,wBAAgB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAEjD;AAMD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,SAAS,GAAG,UAAU,CAE1D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,CAiBvF;AAMD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAOpD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEjD;AAMD,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,WAAW,GAAG,UAAU,CAG7D;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,UAAU,CAAC,CAkB3F"}
1
+ {"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../src/codec.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1D,eAAO,MAAM,MAAM,GAAI,OAAO,OAAO,KAAG,UAAkC,CAAC;AAE3E,eAAO,MAAM,MAAM,GAAI,OAAO,UAAU,KAAG,OAA+B,CAAC;AAE3E,eAAO,MAAM,eAAe,GAAI,KAAK,SAAS,KAAG,UAAyB,CAAC;AAE3E,eAAO,MAAM,eAAe,GAAI,OAAO,UAAU,KAAG,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,UAAU,CAgBtF,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,MAAM,MAAM,KAAG,UAO1C,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,IAAI,WAAW,KAAG,UAAqC,CAAC;AAE1F,eAAO,MAAM,iBAAiB,GAAI,OAAO,UAAU,KAAG,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,UAAU,CAkB1F,CAAC"}
package/dist/codec.js CHANGED
@@ -1,88 +1,36 @@
1
- /**
2
- * Msgpack codec — wraps msgpackr with Meridian-specific conventions.
3
- *
4
- * The server uses rmp-serde with `to_vec_named` (named fields) so enum
5
- * variants are encoded as `{ "VariantName": { ...fields } }` maps.
6
- * msgpackr handles this transparently in JS land.
7
- */
8
- import { pack, unpack } from "msgpackr";
1
+ import { decode as msgpackDecode, encode as msgpackEncode } from "@msgpack/msgpack";
9
2
  import { Effect, Schema } from "effect";
10
3
  import { CodecError } from "./errors.js";
11
4
  import { ServerMsg } from "./schema.js";
12
- // ---------------------------------------------------------------------------
13
- // Low-level encode / decode
14
- // ---------------------------------------------------------------------------
15
- /** Encode any value to msgpack bytes. */
16
- export function encode(value) {
17
- return pack(value);
18
- }
19
- /** Decode msgpack bytes to a plain JS value (unsafe — no schema validation). */
20
- export function decode(bytes) {
21
- return unpack(bytes);
22
- }
23
- // ---------------------------------------------------------------------------
24
- // Typed helpers for WebSocket frames
25
- // ---------------------------------------------------------------------------
26
- /**
27
- * Encode a ClientMsg to a binary WebSocket frame.
28
- * The msgpack encoding matches rmp-serde's "named" enum format:
29
- * `{ Subscribe: { crdt_id: "foo" } }` → msgpack map with one key.
30
- */
31
- export function encodeClientMsg(msg) {
32
- return encode(msg);
33
- }
34
- /**
35
- * Decode a binary WebSocket frame into a ServerMsg.
36
- * Returns Effect<ServerMsg, CodecError>.
37
- */
38
- export function decodeServerMsg(bytes) {
5
+ export const encode = (value) => msgpackEncode(value);
6
+ export const decode = (bytes) => msgpackDecode(bytes);
7
+ export const encodeClientMsg = (msg) => encode(msg);
8
+ export const decodeServerMsg = (bytes) => {
39
9
  let raw;
40
10
  try {
41
- raw = unpack(bytes);
11
+ raw = decode(bytes);
42
12
  }
43
13
  catch {
44
14
  return Effect.fail(new CodecError({ message: "msgpack decode failed", raw: bytes }));
45
15
  }
46
- // Schema.decodeUnknown accepts `unknown` input — correct for runtime decode boundaries
47
16
  return Schema.decodeUnknown(ServerMsg)(raw).pipe(Effect.mapError((parseError) => new CodecError({
48
17
  message: `ServerMsg schema validation failed: ${parseError.message}`,
49
18
  raw: bytes,
50
19
  })));
51
- }
52
- // ---------------------------------------------------------------------------
53
- // Wire type helpers
54
- // ---------------------------------------------------------------------------
55
- /**
56
- * Convert a UUID string ("xxxxxxxx-xxxx-...") to a 16-byte Uint8Array.
57
- * Rust's `uuid::Uuid` is serialized by rmp-serde as raw bytes (bin type).
58
- */
59
- export function uuidToBytes(uuid) {
20
+ };
21
+ export const uuidToBytes = (uuid) => {
60
22
  const hex = uuid.replace(/-/g, "");
61
23
  const bytes = new Uint8Array(16);
62
24
  for (let i = 0; i < 16; i++) {
63
25
  bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
64
26
  }
65
27
  return bytes;
66
- }
67
- /**
68
- * Encode a wall-clock timestamp (ms) as BigInt for msgpack u64 encoding.
69
- * msgpackr encodes JS `number` as float64 for large values; Rust u64 fields
70
- * require an integer encoding — BigInt forces msgpackr to use uint64.
71
- */
72
- export function wallMsToBigInt(ms) {
73
- return BigInt(ms);
74
- }
75
- // ---------------------------------------------------------------------------
76
- // VectorClock <-> msgpack bytes
77
- // ---------------------------------------------------------------------------
78
- export function encodeVectorClock(vc) {
79
- // Server expects { entries: { "client_id": version, ... } }
80
- return encode({ entries: vc });
81
- }
82
- export function decodeVectorClock(bytes) {
28
+ };
29
+ export const encodeVectorClock = (vc) => encode({ entries: vc });
30
+ export const decodeVectorClock = (bytes) => {
83
31
  let raw;
84
32
  try {
85
- raw = unpack(bytes);
33
+ raw = decode(bytes);
86
34
  }
87
35
  catch {
88
36
  return Effect.fail(new CodecError({ message: "VectorClock msgpack decode failed", raw: bytes }));
@@ -91,5 +39,5 @@ export function decodeVectorClock(bytes) {
91
39
  ? raw.entries
92
40
  : {};
93
41
  return Schema.decodeUnknown(Schema.Record({ key: Schema.String, value: Schema.Number }))(entries ?? {}).pipe(Effect.mapError((e) => new CodecError({ message: `VectorClock schema validation failed: ${e.message}`, raw: bytes })));
94
- }
42
+ };
95
43
  //# sourceMappingURL=codec.js.map
package/dist/codec.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"codec.js","sourceRoot":"","sources":["../src/codec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"codec.js","sourceRoot":"","sources":["../src/codec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACpF,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,KAAc,EAAc,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;AAE3E,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,KAAiB,EAAW,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;AAE3E,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAc,EAAc,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAE3E,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAiB,EAAwC,EAAE;IACzF,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,EAAE,OAAO,EAAE,uBAAuB,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACvF,CAAC;IAED,OAAO,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAC9C,MAAM,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,EAAE,CAC7B,IAAI,UAAU,CAAC;QACb,OAAO,EAAE,uCAAuC,UAAU,CAAC,OAAO,EAAE;QACpE,GAAG,EAAE,KAAK;KACX,CAAC,CACH,CACF,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAY,EAAc,EAAE;IACtD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,KAAK,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,EAAe,EAAc,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;AAE1F,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAiB,EAA0C,EAAE;IAC7F,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,EAAE,OAAO,EAAE,mCAAmC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACnG,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,SAAS,IAAI,GAAG;QACzE,CAAC,CAAE,GAA4B,CAAC,OAAO;QACvC,CAAC,CAAC,EAAE,CAAC;IACP,OAAO,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CACtF,OAAO,IAAI,EAAE,CACd,CAAC,IAAI,CACJ,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CACpB,IAAI,UAAU,CAAC,EAAE,OAAO,EAAE,yCAAyC,CAAC,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAC9F,CACF,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ export declare const BACKOFF_INITIAL_MS = 100;
2
+ export declare const BACKOFF_MAX_MS = 30000;
3
+ export declare const BACKOFF_MULTIPLIER = 2;
4
+ export declare const JITTER_MULTIPLIER = 0.2;
5
+ export declare const DEFAULT_TIMEOUT_MS = 5000;
6
+ export declare const TOKEN_SKEW_MS = 5000;
7
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB,MAAM,CAAC;AACtC,eAAO,MAAM,cAAc,QAAS,CAAC;AACrC,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,eAAO,MAAM,iBAAiB,MAAM,CAAC;AACrC,eAAO,MAAM,kBAAkB,OAAQ,CAAC;AACxC,eAAO,MAAM,aAAa,OAAQ,CAAC"}
@@ -0,0 +1,7 @@
1
+ export const BACKOFF_INITIAL_MS = 100;
2
+ export const BACKOFF_MAX_MS = 30_000;
3
+ export const BACKOFF_MULTIPLIER = 2;
4
+ export const JITTER_MULTIPLIER = 0.2;
5
+ export const DEFAULT_TIMEOUT_MS = 5_000;
6
+ export const TOKEN_SKEW_MS = 5_000;
7
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AACtC,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC;AACrC,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AACpC,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AACrC,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC;AACxC,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,CAAC"}
@@ -1,21 +1,20 @@
1
- /**
2
- * GCounter handle — increment-only counter.
3
- *
4
- * Local state is kept as a sparse map `{ client_id → count }`.
5
- * `value()` returns the sum. Deltas are merged on incoming ServerMsg.Delta.
6
- */
7
1
  import type { WsTransport } from "../transport/websocket.js";
8
2
  import type { GCounterDelta } from "../sync/delta.js";
9
3
  export interface GCounterState {
10
4
  counts: Record<string, number>;
11
5
  }
6
+ /**
7
+ * Low-level handle for a grow-only counter (GCounter) CRDT.
8
+ *
9
+ * Obtained via `MeridianClient.gcounter()`. Prefer the `useGCounter` React hook
10
+ * for component-level usage; use this handle directly in non-React environments.
11
+ */
12
12
  export declare class GCounterHandle {
13
13
  private state;
14
14
  private readonly clientId;
15
15
  private readonly crdtId;
16
16
  private readonly ns;
17
17
  private readonly transport;
18
- /** Emits on every state change. */
19
18
  private readonly listeners;
20
19
  constructor(opts: {
21
20
  ns: string;
@@ -24,11 +23,21 @@ export declare class GCounterHandle {
24
23
  transport: WsTransport;
25
24
  initial?: GCounterState;
26
25
  });
26
+ /** Returns the current counter value (sum of all client contributions). */
27
27
  value(): number;
28
+ /** Returns the raw per-client contribution map, keyed by client id string. */
28
29
  counts(): Readonly<Record<string, number>>;
29
- /** Subscribe to value changes. Returns an unsubscribe function. */
30
+ /**
31
+ * Registers a listener that is called whenever the counter value changes.
32
+ *
33
+ * @returns An unsubscribe function — call it to stop receiving updates.
34
+ */
30
35
  onChange(listener: (value: number) => void): () => void;
31
- /** Increment by `amount` (must be > 0). */
36
+ /**
37
+ * Increments the counter by `amount` (default `1`) and broadcasts the delta.
38
+ *
39
+ * @throws {RangeError} If `amount` is not greater than zero.
40
+ */
32
41
  increment(amount?: number): void;
33
42
  applyDelta(delta: GCounterDelta): void;
34
43
  private emit;
@@ -1 +1 @@
1
- {"version":3,"file":"gcounter.d.ts","sourceRoot":"","sources":["../../src/crdt/gcounter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IAExC,mCAAmC;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsC;gBAEpD,IAAI,EAAE;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,WAAW,CAAC;QACvB,OAAO,CAAC,EAAE,aAAa,CAAC;KACzB;IAUD,KAAK,IAAI,MAAM;IAIf,MAAM,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAI1C,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI;IAOvD,2CAA2C;IAC3C,SAAS,CAAC,MAAM,GAAE,MAAU,GAAG,IAAI;IAsBnC,UAAU,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IActC,OAAO,CAAC,IAAI;CAMb"}
1
+ {"version":3,"file":"gcounter.d.ts","sourceRoot":"","sources":["../../src/crdt/gcounter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IAExC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsC;gBAEpD,IAAI,EAAE;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,WAAW,CAAC;QACvB,OAAO,CAAC,EAAE,aAAa,CAAC;KACzB;IAQD,2EAA2E;IAC3E,KAAK,IAAI,MAAM;IAIf,8EAA8E;IAC9E,MAAM,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAI1C;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI;IAKvD;;;;OAIG;IACH,SAAS,CAAC,MAAM,GAAE,MAAU,GAAG,IAAI;IAkBnC,UAAU,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAYtC,OAAO,CAAC,IAAI;CAMb"}
@@ -1,17 +1,16 @@
1
+ import { encode } from "../codec.js";
1
2
  /**
2
- * GCounter handle increment-only counter.
3
+ * Low-level handle for a grow-only counter (GCounter) CRDT.
3
4
  *
4
- * Local state is kept as a sparse map `{ client_id → count }`.
5
- * `value()` returns the sum. Deltas are merged on incoming ServerMsg.Delta.
5
+ * Obtained via `MeridianClient.gcounter()`. Prefer the `useGCounter` React hook
6
+ * for component-level usage; use this handle directly in non-React environments.
6
7
  */
7
- import { encode } from "../codec.js";
8
8
  export class GCounterHandle {
9
9
  state;
10
10
  clientId;
11
11
  crdtId;
12
12
  ns;
13
13
  transport;
14
- /** Emits on every state change. */
15
14
  listeners = new Set();
16
15
  constructor(opts) {
17
16
  this.ns = opts.ns;
@@ -20,28 +19,34 @@ export class GCounterHandle {
20
19
  this.transport = opts.transport;
21
20
  this.state = opts.initial ?? { counts: {} };
22
21
  }
23
- // ---- Read ----
22
+ /** Returns the current counter value (sum of all client contributions). */
24
23
  value() {
25
24
  return Object.values(this.state.counts).reduce((a, b) => a + b, 0);
26
25
  }
26
+ /** Returns the raw per-client contribution map, keyed by client id string. */
27
27
  counts() {
28
28
  return this.state.counts;
29
29
  }
30
- /** Subscribe to value changes. Returns an unsubscribe function. */
30
+ /**
31
+ * Registers a listener that is called whenever the counter value changes.
32
+ *
33
+ * @returns An unsubscribe function — call it to stop receiving updates.
34
+ */
31
35
  onChange(listener) {
32
36
  this.listeners.add(listener);
33
37
  return () => { this.listeners.delete(listener); };
34
38
  }
35
- // ---- Write ----
36
- /** Increment by `amount` (must be > 0). */
39
+ /**
40
+ * Increments the counter by `amount` (default `1`) and broadcasts the delta.
41
+ *
42
+ * @throws {RangeError} If `amount` is not greater than zero.
43
+ */
37
44
  increment(amount = 1) {
38
45
  if (amount <= 0)
39
46
  throw new RangeError("GCounter: increment amount must be > 0");
40
- // Optimistic local update
41
47
  const key = String(this.clientId);
42
48
  this.state.counts[key] = (this.state.counts[key] ?? 0) + amount;
43
49
  this.emit();
44
- // Send Op to server
45
50
  const op = encode({
46
51
  GCounter: {
47
52
  client_id: this.clientId,
@@ -52,7 +57,6 @@ export class GCounterHandle {
52
57
  Op: { crdt_id: this.crdtId, op_bytes: op },
53
58
  });
54
59
  }
55
- // ---- Delta application (called by MeridianClient on incoming Delta) ----
56
60
  applyDelta(delta) {
57
61
  let changed = false;
58
62
  for (const [id, count] of Object.entries(delta.counters)) {
@@ -65,7 +69,6 @@ export class GCounterHandle {
65
69
  if (changed)
66
70
  this.emit();
67
71
  }
68
- // ---- Internal ----
69
72
  emit() {
70
73
  const v = this.value();
71
74
  for (const listener of this.listeners) {
@@ -1 +1 @@
1
- {"version":3,"file":"gcounter.js","sourceRoot":"","sources":["../../src/crdt/gcounter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQrC,MAAM,OAAO,cAAc;IACjB,KAAK,CAAgB;IACZ,QAAQ,CAAS;IACjB,MAAM,CAAS;IACf,EAAE,CAAS;IACX,SAAS,CAAc;IAExC,mCAAmC;IAClB,SAAS,GAAG,IAAI,GAAG,EAA2B,CAAC;IAEhE,YAAY,IAMX;QACC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;QAClB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAChC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAC9C,CAAC;IAED,iBAAiB;IAEjB,KAAK;QACH,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACrE,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED,mEAAmE;IACnE,QAAQ,CAAC,QAAiC;QACxC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC;IAED,kBAAkB;IAElB,2CAA2C;IAC3C,SAAS,CAAC,SAAiB,CAAC;QAC1B,IAAI,MAAM,IAAI,CAAC;YAAE,MAAM,IAAI,UAAU,CAAC,wCAAwC,CAAC,CAAC;QAEhF,0BAA0B;QAC1B,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC;QAChE,IAAI,CAAC,IAAI,EAAE,CAAC;QAEZ,oBAAoB;QACpB,MAAM,EAAE,GAAG,MAAM,CAAC;YAChB,QAAQ,EAAE;gBACR,SAAS,EAAE,IAAI,CAAC,QAAQ;gBACxB,MAAM;aACP;SACF,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YAClB,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE;SAC3C,CAAC,CAAC;IACL,CAAC;IAED,2EAA2E;IAE3E,UAAU,CAAC,KAAoB;QAC7B,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;YAC3C,IAAI,KAAK,GAAG,OAAO,EAAE,CAAC;gBACpB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC;gBAC9B,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;QACD,IAAI,OAAO;YAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,qBAAqB;IAEb,IAAI;QACV,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QACvB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACd,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"gcounter.js","sourceRoot":"","sources":["../../src/crdt/gcounter.ts"],"names":[],"mappings":"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"}
@@ -1,16 +1,12 @@
1
- /**
2
- * LWW Register handle — Last-Write-Wins single-value cell.
3
- *
4
- * The winning write is determined by HLC (highest wall_ms wins),
5
- * tie-broken by author (higher client_id wins). The client sends its
6
- * local wall clock as HLC wall_ms; the server enforces ±30s drift limit.
7
- *
8
- * Pass a `schema` to get runtime validation of incoming deltas:
9
- * client.lwwregister("id", Schema.Struct({ x: Schema.Number }))
10
- */
11
1
  import { Schema } from "effect";
12
2
  import type { WsTransport } from "../transport/websocket.js";
13
3
  import type { LwwDelta, LwwEntry } from "../sync/delta.js";
4
+ /**
5
+ * Low-level handle for a Last-Write-Wins register (LWW-Register) CRDT.
6
+ *
7
+ * Obtained via `MeridianClient.lwwregister()`. Prefer the `useLwwRegister` React
8
+ * hook for component-level usage; use this handle directly in non-React environments.
9
+ */
14
10
  export declare class LwwRegisterHandle<T> {
15
11
  private entry;
16
12
  private readonly crdtId;
@@ -26,13 +22,30 @@ export declare class LwwRegisterHandle<T> {
26
22
  schema?: Schema.Schema<T>;
27
23
  initial?: LwwEntry | null;
28
24
  });
25
+ /** Returns the current register value, or `null` if no value has been written yet. */
29
26
  value(): T | null;
30
- /** Metadata: when was the last write and by whom. */
27
+ /**
28
+ * Returns metadata about the winning entry, or `null` if the register is empty.
29
+ *
30
+ * `updatedAtMs` is the wall-clock timestamp of the write; `author` is the
31
+ * numeric client id of the writer.
32
+ */
31
33
  meta(): {
32
34
  updatedAtMs: number;
33
35
  author: number;
34
36
  } | null;
37
+ /**
38
+ * Registers a listener that is called whenever the register value changes.
39
+ *
40
+ * @returns An unsubscribe function — call it to stop receiving updates.
41
+ */
35
42
  onChange(listener: (value: T | null) => void): () => void;
43
+ /**
44
+ * Writes `value` to the register and broadcasts the operation.
45
+ *
46
+ * The write is stamped with the current wall-clock time. If a concurrent
47
+ * write from another client has a later timestamp it will win over this one.
48
+ */
36
49
  set(value: T): void;
37
50
  applyDelta(delta: LwwDelta): void;
38
51
  private decode;
@@ -1 +1 @@
1
- {"version":3,"file":"lwwregister.d.ts","sourceRoot":"","sources":["../../src/crdt/lwwregister.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE3D,qBAAa,iBAAiB,CAAC,CAAC;IAC9B,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwC;gBAEtD,IAAI,EAAE;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,WAAW,CAAC;QACvB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC1B,OAAO,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;KAC3B;IAUD,KAAK,IAAI,CAAC,GAAG,IAAI;IAKjB,qDAAqD;IACrD,IAAI,IAAI;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAKtD,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,GAAG,MAAM,IAAI;IAOzD,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI;IAuBnB,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAUjC,OAAO,CAAC,MAAM;IAQd,OAAO,CAAC,SAAS;IAWjB,OAAO,CAAC,IAAI;CAIb"}
1
+ {"version":3,"file":"lwwregister.d.ts","sourceRoot":"","sources":["../../src/crdt/lwwregister.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE3D;;;;;GAKG;AACH,qBAAa,iBAAiB,CAAC,CAAC;IAC9B,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwC;gBAEtD,IAAI,EAAE;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,WAAW,CAAC;QACvB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC1B,OAAO,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;KAC3B;IAQD,sFAAsF;IACtF,KAAK,IAAI,CAAC,GAAG,IAAI;IAKjB;;;;;OAKG;IACH,IAAI,IAAI;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAKtD;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,GAAG,MAAM,IAAI;IAKzD;;;;;OAKG;IACH,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI;IAkBnB,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAQjC,OAAO,CAAC,MAAM;IAQd,OAAO,CAAC,SAAS;IAWjB,OAAO,CAAC,IAAI;CAIb"}
@@ -1,15 +1,11 @@
1
+ import { Schema } from "effect";
2
+ import { encode } from "../codec.js";
1
3
  /**
2
- * LWW Register handle Last-Write-Wins single-value cell.
3
- *
4
- * The winning write is determined by HLC (highest wall_ms wins),
5
- * tie-broken by author (higher client_id wins). The client sends its
6
- * local wall clock as HLC wall_ms; the server enforces ±30s drift limit.
4
+ * Low-level handle for a Last-Write-Wins register (LWW-Register) CRDT.
7
5
  *
8
- * Pass a `schema` to get runtime validation of incoming deltas:
9
- * client.lwwregister("id", Schema.Struct({ x: Schema.Number }))
6
+ * Obtained via `MeridianClient.lwwregister()`. Prefer the `useLwwRegister` React
7
+ * hook for component-level usage; use this handle directly in non-React environments.
10
8
  */
11
- import { Schema } from "effect";
12
- import { encode, wallMsToBigInt } from "../codec.js";
13
9
  export class LwwRegisterHandle {
14
10
  entry = null;
15
11
  crdtId;
@@ -24,23 +20,38 @@ export class LwwRegisterHandle {
24
20
  this.schema = opts.schema ?? null;
25
21
  this.entry = opts.initial ?? null;
26
22
  }
27
- // ---- Read ----
23
+ /** Returns the current register value, or `null` if no value has been written yet. */
28
24
  value() {
29
25
  if (this.entry === null)
30
26
  return null;
31
27
  return this.decode(this.entry.value);
32
28
  }
33
- /** Metadata: when was the last write and by whom. */
29
+ /**
30
+ * Returns metadata about the winning entry, or `null` if the register is empty.
31
+ *
32
+ * `updatedAtMs` is the wall-clock timestamp of the write; `author` is the
33
+ * numeric client id of the writer.
34
+ */
34
35
  meta() {
35
36
  if (this.entry === null)
36
37
  return null;
37
38
  return { updatedAtMs: Number(this.entry.hlc.wall_ms), author: Number(this.entry.author) };
38
39
  }
40
+ /**
41
+ * Registers a listener that is called whenever the register value changes.
42
+ *
43
+ * @returns An unsubscribe function — call it to stop receiving updates.
44
+ */
39
45
  onChange(listener) {
40
46
  this.listeners.add(listener);
41
47
  return () => { this.listeners.delete(listener); };
42
48
  }
43
- // ---- Write ----
49
+ /**
50
+ * Writes `value` to the register and broadcasts the operation.
51
+ *
52
+ * The write is stamped with the current wall-clock time. If a concurrent
53
+ * write from another client has a later timestamp it will win over this one.
54
+ */
44
55
  set(value) {
45
56
  const wallMs = Date.now();
46
57
  const hlc = { wall_ms: wallMs, logical: 0, node_id: this.clientId };
@@ -49,17 +60,13 @@ export class LwwRegisterHandle {
49
60
  this.entry = newEntry;
50
61
  this.emit();
51
62
  }
52
- // wall_ms must be BigInt — msgpackr encodes large JS numbers as float64,
53
- // but Rust expects u64 integer encoding
54
- const wireHlc = { wall_ms: wallMsToBigInt(wallMs), logical: 0, node_id: this.clientId };
55
63
  this.transport.send({
56
64
  Op: {
57
65
  crdt_id: this.crdtId,
58
- op_bytes: encode({ LwwRegister: { value, hlc: wireHlc, author: this.clientId } }),
66
+ op_bytes: encode({ LwwRegister: { value, hlc: { wall_ms: wallMs, logical: 0, node_id: this.clientId }, author: this.clientId } }),
59
67
  },
60
68
  });
61
69
  }
62
- // ---- Delta application ----
63
70
  applyDelta(delta) {
64
71
  if (delta.entry === null)
65
72
  return;
@@ -68,12 +75,11 @@ export class LwwRegisterHandle {
68
75
  this.emit();
69
76
  }
70
77
  }
71
- // ---- Internal ----
72
78
  decode(raw) {
73
79
  if (this.schema !== null) {
74
80
  return Schema.decodeUnknownSync(this.schema)(raw);
75
81
  }
76
- // No schema provided — T defaults to unknown, cast is the caller's responsibility
82
+ // HACK: No schema provided — T defaults to unknown, cast is the caller's responsibility.
77
83
  return raw;
78
84
  }
79
85
  entryWins(candidate, existing) {
@@ -1 +1 @@
1
- {"version":3,"file":"lwwregister.js","sourceRoot":"","sources":["../../src/crdt/lwwregister.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lwwregister.js","sourceRoot":"","sources":["../../src/crdt/lwwregister.ts"],"names":[],"mappings":"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"}
@@ -1,19 +1,13 @@
1
- /**
2
- * ORSet handle — add-wins observed-remove set.
3
- *
4
- * Each element has a set of add-tags (UUIDs). Remove only removes tags
5
- * known at remove time — a concurrent add with a new tag survives.
6
- *
7
- * Elements are serialized as JSON for the wire (serde_json::Value).
8
- *
9
- * Pass a `schema` to get runtime validation of elements deserialized from deltas:
10
- * client.orset("id", Schema.Struct({ id: Schema.String }))
11
- */
12
1
  import { Schema } from "effect";
13
2
  import type { WsTransport } from "../transport/websocket.js";
14
3
  import type { ORSetDelta } from "../sync/delta.js";
4
+ /**
5
+ * Low-level handle for an Observed-Remove Set (OR-Set) CRDT.
6
+ *
7
+ * Obtained via `MeridianClient.orset()`. Prefer the `useORSet` React hook for
8
+ * component-level usage; use this handle directly in non-React environments.
9
+ */
15
10
  export declare class ORSetHandle<T> {
16
- /** element (JSON-stringified) → Set of live add-tags */
17
11
  private readonly tags;
18
12
  private readonly crdtId;
19
13
  private readonly clientId;
@@ -27,11 +21,29 @@ export declare class ORSetHandle<T> {
27
21
  transport: WsTransport;
28
22
  schema?: Schema.Schema<T>;
29
23
  });
30
- /** Returns all live elements (add-wins). */
24
+ /** Returns the current set elements as an array, decoded via the optional schema. */
31
25
  elements(): T[];
26
+ /** Returns `true` if the set currently contains `element`. */
32
27
  has(element: T): boolean;
28
+ /**
29
+ * Registers a listener that is called whenever the set contents change.
30
+ *
31
+ * @returns An unsubscribe function — call it to stop receiving updates.
32
+ */
33
33
  onChange(listener: (elements: T[]) => void): () => void;
34
+ /**
35
+ * Adds `element` to the set and broadcasts the operation.
36
+ *
37
+ * Each call generates a unique tag so concurrent adds of the same value
38
+ * are treated as distinct entries.
39
+ */
34
40
  add(element: T): void;
41
+ /**
42
+ * Removes `element` from the set and broadcasts the operation.
43
+ *
44
+ * Only the tags observed locally at the time of this call are removed;
45
+ * concurrently added copies on other clients are left intact.
46
+ */
35
47
  remove(element: T): void;
36
48
  applyDelta(delta: ORSetDelta): void;
37
49
  private decode;
@@ -1 +1 @@
1
- {"version":3,"file":"orset.d.ts","sourceRoot":"","sources":["../../src/crdt/orset.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,qBAAa,WAAW,CAAC,CAAC;IACxB,wDAAwD;IACxD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAkC;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsC;gBAEpD,IAAI,EAAE;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,WAAW,CAAC;QACvB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;KAC3B;IASD,4CAA4C;IAC5C,QAAQ,IAAI,CAAC,EAAE;IAMf,GAAG,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO;IAKxB,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,EAAE,KAAK,IAAI,GAAG,MAAM,IAAI;IAOvD,GAAG,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI;IAiBrB,MAAM,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI;IAmBxB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IA2BnC,OAAO,CAAC,MAAM;IAOd,OAAO,CAAC,IAAI;CAIb"}
1
+ {"version":3,"file":"orset.d.ts","sourceRoot":"","sources":["../../src/crdt/orset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGnD;;;;;GAKG;AACH,qBAAa,WAAW,CAAC,CAAC;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAkC;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsC;gBAEpD,IAAI,EAAE;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,WAAW,CAAC;QACvB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;KAC3B;IAOD,qFAAqF;IACrF,QAAQ,IAAI,CAAC,EAAE;IAMf,8DAA8D;IAC9D,GAAG,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO;IAKxB;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,EAAE,KAAK,IAAI,GAAG,MAAM,IAAI;IAKvD;;;;;OAKG;IACH,GAAG,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI;IAiBrB;;;;;OAKG;IACH,MAAM,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI;IAgBxB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAyBnC,OAAO,CAAC,MAAM;IAOd,OAAO,CAAC,IAAI;CAIb"}