cojson 0.19.21 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +67 -0
  3. package/dist/CojsonMessageChannel/CojsonMessageChannel.d.ts +42 -0
  4. package/dist/CojsonMessageChannel/CojsonMessageChannel.d.ts.map +1 -0
  5. package/dist/CojsonMessageChannel/CojsonMessageChannel.js +261 -0
  6. package/dist/CojsonMessageChannel/CojsonMessageChannel.js.map +1 -0
  7. package/dist/CojsonMessageChannel/MessagePortOutgoingChannel.d.ts +18 -0
  8. package/dist/CojsonMessageChannel/MessagePortOutgoingChannel.d.ts.map +1 -0
  9. package/dist/CojsonMessageChannel/MessagePortOutgoingChannel.js +37 -0
  10. package/dist/CojsonMessageChannel/MessagePortOutgoingChannel.js.map +1 -0
  11. package/dist/CojsonMessageChannel/index.d.ts +3 -0
  12. package/dist/CojsonMessageChannel/index.d.ts.map +1 -0
  13. package/dist/CojsonMessageChannel/index.js +2 -0
  14. package/dist/CojsonMessageChannel/index.js.map +1 -0
  15. package/dist/CojsonMessageChannel/types.d.ts +149 -0
  16. package/dist/CojsonMessageChannel/types.d.ts.map +1 -0
  17. package/dist/CojsonMessageChannel/types.js +36 -0
  18. package/dist/CojsonMessageChannel/types.js.map +1 -0
  19. package/dist/GarbageCollector.d.ts +4 -2
  20. package/dist/GarbageCollector.d.ts.map +1 -1
  21. package/dist/GarbageCollector.js +5 -3
  22. package/dist/GarbageCollector.js.map +1 -1
  23. package/dist/SyncStateManager.d.ts +3 -3
  24. package/dist/SyncStateManager.d.ts.map +1 -1
  25. package/dist/SyncStateManager.js +4 -4
  26. package/dist/SyncStateManager.js.map +1 -1
  27. package/dist/coValueContentMessage.d.ts +0 -2
  28. package/dist/coValueContentMessage.d.ts.map +1 -1
  29. package/dist/coValueContentMessage.js +0 -8
  30. package/dist/coValueContentMessage.js.map +1 -1
  31. package/dist/coValueCore/SessionMap.d.ts +4 -2
  32. package/dist/coValueCore/SessionMap.d.ts.map +1 -1
  33. package/dist/coValueCore/SessionMap.js +30 -0
  34. package/dist/coValueCore/SessionMap.js.map +1 -1
  35. package/dist/coValueCore/coValueCore.d.ts +86 -4
  36. package/dist/coValueCore/coValueCore.d.ts.map +1 -1
  37. package/dist/coValueCore/coValueCore.js +318 -17
  38. package/dist/coValueCore/coValueCore.js.map +1 -1
  39. package/dist/coValueCore/verifiedState.d.ts +6 -1
  40. package/dist/coValueCore/verifiedState.d.ts.map +1 -1
  41. package/dist/coValueCore/verifiedState.js +9 -0
  42. package/dist/coValueCore/verifiedState.js.map +1 -1
  43. package/dist/coValues/coList.d.ts +3 -2
  44. package/dist/coValues/coList.d.ts.map +1 -1
  45. package/dist/coValues/coList.js.map +1 -1
  46. package/dist/coValues/group.d.ts.map +1 -1
  47. package/dist/coValues/group.js +3 -6
  48. package/dist/coValues/group.js.map +1 -1
  49. package/dist/config.d.ts +0 -6
  50. package/dist/config.d.ts.map +1 -1
  51. package/dist/config.js +0 -8
  52. package/dist/config.js.map +1 -1
  53. package/dist/crypto/NapiCrypto.d.ts +1 -2
  54. package/dist/crypto/NapiCrypto.d.ts.map +1 -1
  55. package/dist/crypto/NapiCrypto.js +19 -4
  56. package/dist/crypto/NapiCrypto.js.map +1 -1
  57. package/dist/crypto/RNCrypto.d.ts.map +1 -1
  58. package/dist/crypto/RNCrypto.js +19 -4
  59. package/dist/crypto/RNCrypto.js.map +1 -1
  60. package/dist/crypto/WasmCrypto.d.ts +11 -4
  61. package/dist/crypto/WasmCrypto.d.ts.map +1 -1
  62. package/dist/crypto/WasmCrypto.js +52 -10
  63. package/dist/crypto/WasmCrypto.js.map +1 -1
  64. package/dist/crypto/WasmCryptoEdge.d.ts +1 -0
  65. package/dist/crypto/WasmCryptoEdge.d.ts.map +1 -1
  66. package/dist/crypto/WasmCryptoEdge.js +4 -1
  67. package/dist/crypto/WasmCryptoEdge.js.map +1 -1
  68. package/dist/crypto/crypto.d.ts +3 -3
  69. package/dist/crypto/crypto.d.ts.map +1 -1
  70. package/dist/crypto/crypto.js +6 -1
  71. package/dist/crypto/crypto.js.map +1 -1
  72. package/dist/exports.d.ts +3 -2
  73. package/dist/exports.d.ts.map +1 -1
  74. package/dist/exports.js +3 -1
  75. package/dist/exports.js.map +1 -1
  76. package/dist/ids.d.ts +4 -1
  77. package/dist/ids.d.ts.map +1 -1
  78. package/dist/ids.js +4 -0
  79. package/dist/ids.js.map +1 -1
  80. package/dist/knownState.d.ts +2 -0
  81. package/dist/knownState.d.ts.map +1 -1
  82. package/dist/localNode.d.ts +13 -3
  83. package/dist/localNode.d.ts.map +1 -1
  84. package/dist/localNode.js +17 -2
  85. package/dist/localNode.js.map +1 -1
  86. package/dist/platformUtils.d.ts +3 -0
  87. package/dist/platformUtils.d.ts.map +1 -0
  88. package/dist/platformUtils.js +24 -0
  89. package/dist/platformUtils.js.map +1 -0
  90. package/dist/storage/DeletedCoValuesEraserScheduler.d.ts +30 -0
  91. package/dist/storage/DeletedCoValuesEraserScheduler.d.ts.map +1 -0
  92. package/dist/storage/DeletedCoValuesEraserScheduler.js +84 -0
  93. package/dist/storage/DeletedCoValuesEraserScheduler.js.map +1 -0
  94. package/dist/storage/sqlite/client.d.ts +3 -0
  95. package/dist/storage/sqlite/client.d.ts.map +1 -1
  96. package/dist/storage/sqlite/client.js +44 -0
  97. package/dist/storage/sqlite/client.js.map +1 -1
  98. package/dist/storage/sqlite/sqliteMigrations.d.ts.map +1 -1
  99. package/dist/storage/sqlite/sqliteMigrations.js +7 -0
  100. package/dist/storage/sqlite/sqliteMigrations.js.map +1 -1
  101. package/dist/storage/sqliteAsync/client.d.ts +3 -0
  102. package/dist/storage/sqliteAsync/client.d.ts.map +1 -1
  103. package/dist/storage/sqliteAsync/client.js +42 -0
  104. package/dist/storage/sqliteAsync/client.js.map +1 -1
  105. package/dist/storage/storageAsync.d.ts +15 -3
  106. package/dist/storage/storageAsync.d.ts.map +1 -1
  107. package/dist/storage/storageAsync.js +60 -3
  108. package/dist/storage/storageAsync.js.map +1 -1
  109. package/dist/storage/storageSync.d.ts +14 -3
  110. package/dist/storage/storageSync.d.ts.map +1 -1
  111. package/dist/storage/storageSync.js +54 -3
  112. package/dist/storage/storageSync.js.map +1 -1
  113. package/dist/storage/types.d.ts +64 -0
  114. package/dist/storage/types.d.ts.map +1 -1
  115. package/dist/storage/types.js +12 -1
  116. package/dist/storage/types.js.map +1 -1
  117. package/dist/sync.d.ts +6 -0
  118. package/dist/sync.d.ts.map +1 -1
  119. package/dist/sync.js +69 -15
  120. package/dist/sync.js.map +1 -1
  121. package/dist/tests/CojsonMessageChannel.test.d.ts +2 -0
  122. package/dist/tests/CojsonMessageChannel.test.d.ts.map +1 -0
  123. package/dist/tests/CojsonMessageChannel.test.js +236 -0
  124. package/dist/tests/CojsonMessageChannel.test.js.map +1 -0
  125. package/dist/tests/DeletedCoValuesEraserScheduler.test.d.ts +2 -0
  126. package/dist/tests/DeletedCoValuesEraserScheduler.test.d.ts.map +1 -0
  127. package/dist/tests/DeletedCoValuesEraserScheduler.test.js +149 -0
  128. package/dist/tests/DeletedCoValuesEraserScheduler.test.js.map +1 -0
  129. package/dist/tests/GarbageCollector.test.js +91 -18
  130. package/dist/tests/GarbageCollector.test.js.map +1 -1
  131. package/dist/tests/StorageApiAsync.test.js +510 -146
  132. package/dist/tests/StorageApiAsync.test.js.map +1 -1
  133. package/dist/tests/StorageApiSync.test.js +531 -130
  134. package/dist/tests/StorageApiSync.test.js.map +1 -1
  135. package/dist/tests/SyncManager.processQueues.test.js +1 -1
  136. package/dist/tests/SyncManager.processQueues.test.js.map +1 -1
  137. package/dist/tests/SyncStateManager.test.js +1 -1
  138. package/dist/tests/SyncStateManager.test.js.map +1 -1
  139. package/dist/tests/WasmCrypto.test.js +6 -3
  140. package/dist/tests/WasmCrypto.test.js.map +1 -1
  141. package/dist/tests/coPlainText.test.js +1 -1
  142. package/dist/tests/coPlainText.test.js.map +1 -1
  143. package/dist/tests/coValueCore.loadFromStorage.test.js +4 -0
  144. package/dist/tests/coValueCore.loadFromStorage.test.js.map +1 -1
  145. package/dist/tests/coValueCore.test.js +34 -13
  146. package/dist/tests/coValueCore.test.js.map +1 -1
  147. package/dist/tests/coreWasm.test.js +127 -4
  148. package/dist/tests/coreWasm.test.js.map +1 -1
  149. package/dist/tests/crypto.test.js +89 -93
  150. package/dist/tests/crypto.test.js.map +1 -1
  151. package/dist/tests/deleteCoValue.test.d.ts +2 -0
  152. package/dist/tests/deleteCoValue.test.d.ts.map +1 -0
  153. package/dist/tests/deleteCoValue.test.js +313 -0
  154. package/dist/tests/deleteCoValue.test.js.map +1 -0
  155. package/dist/tests/group.removeMember.test.js +18 -30
  156. package/dist/tests/group.removeMember.test.js.map +1 -1
  157. package/dist/tests/knownState.lazyLoading.test.js +4 -0
  158. package/dist/tests/knownState.lazyLoading.test.js.map +1 -1
  159. package/dist/tests/sync.deleted.test.d.ts +2 -0
  160. package/dist/tests/sync.deleted.test.d.ts.map +1 -0
  161. package/dist/tests/sync.deleted.test.js +214 -0
  162. package/dist/tests/sync.deleted.test.js.map +1 -0
  163. package/dist/tests/sync.garbageCollection.test.js +56 -32
  164. package/dist/tests/sync.garbageCollection.test.js.map +1 -1
  165. package/dist/tests/sync.load.test.js +3 -5
  166. package/dist/tests/sync.load.test.js.map +1 -1
  167. package/dist/tests/sync.mesh.test.js +4 -3
  168. package/dist/tests/sync.mesh.test.js.map +1 -1
  169. package/dist/tests/sync.peerReconciliation.test.js +3 -3
  170. package/dist/tests/sync.peerReconciliation.test.js.map +1 -1
  171. package/dist/tests/sync.storage.test.js +12 -11
  172. package/dist/tests/sync.storage.test.js.map +1 -1
  173. package/dist/tests/sync.storageAsync.test.js +7 -7
  174. package/dist/tests/sync.storageAsync.test.js.map +1 -1
  175. package/dist/tests/sync.test.js +3 -2
  176. package/dist/tests/sync.test.js.map +1 -1
  177. package/dist/tests/sync.tracking.test.js +35 -4
  178. package/dist/tests/sync.tracking.test.js.map +1 -1
  179. package/dist/tests/testStorage.d.ts +3 -0
  180. package/dist/tests/testStorage.d.ts.map +1 -1
  181. package/dist/tests/testStorage.js +16 -2
  182. package/dist/tests/testStorage.js.map +1 -1
  183. package/dist/tests/testUtils.d.ts +29 -4
  184. package/dist/tests/testUtils.d.ts.map +1 -1
  185. package/dist/tests/testUtils.js +84 -9
  186. package/dist/tests/testUtils.js.map +1 -1
  187. package/package.json +6 -16
  188. package/src/CojsonMessageChannel/CojsonMessageChannel.ts +332 -0
  189. package/src/CojsonMessageChannel/MessagePortOutgoingChannel.ts +52 -0
  190. package/src/CojsonMessageChannel/index.ts +9 -0
  191. package/src/CojsonMessageChannel/types.ts +200 -0
  192. package/src/GarbageCollector.ts +5 -5
  193. package/src/SyncStateManager.ts +6 -6
  194. package/src/coValueContentMessage.ts +0 -14
  195. package/src/coValueCore/SessionMap.ts +43 -1
  196. package/src/coValueCore/coValueCore.ts +430 -15
  197. package/src/coValueCore/verifiedState.ts +26 -3
  198. package/src/coValues/coList.ts +5 -3
  199. package/src/coValues/group.ts +5 -6
  200. package/src/config.ts +0 -9
  201. package/src/crypto/NapiCrypto.ts +29 -13
  202. package/src/crypto/RNCrypto.ts +29 -11
  203. package/src/crypto/WasmCrypto.ts +67 -20
  204. package/src/crypto/WasmCryptoEdge.ts +5 -1
  205. package/src/crypto/crypto.ts +16 -4
  206. package/src/exports.ts +3 -0
  207. package/src/ids.ts +11 -1
  208. package/src/localNode.ts +18 -5
  209. package/src/platformUtils.ts +26 -0
  210. package/src/storage/DeletedCoValuesEraserScheduler.ts +124 -0
  211. package/src/storage/sqlite/client.ts +77 -0
  212. package/src/storage/sqlite/sqliteMigrations.ts +7 -0
  213. package/src/storage/sqliteAsync/client.ts +75 -0
  214. package/src/storage/storageAsync.ts +77 -4
  215. package/src/storage/storageSync.ts +73 -4
  216. package/src/storage/types.ts +75 -0
  217. package/src/sync.ts +84 -15
  218. package/src/tests/CojsonMessageChannel.test.ts +306 -0
  219. package/src/tests/DeletedCoValuesEraserScheduler.test.ts +185 -0
  220. package/src/tests/GarbageCollector.test.ts +119 -22
  221. package/src/tests/StorageApiAsync.test.ts +615 -156
  222. package/src/tests/StorageApiSync.test.ts +623 -137
  223. package/src/tests/SyncManager.processQueues.test.ts +1 -1
  224. package/src/tests/SyncStateManager.test.ts +1 -1
  225. package/src/tests/WasmCrypto.test.ts +8 -3
  226. package/src/tests/coPlainText.test.ts +1 -1
  227. package/src/tests/coValueCore.loadFromStorage.test.ts +8 -0
  228. package/src/tests/coValueCore.test.ts +49 -14
  229. package/src/tests/coreWasm.test.ts +319 -10
  230. package/src/tests/crypto.test.ts +141 -150
  231. package/src/tests/deleteCoValue.test.ts +528 -0
  232. package/src/tests/group.removeMember.test.ts +35 -35
  233. package/src/tests/knownState.lazyLoading.test.ts +8 -0
  234. package/src/tests/sync.deleted.test.ts +294 -0
  235. package/src/tests/sync.garbageCollection.test.ts +69 -36
  236. package/src/tests/sync.load.test.ts +3 -5
  237. package/src/tests/sync.mesh.test.ts +6 -3
  238. package/src/tests/sync.peerReconciliation.test.ts +3 -3
  239. package/src/tests/sync.storage.test.ts +14 -11
  240. package/src/tests/sync.storageAsync.test.ts +7 -7
  241. package/src/tests/sync.test.ts +5 -2
  242. package/src/tests/sync.tracking.test.ts +54 -4
  243. package/src/tests/testStorage.ts +30 -3
  244. package/src/tests/testUtils.ts +113 -15
  245. package/dist/crypto/PureJSCrypto.d.ts +0 -77
  246. package/dist/crypto/PureJSCrypto.d.ts.map +0 -1
  247. package/dist/crypto/PureJSCrypto.js +0 -236
  248. package/dist/crypto/PureJSCrypto.js.map +0 -1
  249. package/dist/tests/PureJSCrypto.test.d.ts +0 -2
  250. package/dist/tests/PureJSCrypto.test.d.ts.map +0 -1
  251. package/dist/tests/PureJSCrypto.test.js +0 -145
  252. package/dist/tests/PureJSCrypto.test.js.map +0 -1
  253. package/src/crypto/PureJSCrypto.ts +0 -429
  254. package/src/tests/PureJSCrypto.test.ts +0 -217
