@rocicorp/zero 0.2.2024101101 → 0.3.2024102500

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 (632) hide show
  1. package/out/react.js +91 -39
  2. package/out/react.js.map +2 -2
  3. package/out/replicache/src/async-iterable-to-array.js +8 -0
  4. package/out/replicache/src/async-iterable-to-array.js.map +1 -0
  5. package/out/replicache/src/bg-interval.js +38 -0
  6. package/out/replicache/src/bg-interval.js.map +1 -0
  7. package/out/replicache/src/binary-search.js +31 -0
  8. package/out/replicache/src/binary-search.js.map +1 -0
  9. package/out/replicache/src/broadcast-channel.js +29 -0
  10. package/out/replicache/src/broadcast-channel.js.map +1 -0
  11. package/out/replicache/src/btree/diff.js +6 -0
  12. package/out/replicache/src/btree/diff.js.map +1 -0
  13. package/out/replicache/src/btree/node.js +392 -0
  14. package/out/replicache/src/btree/node.js.map +1 -0
  15. package/out/replicache/src/btree/read.js +227 -0
  16. package/out/replicache/src/btree/read.js.map +1 -0
  17. package/out/replicache/src/btree/splice.js +79 -0
  18. package/out/replicache/src/btree/splice.js.map +1 -0
  19. package/out/replicache/src/btree/write.js +154 -0
  20. package/out/replicache/src/btree/write.js.map +1 -0
  21. package/out/replicache/src/call-default-fetch.js +37 -0
  22. package/out/replicache/src/call-default-fetch.js.map +1 -0
  23. package/out/replicache/src/config.js +13 -0
  24. package/out/replicache/src/config.js.map +1 -0
  25. package/out/replicache/src/connection-loop-delegates.js +30 -0
  26. package/out/replicache/src/connection-loop-delegates.js.map +1 -0
  27. package/out/replicache/src/connection-loop.js +268 -0
  28. package/out/replicache/src/connection-loop.js.map +1 -0
  29. package/out/replicache/src/cookies.js +41 -0
  30. package/out/replicache/src/cookies.js.map +1 -0
  31. package/out/replicache/src/dag/chunk.js +60 -0
  32. package/out/replicache/src/dag/chunk.js.map +1 -0
  33. package/out/replicache/src/dag/gc.js +126 -0
  34. package/out/replicache/src/dag/gc.js.map +1 -0
  35. package/out/replicache/src/dag/key-type-enum.js +6 -0
  36. package/out/replicache/src/dag/key-type-enum.js.map +1 -0
  37. package/out/replicache/src/dag/key.js +54 -0
  38. package/out/replicache/src/dag/key.js.map +1 -0
  39. package/out/replicache/src/dag/lazy-store.js +532 -0
  40. package/out/replicache/src/dag/lazy-store.js.map +1 -0
  41. package/out/replicache/src/dag/store-impl.js +175 -0
  42. package/out/replicache/src/dag/store-impl.js.map +1 -0
  43. package/out/replicache/src/dag/store.js +22 -0
  44. package/out/replicache/src/dag/store.js.map +1 -0
  45. package/out/replicache/src/dag/visitor.js +22 -0
  46. package/out/replicache/src/dag/visitor.js.map +1 -0
  47. package/out/replicache/src/db/commit.js +443 -0
  48. package/out/replicache/src/db/commit.js.map +1 -0
  49. package/out/replicache/src/db/index-operation-enum.js +4 -0
  50. package/out/replicache/src/db/index-operation-enum.js.map +1 -0
  51. package/out/replicache/src/db/index.js +170 -0
  52. package/out/replicache/src/db/index.js.map +1 -0
  53. package/out/replicache/src/db/meta-type-enum.js +7 -0
  54. package/out/replicache/src/db/meta-type-enum.js.map +1 -0
  55. package/out/replicache/src/db/read.js +59 -0
  56. package/out/replicache/src/db/read.js.map +1 -0
  57. package/out/replicache/src/db/rebase.js +56 -0
  58. package/out/replicache/src/db/rebase.js.map +1 -0
  59. package/out/replicache/src/db/scan.js +2 -0
  60. package/out/replicache/src/db/scan.js.map +1 -0
  61. package/out/replicache/src/db/write.js +260 -0
  62. package/out/replicache/src/db/write.js.map +1 -0
  63. package/out/replicache/src/error-responses.js +30 -0
  64. package/out/replicache/src/error-responses.js.map +1 -0
  65. package/out/replicache/src/filter-async-iterable.js +15 -0
  66. package/out/replicache/src/filter-async-iterable.js.map +1 -0
  67. package/out/replicache/src/format-version-enum.js +9 -0
  68. package/out/replicache/src/format-version-enum.js.map +1 -0
  69. package/out/replicache/src/format-version.js +8 -0
  70. package/out/replicache/src/format-version.js.map +1 -0
  71. package/out/replicache/src/frozen-json.js +151 -0
  72. package/out/replicache/src/frozen-json.js.map +1 -0
  73. package/out/replicache/src/get-default-puller.js +74 -0
  74. package/out/replicache/src/get-default-puller.js.map +1 -0
  75. package/out/replicache/src/get-default-pusher.js +36 -0
  76. package/out/replicache/src/get-default-pusher.js.map +1 -0
  77. package/out/replicache/src/hash.js +73 -0
  78. package/out/replicache/src/hash.js.map +1 -0
  79. package/out/replicache/src/http-request-info.js +7 -0
  80. package/out/replicache/src/http-request-info.js.map +1 -0
  81. package/out/replicache/src/impl.js +2 -0
  82. package/out/replicache/src/impl.js.map +1 -0
  83. package/out/replicache/src/index-defs.js +28 -0
  84. package/out/replicache/src/index-defs.js.map +1 -0
  85. package/out/replicache/src/invoke-kind-enum.js +4 -0
  86. package/out/replicache/src/invoke-kind-enum.js.map +1 -0
  87. package/out/replicache/src/iterable-union.js +5 -0
  88. package/out/replicache/src/iterable-union.js.map +1 -0
  89. package/out/replicache/src/kv/idb-store-with-mem-fallback.js +93 -0
  90. package/out/replicache/src/kv/idb-store-with-mem-fallback.js.map +1 -0
  91. package/out/replicache/src/kv/idb-store.js +179 -0
  92. package/out/replicache/src/kv/idb-store.js.map +1 -0
  93. package/out/replicache/src/kv/mem-store.js +61 -0
  94. package/out/replicache/src/kv/mem-store.js.map +1 -0
  95. package/out/replicache/src/kv/read-impl.js +23 -0
  96. package/out/replicache/src/kv/read-impl.js.map +1 -0
  97. package/out/replicache/src/kv/store.js +2 -0
  98. package/out/replicache/src/kv/store.js.map +1 -0
  99. package/out/replicache/src/kv/write-impl-base.js +48 -0
  100. package/out/replicache/src/kv/write-impl-base.js.map +1 -0
  101. package/out/replicache/src/kv/write-impl.js +25 -0
  102. package/out/replicache/src/kv/write-impl.js.map +1 -0
  103. package/out/replicache/src/lazy.js +10 -0
  104. package/out/replicache/src/lazy.js.map +1 -0
  105. package/out/replicache/src/log-options.js +13 -0
  106. package/out/replicache/src/log-options.js.map +1 -0
  107. package/out/replicache/src/merge-async-iterables.js +61 -0
  108. package/out/replicache/src/merge-async-iterables.js.map +1 -0
  109. package/out/replicache/src/mod.js +14 -0
  110. package/out/replicache/src/mod.js.map +1 -0
  111. package/out/replicache/src/mutation-recovery.js +439 -0
  112. package/out/replicache/src/mutation-recovery.js.map +1 -0
  113. package/out/replicache/src/new-client-channel.js +77 -0
  114. package/out/replicache/src/new-client-channel.js.map +1 -0
  115. package/out/replicache/src/on-persist-channel.js +33 -0
  116. package/out/replicache/src/on-persist-channel.js.map +1 -0
  117. package/out/replicache/src/patch-operation.js +37 -0
  118. package/out/replicache/src/patch-operation.js.map +1 -0
  119. package/out/replicache/src/pending-mutations.js +18 -0
  120. package/out/replicache/src/pending-mutations.js.map +1 -0
  121. package/out/replicache/src/persist/client-gc.js +38 -0
  122. package/out/replicache/src/persist/client-gc.js.map +1 -0
  123. package/out/replicache/src/persist/client-group-gc.js +38 -0
  124. package/out/replicache/src/persist/client-group-gc.js.map +1 -0
  125. package/out/replicache/src/persist/client-groups.js +180 -0
  126. package/out/replicache/src/persist/client-groups.js.map +1 -0
  127. package/out/replicache/src/persist/clients.js +390 -0
  128. package/out/replicache/src/persist/clients.js.map +1 -0
  129. package/out/replicache/src/persist/collect-idb-databases.js +174 -0
  130. package/out/replicache/src/persist/collect-idb-databases.js.map +1 -0
  131. package/out/replicache/src/persist/gather-mem-only-visitor.js +25 -0
  132. package/out/replicache/src/persist/gather-mem-only-visitor.js.map +1 -0
  133. package/out/replicache/src/persist/gather-not-cached-visitor.js +35 -0
  134. package/out/replicache/src/persist/gather-not-cached-visitor.js.map +1 -0
  135. package/out/replicache/src/persist/heartbeat.js +37 -0
  136. package/out/replicache/src/persist/heartbeat.js.map +1 -0
  137. package/out/replicache/src/persist/idb-databases-store-db-name.js +18 -0
  138. package/out/replicache/src/persist/idb-databases-store-db-name.js.map +1 -0
  139. package/out/replicache/src/persist/idb-databases-store.js +90 -0
  140. package/out/replicache/src/persist/idb-databases-store.js.map +1 -0
  141. package/out/replicache/src/persist/make-client-id.js +13 -0
  142. package/out/replicache/src/persist/make-client-id.js.map +1 -0
  143. package/out/replicache/src/persist/persist.js +132 -0
  144. package/out/replicache/src/persist/persist.js.map +1 -0
  145. package/out/replicache/src/persist/refresh.js +147 -0
  146. package/out/replicache/src/persist/refresh.js.map +1 -0
  147. package/out/replicache/src/process-scheduler.js +93 -0
  148. package/out/replicache/src/process-scheduler.js.map +1 -0
  149. package/out/replicache/src/puller.js +2 -0
  150. package/out/replicache/src/puller.js.map +1 -0
  151. package/out/replicache/src/pusher.js +32 -0
  152. package/out/replicache/src/pusher.js.map +1 -0
  153. package/out/replicache/src/replicache-impl.js +1007 -0
  154. package/out/replicache/src/replicache-impl.js.map +1 -0
  155. package/out/replicache/src/replicache-options.js +2 -0
  156. package/out/replicache/src/replicache-options.js.map +1 -0
  157. package/out/replicache/src/replicache.js +387 -0
  158. package/out/replicache/src/replicache.js.map +1 -0
  159. package/out/replicache/src/request-idle.js +15 -0
  160. package/out/replicache/src/request-idle.js.map +1 -0
  161. package/out/replicache/src/scan-iterator.js +202 -0
  162. package/out/replicache/src/scan-iterator.js.map +1 -0
  163. package/out/replicache/src/scan-options.js +45 -0
  164. package/out/replicache/src/scan-options.js.map +1 -0
  165. package/out/replicache/src/set-interval-with-signal.js +7 -0
  166. package/out/replicache/src/set-interval-with-signal.js.map +1 -0
  167. package/out/replicache/src/size-of-value.js +77 -0
  168. package/out/replicache/src/size-of-value.js.map +1 -0
  169. package/out/replicache/src/subscriptions.js +357 -0
  170. package/out/replicache/src/subscriptions.js.map +1 -0
  171. package/out/replicache/src/sync/diff.js +75 -0
  172. package/out/replicache/src/sync/diff.js.map +1 -0
  173. package/out/replicache/src/sync/handle-pull-response-result-type-enum.js +5 -0
  174. package/out/replicache/src/sync/handle-pull-response-result-type-enum.js.map +1 -0
  175. package/out/replicache/src/sync/ids.js +4 -0
  176. package/out/replicache/src/sync/ids.js.map +1 -0
  177. package/out/replicache/src/sync/patch.js +41 -0
  178. package/out/replicache/src/sync/patch.js.map +1 -0
  179. package/out/replicache/src/sync/pull-error.js +16 -0
  180. package/out/replicache/src/sync/pull-error.js.map +1 -0
  181. package/out/replicache/src/sync/pull.js +375 -0
  182. package/out/replicache/src/sync/pull.js.map +1 -0
  183. package/out/replicache/src/sync/push.js +141 -0
  184. package/out/replicache/src/sync/push.js.map +1 -0
  185. package/out/replicache/src/sync/request-id.js +31 -0
  186. package/out/replicache/src/sync/request-id.js.map +1 -0
  187. package/out/replicache/src/sync/sync-head-name.js +2 -0
  188. package/out/replicache/src/sync/sync-head-name.js.map +1 -0
  189. package/out/replicache/src/test-license-key.js +3 -0
  190. package/out/replicache/src/test-license-key.js.map +1 -0
  191. package/out/replicache/src/to-error.js +7 -0
  192. package/out/replicache/src/to-error.js.map +1 -0
  193. package/out/replicache/src/transaction-closed-error.js +17 -0
  194. package/out/replicache/src/transaction-closed-error.js.map +1 -0
  195. package/out/replicache/src/transactions.js +144 -0
  196. package/out/replicache/src/transactions.js.map +1 -0
  197. package/out/replicache/src/types.js +2 -0
  198. package/out/replicache/src/types.js.map +1 -0
  199. package/out/replicache/src/version.js +5 -0
  200. package/out/replicache/src/version.js.map +1 -0
  201. package/out/replicache/src/with-transactions.js +28 -0
  202. package/out/replicache/src/with-transactions.js.map +1 -0
  203. package/out/shared/src/browser-env.js +14 -0
  204. package/out/shared/src/browser-env.js.map +1 -0
  205. package/out/shared/src/document-visible.js +76 -0
  206. package/out/shared/src/document-visible.js.map +1 -0
  207. package/out/shared/src/immutable.js +2 -0
  208. package/out/shared/src/immutable.js.map +1 -0
  209. package/out/shared/src/iterables.d.ts +2 -2
  210. package/out/shared/src/iterables.d.ts.map +1 -1
  211. package/out/shared/src/iterables.js +40 -0
  212. package/out/shared/src/iterables.js.map +1 -0
  213. package/out/shared/src/navigator.js +3 -0
  214. package/out/shared/src/navigator.js.map +1 -0
  215. package/out/shared/src/random-uint64.js +8 -0
  216. package/out/shared/src/random-uint64.js.map +1 -0
  217. package/out/shared/src/random-values.d.ts +1 -0
  218. package/out/shared/src/random-values.d.ts.map +1 -1
  219. package/out/shared/src/random-values.js +22 -0
  220. package/out/shared/src/random-values.js.map +1 -0
  221. package/out/shared/src/set-utils.d.ts +1 -1
  222. package/out/shared/src/set-utils.d.ts.map +1 -1
  223. package/out/shared/src/set-utils.js +6 -4
  224. package/out/shared/src/set-utils.js.map +1 -1
  225. package/out/shared/src/sorted-entries.d.ts +2 -0
  226. package/out/shared/src/sorted-entries.d.ts.map +1 -0
  227. package/out/shared/src/sorted-entries.js +6 -0
  228. package/out/shared/src/sorted-entries.js.map +1 -0
  229. package/out/shared/src/types.js +2 -0
  230. package/out/shared/src/types.js.map +1 -0
  231. package/out/shared/src/valita.d.ts +1 -1
  232. package/out/shared/src/valita.d.ts.map +1 -1
  233. package/out/shared/src/valita.js.map +1 -1
  234. package/out/shared/src/writable.d.ts +4 -0
  235. package/out/shared/src/writable.d.ts.map +1 -0
  236. package/out/shared/src/writable.js +2 -0
  237. package/out/shared/src/writable.js.map +1 -0
  238. package/out/zero/src/config.d.ts +2 -0
  239. package/out/zero/src/config.d.ts.map +1 -0
  240. package/out/zero/src/config.js +2 -0
  241. package/out/zero/src/config.js.map +1 -0
  242. package/out/zero-cache/src/config/config-query.d.ts +18 -0
  243. package/out/zero-cache/src/config/config-query.d.ts.map +1 -0
  244. package/out/zero-cache/src/config/config-query.js +19 -0
  245. package/out/zero-cache/src/config/config-query.js.map +1 -0
  246. package/out/zero-cache/src/config/define-config.d.ts +43 -0
  247. package/out/zero-cache/src/config/define-config.d.ts.map +1 -0
  248. package/out/zero-cache/src/config/define-config.js +120 -0
  249. package/out/zero-cache/src/config/define-config.js.map +1 -0
  250. package/out/zero-cache/src/config/refs.d.ts +3 -0
  251. package/out/zero-cache/src/config/refs.d.ts.map +1 -0
  252. package/out/zero-cache/src/config/refs.js +14 -0
  253. package/out/zero-cache/src/config/refs.js.map +1 -0
  254. package/out/zero-cache/src/config/zero-config.d.ts +126 -686
  255. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  256. package/out/zero-cache/src/config/zero-config.js +43 -161
  257. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  258. package/out/zero-cache/src/db/create.d.ts +8 -0
  259. package/out/zero-cache/src/db/create.d.ts.map +1 -0
  260. package/out/zero-cache/src/db/create.js +39 -0
  261. package/out/zero-cache/src/db/create.js.map +1 -0
  262. package/out/zero-cache/src/db/lite-tables.d.ts +3 -3
  263. package/out/zero-cache/src/db/lite-tables.d.ts.map +1 -1
  264. package/out/zero-cache/src/db/lite-tables.js +29 -20
  265. package/out/zero-cache/src/db/lite-tables.js.map +1 -1
  266. package/out/zero-cache/src/db/migration-lite.d.ts +60 -20
  267. package/out/zero-cache/src/db/migration-lite.d.ts.map +1 -1
  268. package/out/zero-cache/src/db/migration-lite.js +89 -69
  269. package/out/zero-cache/src/db/migration-lite.js.map +1 -1
  270. package/out/zero-cache/src/db/migration.d.ts +61 -20
  271. package/out/zero-cache/src/db/migration.d.ts.map +1 -1
  272. package/out/zero-cache/src/db/migration.js +92 -75
  273. package/out/zero-cache/src/db/migration.js.map +1 -1
  274. package/out/zero-cache/src/db/pg-to-lite.d.ts +11 -0
  275. package/out/zero-cache/src/db/pg-to-lite.d.ts.map +1 -0
  276. package/out/zero-cache/src/{services/change-streamer/pg/schema/lite.js → db/pg-to-lite.js} +27 -15
  277. package/out/zero-cache/src/db/pg-to-lite.js.map +1 -0
  278. package/out/zero-cache/src/db/specs.d.ts +73 -0
  279. package/out/zero-cache/src/db/specs.d.ts.map +1 -0
  280. package/out/zero-cache/src/db/specs.js +30 -0
  281. package/out/zero-cache/src/db/specs.js.map +1 -0
  282. package/out/zero-cache/src/db/statements.d.ts +1 -1
  283. package/out/zero-cache/src/db/statements.d.ts.map +1 -1
  284. package/out/zero-cache/src/server/life-cycle.d.ts.map +1 -1
  285. package/out/zero-cache/src/server/life-cycle.js +9 -5
  286. package/out/zero-cache/src/server/life-cycle.js.map +1 -1
  287. package/out/zero-cache/src/server/main.js +3 -3
  288. package/out/zero-cache/src/server/main.js.map +1 -1
  289. package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
  290. package/out/zero-cache/src/server/syncer.js +2 -1
  291. package/out/zero-cache/src/server/syncer.js.map +1 -1
  292. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +1 -1
  293. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
  294. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +1 -4
  295. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  296. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +455 -13
  297. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
  298. package/out/zero-cache/src/services/change-streamer/change-streamer.js +16 -0
  299. package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
  300. package/out/zero-cache/src/services/change-streamer/pg/change-source.d.ts.map +1 -1
  301. package/out/zero-cache/src/services/change-streamer/pg/change-source.js +313 -88
  302. package/out/zero-cache/src/services/change-streamer/pg/change-source.js.map +1 -1
  303. package/out/zero-cache/src/services/change-streamer/pg/initial-sync.d.ts.map +1 -1
  304. package/out/zero-cache/src/services/change-streamer/pg/initial-sync.js +13 -54
  305. package/out/zero-cache/src/services/change-streamer/pg/initial-sync.js.map +1 -1
  306. package/out/zero-cache/src/services/change-streamer/pg/schema/ddl.d.ts +239 -59
  307. package/out/zero-cache/src/services/change-streamer/pg/schema/ddl.d.ts.map +1 -1
  308. package/out/zero-cache/src/services/change-streamer/pg/schema/ddl.js +291 -183
  309. package/out/zero-cache/src/services/change-streamer/pg/schema/ddl.js.map +1 -1
  310. package/out/zero-cache/src/services/change-streamer/pg/schema/init.d.ts +5 -0
  311. package/out/zero-cache/src/services/change-streamer/pg/schema/init.d.ts.map +1 -0
  312. package/out/zero-cache/src/services/change-streamer/pg/schema/init.js +18 -0
  313. package/out/zero-cache/src/services/change-streamer/pg/schema/init.js.map +1 -0
  314. package/out/zero-cache/src/services/change-streamer/pg/schema/published.d.ts +4 -4
  315. package/out/zero-cache/src/services/change-streamer/pg/schema/published.d.ts.map +1 -1
  316. package/out/zero-cache/src/services/change-streamer/pg/schema/published.js +14 -19
  317. package/out/zero-cache/src/services/change-streamer/pg/schema/published.js.map +1 -1
  318. package/out/zero-cache/src/services/change-streamer/pg/schema/shard.d.ts +17 -0
  319. package/out/zero-cache/src/services/change-streamer/pg/schema/shard.d.ts.map +1 -0
  320. package/out/zero-cache/src/services/change-streamer/pg/schema/shard.js +150 -0
  321. package/out/zero-cache/src/services/change-streamer/pg/schema/shard.js.map +1 -0
  322. package/out/zero-cache/src/services/change-streamer/pg/sync-schema.d.ts.map +1 -1
  323. package/out/zero-cache/src/services/change-streamer/pg/sync-schema.js +11 -5
  324. package/out/zero-cache/src/services/change-streamer/pg/sync-schema.js.map +1 -1
  325. package/out/zero-cache/src/services/change-streamer/schema/change.d.ts +325 -26
  326. package/out/zero-cache/src/services/change-streamer/schema/change.d.ts.map +1 -1
  327. package/out/zero-cache/src/services/change-streamer/schema/change.js +84 -1
  328. package/out/zero-cache/src/services/change-streamer/schema/change.js.map +1 -1
  329. package/out/zero-cache/src/services/change-streamer/schema/init.d.ts +2 -2
  330. package/out/zero-cache/src/services/change-streamer/schema/init.d.ts.map +1 -1
  331. package/out/zero-cache/src/services/change-streamer/schema/init.js +13 -5
  332. package/out/zero-cache/src/services/change-streamer/schema/init.js.map +1 -1
  333. package/out/zero-cache/src/services/change-streamer/schema/tables.js +6 -6
  334. package/out/zero-cache/src/services/change-streamer/storer.js +4 -4
  335. package/out/zero-cache/src/services/dispatcher/connect-params.d.ts +1 -0
  336. package/out/zero-cache/src/services/dispatcher/connect-params.d.ts.map +1 -1
  337. package/out/zero-cache/src/services/dispatcher/connect-params.js +5 -2
  338. package/out/zero-cache/src/services/dispatcher/connect-params.js.map +1 -1
  339. package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
  340. package/out/zero-cache/src/services/mutagen/mutagen.js +21 -22
  341. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  342. package/out/zero-cache/src/services/mutagen/write-authorizer.d.ts.map +1 -1
  343. package/out/zero-cache/src/services/mutagen/write-authorizer.js +18 -9
  344. package/out/zero-cache/src/services/mutagen/write-authorizer.js.map +1 -1
  345. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts.map +1 -1
  346. package/out/zero-cache/src/services/replicator/incremental-sync.js +131 -16
  347. package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
  348. package/out/zero-cache/src/services/replicator/schema/change-log.d.ts +20 -3
  349. package/out/zero-cache/src/services/replicator/schema/change-log.d.ts.map +1 -1
  350. package/out/zero-cache/src/services/replicator/schema/change-log.js +46 -14
  351. package/out/zero-cache/src/services/replicator/schema/change-log.js.map +1 -1
  352. package/out/zero-cache/src/services/replicator/schema/replication-state.d.ts +1 -1
  353. package/out/zero-cache/src/services/replicator/schema/replication-state.d.ts.map +1 -1
  354. package/out/zero-cache/src/services/replicator/schema/replication-state.js +9 -9
  355. package/out/zero-cache/src/services/replicator/schema/replication-state.js.map +1 -1
  356. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +4 -3
  357. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
  358. package/out/zero-cache/src/services/view-syncer/client-handler.js +27 -21
  359. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  360. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts +6 -4
  361. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
  362. package/out/zero-cache/src/services/view-syncer/cvr-store.js +63 -18
  363. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  364. package/out/zero-cache/src/services/view-syncer/cvr.d.ts +11 -8
  365. package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
  366. package/out/zero-cache/src/services/view-syncer/cvr.js +22 -13
  367. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  368. package/out/zero-cache/src/services/view-syncer/database-storage.js +1 -1
  369. package/out/zero-cache/src/services/view-syncer/database-storage.js.map +1 -1
  370. package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts +31 -0
  371. package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts.map +1 -0
  372. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +53 -0
  373. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -0
  374. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +13 -5
  375. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  376. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +27 -0
  377. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  378. package/out/zero-cache/src/services/view-syncer/schema/cvr.d.ts +2 -1
  379. package/out/zero-cache/src/services/view-syncer/schema/cvr.d.ts.map +1 -1
  380. package/out/zero-cache/src/services/view-syncer/schema/cvr.js +5 -4
  381. package/out/zero-cache/src/services/view-syncer/schema/cvr.js.map +1 -1
  382. package/out/zero-cache/src/services/view-syncer/schema/init.d.ts +4 -0
  383. package/out/zero-cache/src/services/view-syncer/schema/init.d.ts.map +1 -0
  384. package/out/zero-cache/src/services/view-syncer/schema/init.js +16 -0
  385. package/out/zero-cache/src/services/view-syncer/schema/init.js.map +1 -0
  386. package/out/zero-cache/src/services/view-syncer/schema/types.d.ts +8 -216
  387. package/out/zero-cache/src/services/view-syncer/schema/types.d.ts.map +1 -1
  388. package/out/zero-cache/src/services/view-syncer/schema/types.js +2 -4
  389. package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
  390. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +12 -4
  391. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
  392. package/out/zero-cache/src/services/view-syncer/snapshotter.js +59 -49
  393. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  394. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +3 -4
  395. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  396. package/out/zero-cache/src/services/view-syncer/view-syncer.js +105 -44
  397. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  398. package/out/zero-cache/src/types/lite.d.ts.map +1 -1
  399. package/out/zero-cache/src/types/lite.js +8 -9
  400. package/out/zero-cache/src/types/lite.js.map +1 -1
  401. package/out/zero-cache/src/types/pg.d.ts +10 -4
  402. package/out/zero-cache/src/types/pg.d.ts.map +1 -1
  403. package/out/zero-cache/src/types/pg.js +37 -15
  404. package/out/zero-cache/src/types/pg.js.map +1 -1
  405. package/out/zero-cache/src/workers/connection.d.ts +4 -2
  406. package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
  407. package/out/zero-cache/src/workers/connection.js +21 -2
  408. package/out/zero-cache/src/workers/connection.js.map +1 -1
  409. package/out/zero-cache/src/workers/syncer.d.ts +2 -1
  410. package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
  411. package/out/zero-cache/src/workers/syncer.js +20 -9
  412. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  413. package/out/zero-client/src/client/context.d.ts +1 -1
  414. package/out/zero-client/src/client/context.d.ts.map +1 -1
  415. package/out/zero-client/src/client/context.js +99 -0
  416. package/out/zero-client/src/client/context.js.map +1 -0
  417. package/out/zero-client/src/client/crud.d.ts +8 -10
  418. package/out/zero-client/src/client/crud.d.ts.map +1 -1
  419. package/out/zero-client/src/client/crud.js +181 -0
  420. package/out/zero-client/src/client/crud.js.map +1 -0
  421. package/out/zero-client/src/client/enable-analytics.js +21 -0
  422. package/out/zero-client/src/client/enable-analytics.js.map +1 -0
  423. package/out/zero-client/src/client/http-string.js +14 -0
  424. package/out/zero-client/src/client/http-string.js.map +1 -0
  425. package/out/zero-client/src/client/keys.d.ts +3 -2
  426. package/out/zero-client/src/client/keys.d.ts.map +1 -1
  427. package/out/zero-client/src/client/keys.js +32 -0
  428. package/out/zero-client/src/client/keys.js.map +1 -0
  429. package/out/zero-client/src/client/log-options.js +57 -0
  430. package/out/zero-client/src/client/log-options.js.map +1 -0
  431. package/out/zero-client/src/client/metrics.js +268 -0
  432. package/out/zero-client/src/client/metrics.js.map +1 -0
  433. package/out/zero-client/src/client/normalized-schema.d.ts +17 -0
  434. package/out/zero-client/src/client/normalized-schema.d.ts.map +1 -0
  435. package/out/zero-client/src/client/normalized-schema.js +31 -0
  436. package/out/zero-client/src/client/normalized-schema.js.map +1 -0
  437. package/out/zero-client/src/client/options.js +2 -0
  438. package/out/zero-client/src/client/options.js.map +1 -0
  439. package/out/zero-client/src/client/query-manager.d.ts +18 -3
  440. package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
  441. package/out/zero-client/src/client/query-manager.js +149 -0
  442. package/out/zero-client/src/client/query-manager.js.map +1 -0
  443. package/out/zero-client/src/client/reload-error-handler.js +23 -0
  444. package/out/zero-client/src/client/reload-error-handler.js.map +1 -0
  445. package/out/zero-client/src/client/replicache-types.js +2 -0
  446. package/out/zero-client/src/client/replicache-types.js.map +1 -0
  447. package/out/zero-client/src/client/server-error.js +22 -0
  448. package/out/zero-client/src/client/server-error.js.map +1 -0
  449. package/out/zero-client/src/client/server-option.js +37 -0
  450. package/out/zero-client/src/client/server-option.js.map +1 -0
  451. package/out/zero-client/src/client/version.js +5 -0
  452. package/out/zero-client/src/client/version.js.map +1 -0
  453. package/out/zero-client/src/client/zero-poke-handler.d.ts +3 -3
  454. package/out/zero-client/src/client/zero-poke-handler.d.ts.map +1 -1
  455. package/out/zero-client/src/client/zero-poke-handler.js +240 -0
  456. package/out/zero-client/src/client/zero-poke-handler.js.map +1 -0
  457. package/out/zero-client/src/client/zero.d.ts +3 -2
  458. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  459. package/out/zero-client/src/client/zero.js +1212 -0
  460. package/out/zero-client/src/client/zero.js.map +1 -0
  461. package/out/zero-client/src/mod.d.ts +1 -0
  462. package/out/zero-client/src/mod.d.ts.map +1 -1
  463. package/out/zero-client/src/mod.js +5 -0
  464. package/out/zero-client/src/mod.js.map +1 -0
  465. package/out/zero-client/src/util/nanoid.js +34 -0
  466. package/out/zero-client/src/util/nanoid.js.map +1 -0
  467. package/out/zero-client/src/util/socket.js +4 -0
  468. package/out/zero-client/src/util/socket.js.map +1 -0
  469. package/out/zero-protocol/src/ast.d.ts +87 -1
  470. package/out/zero-protocol/src/ast.d.ts.map +1 -1
  471. package/out/zero-protocol/src/ast.js +53 -0
  472. package/out/zero-protocol/src/ast.js.map +1 -1
  473. package/out/zero-protocol/src/change-desired-queries.d.ts +6 -6
  474. package/out/zero-protocol/src/change-desired-queries.d.ts.map +1 -1
  475. package/out/zero-protocol/src/clients-patch.d.ts +1 -1
  476. package/out/zero-protocol/src/connect.d.ts +15 -8
  477. package/out/zero-protocol/src/connect.d.ts.map +1 -1
  478. package/out/zero-protocol/src/connect.js +21 -0
  479. package/out/zero-protocol/src/connect.js.map +1 -1
  480. package/out/zero-protocol/src/data.d.ts +36 -0
  481. package/out/zero-protocol/src/data.d.ts.map +1 -0
  482. package/out/zero-protocol/src/data.js +4 -0
  483. package/out/zero-protocol/src/data.js.map +1 -0
  484. package/out/zero-protocol/src/delete-clients.d.ts +4 -4
  485. package/out/zero-protocol/src/delete-clients.d.ts.map +1 -1
  486. package/out/zero-protocol/src/down.d.ts +18 -16
  487. package/out/zero-protocol/src/down.d.ts.map +1 -1
  488. package/out/zero-protocol/src/down.js +2 -1
  489. package/out/zero-protocol/src/down.js.map +1 -1
  490. package/out/zero-protocol/src/mod.d.ts +1 -2
  491. package/out/zero-protocol/src/mod.d.ts.map +1 -1
  492. package/out/zero-protocol/src/mod.js +2 -2
  493. package/out/zero-protocol/src/mod.js.map +1 -1
  494. package/out/zero-protocol/src/ping.d.ts +1 -1
  495. package/out/zero-protocol/src/ping.d.ts.map +1 -1
  496. package/out/zero-protocol/src/poke.d.ts +26 -26
  497. package/out/zero-protocol/src/poke.d.ts.map +1 -1
  498. package/out/zero-protocol/src/poke.js +8 -5
  499. package/out/zero-protocol/src/poke.js.map +1 -1
  500. package/out/zero-protocol/src/pong.d.ts +1 -1
  501. package/out/zero-protocol/src/pong.d.ts.map +1 -1
  502. package/out/zero-protocol/src/primary-key.d.ts +2 -3
  503. package/out/zero-protocol/src/primary-key.d.ts.map +1 -1
  504. package/out/zero-protocol/src/primary-key.js +1 -3
  505. package/out/zero-protocol/src/primary-key.js.map +1 -1
  506. package/out/zero-protocol/src/pull.d.ts +4 -4
  507. package/out/zero-protocol/src/pull.d.ts.map +1 -1
  508. package/out/zero-protocol/src/push.d.ts +105 -98
  509. package/out/zero-protocol/src/push.d.ts.map +1 -1
  510. package/out/zero-protocol/src/push.js +17 -13
  511. package/out/zero-protocol/src/push.js.map +1 -1
  512. package/out/zero-protocol/src/queries-patch.d.ts +4 -4
  513. package/out/zero-protocol/src/row-patch.d.ts +38 -0
  514. package/out/zero-protocol/src/row-patch.d.ts.map +1 -0
  515. package/out/zero-protocol/src/{entities-patch.js → row-patch.js} +10 -11
  516. package/out/zero-protocol/src/row-patch.js.map +1 -0
  517. package/out/zero-protocol/src/up.d.ts +28 -27
  518. package/out/zero-protocol/src/up.d.ts.map +1 -1
  519. package/out/zero-protocol/src/warm.d.ts +10 -0
  520. package/out/zero-protocol/src/warm.d.ts.map +1 -0
  521. package/out/zero-protocol/src/warm.js +6 -0
  522. package/out/zero-protocol/src/warm.js.map +1 -0
  523. package/out/zero-react/src/use-query.d.ts.map +1 -1
  524. package/out/zero.js +522 -217
  525. package/out/zero.js.map +4 -4
  526. package/out/zql/src/zql/builder/builder.d.ts +3 -4
  527. package/out/zql/src/zql/builder/builder.d.ts.map +1 -1
  528. package/out/zql/src/zql/builder/builder.js +1 -2
  529. package/out/zql/src/zql/builder/builder.js.map +1 -1
  530. package/out/zql/src/zql/builder/filter.d.ts +2 -2
  531. package/out/zql/src/zql/builder/filter.d.ts.map +1 -1
  532. package/out/zql/src/zql/builder/filter.js.map +1 -1
  533. package/out/zql/src/zql/ivm/array-view.d.ts +5 -12
  534. package/out/zql/src/zql/ivm/array-view.d.ts.map +1 -1
  535. package/out/zql/src/zql/ivm/array-view.js +226 -0
  536. package/out/zql/src/zql/ivm/array-view.js.map +1 -0
  537. package/out/zql/src/zql/ivm/change.d.ts +2 -1
  538. package/out/zql/src/zql/ivm/change.d.ts.map +1 -1
  539. package/out/zql/src/zql/ivm/data.d.ts +2 -33
  540. package/out/zql/src/zql/ivm/data.d.ts.map +1 -1
  541. package/out/zql/src/zql/ivm/data.js.map +1 -1
  542. package/out/zql/src/zql/ivm/filter.d.ts +2 -1
  543. package/out/zql/src/zql/ivm/filter.d.ts.map +1 -1
  544. package/out/zql/src/zql/ivm/filter.js.map +1 -1
  545. package/out/zql/src/zql/ivm/join.d.ts +1 -1
  546. package/out/zql/src/zql/ivm/join.d.ts.map +1 -1
  547. package/out/zql/src/zql/ivm/join.js +68 -24
  548. package/out/zql/src/zql/ivm/join.js.map +1 -1
  549. package/out/zql/src/zql/ivm/maybe-split-and-push-edit-change.d.ts +1 -1
  550. package/out/zql/src/zql/ivm/maybe-split-and-push-edit-change.d.ts.map +1 -1
  551. package/out/zql/src/zql/ivm/memory-source.d.ts +8 -6
  552. package/out/zql/src/zql/ivm/memory-source.d.ts.map +1 -1
  553. package/out/zql/src/zql/ivm/memory-source.js +2 -0
  554. package/out/zql/src/zql/ivm/memory-source.js.map +1 -1
  555. package/out/zql/src/zql/ivm/memory-storage.js +33 -0
  556. package/out/zql/src/zql/ivm/memory-storage.js.map +1 -0
  557. package/out/zql/src/zql/ivm/operator.d.ts +2 -1
  558. package/out/zql/src/zql/ivm/operator.d.ts.map +1 -1
  559. package/out/zql/src/zql/ivm/schema.d.ts +3 -3
  560. package/out/zql/src/zql/ivm/schema.d.ts.map +1 -1
  561. package/out/zql/src/zql/ivm/schema.js.map +1 -1
  562. package/out/zql/src/zql/ivm/skip.d.ts +2 -1
  563. package/out/zql/src/zql/ivm/skip.d.ts.map +1 -1
  564. package/out/zql/src/zql/ivm/skip.js.map +1 -1
  565. package/out/zql/src/zql/ivm/source.d.ts +2 -2
  566. package/out/zql/src/zql/ivm/source.d.ts.map +1 -1
  567. package/out/zql/src/zql/ivm/take.d.ts.map +1 -1
  568. package/out/zql/src/zql/ivm/take.js.map +1 -1
  569. package/out/zql/src/zql/query/like.d.ts +2 -0
  570. package/out/zql/src/zql/query/like.d.ts.map +1 -0
  571. package/out/zql/src/zql/query/like.js +18 -0
  572. package/out/zql/src/zql/query/like.js.map +1 -0
  573. package/out/zql/src/zql/query/normalize-table-schema.d.ts +48 -0
  574. package/out/zql/src/zql/query/normalize-table-schema.d.ts.map +1 -0
  575. package/out/zql/src/zql/query/normalize-table-schema.js +116 -0
  576. package/out/zql/src/zql/query/normalize-table-schema.js.map +1 -0
  577. package/out/zql/src/zql/query/query-impl.d.ts +6 -5
  578. package/out/zql/src/zql/query/query-impl.d.ts.map +1 -1
  579. package/out/zql/src/zql/query/query-impl.js +263 -0
  580. package/out/zql/src/zql/query/query-impl.js.map +1 -0
  581. package/out/zql/src/zql/query/query.d.ts +1 -1
  582. package/out/zql/src/zql/query/query.d.ts.map +1 -1
  583. package/out/zql/src/zql/query/query.js +3 -0
  584. package/out/zql/src/zql/query/query.js.map +1 -0
  585. package/out/zql/src/zql/query/schema.d.ts +13 -4
  586. package/out/zql/src/zql/query/schema.d.ts.map +1 -1
  587. package/out/zql/src/zql/query/schema.js +7 -0
  588. package/out/zql/src/zql/query/schema.js.map +1 -0
  589. package/out/zql/src/zql/query/typed-view.d.ts +5 -2
  590. package/out/zql/src/zql/query/typed-view.d.ts.map +1 -1
  591. package/out/zql/src/zql/query/typed-view.js +2 -0
  592. package/out/zql/src/zql/query/typed-view.js.map +1 -0
  593. package/out/zqlite/src/db.d.ts +1 -1
  594. package/out/zqlite/src/db.d.ts.map +1 -1
  595. package/out/zqlite/src/db.js +1 -1
  596. package/out/zqlite/src/db.js.map +1 -1
  597. package/out/zqlite/src/table-source.d.ts +2 -2
  598. package/out/zqlite/src/table-source.d.ts.map +1 -1
  599. package/out/zqlite/src/table-source.js.map +1 -1
  600. package/package.json +10 -8
  601. package/deps/sqlite3/sqlite3.c +0 -260574
  602. package/deps/sqlite3/sqlite3.h +0 -13572
  603. package/deps/sqlite3/sqlite3ext.h +0 -719
  604. package/out/zero-cache/src/services/change-streamer/pg/schema/create.d.ts +0 -6
  605. package/out/zero-cache/src/services/change-streamer/pg/schema/create.d.ts.map +0 -1
  606. package/out/zero-cache/src/services/change-streamer/pg/schema/create.js +0 -29
  607. package/out/zero-cache/src/services/change-streamer/pg/schema/create.js.map +0 -1
  608. package/out/zero-cache/src/services/change-streamer/pg/schema/lite.d.ts +0 -6
  609. package/out/zero-cache/src/services/change-streamer/pg/schema/lite.d.ts.map +0 -1
  610. package/out/zero-cache/src/services/change-streamer/pg/schema/lite.js.map +0 -1
  611. package/out/zero-cache/src/services/change-streamer/pg/schema/zero.d.ts +0 -11
  612. package/out/zero-cache/src/services/change-streamer/pg/schema/zero.d.ts.map +0 -1
  613. package/out/zero-cache/src/services/change-streamer/pg/schema/zero.js +0 -86
  614. package/out/zero-cache/src/services/change-streamer/pg/schema/zero.js.map +0 -1
  615. package/out/zero-cache/src/services/view-syncer/schema/pg-migrations.d.ts +0 -4
  616. package/out/zero-cache/src/services/view-syncer/schema/pg-migrations.d.ts.map +0 -1
  617. package/out/zero-cache/src/services/view-syncer/schema/pg-migrations.js +0 -12
  618. package/out/zero-cache/src/services/view-syncer/schema/pg-migrations.js.map +0 -1
  619. package/out/zero-cache/src/types/specs.d.ts +0 -29
  620. package/out/zero-cache/src/types/specs.d.ts.map +0 -1
  621. package/out/zero-cache/src/types/specs.js +0 -2
  622. package/out/zero-cache/src/types/specs.js.map +0 -1
  623. package/out/zero-client/src/client/make-id-from-primary-key.d.ts +0 -5
  624. package/out/zero-client/src/client/make-id-from-primary-key.d.ts.map +0 -1
  625. package/out/zero-protocol/src/entities-patch.d.ts +0 -66
  626. package/out/zero-protocol/src/entities-patch.d.ts.map +0 -1
  627. package/out/zero-protocol/src/entities-patch.js.map +0 -1
  628. package/out/zql/src/zql/ast/ast.d.ts +0 -84
  629. package/out/zql/src/zql/ast/ast.d.ts.map +0 -1
  630. package/out/zql/src/zql/ast/ast.js +0 -54
  631. package/out/zql/src/zql/ast/ast.js.map +0 -1
  632. package/tool/install-sqlite3.js +0 -37
