@syncular/client 0.0.6-96 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (356) hide show
  1. package/README.md +713 -11
  2. package/dist/auth-leases.d.ts +11 -0
  3. package/dist/auth-leases.d.ts.map +1 -0
  4. package/dist/auth-leases.js +140 -0
  5. package/dist/auth-leases.js.map +1 -0
  6. package/dist/blob-limits.d.ts +15 -0
  7. package/dist/blob-limits.d.ts.map +1 -0
  8. package/dist/blob-limits.js +66 -0
  9. package/dist/blob-limits.js.map +1 -0
  10. package/dist/bridge-client.d.ts +69 -0
  11. package/dist/bridge-client.d.ts.map +1 -0
  12. package/dist/bridge-client.js +282 -0
  13. package/dist/bridge-client.js.map +1 -0
  14. package/dist/client-config.d.ts +6 -0
  15. package/dist/client-config.d.ts.map +1 -0
  16. package/dist/client-config.js +18 -0
  17. package/dist/client-config.js.map +1 -0
  18. package/dist/client.d.ts +65 -397
  19. package/dist/client.d.ts.map +1 -1
  20. package/dist/client.js +150 -960
  21. package/dist/client.js.map +1 -1
  22. package/dist/command-history.d.ts +35 -0
  23. package/dist/command-history.d.ts.map +1 -0
  24. package/dist/command-history.js +378 -0
  25. package/dist/command-history.js.map +1 -0
  26. package/dist/console-diagnostics.d.ts +33 -0
  27. package/dist/console-diagnostics.d.ts.map +1 -0
  28. package/dist/console-diagnostics.js +496 -0
  29. package/dist/console-diagnostics.js.map +1 -0
  30. package/dist/crdt-yjs/index.d.ts +4 -0
  31. package/dist/crdt-yjs/index.d.ts.map +1 -0
  32. package/dist/crdt-yjs/index.js +4 -0
  33. package/dist/crdt-yjs/index.js.map +1 -0
  34. package/dist/crdt-yjs/webview-host-facade.d.ts +126 -0
  35. package/dist/crdt-yjs/webview-host-facade.d.ts.map +1 -0
  36. package/dist/crdt-yjs/webview-host-facade.js +284 -0
  37. package/dist/crdt-yjs/webview-host-facade.js.map +1 -0
  38. package/dist/crdt-yjs/yjs-document-field-adapter.d.ts +153 -0
  39. package/dist/crdt-yjs/yjs-document-field-adapter.d.ts.map +1 -0
  40. package/dist/crdt-yjs/yjs-document-field-adapter.js +406 -0
  41. package/dist/crdt-yjs/yjs-document-field-adapter.js.map +1 -0
  42. package/dist/crdt-yjs/yjs-prosemirror-bridge.d.ts +73 -0
  43. package/dist/crdt-yjs/yjs-prosemirror-bridge.d.ts.map +1 -0
  44. package/dist/crdt-yjs/yjs-prosemirror-bridge.js +169 -0
  45. package/dist/crdt-yjs/yjs-prosemirror-bridge.js.map +1 -0
  46. package/dist/database.d.ts +83 -0
  47. package/dist/database.d.ts.map +1 -0
  48. package/dist/database.js +916 -0
  49. package/dist/database.js.map +1 -0
  50. package/dist/diagnostics.d.ts +10 -0
  51. package/dist/diagnostics.d.ts.map +1 -0
  52. package/dist/diagnostics.js +83 -0
  53. package/dist/diagnostics.js.map +1 -0
  54. package/dist/errors.d.ts +24 -0
  55. package/dist/errors.d.ts.map +1 -0
  56. package/dist/errors.js +211 -0
  57. package/dist/errors.js.map +1 -0
  58. package/dist/generated-bridge.d.ts +365 -0
  59. package/dist/generated-bridge.d.ts.map +1 -0
  60. package/dist/generated-bridge.js +250 -0
  61. package/dist/generated-bridge.js.map +1 -0
  62. package/dist/index.d.ts +13 -23
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +14 -25
  65. package/dist/index.js.map +1 -1
  66. package/dist/mutations.d.ts +4 -72
  67. package/dist/mutations.d.ts.map +1 -1
  68. package/dist/mutations.js +2 -568
  69. package/dist/mutations.js.map +1 -1
  70. package/dist/network.d.ts +3 -0
  71. package/dist/network.d.ts.map +1 -0
  72. package/dist/network.js +17 -0
  73. package/dist/network.js.map +1 -0
  74. package/dist/react/index.d.ts +169 -0
  75. package/dist/react/index.d.ts.map +1 -0
  76. package/dist/react/index.js +628 -0
  77. package/dist/react/index.js.map +1 -0
  78. package/dist/react-native/index.d.ts +35 -0
  79. package/dist/react-native/index.d.ts.map +1 -0
  80. package/dist/react-native/index.js +49 -0
  81. package/dist/react-native/index.js.map +1 -0
  82. package/dist/runtime-contract.d.ts +13 -0
  83. package/dist/runtime-contract.d.ts.map +1 -0
  84. package/dist/runtime-contract.js +24 -0
  85. package/dist/runtime-contract.js.map +1 -0
  86. package/dist/rust-client.d.ts +106 -0
  87. package/dist/rust-client.d.ts.map +1 -0
  88. package/dist/rust-client.js +936 -0
  89. package/dist/rust-client.js.map +1 -0
  90. package/dist/sentry.d.ts +35 -0
  91. package/dist/sentry.d.ts.map +1 -0
  92. package/dist/sentry.js +155 -0
  93. package/dist/sentry.js.map +1 -0
  94. package/dist/sql-safety.d.ts +3 -0
  95. package/dist/sql-safety.d.ts.map +1 -0
  96. package/dist/sql-safety.js +62 -0
  97. package/dist/sql-safety.js.map +1 -0
  98. package/dist/syncular-runtime-artifacts.json +61 -0
  99. package/dist/tauri/index.d.ts +35 -0
  100. package/dist/tauri/index.d.ts.map +1 -0
  101. package/dist/tauri/index.js +114 -0
  102. package/dist/tauri/index.js.map +1 -0
  103. package/dist/types.d.ts +1059 -0
  104. package/dist/types.d.ts.map +1 -0
  105. package/dist/types.js +2 -0
  106. package/dist/types.js.map +1 -0
  107. package/dist/wasm/.syncular-wasm-profile +1 -0
  108. package/dist/wasm/syncular-runtime-artifact.json +21 -0
  109. package/dist/wasm/syncular.d.ts +207 -0
  110. package/dist/wasm/syncular.js +2341 -0
  111. package/dist/wasm/syncular_bg.wasm +0 -0
  112. package/dist/wasm/syncular_bg.wasm.d.ts +97 -0
  113. package/dist/wasm-bindings/runtime-contract.d.ts +22 -0
  114. package/dist/wasm-bindings/runtime-contract.d.ts.map +1 -0
  115. package/dist/wasm-bindings/runtime-contract.js +112 -0
  116. package/dist/wasm-bindings/runtime-contract.js.map +1 -0
  117. package/dist/wasm-core/.syncular-wasm-profile +1 -0
  118. package/dist/wasm-core/syncular-runtime-artifact.json +17 -0
  119. package/dist/wasm-core/syncular.d.ts +162 -0
  120. package/dist/wasm-core/syncular.js +1847 -0
  121. package/dist/wasm-core/syncular_bg.wasm +0 -0
  122. package/dist/wasm-core/syncular_bg.wasm.d.ts +77 -0
  123. package/dist/wasm-perf/.syncular-wasm-profile +1 -0
  124. package/dist/wasm-perf/syncular-runtime-artifact.json +21 -0
  125. package/dist/wasm-perf/syncular.d.ts +207 -0
  126. package/dist/wasm-perf/syncular.js +2341 -0
  127. package/dist/wasm-perf/syncular_bg.wasm +0 -0
  128. package/dist/wasm-perf/syncular_bg.wasm.d.ts +97 -0
  129. package/dist/wasm-runtime.d.ts +18 -0
  130. package/dist/wasm-runtime.d.ts.map +1 -0
  131. package/dist/wasm-runtime.js +28 -0
  132. package/dist/wasm-runtime.js.map +1 -0
  133. package/dist/worker-client.d.ts +123 -0
  134. package/dist/worker-client.d.ts.map +1 -0
  135. package/dist/worker-client.js +1686 -0
  136. package/dist/worker-client.js.map +1 -0
  137. package/dist/worker-entry.d.ts +2 -0
  138. package/dist/worker-entry.d.ts.map +1 -0
  139. package/dist/worker-entry.js +479 -0
  140. package/dist/worker-entry.js.map +1 -0
  141. package/dist/worker-protocol.d.ts +64 -0
  142. package/dist/worker-protocol.d.ts.map +1 -0
  143. package/dist/worker-protocol.js +16 -0
  144. package/dist/worker-protocol.js.map +1 -0
  145. package/dist/worker-realtime.d.ts +39 -0
  146. package/dist/worker-realtime.d.ts.map +1 -0
  147. package/dist/worker-realtime.js +677 -0
  148. package/dist/worker-realtime.js.map +1 -0
  149. package/package.json +124 -17
  150. package/src/auth-leases.ts +251 -0
  151. package/src/blob-limits.ts +98 -0
  152. package/src/bridge-client.ts +512 -0
  153. package/src/client-config.ts +29 -0
  154. package/src/client.ts +256 -1414
  155. package/src/command-history.ts +623 -0
  156. package/src/console-diagnostics.ts +617 -0
  157. package/src/crdt-yjs/index.ts +3 -0
  158. package/src/crdt-yjs/webview-host-facade.ts +477 -0
  159. package/src/crdt-yjs/yjs-document-field-adapter.ts +733 -0
  160. package/src/crdt-yjs/yjs-prosemirror-bridge.ts +272 -0
  161. package/src/database.ts +1342 -0
  162. package/src/diagnostics.ts +116 -0
  163. package/src/errors.ts +269 -0
  164. package/src/generated-bridge.ts +741 -0
  165. package/src/index.ts +21 -25
  166. package/src/mutations.ts +12 -821
  167. package/src/network.ts +32 -0
  168. package/src/react/index.ts +1036 -0
  169. package/src/react-native/index.ts +152 -0
  170. package/src/runtime-contract.ts +48 -0
  171. package/src/rust-client.ts +1488 -0
  172. package/src/sentry.ts +215 -0
  173. package/src/sql-safety.ts +61 -0
  174. package/src/tauri/index.ts +211 -0
  175. package/src/types.ts +1356 -0
  176. package/src/wasm-bindings/generated-wasm-bindings.d.ts +70 -0
  177. package/src/wasm-bindings/runtime-contract.ts +158 -0
  178. package/src/wasm-runtime.ts +76 -0
  179. package/src/worker-client.ts +2215 -0
  180. package/src/worker-entry.ts +584 -0
  181. package/src/worker-protocol.ts +109 -0
  182. package/src/worker-realtime.ts +843 -0
  183. package/dist/blobs/index.d.ts +0 -7
  184. package/dist/blobs/index.d.ts.map +0 -1
  185. package/dist/blobs/index.js +0 -7
  186. package/dist/blobs/index.js.map +0 -1
  187. package/dist/blobs/manager.d.ts +0 -345
  188. package/dist/blobs/manager.d.ts.map +0 -1
  189. package/dist/blobs/manager.js +0 -749
  190. package/dist/blobs/manager.js.map +0 -1
  191. package/dist/blobs/migrate.d.ts +0 -14
  192. package/dist/blobs/migrate.d.ts.map +0 -1
  193. package/dist/blobs/migrate.js +0 -59
  194. package/dist/blobs/migrate.js.map +0 -1
  195. package/dist/blobs/types.d.ts +0 -62
  196. package/dist/blobs/types.d.ts.map +0 -1
  197. package/dist/blobs/types.js +0 -5
  198. package/dist/blobs/types.js.map +0 -1
  199. package/dist/conflicts.d.ts +0 -31
  200. package/dist/conflicts.d.ts.map +0 -1
  201. package/dist/conflicts.js +0 -112
  202. package/dist/conflicts.js.map +0 -1
  203. package/dist/create-client.d.ts +0 -118
  204. package/dist/create-client.d.ts.map +0 -1
  205. package/dist/create-client.js +0 -178
  206. package/dist/create-client.js.map +0 -1
  207. package/dist/engine/SyncEngine.d.ts +0 -272
  208. package/dist/engine/SyncEngine.d.ts.map +0 -1
  209. package/dist/engine/SyncEngine.js +0 -1860
  210. package/dist/engine/SyncEngine.js.map +0 -1
  211. package/dist/engine/index.d.ts +0 -6
  212. package/dist/engine/index.d.ts.map +0 -1
  213. package/dist/engine/index.js +0 -6
  214. package/dist/engine/index.js.map +0 -1
  215. package/dist/engine/types.d.ts +0 -345
  216. package/dist/engine/types.d.ts.map +0 -1
  217. package/dist/engine/types.js +0 -7
  218. package/dist/engine/types.js.map +0 -1
  219. package/dist/handlers/collection.d.ts +0 -6
  220. package/dist/handlers/collection.d.ts.map +0 -1
  221. package/dist/handlers/collection.js +0 -21
  222. package/dist/handlers/collection.js.map +0 -1
  223. package/dist/handlers/create-handler.d.ts +0 -120
  224. package/dist/handlers/create-handler.d.ts.map +0 -1
  225. package/dist/handlers/create-handler.js +0 -145
  226. package/dist/handlers/create-handler.js.map +0 -1
  227. package/dist/handlers/types.d.ts +0 -83
  228. package/dist/handlers/types.d.ts.map +0 -1
  229. package/dist/handlers/types.js +0 -5
  230. package/dist/handlers/types.js.map +0 -1
  231. package/dist/migrate.d.ts +0 -19
  232. package/dist/migrate.d.ts.map +0 -1
  233. package/dist/migrate.js +0 -238
  234. package/dist/migrate.js.map +0 -1
  235. package/dist/outbox.d.ts +0 -112
  236. package/dist/outbox.d.ts.map +0 -1
  237. package/dist/outbox.js +0 -294
  238. package/dist/outbox.js.map +0 -1
  239. package/dist/plugins/incrementing-version.d.ts +0 -34
  240. package/dist/plugins/incrementing-version.d.ts.map +0 -1
  241. package/dist/plugins/incrementing-version.js +0 -83
  242. package/dist/plugins/incrementing-version.js.map +0 -1
  243. package/dist/plugins/index.d.ts +0 -3
  244. package/dist/plugins/index.d.ts.map +0 -1
  245. package/dist/plugins/index.js +0 -3
  246. package/dist/plugins/index.js.map +0 -1
  247. package/dist/plugins/types.d.ts +0 -49
  248. package/dist/plugins/types.d.ts.map +0 -1
  249. package/dist/plugins/types.js +0 -15
  250. package/dist/plugins/types.js.map +0 -1
  251. package/dist/proxy/connection.d.ts +0 -33
  252. package/dist/proxy/connection.d.ts.map +0 -1
  253. package/dist/proxy/connection.js +0 -153
  254. package/dist/proxy/connection.js.map +0 -1
  255. package/dist/proxy/dialect.d.ts +0 -46
  256. package/dist/proxy/dialect.d.ts.map +0 -1
  257. package/dist/proxy/dialect.js +0 -58
  258. package/dist/proxy/dialect.js.map +0 -1
  259. package/dist/proxy/driver.d.ts +0 -42
  260. package/dist/proxy/driver.d.ts.map +0 -1
  261. package/dist/proxy/driver.js +0 -78
  262. package/dist/proxy/driver.js.map +0 -1
  263. package/dist/proxy/index.d.ts +0 -10
  264. package/dist/proxy/index.d.ts.map +0 -1
  265. package/dist/proxy/index.js +0 -10
  266. package/dist/proxy/index.js.map +0 -1
  267. package/dist/proxy/mutations.d.ts +0 -9
  268. package/dist/proxy/mutations.d.ts.map +0 -1
  269. package/dist/proxy/mutations.js +0 -11
  270. package/dist/proxy/mutations.js.map +0 -1
  271. package/dist/pull-engine.d.ts +0 -48
  272. package/dist/pull-engine.d.ts.map +0 -1
  273. package/dist/pull-engine.js +0 -648
  274. package/dist/pull-engine.js.map +0 -1
  275. package/dist/push-engine.d.ts +0 -18
  276. package/dist/push-engine.d.ts.map +0 -1
  277. package/dist/push-engine.js +0 -167
  278. package/dist/push-engine.js.map +0 -1
  279. package/dist/query/FingerprintCollector.d.ts +0 -18
  280. package/dist/query/FingerprintCollector.d.ts.map +0 -1
  281. package/dist/query/FingerprintCollector.js +0 -28
  282. package/dist/query/FingerprintCollector.js.map +0 -1
  283. package/dist/query/QueryContext.d.ts +0 -33
  284. package/dist/query/QueryContext.d.ts.map +0 -1
  285. package/dist/query/QueryContext.js +0 -16
  286. package/dist/query/QueryContext.js.map +0 -1
  287. package/dist/query/fingerprint.d.ts +0 -61
  288. package/dist/query/fingerprint.d.ts.map +0 -1
  289. package/dist/query/fingerprint.js +0 -91
  290. package/dist/query/fingerprint.js.map +0 -1
  291. package/dist/query/index.d.ts +0 -7
  292. package/dist/query/index.d.ts.map +0 -1
  293. package/dist/query/index.js +0 -7
  294. package/dist/query/index.js.map +0 -1
  295. package/dist/query/tracked-select.d.ts +0 -18
  296. package/dist/query/tracked-select.d.ts.map +0 -1
  297. package/dist/query/tracked-select.js +0 -90
  298. package/dist/query/tracked-select.js.map +0 -1
  299. package/dist/schema.d.ts +0 -83
  300. package/dist/schema.d.ts.map +0 -1
  301. package/dist/schema.js +0 -7
  302. package/dist/schema.js.map +0 -1
  303. package/dist/subscription-state.d.ts +0 -46
  304. package/dist/subscription-state.d.ts.map +0 -1
  305. package/dist/subscription-state.js +0 -185
  306. package/dist/subscription-state.js.map +0 -1
  307. package/dist/sync-loop.d.ts +0 -34
  308. package/dist/sync-loop.d.ts.map +0 -1
  309. package/dist/sync-loop.js +0 -253
  310. package/dist/sync-loop.js.map +0 -1
  311. package/dist/sync.d.ts +0 -32
  312. package/dist/sync.d.ts.map +0 -1
  313. package/dist/sync.js +0 -55
  314. package/dist/sync.js.map +0 -1
  315. package/dist/utils/id.d.ts +0 -17
  316. package/dist/utils/id.d.ts.map +0 -1
  317. package/dist/utils/id.js +0 -46
  318. package/dist/utils/id.js.map +0 -1
  319. package/src/blobs/index.ts +0 -7
  320. package/src/blobs/manager.ts +0 -1027
  321. package/src/blobs/migrate.ts +0 -67
  322. package/src/blobs/types.ts +0 -84
  323. package/src/client.test.ts +0 -417
  324. package/src/conflicts.ts +0 -171
  325. package/src/create-client.test.ts +0 -83
  326. package/src/create-client.ts +0 -330
  327. package/src/engine/SyncEngine.test.ts +0 -254
  328. package/src/engine/SyncEngine.ts +0 -2375
  329. package/src/engine/index.ts +0 -6
  330. package/src/engine/types.ts +0 -419
  331. package/src/handlers/collection.ts +0 -36
  332. package/src/handlers/create-handler.ts +0 -330
  333. package/src/handlers/types.ts +0 -108
  334. package/src/migrate.ts +0 -318
  335. package/src/outbox.ts +0 -383
  336. package/src/plugins/incrementing-version.ts +0 -133
  337. package/src/plugins/index.ts +0 -2
  338. package/src/plugins/types.ts +0 -63
  339. package/src/proxy/connection.ts +0 -191
  340. package/src/proxy/dialect.ts +0 -76
  341. package/src/proxy/driver.ts +0 -126
  342. package/src/proxy/index.ts +0 -10
  343. package/src/proxy/mutations.ts +0 -18
  344. package/src/pull-engine.test.ts +0 -151
  345. package/src/pull-engine.ts +0 -855
  346. package/src/push-engine.ts +0 -216
  347. package/src/query/FingerprintCollector.ts +0 -29
  348. package/src/query/QueryContext.ts +0 -54
  349. package/src/query/fingerprint.ts +0 -109
  350. package/src/query/index.ts +0 -10
  351. package/src/query/tracked-select.ts +0 -139
  352. package/src/schema.ts +0 -94
  353. package/src/subscription-state.ts +0 -259
  354. package/src/sync-loop.ts +0 -379
  355. package/src/sync.ts +0 -170
  356. package/src/utils/id.ts +0 -55