@@ -1,4 +1,4 @@
1
1
 
2
- > cojson@0.19.21 build /home/runner/_work/jazz/jazz/packages/cojson
2
+ > cojson@0.20.0 build /home/runner/_work/jazz/jazz/packages/cojson
3
3
  > rm -rf ./dist && tsc --sourceMap --outDir dist
4
4
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,69 @@
1
1
  # cojson
2
2
 
3
+ ## 0.20.0
4
+
5
+ ### Minor Changes
6
+
7
+ - f562a1f: Restricted the `Uniqueness` type to only accept specific values instead of any `JsonValue`.
8
+ The allowed types are now: `string`, `number` (as integers), `boolean`, `null`, `undefined`,
9
+ or an object with string values. Arrays, non-integer numbers, and objects with non-string values are no longer
10
+ accepted and will throw an error.
11
+
12
+ Deprecated `number`, even if it is an integer, as it is not a valid uniqueness type in TS, if you want to continue using numbers,
13
+ use a string instead or ignore the type check.
14
+
15
+ - b5ada4d: breaking change: now removeMember throws if unauthorized
16
+ - 8934d8a: ## Full native crypto (0.20.0)
17
+
18
+ With this release we complete the migration to a pure Rust toolchain and remove the JavaScript crypto compatibility layer. The native Rust core now runs everywhere: React Native, Edge runtimes, all server-side environments, and the web.
19
+
20
+ ## 💥 Breaking changes
21
+
22
+ ### Crypto providers / fallback behavior
23
+
24
+ - **Removed `PureJSCrypto`** from `cojson` (including the `cojson/crypto/PureJSCrypto` export).
25
+ - **Removed `RNQuickCrypto`** from `jazz-tools`.
26
+ - **No more fallback to JavaScript crypto**: if crypto fails to initialize, Jazz now throws an error instead of falling back silently.
27
+ - **React Native + Expo**: **`RNCrypto` (via `cojson-core-rn`) is now the default**.
28
+
29
+ Full migration guide: `https://jazz.tools/docs/upgrade/0-20-0`
30
+
31
+ ### Patch Changes
32
+
33
+ - 6b9368a: Added `deleteCoValues` function to permanently delete CoValues and their nested references.
34
+
35
+ - CoValues are marked with a tombstone, making them inaccessible to all users
36
+ - Supports deleting nested CoValues via resolve queries
37
+ - Requires admin permissions on the CoValue's group
38
+ - Introduces new `deleted` loading state for deleted CoValues
39
+ - Groups and Accounts are skipped during deletion
40
+
41
+ See documentation: https://jazz.tools/docs/react/core-concepts/deleting
42
+
43
+ - 89332d5: Moved stable JSON serialization from JavaScript to Rust in SessionLog operations
44
+
45
+ ### Changes
46
+
47
+ - **`tryAdd`**: Stable serialization now happens in Rust. The Rust layer parses each transaction and re-serializes it to ensure a stable JSON representation for signature verification. JavaScript side now uses `JSON.stringify` instead of `stableStringify`.
48
+
49
+ - **`addNewPrivateTransaction`** and **`addNewTrustingTransaction`**: Removed `stableStringify` usage since the data is either encrypted (private) or already in string format (trusting), making stable serialization unnecessary on the JS side.
50
+
51
+ - Updated dependencies [89332d5]
52
+ - Updated dependencies [8934d8a]
53
+ - cojson-core-wasm@0.20.0
54
+ - cojson-core-napi@0.20.0
55
+ - cojson-core-rn@0.20.0
56
+
57
+ ## 0.19.22
58
+
59
+ ### Patch Changes
60
+
61
+ - 3b70482: Wait for CoValues' dependencies to be garbage-collected before collecting them. This makes accounts and groups safe to be collected.
62
+ - 6078ea5: Wait for CoValues to be synced before garbage-collecting them
63
+ - cojson-core-wasm@0.19.22
64
+ - cojson-core-rn@0.19.22
65
+ - cojson-core-napi@0.19.22
66
+
3
67
  ## 0.19.19