@@ -0,0 +1,1212 @@
1
+ import { LogContext } from '@rocicorp/logger';
2
+ import { resolver } from '@rocicorp/resolver';
3
+ import { ReplicacheImpl, } from '../../../replicache/src/impl.js';
4
+ import { dropDatabase, } from '../../../replicache/src/mod.js';
5
+ import { assert, unreachable } from '../../../shared/src/asserts.js';
6
+ import { getBrowserGlobal, mustGetBrowserGlobal, } from '../../../shared/src/browser-env.js';
7
+ import { getDocumentVisibilityWatcher } from '../../../shared/src/document-visible.js';
8
+ import { must } from '../../../shared/src/must.js';
9
+ import { navigator } from '../../../shared/src/navigator.js';
10
+ import { sleep, sleepWithAbort } from '../../../shared/src/sleep.js';
11
+ import * as valita from '../../../shared/src/valita.js';
12
+ import { CRUD_MUTATION_NAME, ErrorKind, MutationType, downstreamSchema, encodeSecProtocols, nullableVersionSchema, } from '../../../zero-protocol/src/mod.js';
13
+ import { newQuery } from '../../../zql/src/zql/query/query-impl.js';
14
+ import { nanoid } from '../util/nanoid.js';
15
+ import { send } from '../util/socket.js';
16
+ import { ZeroContext } from './context.js';
17
+ import { makeCRUDMutate, makeCRUDMutator, } from './crud.js';
18
+ import { shouldEnableAnalytics } from './enable-analytics.js';
19
+ import { toWSString } from './http-string.js';
20
+ import { ENTITIES_KEY_PREFIX } from './keys.js';
21
+ import { createLogOptions } from './log-options.js';
22
+ import { DID_NOT_CONNECT_VALUE, MetricManager, REPORT_INTERVAL_MS, getLastConnectErrorValue, } from './metrics.js';
23
+ import { normalizeSchema } from './normalized-schema.js';
24
+ import { QueryManager } from './query-manager.js';
25
+ import { reloadWithReason, reportReloadReason } from './reload-error-handler.js';
26
+ import { ServerError, isAuthError, isServerError } from './server-error.js';
27
+ import { getServer } from './server-option.js';
28
+ import { version } from './version.js';
29
+ import { PokeHandler } from './zero-poke-handler.js';
30
+ export const onSetConnectionStateSymbol = Symbol();
31
+ export const exposedToTestingSymbol = Symbol();
32
+ export const createLogOptionsSymbol = Symbol();
33
+ function asTestZero(z) {
34
+ return z;
35
+ }
36
+ export var ConnectionState;
37
+ (function (ConnectionState) {
38
+ ConnectionState[ConnectionState["Disconnected"] = 0] = "Disconnected";
39
+ ConnectionState[ConnectionState["Connecting"] = 1] = "Connecting";
40
+ ConnectionState[ConnectionState["Connected"] = 2] = "Connected";
41
+ })(ConnectionState || (ConnectionState = {}));
42
+ export const RUN_LOOP_INTERVAL_MS = 5_000;
43
+ /**
44
+ * How frequently we should ping the server to keep the connection alive.
45
+ */
46
+ export const PING_INTERVAL_MS = 5_000;
47
+ /**
48
+ * The amount of time we wait for a pong before we consider the ping timed out.
49
+ */
50
+ export const PING_TIMEOUT_MS = 5_000;
51
+ /**
52
+ * The amount of time we wait for a pull response before we consider a pull
53
+ * request timed out.
54
+ */
55
+ export const PULL_TIMEOUT_MS = 5_000;
56
+ export const DEFAULT_DISCONNECT_HIDDEN_DELAY_MS = 5_000;
57
+ /**
58
+ * The amount of time we wait for a connection to be established before we
59
+ * consider it timed out.
60
+ */
61
+ export const CONNECT_TIMEOUT_MS = 10_000;
62
+ const CHECK_CONNECTIVITY_ON_ERROR_FREQUENCY = 6;
63
+ const NULL_LAST_MUTATION_ID_SENT = { clientID: '', id: -1 };
64
+ // When the protocol changes (pull, push, poke,...) we need to bump this.
65
+ const REFLECT_VERSION = 1;
66
+ function convertOnUpdateNeededReason(reason) {
67
+ return { type: reason.type };
68
+ }
69
+ function updateNeededReloadReason(reason, serverErrMsg) {
70
+ const { type } = reason;
71
+ let reasonMsg = '';
72
+ switch (type) {
73
+ case 'NewClientGroup':
74
+ reasonMsg =
75
+ "This client could not sync with a newer client. This is probably due to another tab loading a newer incompatible version of the app's code.";
76
+ break;
77
+ case 'VersionNotSupported':
78
+ reasonMsg =
79
+ "The server no longer supports this client's protocol version.";
80
+ break;
81
+ case 'SchemaVersionNotSupported':
82
+ reasonMsg = "The server no longer supports this client's schema version.";
83
+ break;
84
+ default:
85
+ unreachable(type);
86
+ }
87
+ if (serverErrMsg) {
88
+ reasonMsg += ' ' + serverErrMsg;
89
+ }
90
+ return reasonMsg;
91
+ }
92
+ function serverAheadReloadReason(kind) {
93
+ return `Server reported that client is ahead of server (${kind}). This probably happened because the server is in development mode and restarted. Currently when this happens, the dev server loses its state and on reconnect sees the client as ahead. If you see this in other cases, it may be a bug in Zero.`;
94
+ }
95
+ function onClientStateNotFoundServerReason(serverErrMsg) {
96
+ return `Server could not find state needed to synchronize this client. ${serverErrMsg}`;
97
+ }
98
+ const ON_CLIENT_STATE_NOT_FOUND_REASON_CLIENT = 'The local persistent state needed to synchronize this client has been garbage collected.';
99
+ var PingResult;
100
+ (function (PingResult) {
101
+ PingResult[PingResult["TimedOut"] = 0] = "TimedOut";
102
+ PingResult[PingResult["Success"] = 1] = "Success";
103
+ })(PingResult || (PingResult = {}));
104
+ const internalReplicacheImplMap = new WeakMap();
105
+ export function getInternalReplicacheImplForTesting(z) {
106
+ return must(internalReplicacheImplMap.get(z));
107
+ }
108
+ export class Zero {
109
+ version = version;
110
+ #rep;
111
+ #server;
112
+ userID;
113
+ #lc;
114
+ #logOptions;
115
+ #enableAnalytics;
116
+ #pokeHandler;
117
+ #queryManager;
118
+ /**
119
+ * The queries we sent when establishing a connection.
120
+ * More queries could be registered while we're waiting for the 'connected' message
121
+ * to come back from the server. To understand what queries we need to send
122
+ * to the server, we diff the `initConnectionQueries` with the current set of desired queries.
123
+ */
124
+ #initConnectionQueries = new Map();
125
+ #lastMutationIDSent = NULL_LAST_MUTATION_ID_SENT;
126
+ #onPong = () => undefined;
127
+ #online = false;
128
+ /**
129
+ * `onOnlineChange` is called when the Zero instance's online status
130
+ * changes.
131
+ */
132
+ onOnlineChange = null;
133
+ #onUpdateNeeded = null;
134
+ #onClientStateNotFound = null;
135
+ #jurisdiction;
136
+ // Last cookie used to initiate a connection
137
+ #connectCookie = null;
138
+ // Total number of sockets successfully connected by this client
139
+ #connectedCount = 0;
140
+ // Number of messages received over currently connected socket. Reset
141
+ // on disconnect.
142
+ #messageCount = 0;
143
+ #connectedAt = 0;
144
+ // Reset on successful connection.
145
+ #connectErrorCount = 0;
146
+ #abortPingTimeout = () => {
147
+ // intentionally empty
148
+ };
149
+ #zeroContext;
150
+ /**
151
+ * `onUpdateNeeded` is called when a code update is needed.
152
+ *
153
+ * A code update can be needed because:
154
+ * - the server no longer supports the protocol version of the current code,
155
+ * - a new Zero client has created a new client group, because its code
156
+ * has different mutators, indexes, schema version and/or format version
157
+ * from this Zero client. This is likely due to the new client having
158
+ * newer code. A code update is needed to be able to locally sync with this
159
+ * new Zero client (i.e. to sync while offline, the clients can can
160
+ * still sync with each other via the server).
161
+ *
162
+ * The default behavior is to reload the page (using `location.reload()`). Set
163
+ * this to `null` or provide your own function to prevent the page from
164
+ * reloading automatically. You may want to provide your own function to
165
+ * display a toast to inform the end user there is a new version of your app
166
+ * available and prompting them to refresh.
167
+ */
168
+ get onUpdateNeeded() {
169
+ return this.#onUpdateNeeded;
170
+ }
171
+ set onUpdateNeeded(callback) {
172
+ this.#onUpdateNeeded = callback;
173
+ this.#rep.onUpdateNeeded =
174
+ callback &&
175
+ (reason => {
176
+ callback(convertOnUpdateNeededReason(reason));
177
+ });
178
+ }
179
+ /**
180
+ * `onClientStateNotFound` is called when this client will no longer be able
181
+ * to sync due to missing synchronization state. This can be because:
182
+ * - the local persistent synchronization state has been garbage collected.
183
+ * This can happen if the client has no pending mutations and has not been
184
+ * used for a while.
185
+ * - the zero-cache fails to find the synchronization state of this client.
186
+ *
187
+ * The default behavior is to reload the page (using `location.reload()`). Set
188
+ * this to `null` or provide your own function to prevent the page from
189
+ * reloading automatically.
190
+ */
191
+ get onClientStateNotFound() {
192
+ return this.#onClientStateNotFound;
193
+ }
194
+ set onClientStateNotFound(value) {
195
+ this.#onClientStateNotFound = value;
196
+ this.#rep.onClientStateNotFound = value;
197
+ }
198
+ #connectResolver = resolver();
199
+ #pendingPullsByRequestID = new Map();
200
+ #lastMutationIDReceived = 0;
201
+ #socket = undefined;
202
+ #socketResolver = resolver();
203
+ #connectionStateChangeResolver = resolver();
204
+ /**
205
+ * This resolver is only used for rejections. It is awaited in the connected
206
+ * state (including when waiting for a pong). It is rejected when we get an
207
+ * invalid message or an 'error' message.
208
+ */
209
+ #rejectMessageError = undefined;
210
+ #closeAbortController = new AbortController();
211
+ #visibilityWatcher;
212
+ // We use an accessor pair to allow the subclass to override the setter.
213
+ #connectionState = ConnectionState.Disconnected;
214
+ #setConnectionState(state) {
215
+ if (state === this.#connectionState) {
216
+ return;
217
+ }
218
+ this.#connectionState = state;
219
+ this.#connectionStateChangeResolver.resolve(state);
220
+ this.#connectionStateChangeResolver = resolver();
221
+ if (TESTING) {
222
+ asTestZero(this)[onSetConnectionStateSymbol]?.(state);
223
+ }
224
+ }
225
+ #connectStart = undefined;
226
+ // Set on connect attempt if currently undefined.
227
+ // Reset to undefined when
228
+ // 1. client stops trying to connect because it is hidden
229
+ // 2. client encounters a connect error and canary request indicates
230
+ // the client is offline
231
+ // 2. client successfully connects
232
+ #totalToConnectStart = undefined;
233
+ #options;
234
+ query;
235
+ // TODO: Metrics needs to be rethought entirely as we're not going to
236
+ // send metrics to customer server.
237
+ #metrics;
238
+ // Store as field to allow test subclass to override. Web API doesn't allow
239
+ // overwriting location fields for security reasons.
240
+ #reload = () => getBrowserGlobal('location')?.reload();
241
+ /**
242
+ * Constructs a new Zero client.
243
+ */
244
+ constructor(options) {
245
+ const { userID, onOnlineChange, jurisdiction, hiddenTabDisconnectDelay = DEFAULT_DISCONNECT_HIDDEN_DELAY_MS, kvStore = 'idb', schema, } = options;
246
+ if (!userID) {
247
+ throw new Error('ZeroOptions.userID must not be empty.');
248
+ }
249
+ const server = getServer(options.server);
250
+ this.#enableAnalytics = shouldEnableAnalytics(server, options.enableAnalytics);
251
+ if (jurisdiction !== undefined && jurisdiction !== 'eu') {
252
+ throw new Error('ZeroOptions.jurisdiction must be "eu" if present.');
253
+ }
254
+ if (hiddenTabDisconnectDelay < 0) {
255
+ throw new Error('ZeroOptions.hiddenTabDisconnectDelay must not be negative.');
256
+ }
257
+ this.onOnlineChange = onOnlineChange;
258
+ this.#options = options;
259
+ this.#logOptions = this.#createLogOptions({
260
+ consoleLogLevel: options.logLevel ?? 'error',
261
+ server: null, //server, // Reenable remote logging
262
+ enableAnalytics: this.#enableAnalytics,
263
+ });
264
+ const logOptions = this.#logOptions;
265
+ const normalizedSchema = normalizeSchema(schema);
266
+ const replicacheMutators = {
267
+ ['_zero_crud']: makeCRUDMutator(normalizedSchema),
268
+ };
269
+ const replicacheOptions = {
270
+ schemaVersion: normalizedSchema.version.toString(),
271
+ logLevel: logOptions.logLevel,
272
+ logSinks: [logOptions.logSink],
273
+ mutators: replicacheMutators,
274
+ name: `zero-${userID}`,
275
+ pusher: (req, reqID) => this.#pusher(req, reqID),
276
+ puller: (req, reqID) => this.#puller(req, reqID),
277
+ pushDelay: 0,
278
+ requestOptions: {
279
+ maxDelayMs: 0,
280
+ minDelayMs: 0,
281
+ },
282
+ licenseKey: 'zero-client-static-key',
283
+ kvStore,
284
+ };
285
+ const replicacheImplOptions = {
286
+ enableClientGroupForking: false,
287
+ };
288
+ const rep = new ReplicacheImpl(replicacheOptions, replicacheImplOptions);
289
+ this.#rep = rep;
290
+ if (TESTING) {
291
+ internalReplicacheImplMap.set(this, rep);
292
+ }
293
+ rep.getAuth = this.#getAuthToken;
294
+ this.#server = server;
295
+ this.userID = userID;
296
+ this.#jurisdiction = jurisdiction;
297
+ this.#lc = new LogContext(logOptions.logLevel, { clientID: rep.clientID }, logOptions.logSink);
298
+ this.onUpdateNeeded = (reason, serverErrorMsg) => {
299
+ reloadWithReason(this.#lc, this.#reload, updateNeededReloadReason(reason, serverErrorMsg));
300
+ };
301
+ this.onClientStateNotFound = (reason) => {
302
+ reloadWithReason(this.#lc, this.#reload, reason ?? ON_CLIENT_STATE_NOT_FOUND_REASON_CLIENT);
303
+ };
304
+ this.mutate = makeCRUDMutate(normalizedSchema, rep.mutate);
305
+ this.#queryManager = new QueryManager(rep.clientID, msg => this.#sendChangeDesiredQueries(msg), rep.experimentalWatch.bind(rep));
306
+ this.#zeroContext = new ZeroContext(normalizedSchema.tables, (ast, gotCallback) => this.#queryManager.add(ast, gotCallback));
307
+ rep.experimentalWatch(diff => this.#zeroContext.processChanges(diff), {
308
+ prefix: ENTITIES_KEY_PREFIX,
309
+ initialValuesInFirstDiff: true,
310
+ });
311
+ this.query = this.#registerQueries(normalizedSchema);
312
+ reportReloadReason(this.#lc);
313
+ this.#metrics = new MetricManager({
314
+ reportIntervalMs: REPORT_INTERVAL_MS,
315
+ host: getBrowserGlobal('location')?.host ?? '',
316
+ source: 'client',
317
+ reporter: this.#enableAnalytics
318
+ ? allSeries => this.#reportMetrics(allSeries)
319
+ : () => Promise.resolve(),
320
+ lc: this.#lc,
321
+ });
322
+ this.#metrics.tags.push(`version:${this.version}`);
323
+ this.#pokeHandler = new PokeHandler(poke => this.#rep.poke(poke), () => this.#onPokeError(), rep.clientID, normalizedSchema, this.#lc);
324
+ this.#visibilityWatcher = getDocumentVisibilityWatcher(getBrowserGlobal('document'), hiddenTabDisconnectDelay, this.#closeAbortController.signal);
325
+ void this.#runLoop();
326
+ if (TESTING) {
327
+ asTestZero(this)[exposedToTestingSymbol] = {
328
+ puller: this.#puller,
329
+ pusher: this.#pusher,
330
+ setReload: (r) => {
331
+ this.#reload = r;
332
+ },
333
+ logOptions: this.#logOptions,
334
+ connectStart: () => this.#connectStart,
335
+ socketResolver: () => this.#socketResolver,
336
+ connectionState: () => this.#connectionState,
337
+ };
338
+ }
339
+ }
340
+ #sendChangeDesiredQueries(msg) {
341
+ if (this.#socket && this.#connectionState === ConnectionState.Connected) {
342
+ send(this.#socket, msg);
343
+ }
344
+ }
345
+ #createLogOptions(options) {
346
+ if (TESTING) {
347
+ const testZero = asTestZero(this);
348
+ if (testZero[createLogOptionsSymbol]) {
349
+ return testZero[createLogOptionsSymbol](options);
350
+ }
351
+ }
352
+ return createLogOptions(options);
353
+ }
354
+ /**
355
+ * The name of the IndexedDB database in which the data of this
356
+ * instance of Zero is stored.
357
+ */
358
+ get idbName() {
359
+ return this.#rep.idbName;
360
+ }
361
+ /**
362
+ * The schema version of the data understood by this application.
363
+ * See [[ZeroOptions.schemaVersion]].
364
+ */
365
+ get schemaVersion() {
366
+ return this.#rep.schemaVersion;
367
+ }
368
+ /**
369
+ * The client ID for this instance of Zero. Each instance
370
+ * gets a unique client ID.
371
+ */
372
+ get clientID() {
373
+ return this.#rep.clientID;
374
+ }
375
+ get clientGroupID() {
376
+ return this.#rep.clientGroupID;
377
+ }
378
+ /**
379
+ * Provides facilities to write data to Zero.
380
+ *
381
+ * `mutate` is a function as well as a "namespace" object for doing CRUD style
382
+ * mutations. When used as a function it is used to batch multiple mutations.
383
+ *
384
+ * ```ts
385
+ * await zero.mutate.issue.create({id: '1', title: 'First issue'});
386
+ * await zero.mutate.comment.create({id: '1', text: 'First comment', issueID: '1'});
387
+ *
388
+ * // or as a function:
389
+ * await zero.mutate(m => {
390
+ * await m.issue.create({id: '1', title: 'First issue'});
391
+ * await m.comment.create({id: '1', text: 'First comment', issueID: '1'});
392
+ * });
393
+ * ```
394
+ *
395
+ * The benefit of using the function form is that it allows you to batch
396
+ * multiple mutations together. This can be more efficient than making
397
+ * individual calls to `create`, `update`, `set`, and `delete`.
398
+ *
399
+ * The function form of `mutate` is not allowed to be called inside another
400
+ * `mutate` function. Doing so will throw an error.
401
+ */
402
+ mutate;
403
+ /**
404
+ * Whether this Zero instance has been closed. Once a Zero instance has
405
+ * been closed it no longer syncs and you can no longer read or write data out
406
+ * of it. After it has been closed it is pretty much useless and should not be
407
+ * used any more.
408
+ */
409
+ get closed() {
410
+ return this.#rep.closed;
411
+ }
412
+ /**
413
+ * Closes this Zero instance.
414
+ *
415
+ * When closed all subscriptions end and no more read or writes are allowed.
416
+ */
417
+ close() {
418
+ const lc = this.#lc.withContext('close');
419
+ if (this.#connectionState !== ConnectionState.Disconnected) {
420
+ this.#disconnect(lc, {
421
+ client: 'ClientClosed',
422
+ });
423
+ }
424
+ lc.debug?.('Aborting closeAbortController due to close()');
425
+ this.#closeAbortController.abort();
426
+ this.#metrics.stop();
427
+ return this.#rep.close();
428
+ }
429
+ #onMessage = (e) => {
430
+ const lc = this.#lc;
431
+ lc.debug?.('received message', e.data);
432
+ if (this.closed) {
433
+ lc.debug?.('ignoring message because already closed');
434
+ return;
435
+ }
436
+ const rejectInvalidMessage = (e) => this.#rejectMessageError?.reject(new Error(`Invalid message received from server: ${e instanceof Error ? e.message + '. ' : ''}${data}`));
437
+ let downMessage;
438
+ const { data } = e;
439
+ try {
440
+ downMessage = valita.parse(JSON.parse(data), downstreamSchema);
441
+ }
442
+ catch (e) {
443
+ rejectInvalidMessage(e);
444
+ return;
445
+ }
446
+ this.#messageCount++;
447
+ const msgType = downMessage[0];
448
+ switch (msgType) {
449
+ case 'connected':
450
+ return this.#handleConnectedMessage(lc, downMessage);
451
+ case 'error':
452
+ return this.#handleErrorMessage(lc, downMessage);
453
+ case 'pong':
454
+ return this.#onPong();
455
+ case 'pokeStart':
456
+ return this.#handlePokeStart(lc, downMessage);
457
+ case 'pokePart':
458
+ return this.#handlePokePart(lc, downMessage);
459
+ case 'pokeEnd':
460
+ return this.#handlePokeEnd(lc, downMessage);
461
+ case 'pull':
462
+ return this.#handlePullResponse(lc, downMessage);
463
+ case 'warm':
464
+ // we ignore warming messages
465
+ break;
466
+ default:
467
+ msgType;
468
+ rejectInvalidMessage();
469
+ }
470
+ };
471
+ #onOpen = (e) => {
472
+ const l = addWebSocketIDFromSocketToLogContext(e.target, this.#lc);
473
+ if (this.#connectStart === undefined) {
474
+ l.error?.('Got open event but connect start time is undefined. This should not happen.');
475
+ }
476
+ else {
477
+ const now = Date.now();
478
+ const timeToOpenMs = now - this.#connectStart;
479
+ l.info?.('Got socket open event', {
480
+ navigatorOnline: navigator?.onLine,
481
+ timeToOpenMs,
482
+ });
483
+ }
484
+ };
485
+ #onClose = (e) => {
486
+ const l = addWebSocketIDFromSocketToLogContext(e.target, this.#lc);
487
+ const { code, reason, wasClean } = e;
488
+ l.info?.('Got socket close event', { code, reason, wasClean });
489
+ const closeKind = wasClean ? 'CleanClose' : 'AbruptClose';
490
+ this.#connectResolver.reject(new CloseError(closeKind));
491
+ this.#disconnect(l, { client: closeKind });
492
+ };
493
+ // An error on the connection is fatal for the connection.
494
+ async #handleErrorMessage(lc, downMessage) {
495
+ const [, kind, message] = downMessage;
496
+ // Rate limit errors are not fatal to the connection.
497
+ // We really don't want to disconnect and reconnect a rate limited user as
498
+ // it'll use more resources on the server
499
+ if (kind === ErrorKind.MutationRateLimited) {
500
+ this.#lastMutationIDSent = NULL_LAST_MUTATION_ID_SENT;
501
+ lc.error?.('Mutation rate limited', { message });
502
+ return;
503
+ }
504
+ lc.info?.(`${kind}: ${message}}`);
505
+ const error = new ServerError(kind, message);
506
+ this.#rejectMessageError?.reject(error);
507
+ lc.debug?.('Rejecting connect resolver due to error', error);
508
+ this.#connectResolver.reject(error);
509
+ this.#disconnect(lc, { server: kind });
510
+ if (kind === ErrorKind.VersionNotSupported) {
511
+ this.#onUpdateNeeded?.({ type: kind }, message);
512
+ }
513
+ else if (kind === ErrorKind.SchemaVersionNotSupported) {
514
+ await this.#rep.disableClientGroup();
515
+ this.#onUpdateNeeded?.({ type: 'SchemaVersionNotSupported' }, message);
516
+ }
517
+ else if (kind === ErrorKind.ClientNotFound) {
518
+ await this.#rep.disableClientGroup();
519
+ this.#onClientStateNotFound?.(onClientStateNotFoundServerReason(message));
520
+ }
521
+ else if (kind === ErrorKind.InvalidConnectionRequestLastMutationID ||
522
+ kind === ErrorKind.InvalidConnectionRequestBaseCookie) {
523
+ await dropDatabase(this.#rep.idbName);
524
+ reloadWithReason(lc, this.#reload, serverAheadReloadReason(kind));
525
+ }
526
+ }
527
+ async #handleConnectedMessage(lc, connectedMessage) {
528
+ const now = Date.now();
529
+ const [, connectBody] = connectedMessage;
530
+ lc = addWebSocketIDToLogContext(connectBody.wsid, lc);
531
+ if (this.#connectedCount === 0) {
532
+ this.#checkConnectivity('firstConnect');
533
+ }
534
+ else if (this.#connectErrorCount > 0) {
535
+ this.#checkConnectivity('connectAfterError');
536
+ }
537
+ this.#connectedCount++;
538
+ this.#connectedAt = now;
539
+ this.#metrics.lastConnectError.clear();
540
+ const proceedingConnectErrorCount = this.#connectErrorCount;
541
+ this.#connectErrorCount = 0;
542
+ let timeToConnectMs = undefined;
543
+ let connectMsgLatencyMs = undefined;
544
+ if (this.#connectStart === undefined) {
545
+ lc.error?.('Got connected message but connect start time is undefined. This should not happen.');
546
+ }
547
+ else {
548
+ timeToConnectMs = now - this.#connectStart;
549
+ this.#metrics.timeToConnectMs.set(timeToConnectMs);
550
+ connectMsgLatencyMs =
551
+ connectBody.timestamp !== undefined
552
+ ? now - connectBody.timestamp
553
+ : undefined;
554
+ this.#connectStart = undefined;
555
+ }
556
+ let totalTimeToConnectMs = undefined;
557
+ if (this.#totalToConnectStart === undefined) {
558
+ lc.error?.('Got connected message but total to connect start time is undefined. This should not happen.');
559
+ }
560
+ else {
561
+ totalTimeToConnectMs = now - this.#totalToConnectStart;
562
+ this.#totalToConnectStart = undefined;
563
+ }
564
+ this.#metrics.setConnected(timeToConnectMs ?? 0, totalTimeToConnectMs ?? 0);
565
+ lc.info?.('Connected', {
566
+ navigatorOnline: navigator?.onLine,
567
+ timeToConnectMs,
568
+ totalTimeToConnectMs,
569
+ connectMsgLatencyMs,
570
+ connectedCount: this.#connectedCount,
571
+ proceedingConnectErrorCount,
572
+ });
573
+ this.#lastMutationIDSent = NULL_LAST_MUTATION_ID_SENT;
574
+ lc.debug?.('Resolving connect resolver');
575
+ assert(this.#socket);
576
+ const queriesPatch = await this.#rep.query(tx => this.#queryManager.getQueriesPatch(tx, this.#initConnectionQueries));
577
+ if (queriesPatch.size > 0) {
578
+ send(this.#socket, [
579
+ 'changeDesiredQueries',
580
+ {
581
+ desiredQueriesPatch: [...queriesPatch.values()],
582
+ },
583
+ ]);
584
+ }
585
+ this.#initConnectionQueries = new Map();
586
+ this.#setConnectionState(ConnectionState.Connected);
587
+ this.#connectResolver.resolve();
588
+ }
589
+ /**
590
+ * Starts a new connection. This will create the WebSocket that does the HTTP
591
+ * request to the server.
592
+ *
593
+ * {@link #connect} will throw an assertion error if the
594
+ * {@link #connectionState} is not {@link ConnectionState.Disconnected}.
595
+ * Callers MUST check the connection state before calling this method and log
596
+ * an error as needed.
597
+ *
598
+ * The function will resolve once the socket is connected. If you need to know
599
+ * when a connection has been established, as in we have received the
600
+ * {@link ConnectedMessage}, you should await the {@link #connectResolver}
601
+ * promise. The {@link #connectResolver} promise rejects if an error message
602
+ * is received before the connected message is received or if the connection
603
+ * attempt times out.
604
+ */
605
+ async #connect(l) {
606
+ assert(this.#server);
607
+ // All the callers check this state already.
608
+ assert(this.#connectionState === ConnectionState.Disconnected);
609
+ const wsid = nanoid();
610
+ l = addWebSocketIDToLogContext(wsid, l);
611
+ l.info?.('Connecting...', { navigatorOnline: navigator?.onLine });
612
+ this.#setConnectionState(ConnectionState.Connecting);
613
+ // connect() called but connect start time is defined. This should not
614
+ // happen.
615
+ assert(this.#connectStart === undefined);
616
+ const now = Date.now();
617
+ this.#connectStart = now;
618
+ if (this.#totalToConnectStart === undefined) {
619
+ this.#totalToConnectStart = now;
620
+ }
621
+ if (this.closed) {
622
+ return;
623
+ }
624
+ this.#connectCookie = valita.parse(await this.#rep.cookie, nullableVersionSchema);
625
+ if (this.closed) {
626
+ return;
627
+ }
628
+ // Reject connect after a timeout.
629
+ const timeoutID = setTimeout(() => {
630
+ l.debug?.('Rejecting connect resolver due to timeout');
631
+ this.#connectResolver.reject(new TimedOutError('Connect'));
632
+ this.#disconnect(l, {
633
+ client: 'ConnectTimeout',
634
+ });
635
+ }, CONNECT_TIMEOUT_MS);
636
+ const abortHandler = () => {
637
+ clearTimeout(timeoutID);
638
+ };
639
+ this.#closeAbortController.signal.addEventListener('abort', abortHandler);
640
+ const [ws, initConnectionQueries] = await createSocket(this.#rep, this.#queryManager, toWSString(this.#server), this.#connectCookie, this.clientID, await this.clientGroupID, this.#options.schema.version, this.userID, this.#rep.auth, this.#jurisdiction, this.#lastMutationIDReceived, wsid, this.#options.logLevel === 'debug', l);
641
+ if (this.closed) {
642
+ return;
643
+ }
644
+ this.#initConnectionQueries = initConnectionQueries;
645
+ ws.addEventListener('message', this.#onMessage);
646
+ ws.addEventListener('open', this.#onOpen);
647
+ ws.addEventListener('close', this.#onClose);
648
+ this.#socket = ws;
649
+ this.#socketResolver.resolve(ws);
650
+ try {
651
+ l.debug?.('Waiting for connection to be acknowledged');
652
+ await this.#connectResolver.promise;
653
+ }
654
+ finally {
655
+ clearTimeout(timeoutID);
656
+ this.#closeAbortController.signal.removeEventListener('abort', abortHandler);
657
+ }
658
+ }
659
+ #disconnect(l, reason) {
660
+ if (this.#connectionState === ConnectionState.Connecting) {
661
+ this.#connectErrorCount++;
662
+ }
663
+ l.info?.('disconnecting', {
664
+ navigatorOnline: navigator?.onLine,
665
+ reason,
666
+ connectStart: this.#connectStart,
667
+ totalToConnectStart: this.#totalToConnectStart,
668
+ connectedAt: this.#connectedAt,
669
+ connectionDuration: this.#connectedAt
670
+ ? Date.now() - this.#connectedAt
671
+ : 0,
672
+ messageCount: this.#messageCount,
673
+ connectionState: this.#connectionState,
674
+ connectErrorCount: this.#connectErrorCount,
675
+ });
676
+ switch (this.#connectionState) {
677
+ case ConnectionState.Connected: {
678
+ if (this.#connectStart !== undefined) {
679
+ l.error?.('disconnect() called while connected but connect start time is defined. This should not happen.');
680
+ // this._connectStart reset below.
681
+ }
682
+ break;
683
+ }
684
+ case ConnectionState.Connecting: {
685
+ this.#metrics.lastConnectError.set(getLastConnectErrorValue(reason));
686
+ this.#metrics.timeToConnectMs.set(DID_NOT_CONNECT_VALUE);
687
+ this.#metrics.setConnectError(reason);
688
+ if (this.#connectErrorCount % CHECK_CONNECTIVITY_ON_ERROR_FREQUENCY ===
689
+ 1) {
690
+ this.#checkConnectivity(`connectErrorCount=${this.#connectErrorCount}`);
691
+ }
692
+ // this._connectStart reset below.
693
+ if (this.#connectStart === undefined) {
694
+ l.error?.('disconnect() called while connecting but connect start time is undefined. This should not happen.');
695
+ }
696
+ break;
697
+ }
698
+ case ConnectionState.Disconnected:
699
+ l.error?.('disconnect() called while disconnected');
700
+ break;
701
+ }
702
+ this.#socketResolver = resolver();
703
+ l.debug?.('Creating new connect resolver');
704
+ this.#connectResolver = resolver();
705
+ this.#setConnectionState(ConnectionState.Disconnected);
706
+ this.#messageCount = 0;
707
+ this.#connectStart = undefined; // don't reset this._totalToConnectStart
708
+ this.#connectedAt = 0;
709
+ this.#socket?.removeEventListener('message', this.#onMessage);
710
+ this.#socket?.removeEventListener('open', this.#onOpen);
711
+ this.#socket?.removeEventListener('close', this.#onClose);
712
+ this.#socket?.close();
713
+ this.#socket = undefined;
714
+ this.#lastMutationIDSent = NULL_LAST_MUTATION_ID_SENT;
715
+ this.#pokeHandler.handleDisconnect();
716
+ }
717
+ async #handlePokeStart(_lc, pokeMessage) {
718
+ this.#abortPingTimeout();
719
+ await this.#pokeHandler.handlePokeStart(pokeMessage[1]);
720
+ }
721
+ async #handlePokePart(_lc, pokeMessage) {
722
+ this.#abortPingTimeout();
723
+ const lastMutationIDChangeForSelf = await this.#pokeHandler.handlePokePart(pokeMessage[1]);
724
+ if (lastMutationIDChangeForSelf !== undefined) {
725
+ this.#lastMutationIDReceived = lastMutationIDChangeForSelf;
726
+ }
727
+ }
728
+ async #handlePokeEnd(_lc, pokeMessage) {
729
+ this.#abortPingTimeout();
730
+ await this.#pokeHandler.handlePokeEnd(pokeMessage[1]);
731
+ }
732
+ #onPokeError() {
733
+ const lc = this.#lc;
734
+ lc.info?.('poke error, disconnecting?', this.#connectionState !== ConnectionState.Disconnected);
735
+ // It is theoretically possible that we get disconnected during the
736
+ // async poke above. Only disconnect if we are not already
737
+ // disconnected.
738
+ if (this.#connectionState !== ConnectionState.Disconnected) {
739
+ this.#disconnect(lc, {
740
+ client: 'UnexpectedBaseCookie',
741
+ });
742
+ }
743
+ }
744
+ #handlePullResponse(lc, pullResponseMessage) {
745
+ this.#abortPingTimeout();
746
+ const body = pullResponseMessage[1];
747
+ lc = lc.withContext('requestID', body.requestID);
748
+ lc.debug?.('Handling pull response', body);
749
+ const resolver = this.#pendingPullsByRequestID.get(body.requestID);
750
+ if (!resolver) {
751
+ // This can happen because resolvers are deleted
752
+ // from this._pendingPullsByRequestID when pulls timeout.
753
+ lc.debug?.('No resolver found');
754
+ return;
755
+ }
756
+ resolver.resolve(pullResponseMessage[1]);
757
+ }
758
+ async #pusher(req, requestID) {
759
+ // The deprecation of pushVersion 0 predates zero-client
760
+ assert(req.pushVersion === 1);
761
+ // If we are connecting we wait until we are connected.
762
+ await this.#connectResolver.promise;
763
+ const lc = this.#lc.withContext('requestID', requestID);
764
+ lc.debug?.(`pushing ${req.mutations.length} mutations`);
765
+ const socket = this.#socket;
766
+ assert(socket);
767
+ const isMutationRecoveryPush = req.clientGroupID !== (await this.clientGroupID);
768
+ const start = isMutationRecoveryPush
769
+ ? 0
770
+ : req.mutations.findIndex(m => m.clientID === this.#lastMutationIDSent.clientID &&
771
+ m.id === this.#lastMutationIDSent.id) + 1;
772
+ lc.debug?.(isMutationRecoveryPush ? 'pushing for recovery' : 'pushing', req.mutations.length - start, 'mutations of', req.mutations.length, 'mutations.');
773
+ const now = Date.now();
774
+ for (let i = start; i < req.mutations.length; i++) {
775
+ const m = req.mutations[i];
776
+ const timestamp = now - Math.round(performance.now() - m.timestamp);
777
+ const zeroM = m.name === CRUD_MUTATION_NAME
778
+ ? {
779
+ type: MutationType.CRUD,
780
+ timestamp,
781
+ id: m.id,
782
+ clientID: m.clientID,
783
+ name: m.name,
784
+ args: [m.args],
785
+ }
786
+ : {
787
+ type: MutationType.Custom,
788
+ timestamp,
789
+ id: m.id,
790
+ clientID: m.clientID,
791
+ name: m.name,
792
+ args: [m.args],
793
+ };
794
+ const msg = [
795
+ 'push',
796
+ {
797
+ timestamp: now,
798
+ clientGroupID: req.clientGroupID,
799
+ mutations: [zeroM],
800
+ pushVersion: req.pushVersion,
801
+ // Zero schema versions are always numbers.
802
+ schemaVersion: parseInt(req.schemaVersion),
803
+ requestID,
804
+ },
805
+ ];
806
+ send(socket, msg);
807
+ if (!isMutationRecoveryPush) {
808
+ this.#lastMutationIDSent = { clientID: m.clientID, id: m.id };
809
+ }
810
+ }
811
+ return {
812
+ httpRequestInfo: {
813
+ errorMessage: '',
814
+ httpStatusCode: 200,
815
+ },
816
+ };
817
+ }
818
+ #getAuthToken = () => {
819
+ const { auth } = this.#options;
820
+ return typeof auth === 'function' ? auth() : auth;
821
+ };
822
+ async #updateAuthToken(lc) {
823
+ const auth = await this.#getAuthToken();
824
+ if (auth) {
825
+ lc.debug?.('Got auth token');
826
+ this.#rep.auth = auth;
827
+ }
828
+ }
829
+ async #runLoop() {
830
+ this.#lc.info?.(`Starting Zero version: ${this.version}`);
831
+ if (this.#server === null) {
832
+ this.#lc.info?.('No socket origin provided, not starting connect loop.');
833
+ return;
834
+ }
835
+ let runLoopCounter = 0;
836
+ const bareLogContext = this.#lc;
837
+ const getLogContext = () => {
838
+ let lc = bareLogContext;
839
+ if (this.#socket) {
840
+ lc = addWebSocketIDFromSocketToLogContext(this.#socket, lc);
841
+ }
842
+ return lc.withContext('runLoopCounter', runLoopCounter);
843
+ };
844
+ await this.#updateAuthToken(bareLogContext);
845
+ let needsReauth = false;
846
+ let gotError = false;
847
+ while (!this.closed) {
848
+ runLoopCounter++;
849
+ let lc = getLogContext();
850
+ try {
851
+ switch (this.#connectionState) {
852
+ case ConnectionState.Disconnected: {
853
+ if (this.#visibilityWatcher.visibilityState === 'hidden') {
854
+ this.#metrics.setDisconnectedWaitingForVisible();
855
+ // reset this._totalToConnectStart since this client
856
+ // is no longer trying to connect due to being hidden.
857
+ this.#totalToConnectStart = undefined;
858
+ }
859
+ // If hidden, we wait for the tab to become visible before trying again.
860
+ await this.#visibilityWatcher.waitForVisible();
861
+ // If we got an auth error we try to get a new auth token before reconnecting.
862
+ if (needsReauth) {
863
+ await this.#updateAuthToken(lc);
864
+ }
865
+ await this.#connect(lc);
866
+ if (this.closed) {
867
+ break;
868
+ }
869
+ // Now we have a new socket, update lc with the new wsid.
870
+ assert(this.#socket);
871
+ lc = getLogContext();
872
+ lc.debug?.('Connected successfully');
873
+ gotError = false;
874
+ needsReauth = false;
875
+ this.#setOnline(true);
876
+ break;
877
+ }
878
+ case ConnectionState.Connecting:
879
+ // Can't get here because Disconnected waits for Connected or
880
+ // rejection.
881
+ lc.error?.('unreachable');
882
+ gotError = true;
883
+ break;
884
+ case ConnectionState.Connected: {
885
+ // When connected we wait for whatever happens first out of:
886
+ // - After PING_INTERVAL_MS we send a ping
887
+ // - We get disconnected
888
+ // - We get a message
889
+ // - We get an error (rejectMessageError rejects)
890
+ // - The tab becomes hidden (with a delay)
891
+ const controller = new AbortController();
892
+ this.#abortPingTimeout = () => controller.abort();
893
+ const [pingTimeoutPromise, pingTimeoutAborted] = sleepWithAbort(PING_INTERVAL_MS, controller.signal);
894
+ this.#rejectMessageError = resolver();
895
+ let RaceCases;
896
+ (function (RaceCases) {
897
+ RaceCases[RaceCases["Ping"] = 0] = "Ping";
898
+ RaceCases[RaceCases["Hidden"] = 2] = "Hidden";
899
+ })(RaceCases || (RaceCases = {}));
900
+ const raceResult = await promiseRace([
901
+ pingTimeoutPromise,
902
+ pingTimeoutAborted,
903
+ this.#visibilityWatcher.waitForHidden(),
904
+ this.#connectionStateChangeResolver.promise,
905
+ this.#rejectMessageError.promise,
906
+ ]);
907
+ if (this.closed) {
908
+ this.#rejectMessageError = undefined;
909
+ break;
910
+ }
911
+ switch (raceResult) {
912
+ case RaceCases.Ping: {
913
+ const pingResult = await this.#ping(lc, this.#rejectMessageError.promise);
914
+ if (pingResult === PingResult.TimedOut) {
915
+ gotError = true;
916
+ }
917
+ break;
918
+ }
919
+ case RaceCases.Hidden:
920
+ this.#disconnect(lc, {
921
+ client: 'Hidden',
922
+ });
923
+ this.#setOnline(false);
924
+ break;
925
+ }
926
+ this.#rejectMessageError = undefined;
927
+ }
928
+ }
929
+ }
930
+ catch (ex) {
931
+ if (this.#connectionState !== ConnectionState.Connected) {
932
+ lc.error?.('Failed to connect', ex, {
933
+ lmid: this.#lastMutationIDReceived,
934
+ baseCookie: this.#connectCookie,
935
+ });
936
+ }
937
+ lc.debug?.('Got an exception in the run loop', 'state:', this.#connectionState, 'exception:', ex);
938
+ if (isAuthError(ex)) {
939
+ if (!needsReauth) {
940
+ needsReauth = true;
941
+ // First auth error, try right away without waiting.
942
+ continue;
943
+ }
944
+ needsReauth = true;
945
+ }
946
+ if (isServerError(ex) ||
947
+ ex instanceof TimedOutError ||
948
+ ex instanceof CloseError) {
949
+ gotError = true;
950
+ }
951
+ }
952
+ // Only authentication errors are retried immediately the first time they
953
+ // occur. All other errors wait a few seconds before retrying the first
954
+ // time. We specifically do not use a backoff for consecutive errors
955
+ // because it's a bad experience to wait many seconds for reconnection.
956
+ if (gotError) {
957
+ this.#setOnline(false);
958
+ let cfGetCheckSucceeded = false;
959
+ const cfGetCheckURL = new URL(this.#server);
960
+ cfGetCheckURL.pathname = '/api/canary/v0/get';
961
+ cfGetCheckURL.searchParams.set('id', nanoid());
962
+ const cfGetCheckController = new AbortController();
963
+ fetch(cfGetCheckURL, { signal: cfGetCheckController.signal })
964
+ .then(_ => {
965
+ cfGetCheckSucceeded = true;
966
+ })
967
+ .catch(_ => {
968
+ cfGetCheckSucceeded = false;
969
+ });
970
+ lc.debug?.('Sleeping', RUN_LOOP_INTERVAL_MS, 'ms before reconnecting due to error, state:', this.#connectionState);
971
+ await sleep(RUN_LOOP_INTERVAL_MS);
972
+ cfGetCheckController.abort();
973
+ if (!cfGetCheckSucceeded) {
974
+ lc.info?.('Canary request failed, resetting total time to connect start time.');
975
+ this.#totalToConnectStart = undefined;
976
+ }
977
+ }
978
+ }
979
+ }
980
+ async #puller(req, requestID) {
981
+ // The deprecation of pushVersion 0 predates zero-client
982
+ assert(req.pullVersion === 1);
983
+ const lc = this.#lc.withContext('requestID', requestID);
984
+ lc.debug?.('Pull', req);
985
+ // Pull request for this instance's client group. A no-op response is
986
+ // returned as pulls for this client group are handled via poke over the
987
+ // socket.
988
+ if (req.clientGroupID === (await this.clientGroupID)) {
989
+ return {
990
+ httpRequestInfo: {
991
+ errorMessage: '',
992
+ httpStatusCode: 200,
993
+ },
994
+ };
995
+ }
996
+ // If we are connecting we wait until we are connected.
997
+ await this.#connectResolver.promise;
998
+ const socket = this.#socket;
999
+ assert(socket);
1000
+ // Mutation recovery pull.
1001
+ lc.debug?.('Pull is for mutation recovery');
1002
+ const cookie = valita.parse(req.cookie, nullableVersionSchema);
1003
+ const pullRequestMessage = [
1004
+ 'pull',
1005
+ {
1006
+ clientGroupID: req.clientGroupID,
1007
+ cookie,
1008
+ requestID,
1009
+ },
1010
+ ];
1011
+ send(socket, pullRequestMessage);
1012
+ const pullResponseResolver = resolver();
1013
+ this.#pendingPullsByRequestID.set(requestID, pullResponseResolver);
1014
+ try {
1015
+ let RaceCases;
1016
+ (function (RaceCases) {
1017
+ RaceCases[RaceCases["Timeout"] = 0] = "Timeout";
1018
+ RaceCases[RaceCases["Response"] = 1] = "Response";
1019
+ })(RaceCases || (RaceCases = {}));
1020
+ const raceResult = await promiseRace([
1021
+ sleep(PULL_TIMEOUT_MS),
1022
+ pullResponseResolver.promise,
1023
+ ]);
1024
+ switch (raceResult) {
1025
+ case RaceCases.Timeout:
1026
+ lc.debug?.('Mutation recovery pull timed out');
1027
+ throw new Error('Pull timed out');
1028
+ case RaceCases.Response: {
1029
+ lc.debug?.('Returning mutation recovery pull response');
1030
+ const response = await pullResponseResolver.promise;
1031
+ return {
1032
+ response: {
1033
+ cookie: response.cookie,
1034
+ lastMutationIDChanges: response.lastMutationIDChanges,
1035
+ patch: [],
1036
+ },
1037
+ httpRequestInfo: {
1038
+ errorMessage: '',
1039
+ httpStatusCode: 200,
1040
+ },
1041
+ };
1042
+ }
1043
+ default:
1044
+ assert(false, 'unreachable');
1045
+ }
1046
+ }
1047
+ finally {
1048
+ pullResponseResolver.reject('timed out');
1049
+ this.#pendingPullsByRequestID.delete(requestID);
1050
+ }
1051
+ }
1052
+ #setOnline(online) {
1053
+ if (this.#online === online) {
1054
+ return;
1055
+ }
1056
+ this.#online = online;
1057
+ this.onOnlineChange?.(online);
1058
+ }
1059
+ /**
1060
+ * A rough heuristic for whether the client is currently online and
1061
+ * authenticated.
1062
+ */
1063
+ get online() {
1064
+ return this.#online;
1065
+ }
1066
+ /**
1067
+ * Starts a a ping and waits for a pong.
1068
+ *
1069
+ * If it takes too long to get a pong we disconnect and this returns
1070
+ * {@code PingResult.TimedOut}.
1071
+ */
1072
+ async #ping(l, messageErrorRejectionPromise) {
1073
+ l.debug?.('pinging');
1074
+ const { promise, resolve } = resolver();
1075
+ this.#onPong = resolve;
1076
+ const pingMessage = ['ping', {}];
1077
+ const t0 = performance.now();
1078
+ assert(this.#socket);
1079
+ send(this.#socket, pingMessage);
1080
+ const connected = (await promiseRace([
1081
+ promise,
1082
+ sleep(PING_TIMEOUT_MS),
1083
+ messageErrorRejectionPromise,
1084
+ ])) === 0;
1085
+ const delta = performance.now() - t0;
1086
+ if (!connected) {
1087
+ l.info?.('ping failed in', delta, 'ms - disconnecting');
1088
+ this.#disconnect(l, {
1089
+ client: 'PingTimeout',
1090
+ });
1091
+ return PingResult.TimedOut;
1092
+ }
1093
+ l.debug?.('ping succeeded in', delta, 'ms');
1094
+ return PingResult.Success;
1095
+ }
1096
+ // Sends a set of metrics to the server. Throws unless the server
1097
+ // returns 200.
1098
+ // TODO: Reenable metrics reporting
1099
+ async #reportMetrics(_allSeries) {
1100
+ // if (this.#server === null) {
1101
+ // this.#lc.info?.('Skipping metrics report, socketOrigin is null');
1102
+ // return;
1103
+ // }
1104
+ // const body = JSON.stringify({series: allSeries});
1105
+ // const url = new URL('/api/metrics/v0/report', this.#server);
1106
+ // url.searchParams.set('clientID', this.clientID);
1107
+ // url.searchParams.set('clientGroupID', await this.clientGroupID);
1108
+ // url.searchParams.set('userID', this.userID);
1109
+ // url.searchParams.set('requestID', nanoid());
1110
+ // const res = await fetch(url.toString(), {
1111
+ // method: 'POST',
1112
+ // body,
1113
+ // keepalive: true,
1114
+ // });
1115
+ // if (!res.ok) {
1116
+ // const maybeBody = await res.text();
1117
+ // throw new Error(
1118
+ // `unexpected response: ${res.status} ${res.statusText} body: ${maybeBody}`,
1119
+ // );
1120
+ // }
1121
+ }
1122
+ #checkConnectivity(reason) {
1123
+ void this.#checkConnectivityAsync(reason);
1124
+ }
1125
+ #checkConnectivityAsync(_reason) {
1126
+ // skipping connectivity checks for now - the server doesn't respond to
1127
+ // them so it just creates noise.
1128
+ // assert(this.#server);
1129
+ // if (this.closed) {
1130
+ // return;
1131
+ // }
1132
+ // try {
1133
+ // await checkConnectivity(
1134
+ // reason,
1135
+ // this.#server,
1136
+ // this.#lc,
1137
+ // this.#closeAbortController.signal,
1138
+ // this.#enableAnalytics,
1139
+ // );
1140
+ // } catch (e) {
1141
+ // this.#lc.info?.('Error checking connectivity for', reason, e);
1142
+ // }
1143
+ }
1144
+ #registerQueries(schema) {
1145
+ const rv = {};
1146
+ const context = this.#zeroContext;
1147
+ // Not using parse yet
1148
+ for (const [name, table] of Object.entries(schema.tables)) {
1149
+ rv[name] = newQuery(context, table);
1150
+ }
1151
+ return rv;
1152
+ }
1153
+ }
1154
+ export async function createSocket(rep, queryManager, socketOrigin, baseCookie, clientID, clientGroupID, schemaVersion, userID, auth, jurisdiction, lmid, wsid, debugPerf, lc) {
1155
+ const url = new URL(socketOrigin);
1156
+ // Keep this in sync with the server.
1157
+ url.pathname = `/api/sync/v${REFLECT_VERSION}/connect`;
1158
+ const { searchParams } = url;
1159
+ searchParams.set('clientID', clientID);
1160
+ searchParams.set('clientGroupID', clientGroupID);
1161
+ searchParams.set('schemaVersion', schemaVersion.toString());
1162
+ searchParams.set('userID', userID);
1163
+ if (jurisdiction !== undefined) {
1164
+ searchParams.set('jurisdiction', jurisdiction);
1165
+ }
1166
+ searchParams.set('baseCookie', baseCookie === null ? '' : String(baseCookie));
1167
+ searchParams.set('ts', String(performance.now()));
1168
+ searchParams.set('lmid', String(lmid));
1169
+ searchParams.set('wsid', wsid);
1170
+ if (debugPerf) {
1171
+ searchParams.set('debugPerf', true.toString());
1172
+ }
1173
+ lc.info?.('Connecting to', url.toString());
1174
+ // Pass auth to the server via the `Sec-WebSocket-Protocol` header by passing
1175
+ // it as a `protocol` to the `WebSocket` constructor. The empty string is an
1176
+ // invalid `protocol`, and will result in an exception, so pass undefined
1177
+ // instead. encodeURIComponent to ensure it only contains chars allowed
1178
+ // for a `protocol`.
1179
+ const WS = mustGetBrowserGlobal('WebSocket');
1180
+ const queriesPatch = await rep.query(tx => queryManager.getQueriesPatch(tx));
1181
+ return [
1182
+ new WS(
1183
+ // toString() required for RN URL polyfill.
1184
+ url.toString(), encodeSecProtocols(['initConnection', { desiredQueriesPatch: [...queriesPatch.values()] }], auth)),
1185
+ queriesPatch,
1186
+ ];
1187
+ }
1188
+ /**
1189
+ * Adds the wsid query parameter to the log context. If the URL does not
1190
+ * have a wsid we use a randomID instead.
1191
+ */
1192
+ function addWebSocketIDFromSocketToLogContext({ url }, lc) {
1193
+ const wsid = new URL(url).searchParams.get('wsid') ?? nanoid();
1194
+ return addWebSocketIDToLogContext(wsid, lc);
1195
+ }
1196
+ function addWebSocketIDToLogContext(wsid, lc) {
1197
+ return lc.withContext('wsid', wsid);
1198
+ }
1199
+ /**
1200
+ * Like Promise.race but returns the index of the first promise that resolved.
1201
+ */
1202
+ function promiseRace(ps) {
1203
+ return Promise.race(ps.map((p, i) => p.then(() => i)));
1204
+ }
1205
+ class TimedOutError extends Error {
1206
+ constructor(m) {
1207
+ super(`${m} timed out`);
1208
+ }
1209
+ }
1210
+ class CloseError extends Error {
1211
+ }
1212
+ //# sourceMappingURL=zero.js.map