@@ -0,0 +1,617 @@
1
+ import { browserSyncularNetworkStatusSource } from './network';
2
+ import type {
3
+ SyncularAuthHeaders,
4
+ SyncularClientConfig,
5
+ SyncularConsoleDiagnosticsOptions,
6
+ SyncularDiagnosticEvent,
7
+ SyncularDiagnosticSnapshot,
8
+ SyncularLifecycleState,
9
+ SyncularNetworkStatusSource,
10
+ SyncularRuntimeClient,
11
+ SyncularSyncTimings,
12
+ } from './types';
13
+
14
+ const DEFAULT_MAX_PAYLOAD_BYTES = 48 * 1024;
15
+ const MIN_MAX_PAYLOAD_BYTES = 1024;
16
+ const DEFAULT_DEBOUNCE_MS = 100;
17
+ const MAX_MESSAGE_LENGTH = 240;
18
+ const MAX_STRING_DETAIL_LENGTH = 160;
19
+ const MAX_ARRAY_DETAIL_ITEMS = 8;
20
+
21
+ type ConsoleDiagnosticsClient = Pick<
22
+ SyncularRuntimeClient,
23
+ | 'addDiagnosticListener'
24
+ | 'addEventListener'
25
+ | 'diagnosticSnapshot'
26
+ | 'lifecycleState'
27
+ >;
28
+
29
+ export interface SyncularConsoleDiagnosticsPayload {
30
+ clientId: string;
31
+ actorId?: string;
32
+ partitionId: string;
33
+ lifecycle?: Record<string, unknown>;
34
+ snapshot: Record<string, unknown>;
35
+ }
36
+
37
+ export interface SyncularConsoleDiagnosticsPayloadResult {
38
+ payload: SyncularConsoleDiagnosticsPayload;
39
+ body: string;
40
+ byteLength: number;
41
+ compacted: boolean;
42
+ }
43
+
44
+ interface CreateSyncularConsoleDiagnosticsPublisherOptions
45
+ extends SyncularConsoleDiagnosticsOptions {
46
+ config: SyncularClientConfig;
47
+ isClosed: () => boolean;
48
+ }
49
+
50
+ interface ResolvedConsoleDiagnosticsOptions {
51
+ endpoint: string;
52
+ clientId: string;
53
+ actorId?: string;
54
+ partitionId: string;
55
+ token?: string;
56
+ getHeaders?: () => SyncularAuthHeaders | Promise<SyncularAuthHeaders>;
57
+ debounceMs: number | false;
58
+ maxPayloadBytes: number;
59
+ network: SyncularNetworkStatusSource | undefined;
60
+ }
61
+
62
+ interface CompactProfile {
63
+ diagnosticCount: number;
64
+ syncTimingCount: number;
65
+ includeDetails: boolean;
66
+ includeConnectionLastDiagnostic: boolean;
67
+ }
68
+
69
+ const COMPACT_PROFILES: CompactProfile[] = [
70
+ {
71
+ diagnosticCount: 40,
72
+ syncTimingCount: 20,
73
+ includeDetails: true,
74
+ includeConnectionLastDiagnostic: true,
75
+ },
76
+ {
77
+ diagnosticCount: 20,
78
+ syncTimingCount: 10,
79
+ includeDetails: true,
80
+ includeConnectionLastDiagnostic: true,
81
+ },
82
+ {
83
+ diagnosticCount: 10,
84
+ syncTimingCount: 5,
85
+ includeDetails: true,
86
+ includeConnectionLastDiagnostic: true,
87
+ },
88
+ {
89
+ diagnosticCount: 5,
90
+ syncTimingCount: 3,
91
+ includeDetails: false,
92
+ includeConnectionLastDiagnostic: false,
93
+ },
94
+ {
95
+ diagnosticCount: 2,
96
+ syncTimingCount: 1,
97
+ includeDetails: false,
98
+ includeConnectionLastDiagnostic: false,
99
+ },
100
+ {
101
+ diagnosticCount: 0,
102
+ syncTimingCount: 0,
103
+ includeDetails: false,
104
+ includeConnectionLastDiagnostic: false,
105
+ },
106
+ ];
107
+
108
+ const SIMPLE_DETAIL_KEYS = new Set([
109
+ 'acked',
110
+ 'bytes',
111
+ 'changedRowCount',
112
+ 'changedRows',
113
+ 'changedRowsTruncated',
114
+ 'changedTableCount',
115
+ 'changedTables',
116
+ 'commitApplyMs',
117
+ 'conflicts',
118
+ 'cursor',
119
+ 'durationMs',
120
+ 'failed',
121
+ 'headerCount',
122
+ 'integrityVerifyMs',
123
+ 'message',
124
+ 'notifyMs',
125
+ 'operation',
126
+ 'pending',
127
+ 'pullApplyMs',
128
+ 'pullTransformMs',
129
+ 'pushedCommits',
130
+ 'reason',
131
+ 'requestType',
132
+ 'responseBytes',
133
+ 'rowId',
134
+ 'source',
135
+ 'status',
136
+ 'statusText',
137
+ 'subscriptionStateMs',
138
+ 'syncPackDecodeMs',
139
+ 'table',
140
+ 'total',
141
+ 'totalMs',
142
+ 'uploading',
143
+ ]);
144
+
145
+ const OMITTED_DETAIL_KEYS = new Set([
146
+ 'changedRows',
147
+ 'subscriptions',
148
+ 'phases',
149
+ 'expectedSubscriptionIds',
150
+ 'readySubscriptionIds',
151
+ 'pendingSubscriptionIds',
152
+ ]);
153
+
154
+ const SENSITIVE_DETAIL_KEYS = new Set([
155
+ 'accesstoken',
156
+ 'apikey',
157
+ 'authorization',
158
+ 'authtoken',
159
+ 'mnemonic',
160
+ 'password',
161
+ 'plaintext',
162
+ 'privatekey',
163
+ 'refreshtoken',
164
+ 'secret',
165
+ 'seedphrase',
166
+ ]);
167
+
168
+ export function createSyncularConsoleDiagnosticsPublisher(
169
+ client: ConsoleDiagnosticsClient,
170
+ options: CreateSyncularConsoleDiagnosticsPublisherOptions
171
+ ): { schedule(): void; destroy(): void } {
172
+ const resolved = resolveConsoleDiagnosticsOptions(options);
173
+ if (!resolved || typeof globalThis.fetch !== 'function') {
174
+ return noopPublisher();
175
+ }
176
+
177
+ let closed = false;
178
+ let timer: ReturnType<typeof setTimeout> | undefined;
179
+ let inFlight = false;
180
+ let publishAgain = false;
181
+ let queuedWhileOffline = false;
182
+ let lastCompletedFingerprint: string | undefined;
183
+
184
+ const clearTimer = () => {
185
+ if (timer) clearTimeout(timer);
186
+ timer = undefined;
187
+ };
188
+ const isClosed = () => closed || options.isClosed();
189
+ const isOnline = () => resolved.network?.isOnline() !== false;
190
+
191
+ const publish = async () => {
192
+ if (isClosed()) return;
193
+ if (!isOnline()) {
194
+ queuedWhileOffline = true;
195
+ return;
196
+ }
197
+ if (inFlight) {
198
+ publishAgain = true;
199
+ return;
200
+ }
201
+
202
+ inFlight = true;
203
+ try {
204
+ const snapshot = await client.diagnosticSnapshot();
205
+ const lifecycle = client.lifecycleState();
206
+ const payload = buildSyncularConsoleDiagnosticsPayload({
207
+ actorId: resolved.actorId,
208
+ clientId: resolved.clientId,
209
+ lifecycle,
210
+ maxPayloadBytes: resolved.maxPayloadBytes,
211
+ partitionId: resolved.partitionId,
212
+ snapshot,
213
+ });
214
+ const fingerprint = payloadFingerprint(payload.payload);
215
+ if (fingerprint === lastCompletedFingerprint) return;
216
+
217
+ const response = await globalThis.fetch(resolved.endpoint, {
218
+ method: 'POST',
219
+ headers: await buildHeaders(resolved),
220
+ body: payload.body,
221
+ });
222
+ if (response.ok || response.status < 500) {
223
+ lastCompletedFingerprint = fingerprint;
224
+ }
225
+ } catch {
226
+ if (!isOnline()) queuedWhileOffline = true;
227
+ } finally {
228
+ inFlight = false;
229
+ if (publishAgain && !isClosed()) {
230
+ publishAgain = false;
231
+ schedule();
232
+ }
233
+ }
234
+ };
235
+
236
+ const schedule = () => {
237
+ if (isClosed()) return;
238
+ if (!isOnline()) {
239
+ queuedWhileOffline = true;
240
+ clearTimer();
241
+ return;
242
+ }
243
+ if (inFlight) {
244
+ publishAgain = true;
245
+ return;
246
+ }
247
+ clearTimer();
248
+ if (resolved.debounceMs === false || resolved.debounceMs <= 0) {
249
+ queueMicrotask(() => void publish());
250
+ return;
251
+ }
252
+ timer = setTimeout(() => void publish(), resolved.debounceMs);
253
+ };
254
+
255
+ const handleOnline = () => {
256
+ if (!queuedWhileOffline || isClosed()) return;
257
+ queuedWhileOffline = false;
258
+ schedule();
259
+ };
260
+
261
+ const stopListening = [
262
+ client.addDiagnosticListener(schedule),
263
+ client.addEventListener('bootstrapChanged', schedule),
264
+ client.addEventListener('outboxChanged', schedule),
265
+ client.addEventListener('conflictsChanged', schedule),
266
+ client.addEventListener('blobUploadsChanged', schedule),
267
+ ];
268
+ resolved.network?.addEventListener?.('online', handleOnline);
269
+ schedule();
270
+
271
+ return {
272
+ schedule,
273
+ destroy() {
274
+ closed = true;
275
+ clearTimer();
276
+ queuedWhileOffline = false;
277
+ publishAgain = false;
278
+ resolved.network?.removeEventListener?.('online', handleOnline);
279
+ for (const stop of stopListening) stop();
280
+ },
281
+ };
282
+ }
283
+
284
+ export function buildSyncularConsoleDiagnosticsPayload(args: {
285
+ clientId: string;
286
+ actorId?: string;
287
+ partitionId?: string;
288
+ lifecycle?: SyncularLifecycleState;
289
+ snapshot: SyncularDiagnosticSnapshot;
290
+ maxPayloadBytes?: number;
291
+ }): SyncularConsoleDiagnosticsPayloadResult {
292
+ const maxPayloadBytes = normalizeMaxPayloadBytes(args.maxPayloadBytes);
293
+ let best: SyncularConsoleDiagnosticsPayloadResult | undefined;
294
+
295
+ for (const profile of COMPACT_PROFILES) {
296
+ const payload = createPayloadForProfile(args, profile);
297
+ const body = JSON.stringify(payload);
298
+ const byteLength = jsonByteLength(body);
299
+ const result = {
300
+ payload,
301
+ body,
302
+ byteLength,
303
+ compacted: true,
304
+ };
305
+ best = result;
306
+ if (byteLength <= maxPayloadBytes) return result;
307
+ }
308
+
309
+ return best as SyncularConsoleDiagnosticsPayloadResult;
310
+ }
311
+
312
+ function createPayloadForProfile(
313
+ args: {
314
+ clientId: string;
315
+ actorId?: string;
316
+ partitionId?: string;
317
+ lifecycle?: SyncularLifecycleState;
318
+ snapshot: SyncularDiagnosticSnapshot;
319
+ },
320
+ profile: CompactProfile
321
+ ): SyncularConsoleDiagnosticsPayload {
322
+ const payload: SyncularConsoleDiagnosticsPayload = {
323
+ clientId: args.clientId,
324
+ partitionId: args.partitionId || 'default',
325
+ snapshot: compactSnapshot(args.snapshot, profile),
326
+ };
327
+ if (args.actorId) payload.actorId = args.actorId;
328
+ if (args.lifecycle) {
329
+ payload.lifecycle = compactLifecycle(args.lifecycle, profile);
330
+ }
331
+ return payload;
332
+ }
333
+
334
+ function compactSnapshot(
335
+ snapshot: SyncularDiagnosticSnapshot,
336
+ profile: CompactProfile
337
+ ): Record<string, unknown> {
338
+ const result: Record<string, unknown> = {
339
+ generatedAt: snapshot.generatedAt,
340
+ runtime: snapshot.runtime,
341
+ connection: compactConnection(
342
+ snapshot.connection,
343
+ profile.includeConnectionLastDiagnostic
344
+ ),
345
+ subscriptions: snapshot.subscriptions,
346
+ recentDiagnostics: takeLast(
347
+ snapshot.recentDiagnostics,
348
+ profile.diagnosticCount
349
+ ).map((event) => compactDiagnosticEvent(event, profile.includeDetails)),
350
+ recentSyncTimings: takeLast(
351
+ snapshot.recentSyncTimings,
352
+ profile.syncTimingCount
353
+ ).map(compactSyncTiming),
354
+ };
355
+ if (snapshot.bootstrap)
356
+ result.bootstrap = compactBootstrap(snapshot.bootstrap);
357
+ if (snapshot.transportStats) result.transportStats = snapshot.transportStats;
358
+ if (snapshot.outboxStats) result.outboxStats = snapshot.outboxStats;
359
+ if (snapshot.conflictStats) result.conflictStats = snapshot.conflictStats;
360
+ if (snapshot.blobUploadStats) {
361
+ result.blobUploadStats = snapshot.blobUploadStats;
362
+ }
363
+ return result;
364
+ }
365
+
366
+ function compactLifecycle(
367
+ lifecycle: SyncularLifecycleState,
368
+ profile: CompactProfile
369
+ ): Record<string, unknown> {
370
+ return {
371
+ ...lifecycle,
372
+ lastDiagnostic: lifecycle.lastDiagnostic
373
+ ? compactDiagnosticEvent(lifecycle.lastDiagnostic, profile.includeDetails)
374
+ : undefined,
375
+ };
376
+ }
377
+
378
+ function compactConnection(
379
+ connection: SyncularDiagnosticSnapshot['connection'],
380
+ includeLastDiagnostic: boolean
381
+ ): Record<string, unknown> {
382
+ return {
383
+ ...connection,
384
+ lastDiagnostic:
385
+ includeLastDiagnostic && connection.lastDiagnostic
386
+ ? compactDiagnosticEvent(connection.lastDiagnostic, true)
387
+ : undefined,
388
+ };
389
+ }
390
+
391
+ function compactDiagnosticEvent(
392
+ event: SyncularDiagnosticEvent,
393
+ includeDetails: boolean
394
+ ): SyncularDiagnosticEvent {
395
+ const compacted: SyncularDiagnosticEvent = {
396
+ at: event.at,
397
+ level: event.level,
398
+ source: event.source,
399
+ code: event.code,
400
+ message: truncateString(event.message, MAX_MESSAGE_LENGTH),
401
+ };
402
+ if (event.syncAttemptId) compacted.syncAttemptId = event.syncAttemptId;
403
+ if (event.traceId) compacted.traceId = event.traceId;
404
+ if (event.spanId) compacted.spanId = event.spanId;
405
+ if (event.clientId) compacted.clientId = event.clientId;
406
+ if (event.subscriptionId) compacted.subscriptionId = event.subscriptionId;
407
+ if (event.table) compacted.table = event.table;
408
+ if (event.rowId) compacted.rowId = event.rowId;
409
+ if (event.cursor !== undefined) compacted.cursor = event.cursor;
410
+ if (includeDetails && event.details) {
411
+ const details = compactDiagnosticDetails(event.details);
412
+ if (details) compacted.details = details;
413
+ }
414
+ return compacted;
415
+ }
416
+
417
+ function compactDiagnosticDetails(
418
+ details: Record<string, unknown>
419
+ ): Record<string, unknown> | undefined {
420
+ const compacted: Record<string, unknown> = {};
421
+ for (const [key, value] of Object.entries(details)) {
422
+ const normalizedKey = normalizeDiagnosticKey(key);
423
+ if (
424
+ SENSITIVE_DETAIL_KEYS.has(normalizedKey) ||
425
+ OMITTED_DETAIL_KEYS.has(key)
426
+ ) {
427
+ continue;
428
+ }
429
+ if (key === 'bootstrap') {
430
+ compacted.bootstrap = compactBootstrap(value);
431
+ continue;
432
+ }
433
+ if (!SIMPLE_DETAIL_KEYS.has(key)) continue;
434
+ const compactedValue = compactDetailValue(value);
435
+ if (compactedValue !== undefined) compacted[key] = compactedValue;
436
+ }
437
+ return Object.keys(compacted).length > 0 ? compacted : undefined;
438
+ }
439
+
440
+ function compactDetailValue(value: unknown): unknown {
441
+ if (
442
+ value === null ||
443
+ typeof value === 'boolean' ||
444
+ typeof value === 'number'
445
+ ) {
446
+ return value;
447
+ }
448
+ if (typeof value === 'string') {
449
+ return truncateString(value, MAX_STRING_DETAIL_LENGTH);
450
+ }
451
+ if (Array.isArray(value)) {
452
+ return value
453
+ .slice(0, MAX_ARRAY_DETAIL_ITEMS)
454
+ .map(compactDetailValue)
455
+ .filter((entry) => entry !== undefined);
456
+ }
457
+ if (typeof value !== 'object') return undefined;
458
+ const object = value as Record<string, unknown>;
459
+ const compacted: Record<string, unknown> = {};
460
+ for (const key of [
461
+ 'table',
462
+ 'rowId',
463
+ 'operation',
464
+ 'commitId',
465
+ 'commitSeq',
466
+ 'subscriptionId',
467
+ 'serverVersion',
468
+ ]) {
469
+ const entry = compactDetailValue(object[key]);
470
+ if (entry !== undefined) compacted[key] = entry;
471
+ }
472
+ return Object.keys(compacted).length > 0 ? compacted : undefined;
473
+ }
474
+
475
+ function compactBootstrap(value: unknown): Record<string, unknown> | unknown {
476
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return value;
477
+ const bootstrap = value as Record<string, unknown>;
478
+ const compacted: Record<string, unknown> = {};
479
+ for (const key of [
480
+ 'channelPhase',
481
+ 'progressPercent',
482
+ 'isBootstrapping',
483
+ 'criticalReady',
484
+ 'interactiveReady',
485
+ 'complete',
486
+ 'activePhase',
487
+ ]) {
488
+ if (bootstrap[key] !== undefined) compacted[key] = bootstrap[key];
489
+ }
490
+ for (const [sourceKey, targetKey] of [
491
+ ['expectedSubscriptionIds', 'expectedSubscriptionCount'],
492
+ ['readySubscriptionIds', 'readySubscriptionCount'],
493
+ ['pendingSubscriptionIds', 'pendingSubscriptionCount'],
494
+ ['subscriptions', 'subscriptionCount'],
495
+ ['phases', 'phaseCount'],
496
+ ] as const) {
497
+ const entry = bootstrap[sourceKey];
498
+ if (Array.isArray(entry)) compacted[targetKey] = entry.length;
499
+ }
500
+ return compacted;
501
+ }
502
+
503
+ function compactSyncTiming(
504
+ timing: SyncularSyncTimings
505
+ ): Record<string, unknown> {
506
+ const compacted: Record<string, unknown> = {};
507
+ for (const [key, value] of Object.entries(timing)) {
508
+ if (typeof value === 'number' && Number.isFinite(value)) {
509
+ compacted[key] = value;
510
+ }
511
+ }
512
+ return compacted;
513
+ }
514
+
515
+ function resolveConsoleDiagnosticsOptions(
516
+ options: CreateSyncularConsoleDiagnosticsPublisherOptions
517
+ ): ResolvedConsoleDiagnosticsOptions | undefined {
518
+ if (options.enabled === false) return undefined;
519
+ const endpoint =
520
+ normalizeEndpoint(options.endpoint) ??
521
+ endpointFromConsoleBaseUrl(options.baseUrl) ??
522
+ endpointFromSyncBaseUrl(options.config.baseUrl);
523
+ if (!endpoint) return undefined;
524
+
525
+ return {
526
+ endpoint,
527
+ clientId: options.clientId || options.config.clientId,
528
+ actorId: options.actorId ?? options.config.actorId,
529
+ partitionId: options.partitionId || 'default',
530
+ ...(options.token ? { token: options.token } : {}),
531
+ ...(options.getHeaders ? { getHeaders: options.getHeaders } : {}),
532
+ debounceMs: options.debounceMs ?? DEFAULT_DEBOUNCE_MS,
533
+ maxPayloadBytes: normalizeMaxPayloadBytes(options.maxPayloadBytes),
534
+ network:
535
+ options.network === false
536
+ ? undefined
537
+ : (options.network ?? browserSyncularNetworkStatusSource()),
538
+ };
539
+ }
540
+
541
+ function normalizeEndpoint(value: string | undefined): string | undefined {
542
+ const trimmed = value?.trim().replace(/\/+$/u, '');
543
+ return trimmed || undefined;
544
+ }
545
+
546
+ function endpointFromConsoleBaseUrl(
547
+ value: string | undefined
548
+ ): string | undefined {
549
+ const trimmed = value?.trim().replace(/\/+$/u, '');
550
+ if (!trimmed) return undefined;
551
+ if (trimmed.endsWith('/client-diagnostics')) return trimmed;
552
+ if (trimmed.endsWith('/console')) return `${trimmed}/client-diagnostics`;
553
+ return `${trimmed}/console/client-diagnostics`;
554
+ }
555
+
556
+ function endpointFromSyncBaseUrl(
557
+ value: string | undefined
558
+ ): string | undefined {
559
+ const trimmed = value?.trim().replace(/\/+$/u, '');
560
+ if (!trimmed) return undefined;
561
+ if (trimmed.endsWith('/sync')) {
562
+ return `${trimmed.slice(0, -'/sync'.length)}/console/client-diagnostics`;
563
+ }
564
+ return `${trimmed}/console/client-diagnostics`;
565
+ }
566
+
567
+ async function buildHeaders(
568
+ options: Pick<ResolvedConsoleDiagnosticsOptions, 'getHeaders' | 'token'>
569
+ ): Promise<SyncularAuthHeaders> {
570
+ return {
571
+ 'Content-Type': 'application/json',
572
+ ...(options.token ? { Authorization: `Bearer ${options.token}` } : {}),
573
+ ...(options.getHeaders ? await options.getHeaders() : {}),
574
+ };
575
+ }
576
+
577
+ function payloadFingerprint(
578
+ payload: SyncularConsoleDiagnosticsPayload
579
+ ): string {
580
+ const snapshot = { ...payload.snapshot, generatedAt: 0 };
581
+ return JSON.stringify({
582
+ ...payload,
583
+ snapshot,
584
+ });
585
+ }
586
+
587
+ function normalizeMaxPayloadBytes(value: number | undefined): number {
588
+ if (typeof value !== 'number' || !Number.isFinite(value)) {
589
+ return DEFAULT_MAX_PAYLOAD_BYTES;
590
+ }
591
+ return Math.max(MIN_MAX_PAYLOAD_BYTES, Math.floor(value));
592
+ }
593
+
594
+ function jsonByteLength(json: string): number {
595
+ return new TextEncoder().encode(json).byteLength;
596
+ }
597
+
598
+ function takeLast<T>(entries: readonly T[], count: number): T[] {
599
+ if (count <= 0) return [];
600
+ return entries.slice(Math.max(0, entries.length - count));
601
+ }
602
+
603
+ function truncateString(value: string, maxLength: number): string {
604
+ if (value.length <= maxLength) return value;
605
+ return `${value.slice(0, maxLength - 3)}...`;
606
+ }
607
+
608
+ function normalizeDiagnosticKey(key: string): string {
609
+ return key.toLowerCase().replace(/[^a-z0-9]/gu, '');
610
+ }
611
+
612
+ function noopPublisher(): { schedule(): void; destroy(): void } {
613
+ return {
614
+ schedule() {},
615
+ destroy() {},
616
+ };
617
+ }
@@ -0,0 +1,3 @@
1
+ export * from './webview-host-facade';
2
+ export * from './yjs-document-field-adapter';
3
+ export * from './yjs-prosemirror-bridge';