4
68
 
5
69
  ### Patch Changes
@@ -355,6 +419,7 @@
355
419
  ### Patch Changes
356
420
 
357
421
  - a584ab3: Add WasmCrypto support for Cloudflare Workers and edge runtimes by importing `jazz-tools/load-edge-wasm`.
422
+
358
423
  - Enable WasmCrypto functionality by initializing the WebAssembly environment with the import: `import "jazz-tools/load-edge-wasm"` in edge runtimes.
359
424
  - Guarantee compatibility across Cloudflare Workers and other edge runtime environments.
360
425
 
@@ -375,6 +440,7 @@
375
440
  - 2ddf4d9: Introducing version control APIs, unstable_branch and unstable_merge
376
441
 
377
442
  Flagged as unstable because branch & merge scope & propagation needs to be validated.
443
+
378
444
  - cojson-core-wasm@0.18.13
379
445
 
380
446
  ## 0.18.12
@@ -590,6 +656,7 @@
590
656
  - 3cd1586: Makes the key rotation not fail when child groups are unavailable or their readkey is not accessible.
591
657
 
592
658
  Also changes the Group.removeMember method to not return a Promise, because:
659
+
593
660
  - All the locally available child groups are rotated immediately
594
661
  - All the remote child groups are rotated in background, but since they are not locally available the user won't need the new key immediately
595
662
 
@@ -0,0 +1,42 @@
1
+ import type { Peer } from "../sync.js";
2
+ import type { AcceptFromPortOptions, WaitForConnectionOptions, ExposeOptions, MessagePortLike, PostMessageTarget } from "./types.js";
3
+ /**
4
+ * CojsonMessageChannel provides a low-level API for creating cojson peers
5
+ * that communicate via the MessageChannel API (or compatible implementations
6
+ * like Electron's MessageChannelMain).
7
+ *
8
+ * Inspired by Comlink, it handles:
9
+ * - Port management (creating MessageChannels and transferring ports)
10
+ * - Handshake protocol (ensuring both sides are ready)
11
+ * - Peer creation (returning a standard cojson Peer)
12
+ */
13
+ export declare class CojsonMessageChannel {
14
+ /**
15
+ * Expose a cojson connection to a target with a postMessage API.
16
+ * Creates a MessageChannel, transfers port2 to the target, and waits for handshake.
17
+ *
18
+ * @param target - Any object with a postMessage method (Worker, Window, MessagePort, etc.)
19
+ * @param opts - Configuration options
20
+ * @returns A promise that resolves to a Peer once the handshake completes
21
+ */
22
+ static expose(target: PostMessageTarget, opts?: ExposeOptions): Promise<Peer>;
23
+ /**
24
+ * Wait for an incoming Jazz connection.
25
+ * Listens for a port transfer message on the global scope and completes the handshake.
26
+ *
27
+ * @param opts - Configuration options
28
+ * @returns A promise that resolves to a Peer once the handshake completes
29
+ */
30
+ static waitForConnection(opts?: WaitForConnectionOptions): Promise<Peer>;
31
+ /**
32
+ * Accept an incoming Jazz connection from a specific port.
33
+ * Lower-level API useful for testing or when you already have the port.
34
+ * This method has no timeout - it will wait indefinitely for the handshake.
35
+ *
36
+ * @param port - The MessagePort to accept the connection on
37
+ * @param opts - Configuration options
38
+ * @returns A promise that resolves to a Peer once the handshake completes
39
+ */
40
+ static acceptFromPort(port: MessagePortLike, opts?: AcceptFromPortOptions): Promise<Peer>;
41
+ }
42
+ //# sourceMappingURL=CojsonMessageChannel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CojsonMessageChannel.d.ts","sourceRoot":"","sources":["../../src/CojsonMessageChannel/CojsonMessageChannel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGvC,OAAO,KAAK,EACV,qBAAqB,EACrB,wBAAwB,EACxB,aAAa,EAEb,eAAe,EACf,iBAAiB,EAElB,MAAM,YAAY,CAAC;AASpB;;;;;;;;;GASG;AACH,qBAAa,oBAAoB;IAC/B;;;;;;;OAOG;IACH,MAAM,CAAC,MAAM,CACX,MAAM,EAAE,iBAAiB,EACzB,IAAI,GAAE,aAAkB,GACvB,OAAO,CAAC,IAAI,CAAC;IA0FhB;;;;;;OAMG;IACH,MAAM,CAAC,iBAAiB,CAAC,IAAI,GAAE,wBAA6B,GAAG,OAAO,CAAC,IAAI,CAAC;IA4D5E;;;;;;;;OAQG;IACH,MAAM,CAAC,cAAc,CACnB,IAAI,EAAE,eAAe,EACrB,IAAI,GAAE,qBAA0B,GAC/B,OAAO,CAAC,IAAI,CAAC;CA2DjB"}
@@ -0,0 +1,261 @@
1
+ import { ConnectedPeerChannel } from "../streamUtils.js";
2
+ import { MessagePortOutgoingChannel } from "./MessagePortOutgoingChannel.js";
3
+ import { isControlMessage, isPortTransferMessage, isReadyAckMessage, isReadyMessage, } from "./types.js";
4
+ import { logger } from "../logger.js";
5
+ /**
6
+ * CojsonMessageChannel provides a low-level API for creating cojson peers
7
+ * that communicate via the MessageChannel API (or compatible implementations
8
+ * like Electron's MessageChannelMain).
9
+ *
10
+ * Inspired by Comlink, it handles:
11
+ * - Port management (creating MessageChannels and transferring ports)
12
+ * - Handshake protocol (ensuring both sides are ready)
13
+ * - Peer creation (returning a standard cojson Peer)
14
+ */
15
+ export class CojsonMessageChannel {
16
+ /**
17
+ * Expose a cojson connection to a target with a postMessage API.
18
+ * Creates a MessageChannel, transfers port2 to the target, and waits for handshake.
19
+ *
20
+ * @param target - Any object with a postMessage method (Worker, Window, MessagePort, etc.)
21
+ * @param opts - Configuration options
22
+ * @returns A promise that resolves to a Peer once the handshake completes
23
+ */
24
+ static expose(target, opts = {}) {
25
+ const id = opts.id ?? `channel_${Math.random()}`;
26
+ const role = opts.role ?? "client";
27
+ // Create or use provided MessageChannel
28
+ const channel = opts.messageChannel ?? new MessageChannel();
29
+ const { port1, port2 } = channel;
30
+ return new Promise((resolve, reject) => {
31
+ let resolved = false;
32
+ const cleanup = () => {
33
+ port1.removeEventListener("message", handleMessage);
34
+ port1.removeEventListener("messageerror", handleError);
35
+ };
36
+ const handleError = (evt) => {
37
+ if (resolved)
38
+ return;
39
+ cleanup();
40
+ port1.close();
41
+ reject(new Error("MessageChannel error during handshake", {
42
+ cause: evt,
43
+ }));
44
+ };
45
+ const handleMessage = (event) => {
46
+ const data = event.data;
47
+ // Wait for ready acknowledgment from guest
48
+ if (isReadyAckMessage(data)) {
49
+ if (resolved)
50
+ return;
51
+ resolved = true;
52
+ cleanup();
53
+ // Create the peer
54
+ const peer = createPeerFromPort(port1, {
55
+ id,
56
+ role,
57
+ onClose: opts.onClose,
58
+ });
59
+ resolve(peer);
60
+ }
61
+ };
62
+ // Start listening on port1
63
+ port1.addEventListener("message", handleMessage);
64
+ port1.addEventListener("messageerror", handleError);
65
+ // Start the port if needed (browser MessagePort requires this)
66
+ if (port1.start) {
67
+ port1.start();
68
+ }
69
+ // Transfer port2 to target
70
+ // Detect if target is a Window (has postMessage with targetOrigin signature)
71
+ // We use duck typing: if targetOrigin is provided, assume it's a Window
72
+ const targetOrigin = opts.targetOrigin ?? "*";
73
+ const portTransferMessage = { type: "jazz:port", id };
74
+ try {
75
+ // Try Window-style postMessage first if targetOrigin is specified
76
+ if (opts.targetOrigin !== undefined) {
77
+ // Window/iframe: postMessage(data, targetOrigin, [transfer])
78
+ target.postMessage(portTransferMessage, targetOrigin, [port2]);
79
+ }
80
+ else {
81
+ // Worker/MessagePort style: postMessage(data, [transfer])
82
+ target.postMessage(portTransferMessage, [port2]);
83
+ }
84
+ }
85
+ catch {
86
+ // Fallback: try the other signature
87
+ try {
88
+ target.postMessage(portTransferMessage, [port2]);
89
+ }
90
+ catch (e) {
91
+ cleanup();
92
+ port1.close();
93
+ reject(new Error(`Failed to transfer port to target: ${e}`));
94
+ return;
95
+ }
96
+ }
97
+ // Send ready message with our ID
98
+ const readyMessage = { type: "jazz:ready", id };
99
+ port1.postMessage(readyMessage);
100
+ });
101
+ }
102
+ /**
103
+ * Wait for an incoming Jazz connection.
104
+ * Listens for a port transfer message on the global scope and completes the handshake.
105
+ *
106
+ * @param opts - Configuration options
107
+ * @returns A promise that resolves to a Peer once the handshake completes
108
+ */
109
+ static waitForConnection(opts = {}) {
110
+ return new Promise((resolve) => {
111
+ let resolved = false;
112
+ const scope = globalThis;
113
+ const cleanup = () => {
114
+ scope.removeEventListener("message", handlePortTransfer);
115
+ };
116
+ const handlePortTransfer = async (event) => {
117
+ const messageEvent = event;
118
+ const data = messageEvent.data;
119
+ // Check if this is a valid port transfer message
120
+ if (!isPortTransferMessage(data)) {
121
+ return;
122
+ }
123
+ // If id filter is provided, check it against the port transfer message
124
+ if (opts.id !== undefined && data.id !== opts.id) {
125
+ return; // Ignore, keep waiting for matching id
126
+ }
127
+ // Validate origin if in Window context and allowedOrigins is specified
128
+ if (opts.allowedOrigins && opts.allowedOrigins.length > 0) {
129
+ const origin = messageEvent.origin;
130
+ const isAllowed = opts.allowedOrigins.some((allowed) => allowed === "*" || allowed === origin);
131
+ if (!isAllowed) {
132
+ logger.warn(`Ignoring message from non-allowed origin: ${origin}`);
133
+ return; // Ignore messages from non-allowed origins
134
+ }
135
+ }
136
+ // Get the transferred port
137
+ const port = messageEvent.ports?.[0];
138
+ if (!port) {
139
+ return; // No port transferred, ignore
140
+ }
141
+ if (resolved)
142
+ return;
143
+ resolved = true;
144
+ cleanup();
145
+ // Complete the handshake using acceptFromPort
146
+ // Pass the id from the port transfer message to acceptFromPort
147
+ const peer = await CojsonMessageChannel.acceptFromPort(port, {
148
+ ...opts,
149
+ id: data.id, // Use the id from the port transfer message
150
+ });
151
+ resolve(peer);
152
+ };
153
+ // Start listening for port transfer
154
+ scope.addEventListener("message", handlePortTransfer);
155
+ });
156
+ }
157
+ /**
158
+ * Accept an incoming Jazz connection from a specific port.
159
+ * Lower-level API useful for testing or when you already have the port.
160
+ * This method has no timeout - it will wait indefinitely for the handshake.
161
+ *
162
+ * @param port - The MessagePort to accept the connection on
163
+ * @param opts - Configuration options
164
+ * @returns A promise that resolves to a Peer once the handshake completes
165
+ */
166
+ static acceptFromPort(port, opts = {}) {
167
+ const role = opts.role ?? "client";
168
+ return new Promise((resolve) => {
169
+ let resolved = false;
170
+ let peerId;
171
+ const cleanup = () => {
172
+ port.removeEventListener("message", handleMessage);
173
+ port.removeEventListener("messageerror", handleError);
174
+ };
175
+ const handleError = () => {
176
+ if (resolved)
177
+ return;
178
+ // On error, just close and let the caller handle it
179
+ cleanup();
180
+ port.close();
181
+ };
182
+ const handleMessage = (event) => {
183
+ const data = event.data;
184
+ // Wait for ready message from host
185
+ if (isReadyMessage(data)) {
186
+ // If id filter is provided, validate it
187
+ if (opts.id !== undefined && data.id !== opts.id) {
188
+ return; // Ignore, keep waiting for matching id
189
+ }
190
+ peerId = data.id;
191
+ // Send acknowledgment
192
+ port.postMessage({ type: "jazz:ready" });
193
+ if (resolved)
194
+ return;
195
+ resolved = true;
196
+ cleanup();
197
+ // Create the peer
198
+ const peer = createPeerFromPort(port, {
199
+ id: peerId,
200
+ role,
201
+ onClose: opts.onClose,
202
+ });
203
+ resolve(peer);
204
+ }
205
+ };
206
+ // Start listening
207
+ port.addEventListener("message", handleMessage);
208
+ port.addEventListener("messageerror", handleError);
209
+ // Start the port if needed (browser MessagePort requires this)
210
+ if (port.start) {
211
+ port.start();
212
+ }
213
+ });
214
+ }
215
+ }
216
+ /**
217
+ * Create a Peer from a MessagePort after handshake is complete.
218
+ */
219
+ function createPeerFromPort(port, opts) {
220
+ const incoming = new ConnectedPeerChannel();
221
+ const outgoing = new MessagePortOutgoingChannel(port);
222
+ // Forward messages from port to incoming channel
223
+ const handleMessage = (event) => {
224
+ const data = event.data;
225
+ // Skip control messages (they're for handshake only)
226
+ if (isControlMessage(data)) {
227
+ return;
228
+ }
229
+ incoming.push(data);
230
+ };
231
+ const handleError = () => {
232
+ incoming.push("Disconnected");
233
+ incoming.close();
234
+ };
235
+ port.addEventListener("message", handleMessage);
236
+ port.addEventListener("messageerror", handleError);
237
+ port.addEventListener("close", () => {
238
+ incoming.push("Disconnected");
239
+ incoming.close();
240
+ });
241
+ // Handle outgoing channel close
242
+ outgoing.onClose(() => {
243
+ port.removeEventListener("message", handleMessage);
244
+ port.removeEventListener("messageerror", handleError);
245
+ port.close();
246
+ incoming.push("Disconnected");
247
+ incoming.close();
248
+ opts.onClose?.();
249
+ });
250
+ // Handle incoming channel close (propagate to outgoing)
251
+ incoming.onClose(() => {
252
+ outgoing.close();
253
+ });
254
+ return {
255
+ id: opts.id,
256
+ incoming,
257
+ outgoing,
258
+ role: opts.role,
259
+ };
260
+ }
261
+ //# sourceMappingURL=CojsonMessageChannel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CojsonMessageChannel.js","sourceRoot":"","sources":["../../src/CojsonMessageChannel/CojsonMessageChannel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { DisconnectedError, OutgoingPeerChannel, SyncMessage } from "../sync.js";
2
+ import type { MessagePortLike } from "./types.js";
3
+ /**
4
+ * An implementation of OutgoingPeerChannel that sends messages via a MessagePortLike.
5
+ *
6
+ * Messages are sent directly using the port's postMessage method,
7
+ * which uses structured cloning (no JSON serialization needed).
8
+ */
9
+ export declare class MessagePortOutgoingChannel implements OutgoingPeerChannel {
10
+ private port;
11
+ private closed;
12
+ private closeListeners;
13
+ constructor(port: MessagePortLike);
14
+ push(msg: SyncMessage | DisconnectedError): void;
15
+ close(): void;
16
+ onClose(callback: () => void): void;
17
+ }
18
+ //# sourceMappingURL=MessagePortOutgoingChannel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessagePortOutgoingChannel.d.ts","sourceRoot":"","sources":["../../src/CojsonMessageChannel/MessagePortOutgoingChannel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACZ,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;GAKG;AACH,qBAAa,0BAA2B,YAAW,mBAAmB;IACpE,OAAO,CAAC,IAAI,CAAkB;IAC9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,cAAc,CAAyB;gBAEnC,IAAI,EAAE,eAAe;IAIjC,IAAI,CAAC,GAAG,EAAE,WAAW,GAAG,iBAAiB,GAAG,IAAI;IAahD,KAAK,IAAI,IAAI;IAab,OAAO,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;CAGpC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * An implementation of OutgoingPeerChannel that sends messages via a MessagePortLike.
3
+ *
4
+ * Messages are sent directly using the port's postMessage method,
5
+ * which uses structured cloning (no JSON serialization needed).
6
+ */
7
+ export class MessagePortOutgoingChannel {
8
+ constructor(port) {
9
+ this.closed = false;
10
+ this.closeListeners = new Set();
11
+ this.port = port;
12
+ }
13
+ push(msg) {
14
+ if (this.closed) {
15
+ return;
16
+ }
17
+ if (msg === "Disconnected") {
18
+ this.close();
19
+ return;
20
+ }
21
+ this.port.postMessage(msg);
22
+ }
23
+ close() {
24
+ if (this.closed) {
25
+ return;
26
+ }
27
+ this.closed = true;
28
+ this.port.close();
29
+ for (const listener of this.closeListeners) {
30
+ listener();
31
+ }
32
+ }
33
+ onClose(callback) {
34
+ this.closeListeners.add(callback);
35
+ }
36
+ }
37
+ //# sourceMappingURL=MessagePortOutgoingChannel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessagePortOutgoingChannel.js","sourceRoot":"","sources":["../../src/CojsonMessageChannel/MessagePortOutgoingChannel.ts"],"names":[],"mappings":"AAOA;;;;;GAKG;AACH,MAAM,OAAO,0BAA0B;IAKrC,YAAY,IAAqB;QAHzB,WAAM,GAAG,KAAK,CAAC;QACf,mBAAc,GAAG,IAAI,GAAG,EAAc,CAAC;QAG7C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,IAAI,CAAC,GAAoC;QACvC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QAED,IAAI,GAAG,KAAK,cAAc,EAAE,CAAC;YAC3B,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAElB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YAC3C,QAAQ,EAAE,CAAC;QACb,CAAC;IACH,CAAC;IAED,OAAO,CAAC,QAAoB;QAC1B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ export { CojsonMessageChannel } from "./CojsonMessageChannel.js";
2
+ export type { AcceptFromPortOptions, WaitForConnectionOptions, ExposeOptions, MessageChannelLike, PostMessageTarget, MessagePortLike, } from "./types.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/CojsonMessageChannel/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,YAAY,EACV,qBAAqB,EACrB,wBAAwB,EACxB,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,GAChB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { CojsonMessageChannel } from "./CojsonMessageChannel.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/CojsonMessageChannel/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Type definitions for JazzMessageChannel
3
+ *
4
+ * These types support cross-context communication via MessageChannel API
5
+ * and compatible implementations (e.g., Electron's MessageChannelMain).
6
+ */
7
+ /**
8
+ * Duck-typed interface for any object that can receive messages via postMessage.
9
+ *
10
+ * Covers:
11
+ * - Worker
12
+ * - Window (including iframes via contentWindow)
13
+ * - MessagePort
14
+ * - ServiceWorker
15
+ * - Client (Service Worker clients)
16
+ * - Electron's WebContents (renderer windows)
17
+ */
18
+ export interface PostMessageTarget {
19
+ postMessage(message: unknown, transfer?: MessagePortLike[]): void;
20
+ postMessage(message: unknown, targetOrigin: string, transfer?: MessagePortLike[]): void;
21
+ }
22
+ /**
23
+ * MessagePort-like interface that covers browser MessagePort and Electron MessagePortMain.
24
+ *
25
+ * Note: Electron's MessagePortMain does not have a start() method,
26
+ * so it's optional here.
27
+ */
28
+ export interface MessagePortLike {
29
+ postMessage(message: unknown): void;
30
+ addEventListener(type: "message" | "messageerror", listener: (event: unknown) => void): void;
31
+ removeEventListener(type: "message" | "messageerror", listener: (event: unknown) => void): void;
32
+ addEventListener(event: "close", listener: () => void): void;
33
+ removeEventListener(type: "close", listener: () => void): void;
34
+ /** Optional - not present on Electron's MessagePortMain */
35
+ start?(): void;
36
+ close(): void;
37
+ }
38
+ /**
39
+ * MessageChannel-like interface that covers browser MessageChannel
40
+ * and Electron MessageChannelMain.
41
+ */
42
+ export interface MessageChannelLike {
43
+ port1: MessagePortLike;
44
+ port2: MessagePortLike;
45
+ }
46
+ /**
47
+ * Options for JazzMessageChannel.expose()
48
+ */
49
+ export interface ExposeOptions {
50
+ /**
51
+ * Unique identifier for the peer connection, sent to the guest during handshake.
52
+ * Both sides will use this same ID for the Peer object.
53
+ * If not provided, a unique ID will be generated using `channel_${Math.random()}`.
54
+ */
55
+ id?: string;
56
+ /** Role of the peer in the sync topology */
57
+ role?: "client" | "server";
58
+ /** Target origin for Window targets (default: "*") */
59
+ targetOrigin?: string;
60
+ /**
61
+ * A pre-created MessageChannel to use instead of creating a new one.
62
+ * Use this for environments where the global MessageChannel is not available,
63
+ * e.g., Electron main process with MessageChannelMain.
64
+ * If not provided, a new MessageChannel will be created.
65
+ */
66
+ messageChannel?: MessageChannelLike;
67
+ /** Callback when the connection closes */
68
+ onClose?: () => void;
69
+ }
70
+ /**
71
+ * Options for CojsonMessageChannel.waitForConnection()
72
+ */
73
+ export interface WaitForConnectionOptions {
74
+ /**
75
+ * Expected peer ID to accept.
76
+ * If provided, only handshakes with matching id will be accepted; others are ignored.
77
+ * If not provided, any connection will be accepted.
78
+ */
79
+ id?: string;
80
+ /** Role of the peer in the sync topology */
81
+ role?: "client" | "server";
82
+ /** Allowed origins for Window contexts (default: ["*"]) */
83
+ allowedOrigins?: string[];
84
+ /** Callback when the connection closes */
85
+ onClose?: () => void;
86
+ }
87
+ /**
88
+ * Options for CojsonMessageChannel.acceptFromPort()
89
+ * Note: No timeout option - acceptFromPort waits indefinitely.
90
+ */
91
+ export interface AcceptFromPortOptions {
92
+ /**
93
+ * Expected peer ID to accept.
94
+ * If provided, only handshakes with matching id will be accepted; others are ignored.
95
+ * If not provided, any connection will be accepted.
96
+ */
97
+ id?: string;
98
+ /** Role of the peer in the sync topology */
99
+ role?: "client" | "server";
100
+ /** Callback when the connection closes */
101
+ onClose?: () => void;
102
+ }
103
+ /**
104
+ * Port transfer message sent via target.postMessage.
105
+ * The actual port is transferred via Transferable.
106
+ */
107
+ export interface PortTransferMessage {
108
+ type: "jazz:port";
109
+ /** The peer ID for this connection */
110
+ id: string;
111
+ }
112
+ /**
113
+ * Ready signal sent from host to guest via MessagePort.
114
+ * Contains the peer ID that both sides will use.
115
+ */
116
+ export interface ReadyMessage {
117
+ type: "jazz:ready";
118
+ /** The peer ID to use on both sides */
119
+ id: string;
120
+ }
121
+ /**
122
+ * Acknowledgment sent from guest to host via MessagePort.
123
+ * No id needed - guest uses the id from the host's ReadyMessage.
124
+ */
125
+ export interface ReadyAckMessage {
126
+ type: "jazz:ready";
127
+ }
128
+ /**
129
+ * Union of all control messages used in the handshake protocol.
130
+ */
131
+ export type ControlMessage = PortTransferMessage | ReadyMessage | ReadyAckMessage;
132
+ /**
133
+ * Type guard to check if a message is a Jazz control message.
134
+ * Control messages are identified by having a "type" property starting with "jazz:".
135
+ */
136
+ export declare function isControlMessage(msg: unknown): msg is ControlMessage;
137
+ /**
138
+ * Type guard to check if a message is a PortTransferMessage.
139
+ */
140
+ export declare function isPortTransferMessage(msg: unknown): msg is PortTransferMessage;
141
+ /**
142
+ * Type guard to check if a message is a ReadyMessage (with id).
143
+ */
144
+ export declare function isReadyMessage(msg: unknown): msg is ReadyMessage;
145
+ /**
146
+ * Type guard to check if a message is a ReadyAckMessage (without id).
147
+ */
148
+ export declare function isReadyAckMessage(msg: unknown): msg is ReadyAckMessage;
149
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/CojsonMessageChannel/types.ts"],"names":[],"mappings":"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"}