@rocicorp/zero 1.6.0-canary.1 → 1.6.0-canary.11

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 (728) hide show
  1. package/README.md +28 -3
  2. package/out/_virtual/{_@oxc-project_runtime@0.122.0 → _@oxc-project_runtime@0.130.0}/helpers/usingCtx.js +1 -1
  3. package/out/_virtual/__vite-optional-peer-dep_pg-native_pg.js +13 -0
  4. package/out/_virtual/__vite-optional-peer-dep_pg-native_pg.js.map +1 -0
  5. package/out/_virtual/_rolldown/runtime.js +12 -1
  6. package/out/analyze-query/src/analyze-cli.js.map +1 -1
  7. package/out/analyze-query/src/bin-analyze.js +6 -1
  8. package/out/analyze-query/src/bin-analyze.js.map +1 -1
  9. package/out/analyze-query/src/bin-transform.js.map +1 -1
  10. package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
  11. package/out/ast-to-zql/src/bin.js.map +1 -1
  12. package/out/ast-to-zql/src/format.js.map +1 -1
  13. package/out/datadog/src/datadog-log-sink.js.map +1 -1
  14. package/out/node_modules/.pnpm/@opentelemetry_semantic-conventions@1.41.1/node_modules/@opentelemetry/semantic-conventions/build/esm/stable_attributes.js +12 -0
  15. package/out/node_modules/.pnpm/@opentelemetry_semantic-conventions@1.41.1/node_modules/@opentelemetry/semantic-conventions/build/esm/stable_attributes.js.map +1 -0
  16. package/out/node_modules/.pnpm/pg-cloudflare@1.3.0/node_modules/pg-cloudflare/dist/empty.js +11 -0
  17. package/out/node_modules/.pnpm/pg-cloudflare@1.3.0/node_modules/pg-cloudflare/dist/empty.js.map +1 -0
  18. package/out/node_modules/.pnpm/pg-connection-string@2.12.0/node_modules/pg-connection-string/index.js +130 -0
  19. package/out/node_modules/.pnpm/pg-connection-string@2.12.0/node_modules/pg-connection-string/index.js.map +1 -0
  20. package/out/node_modules/.pnpm/pg-int8@1.0.1/node_modules/pg-int8/index.js +62 -0
  21. package/out/node_modules/.pnpm/pg-int8@1.0.1/node_modules/pg-int8/index.js.map +1 -0
  22. package/out/node_modules/.pnpm/pg-pool@3.13.0_pg@8.20.0/node_modules/pg-pool/index.js +353 -0
  23. package/out/node_modules/.pnpm/pg-pool@3.13.0_pg@8.20.0/node_modules/pg-pool/index.js.map +1 -0
  24. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/buffer-reader.js +60 -0
  25. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/buffer-reader.js.map +1 -0
  26. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/buffer-writer.js +81 -0
  27. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/buffer-writer.js.map +1 -0
  28. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/index.js +35 -0
  29. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/index.js.map +1 -0
  30. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/messages.js +167 -0
  31. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/messages.js.map +1 -0
  32. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/parser.js +288 -0
  33. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/parser.js.map +1 -0
  34. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/serializer.js +177 -0
  35. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/serializer.js.map +1 -0
  36. package/out/node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/index.js +46 -0
  37. package/out/node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/index.js.map +1 -0
  38. package/out/node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/lib/arrayParser.js +16 -0
  39. package/out/node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/lib/arrayParser.js.map +1 -0
  40. package/out/node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/lib/binaryParsers.js +165 -0
  41. package/out/node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/lib/binaryParsers.js.map +1 -0
  42. package/out/node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/lib/builtins.js +81 -0
  43. package/out/node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/lib/builtins.js.map +1 -0
  44. package/out/node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/lib/textParsers.js +167 -0
  45. package/out/node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/lib/textParsers.js.map +1 -0
  46. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/esm/index.js +19 -0
  47. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/esm/index.js.map +1 -0
  48. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/client.js +508 -0
  49. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/client.js.map +1 -0
  50. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/connection-parameters.js +104 -0
  51. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/connection-parameters.js.map +1 -0
  52. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/connection.js +160 -0
  53. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/connection.js.map +1 -0
  54. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/crypto/cert-signatures.js +97 -0
  55. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/crypto/cert-signatures.js.map +1 -0
  56. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/crypto/sasl.js +131 -0
  57. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/crypto/sasl.js.map +1 -0
  58. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/crypto/utils-legacy.js +39 -0
  59. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/crypto/utils-legacy.js.map +1 -0
  60. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/crypto/utils-webcrypto.js +89 -0
  61. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/crypto/utils-webcrypto.js.map +1 -0
  62. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/crypto/utils.js +13 -0
  63. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/crypto/utils.js.map +1 -0
  64. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/defaults.js +46 -0
  65. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/defaults.js.map +1 -0
  66. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/index.js +71 -0
  67. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/index.js.map +1 -0
  68. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/native/client.js +226 -0
  69. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/native/client.js.map +1 -0
  70. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/native/index.js +11 -0
  71. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/native/index.js.map +1 -0
  72. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/native/query.js +117 -0
  73. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/native/query.js.map +1 -0
  74. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/query.js +151 -0
  75. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/query.js.map +1 -0
  76. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/result.js +76 -0
  77. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/result.js.map +1 -0
  78. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/stream.js +73 -0
  79. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/stream.js.map +1 -0
  80. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/type-overrides.js +35 -0
  81. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/type-overrides.js.map +1 -0
  82. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/utils.js +118 -0
  83. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/utils.js.map +1 -0
  84. package/out/node_modules/.pnpm/pgpass@1.0.5/node_modules/pgpass/lib/helper.js +147 -0
  85. package/out/node_modules/.pnpm/pgpass@1.0.5/node_modules/pgpass/lib/helper.js.map +1 -0
  86. package/out/node_modules/.pnpm/pgpass@1.0.5/node_modules/pgpass/lib/index.js +21 -0
  87. package/out/node_modules/.pnpm/pgpass@1.0.5/node_modules/pgpass/lib/index.js.map +1 -0
  88. package/out/node_modules/.pnpm/postgres-array@2.0.0/node_modules/postgres-array/index.js +84 -0
  89. package/out/node_modules/.pnpm/postgres-array@2.0.0/node_modules/postgres-array/index.js.map +1 -0
  90. package/out/node_modules/.pnpm/postgres-bytea@1.0.1/node_modules/postgres-bytea/index.js +28 -0
  91. package/out/node_modules/.pnpm/postgres-bytea@1.0.1/node_modules/postgres-bytea/index.js.map +1 -0
  92. package/out/node_modules/.pnpm/postgres-date@1.0.7/node_modules/postgres-date/index.js +65 -0
  93. package/out/node_modules/.pnpm/postgres-date@1.0.7/node_modules/postgres-date/index.js.map +1 -0
  94. package/out/node_modules/.pnpm/postgres-interval@1.2.0/node_modules/postgres-interval/index.js +107 -0
  95. package/out/node_modules/.pnpm/postgres-interval@1.2.0/node_modules/postgres-interval/index.js.map +1 -0
  96. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react-jsx-runtime.development.js +696 -0
  97. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react-jsx-runtime.development.js.map +1 -0
  98. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react-jsx-runtime.production.min.js +44 -0
  99. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react-jsx-runtime.production.min.js.map +1 -0
  100. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.development.js +1585 -0
  101. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.development.js.map +1 -0
  102. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js +329 -0
  103. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js.map +1 -0
  104. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/index.js +13 -0
  105. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/index.js.map +1 -0
  106. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/jsx-runtime.js +13 -0
  107. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/jsx-runtime.js.map +1 -0
  108. package/out/node_modules/.pnpm/solid-js@1.9.13/node_modules/solid-js/dist/server.js +131 -0
  109. package/out/node_modules/.pnpm/solid-js@1.9.13/node_modules/solid-js/dist/server.js.map +1 -0
  110. package/out/node_modules/.pnpm/solid-js@1.9.13/node_modules/solid-js/store/dist/server.js +96 -0
  111. package/out/node_modules/.pnpm/solid-js@1.9.13/node_modules/solid-js/store/dist/server.js.map +1 -0
  112. package/out/node_modules/.pnpm/split2@4.2.0/node_modules/split2/index.js +95 -0
  113. package/out/node_modules/.pnpm/split2@4.2.0/node_modules/split2/index.js.map +1 -0
  114. package/out/node_modules/.pnpm/xtend@4.0.2/node_modules/xtend/mutable.js +18 -0
  115. package/out/node_modules/.pnpm/xtend@4.0.2/node_modules/xtend/mutable.js.map +1 -0
  116. package/out/otel/src/enabled.js.map +1 -1
  117. package/out/otel/src/log-options.js.map +1 -1
  118. package/out/otel/src/maybe-time.js.map +1 -1
  119. package/out/otel/src/span.js.map +1 -1
  120. package/out/replicache/src/async-iterable-to-array.js.map +1 -1
  121. package/out/replicache/src/bg-interval.js.map +1 -1
  122. package/out/replicache/src/btree/diff.js.map +1 -1
  123. package/out/replicache/src/btree/node.js.map +1 -1
  124. package/out/replicache/src/btree/read.js.map +1 -1
  125. package/out/replicache/src/btree/splice.js.map +1 -1
  126. package/out/replicache/src/btree/write.js +6 -3
  127. package/out/replicache/src/btree/write.js.map +1 -1
  128. package/out/replicache/src/call-default-fetch.js.map +1 -1
  129. package/out/replicache/src/connection-loop-delegates.js.map +1 -1
  130. package/out/replicache/src/connection-loop.js.map +1 -1
  131. package/out/replicache/src/cookies.js.map +1 -1
  132. package/out/replicache/src/dag/chunk.js.map +1 -1
  133. package/out/replicache/src/dag/gc.js.map +1 -1
  134. package/out/replicache/src/dag/key.js.map +1 -1
  135. package/out/replicache/src/dag/lazy-store.js.map +1 -1
  136. package/out/replicache/src/dag/store-impl.d.ts.map +1 -1
  137. package/out/replicache/src/dag/store-impl.js +8 -3
  138. package/out/replicache/src/dag/store-impl.js.map +1 -1
  139. package/out/replicache/src/dag/store.js.map +1 -1
  140. package/out/replicache/src/dag/visitor.js.map +1 -1
  141. package/out/replicache/src/db/commit.js.map +1 -1
  142. package/out/replicache/src/db/index.js.map +1 -1
  143. package/out/replicache/src/db/read.js.map +1 -1
  144. package/out/replicache/src/db/rebase.js.map +1 -1
  145. package/out/replicache/src/db/write.js.map +1 -1
  146. package/out/replicache/src/deleted-clients.js.map +1 -1
  147. package/out/replicache/src/error-responses.js.map +1 -1
  148. package/out/replicache/src/frozen-json.js.map +1 -1
  149. package/out/replicache/src/get-default-puller.js.map +1 -1
  150. package/out/replicache/src/get-default-pusher.js.map +1 -1
  151. package/out/replicache/src/get-kv-store-provider.js.map +1 -1
  152. package/out/replicache/src/hash.js.map +1 -1
  153. package/out/replicache/src/http-request-info.js.map +1 -1
  154. package/out/replicache/src/index-defs.js.map +1 -1
  155. package/out/replicache/src/kv/expo-sqlite/store.d.ts +1 -1
  156. package/out/replicache/src/kv/expo-sqlite/store.d.ts.map +1 -1
  157. package/out/replicache/src/kv/expo-sqlite/store.js +6 -7
  158. package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
  159. package/out/replicache/src/kv/idb-store-with-mem-fallback.js.map +1 -1
  160. package/out/replicache/src/kv/idb-store.js.map +1 -1
  161. package/out/replicache/src/kv/mem-store.js.map +1 -1
  162. package/out/replicache/src/kv/op-sqlite/store.d.ts.map +1 -1
  163. package/out/replicache/src/kv/op-sqlite/store.js +6 -6
  164. package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
  165. package/out/replicache/src/kv/read-impl.js.map +1 -1
  166. package/out/replicache/src/kv/sqlite-store.d.ts +6 -6
  167. package/out/replicache/src/kv/sqlite-store.d.ts.map +1 -1
  168. package/out/replicache/src/kv/sqlite-store.js +107 -22
  169. package/out/replicache/src/kv/sqlite-store.js.map +1 -1
  170. package/out/replicache/src/kv/throw-if-closed.d.ts +1 -0
  171. package/out/replicache/src/kv/throw-if-closed.d.ts.map +1 -1
  172. package/out/replicache/src/kv/throw-if-closed.js +1 -4
  173. package/out/replicache/src/kv/throw-if-closed.js.map +1 -1
  174. package/out/replicache/src/kv/write-impl-base.js.map +1 -1
  175. package/out/replicache/src/kv/write-impl.js.map +1 -1
  176. package/out/replicache/src/lazy.js.map +1 -1
  177. package/out/replicache/src/log-options.js.map +1 -1
  178. package/out/replicache/src/make-idb-name.js.map +1 -1
  179. package/out/replicache/src/new-client-channel.js.map +1 -1
  180. package/out/replicache/src/on-persist-channel.js.map +1 -1
  181. package/out/replicache/src/patch-operation.js.map +1 -1
  182. package/out/replicache/src/pending-mutations.js.map +1 -1
  183. package/out/replicache/src/persist/client-gc.js.map +1 -1
  184. package/out/replicache/src/persist/client-group-gc.js.map +1 -1
  185. package/out/replicache/src/persist/client-groups.js +40 -0
  186. package/out/replicache/src/persist/client-groups.js.map +1 -1
  187. package/out/replicache/src/persist/clients.js +28 -0
  188. package/out/replicache/src/persist/clients.js.map +1 -1
  189. package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
  190. package/out/replicache/src/persist/gather-mem-only-visitor.js.map +1 -1
  191. package/out/replicache/src/persist/gather-not-cached-visitor.js.map +1 -1
  192. package/out/replicache/src/persist/heartbeat.js.map +1 -1
  193. package/out/replicache/src/persist/idb-databases-store-db-name.js.map +1 -1
  194. package/out/replicache/src/persist/idb-databases-store.js.map +1 -1
  195. package/out/replicache/src/persist/make-client-id.js.map +1 -1
  196. package/out/replicache/src/persist/persist.d.ts.map +1 -1
  197. package/out/replicache/src/persist/persist.js +4 -2
  198. package/out/replicache/src/persist/persist.js.map +1 -1
  199. package/out/replicache/src/persist/refresh.js.map +1 -1
  200. package/out/replicache/src/process-scheduler.js.map +1 -1
  201. package/out/replicache/src/pusher.js.map +1 -1
  202. package/out/replicache/src/replicache-impl.js.map +1 -1
  203. package/out/replicache/src/report-error.js.map +1 -1
  204. package/out/replicache/src/request-idle.js.map +1 -1
  205. package/out/replicache/src/scan-iterator.js.map +1 -1
  206. package/out/replicache/src/scan-options.js.map +1 -1
  207. package/out/replicache/src/set-interval-with-signal.js.map +1 -1
  208. package/out/replicache/src/subscriptions.js.map +1 -1
  209. package/out/replicache/src/sync/diff.js.map +1 -1
  210. package/out/replicache/src/sync/ids.js.map +1 -1
  211. package/out/replicache/src/sync/patch.js.map +1 -1
  212. package/out/replicache/src/sync/pull-error.js.map +1 -1
  213. package/out/replicache/src/sync/pull.d.ts.map +1 -1
  214. package/out/replicache/src/sync/pull.js +9 -6
  215. package/out/replicache/src/sync/pull.js.map +1 -1
  216. package/out/replicache/src/sync/push.js.map +1 -1
  217. package/out/replicache/src/sync/request-id.js.map +1 -1
  218. package/out/replicache/src/to-error.js.map +1 -1
  219. package/out/replicache/src/transaction-closed-error.js.map +1 -1
  220. package/out/replicache/src/transactions.js.map +1 -1
  221. package/out/replicache/src/with-transactions.js.map +1 -1
  222. package/out/shared/src/abort-error.js.map +1 -1
  223. package/out/shared/src/arrays.js.map +1 -1
  224. package/out/shared/src/asserts.js.map +1 -1
  225. package/out/shared/src/bigint-json.js.map +1 -1
  226. package/out/shared/src/binary-search.js.map +1 -1
  227. package/out/shared/src/broadcast-channel.js.map +1 -1
  228. package/out/shared/src/browser-env.js.map +1 -1
  229. package/out/shared/src/btree-set.js.map +1 -1
  230. package/out/shared/src/cache.js.map +1 -1
  231. package/out/shared/src/centroid.js.map +1 -1
  232. package/out/shared/src/custom-key-map.js.map +1 -1
  233. package/out/shared/src/custom-key-set.js.map +1 -1
  234. package/out/shared/src/deep-clone.js.map +1 -1
  235. package/out/shared/src/deep-merge.js.map +1 -1
  236. package/out/shared/src/document-visible.js.map +1 -1
  237. package/out/shared/src/dotenv.js.map +1 -1
  238. package/out/shared/src/error.js.map +1 -1
  239. package/out/shared/src/hash.js.map +1 -1
  240. package/out/shared/src/iterables.js.map +1 -1
  241. package/out/shared/src/json-schema.js.map +1 -1
  242. package/out/shared/src/json.js.map +1 -1
  243. package/out/shared/src/logging-test-utils.js.map +1 -1
  244. package/out/shared/src/logging.js.map +1 -1
  245. package/out/shared/src/map.d.ts +6 -0
  246. package/out/shared/src/map.d.ts.map +1 -0
  247. package/out/shared/src/map.js +39 -0
  248. package/out/shared/src/map.js.map +1 -0
  249. package/out/shared/src/must.js.map +1 -1
  250. package/out/shared/src/object-traversal.js.map +1 -1
  251. package/out/shared/src/objects.js.map +1 -1
  252. package/out/shared/src/options.js.map +1 -1
  253. package/out/shared/src/parse-big-int.js.map +1 -1
  254. package/out/shared/src/promise-race.js.map +1 -1
  255. package/out/shared/src/queue.d.ts.map +1 -1
  256. package/out/shared/src/queue.js +15 -21
  257. package/out/shared/src/queue.js.map +1 -1
  258. package/out/shared/src/rand.js.map +1 -1
  259. package/out/shared/src/random-uint64.js.map +1 -1
  260. package/out/shared/src/random-values.js.map +1 -1
  261. package/out/shared/src/record-proxy.js.map +1 -1
  262. package/out/shared/src/resolved-promises.js.map +1 -1
  263. package/out/shared/src/ring-buffer.d.ts +32 -0
  264. package/out/shared/src/ring-buffer.d.ts.map +1 -0
  265. package/out/shared/src/ring-buffer.js +109 -0
  266. package/out/shared/src/ring-buffer.js.map +1 -0
  267. package/out/shared/src/sentinels.js.map +1 -1
  268. package/out/shared/src/set-utils.js.map +1 -1
  269. package/out/shared/src/size-of-value.js.map +1 -1
  270. package/out/shared/src/sleep.js.map +1 -1
  271. package/out/shared/src/sorted-entries.js.map +1 -1
  272. package/out/shared/src/string-compare.js.map +1 -1
  273. package/out/shared/src/subscribable.js.map +1 -1
  274. package/out/shared/src/tdigest-schema.js.map +1 -1
  275. package/out/shared/src/tdigest.js.map +1 -1
  276. package/out/shared/src/valita.js.map +1 -1
  277. package/out/z2s/src/compiler.js.map +1 -1
  278. package/out/z2s/src/sql.js.map +1 -1
  279. package/out/zero/package.js +23 -23
  280. package/out/zero/package.js.map +1 -1
  281. package/out/zero/src/build-schema.js.map +1 -1
  282. package/out/zero/src/zero-cache-dev.js.map +1 -1
  283. package/out/zero/src/zero-out.js.map +1 -1
  284. package/out/zero-cache/src/auth/auth.js.map +1 -1
  285. package/out/zero-cache/src/auth/jwt.js.map +1 -1
  286. package/out/zero-cache/src/auth/load-permissions.js.map +1 -1
  287. package/out/zero-cache/src/auth/read-authorizer.js.map +1 -1
  288. package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
  289. package/out/zero-cache/src/config/network.js.map +1 -1
  290. package/out/zero-cache/src/config/normalize.js.map +1 -1
  291. package/out/zero-cache/src/config/server-context.js.map +1 -1
  292. package/out/zero-cache/src/config/zero-config.js +5 -0
  293. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  294. package/out/zero-cache/src/custom/fetch.js.map +1 -1
  295. package/out/zero-cache/src/custom-queries/transform-query.js.map +1 -1
  296. package/out/zero-cache/src/db/create.js.map +1 -1
  297. package/out/zero-cache/src/db/delete-lite-db.js.map +1 -1
  298. package/out/zero-cache/src/db/lite-tables.js.map +1 -1
  299. package/out/zero-cache/src/db/migration-lite.js +19 -0
  300. package/out/zero-cache/src/db/migration-lite.js.map +1 -1
  301. package/out/zero-cache/src/db/migration.js +19 -0
  302. package/out/zero-cache/src/db/migration.js.map +1 -1
  303. package/out/zero-cache/src/db/pg-copy-binary.js.map +1 -1
  304. package/out/zero-cache/src/db/pg-copy.js.map +1 -1
  305. package/out/zero-cache/src/db/pg-to-lite.js.map +1 -1
  306. package/out/zero-cache/src/db/pg-type-parser.js.map +1 -1
  307. package/out/zero-cache/src/db/run-transaction.js.map +1 -1
  308. package/out/zero-cache/src/db/specs.js.map +1 -1
  309. package/out/zero-cache/src/db/statements.js.map +1 -1
  310. package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
  311. package/out/zero-cache/src/db/warmup.js.map +1 -1
  312. package/out/zero-cache/src/observability/events.js.map +1 -1
  313. package/out/zero-cache/src/observability/metrics.js.map +1 -1
  314. package/out/zero-cache/src/scripts/decommission.js.map +1 -1
  315. package/out/zero-cache/src/scripts/deploy-permissions.js.map +1 -1
  316. package/out/zero-cache/src/scripts/permissions.js.map +1 -1
  317. package/out/zero-cache/src/server/anonymous-otel-start.js +11 -10
  318. package/out/zero-cache/src/server/anonymous-otel-start.js.map +1 -1
  319. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  320. package/out/zero-cache/src/server/change-streamer.js +13 -7
  321. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  322. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  323. package/out/zero-cache/src/server/logging.js.map +1 -1
  324. package/out/zero-cache/src/server/main.d.ts.map +1 -1
  325. package/out/zero-cache/src/server/main.js +4 -2
  326. package/out/zero-cache/src/server/main.js.map +1 -1
  327. package/out/zero-cache/src/server/mutator.js +4 -2
  328. package/out/zero-cache/src/server/mutator.js.map +1 -1
  329. package/out/zero-cache/src/server/otel-diag-logger.js.map +1 -1
  330. package/out/zero-cache/src/server/otel-log-sink.js.map +1 -1
  331. package/out/zero-cache/src/server/otel-start.js +1 -1
  332. package/out/zero-cache/src/server/otel-start.js.map +1 -1
  333. package/out/zero-cache/src/server/priority-op.js.map +1 -1
  334. package/out/zero-cache/src/server/reaper.d.ts.map +1 -1
  335. package/out/zero-cache/src/server/reaper.js +6 -4
  336. package/out/zero-cache/src/server/reaper.js.map +1 -1
  337. package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
  338. package/out/zero-cache/src/server/replicator.js +4 -2
  339. package/out/zero-cache/src/server/replicator.js.map +1 -1
  340. package/out/zero-cache/src/server/runner/main.d.ts.map +1 -1
  341. package/out/zero-cache/src/server/runner/main.js +2 -1
  342. package/out/zero-cache/src/server/runner/main.js.map +1 -1
  343. package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
  344. package/out/zero-cache/src/server/runner/runtime.js.map +1 -1
  345. package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
  346. package/out/zero-cache/src/server/shadow-syncer.js +6 -3
  347. package/out/zero-cache/src/server/shadow-syncer.js.map +1 -1
  348. package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
  349. package/out/zero-cache/src/server/syncer.js +8 -6
  350. package/out/zero-cache/src/server/syncer.js.map +1 -1
  351. package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
  352. package/out/zero-cache/src/server/worker-urls.js.map +1 -1
  353. package/out/zero-cache/src/services/analyze.d.ts.map +1 -1
  354. package/out/zero-cache/src/services/analyze.js +5 -2
  355. package/out/zero-cache/src/services/analyze.js.map +1 -1
  356. package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
  357. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
  358. package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
  359. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  360. package/out/zero-cache/src/services/change-source/pg/backfill-metadata.js.map +1 -1
  361. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +2 -2
  362. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
  363. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
  364. package/out/zero-cache/src/services/change-source/pg/change-source.js +2 -2
  365. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  366. package/out/zero-cache/src/services/change-source/pg/decommission.js.map +1 -1
  367. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +8 -2
  368. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
  369. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +13 -12
  370. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  371. package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.js.map +1 -1
  372. package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.js.map +1 -1
  373. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
  374. package/out/zero-cache/src/services/change-source/pg/lsn.js.map +1 -1
  375. package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts +1 -1
  376. package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts.map +1 -1
  377. package/out/zero-cache/src/services/change-source/pg/replication-slots.js +33 -33
  378. package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
  379. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
  380. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  381. package/out/zero-cache/src/services/change-source/pg/schema/published.js.map +1 -1
  382. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +1 -1
  383. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  384. package/out/zero-cache/src/services/change-source/pg/schema/validation.js.map +1 -1
  385. package/out/zero-cache/src/services/change-source/protocol/current/control.js.map +1 -1
  386. package/out/zero-cache/src/services/change-source/protocol/current/data.js +2 -0
  387. package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
  388. package/out/zero-cache/src/services/change-source/protocol/current/downstream.js.map +1 -1
  389. package/out/zero-cache/src/services/change-source/protocol/current/json.js.map +1 -1
  390. package/out/zero-cache/src/services/change-source/protocol/current/status.js.map +1 -1
  391. package/out/zero-cache/src/services/change-source/protocol/current/upstream.js.map +1 -1
  392. package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
  393. package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
  394. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  395. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  396. package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
  397. package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
  398. package/out/zero-cache/src/services/change-streamer/replica-monitor.js.map +1 -1
  399. package/out/zero-cache/src/services/change-streamer/schema/init.js +21 -25
  400. package/out/zero-cache/src/services/change-streamer/schema/init.js.map +1 -1
  401. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts.map +1 -1
  402. package/out/zero-cache/src/services/change-streamer/schema/tables.js +1 -1
  403. package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
  404. package/out/zero-cache/src/services/change-streamer/snapshot.js +15 -0
  405. package/out/zero-cache/src/services/change-streamer/snapshot.js.map +1 -1
  406. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  407. package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
  408. package/out/zero-cache/src/services/heapz.js.map +1 -1
  409. package/out/zero-cache/src/services/http-service.js.map +1 -1
  410. package/out/zero-cache/src/services/life-cycle.d.ts +1 -1
  411. package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
  412. package/out/zero-cache/src/services/life-cycle.js +8 -3
  413. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  414. package/out/zero-cache/src/services/limiter/sliding-window-limiter.js.map +1 -1
  415. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  416. package/out/zero-cache/src/services/mutagen/error.js.map +1 -1
  417. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  418. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  419. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  420. package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
  421. package/out/zero-cache/src/services/replicator/notifier.js.map +1 -1
  422. package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
  423. package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
  424. package/out/zero-cache/src/services/replicator/reporter/recorder.js.map +1 -1
  425. package/out/zero-cache/src/services/replicator/reporter/report-schema.js.map +1 -1
  426. package/out/zero-cache/src/services/replicator/schema/change-log.js.map +1 -1
  427. package/out/zero-cache/src/services/replicator/schema/column-metadata.js.map +1 -1
  428. package/out/zero-cache/src/services/replicator/schema/replication-state.js.map +1 -1
  429. package/out/zero-cache/src/services/replicator/schema/table-metadata.js.map +1 -1
  430. package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
  431. package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
  432. package/out/zero-cache/src/services/run-ast.d.ts.map +1 -1
  433. package/out/zero-cache/src/services/run-ast.js +1 -0
  434. package/out/zero-cache/src/services/run-ast.js.map +1 -1
  435. package/out/zero-cache/src/services/runner.js.map +1 -1
  436. package/out/zero-cache/src/services/running-state.d.ts.map +1 -1
  437. package/out/zero-cache/src/services/running-state.js +3 -0
  438. package/out/zero-cache/src/services/running-state.js.map +1 -1
  439. package/out/zero-cache/src/services/shadow-sync/shadow-sync-service.js.map +1 -1
  440. package/out/zero-cache/src/services/statz.js.map +1 -1
  441. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js.map +1 -1
  442. package/out/zero-cache/src/services/view-syncer/client-handler.js +1 -1
  443. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  444. package/out/zero-cache/src/services/view-syncer/client-schema.js.map +1 -1
  445. package/out/zero-cache/src/services/view-syncer/connection-context-manager.js.map +1 -1
  446. package/out/zero-cache/src/services/view-syncer/cvr-purger.d.ts.map +1 -1
  447. package/out/zero-cache/src/services/view-syncer/cvr-purger.js +2 -1
  448. package/out/zero-cache/src/services/view-syncer/cvr-purger.js.map +1 -1
  449. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  450. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  451. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
  452. package/out/zero-cache/src/services/view-syncer/inspect-handler.js +1 -1
  453. package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
  454. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +1 -1
  455. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  456. package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
  457. package/out/zero-cache/src/services/view-syncer/row-set-signature.js.map +1 -1
  458. package/out/zero-cache/src/services/view-syncer/schema/cvr.js.map +1 -1
  459. package/out/zero-cache/src/services/view-syncer/schema/init.js +97 -113
  460. package/out/zero-cache/src/services/view-syncer/schema/init.js.map +1 -1
  461. package/out/zero-cache/src/services/view-syncer/schema/types.js +103 -1
  462. package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
  463. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  464. package/out/zero-cache/src/services/view-syncer/tracer.js.map +1 -1
  465. package/out/zero-cache/src/services/view-syncer/ttl-clock.js.map +1 -1
  466. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  467. package/out/zero-cache/src/services/view-syncer/view-syncer.js +15 -5
  468. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  469. package/out/zero-cache/src/types/configuration-error.d.ts +4 -0
  470. package/out/zero-cache/src/types/configuration-error.d.ts.map +1 -0
  471. package/out/zero-cache/src/types/configuration-error.js +11 -0
  472. package/out/zero-cache/src/types/configuration-error.js.map +1 -0
  473. package/out/zero-cache/src/types/error-with-level.js.map +1 -1
  474. package/out/zero-cache/src/types/http.js.map +1 -1
  475. package/out/zero-cache/src/types/lexi-version.js.map +1 -1
  476. package/out/zero-cache/src/types/lite.js.map +1 -1
  477. package/out/zero-cache/src/types/names.js.map +1 -1
  478. package/out/zero-cache/src/types/pg-data-type.js.map +1 -1
  479. package/out/zero-cache/src/types/pg.d.ts +2 -0
  480. package/out/zero-cache/src/types/pg.d.ts.map +1 -1
  481. package/out/zero-cache/src/types/pg.js +34 -1
  482. package/out/zero-cache/src/types/pg.js.map +1 -1
  483. package/out/zero-cache/src/types/processes.js.map +1 -1
  484. package/out/zero-cache/src/types/profiler.js.map +1 -1
  485. package/out/zero-cache/src/types/row-key.js.map +1 -1
  486. package/out/zero-cache/src/types/shards.js.map +1 -1
  487. package/out/zero-cache/src/types/sql.js.map +1 -1
  488. package/out/zero-cache/src/types/state-version.js.map +1 -1
  489. package/out/zero-cache/src/types/streams.js.map +1 -1
  490. package/out/zero-cache/src/types/strings.js.map +1 -1
  491. package/out/zero-cache/src/types/subscription.js.map +1 -1
  492. package/out/zero-cache/src/types/timeout.js.map +1 -1
  493. package/out/zero-cache/src/types/url-params.js.map +1 -1
  494. package/out/zero-cache/src/types/websocket-handoff.js.map +1 -1
  495. package/out/zero-cache/src/types/ws.js.map +1 -1
  496. package/out/zero-cache/src/workers/connect-params.js.map +1 -1
  497. package/out/zero-cache/src/workers/connection.js.map +1 -1
  498. package/out/zero-cache/src/workers/mutator.js.map +1 -1
  499. package/out/zero-cache/src/workers/replicator.js.map +1 -1
  500. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  501. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  502. package/out/zero-client/src/client/active-clients-manager.js.map +1 -1
  503. package/out/zero-client/src/client/connection-manager.js +2 -1
  504. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  505. package/out/zero-client/src/client/connection.js.map +1 -1
  506. package/out/zero-client/src/client/context.js.map +1 -1
  507. package/out/zero-client/src/client/crud-impl.js.map +1 -1
  508. package/out/zero-client/src/client/crud.js.map +1 -1
  509. package/out/zero-client/src/client/custom.js +2 -1
  510. package/out/zero-client/src/client/custom.js.map +1 -1
  511. package/out/zero-client/src/client/delete-clients-manager.js.map +1 -1
  512. package/out/zero-client/src/client/enable-analytics.js.map +1 -1
  513. package/out/zero-client/src/client/error.js.map +1 -1
  514. package/out/zero-client/src/client/http-string.js.map +1 -1
  515. package/out/zero-client/src/client/inspector/client-group.js.map +1 -1
  516. package/out/zero-client/src/client/inspector/client.js.map +1 -1
  517. package/out/zero-client/src/client/inspector/html-dialog-prompt.js.map +1 -1
  518. package/out/zero-client/src/client/inspector/inspector.js.map +1 -1
  519. package/out/zero-client/src/client/inspector/lazy-inspector.js.map +1 -1
  520. package/out/zero-client/src/client/inspector/query.js.map +1 -1
  521. package/out/zero-client/src/client/ivm-branch.js.map +1 -1
  522. package/out/zero-client/src/client/keys.js.map +1 -1
  523. package/out/zero-client/src/client/log-options.js.map +1 -1
  524. package/out/zero-client/src/client/make-mutate-property.js.map +1 -1
  525. package/out/zero-client/src/client/make-replicache-mutators.js.map +1 -1
  526. package/out/zero-client/src/client/metrics.js.map +1 -1
  527. package/out/zero-client/src/client/mutation-tracker.js.map +1 -1
  528. package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
  529. package/out/zero-client/src/client/options.js.map +1 -1
  530. package/out/zero-client/src/client/query-manager.js.map +1 -1
  531. package/out/zero-client/src/client/reload-error-handler.js.map +1 -1
  532. package/out/zero-client/src/client/server-option.js.map +1 -1
  533. package/out/zero-client/src/client/version.js +1 -1
  534. package/out/zero-client/src/client/zero-poke-handler.js.map +1 -1
  535. package/out/zero-client/src/client/zero-rep.js.map +1 -1
  536. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  537. package/out/zero-client/src/client/zero.js +58 -32
  538. package/out/zero-client/src/client/zero.js.map +1 -1
  539. package/out/zero-client/src/util/nanoid.js.map +1 -1
  540. package/out/zero-protocol/src/analyze-query-result.js +3 -0
  541. package/out/zero-protocol/src/analyze-query-result.js.map +1 -1
  542. package/out/zero-protocol/src/application-error.js.map +1 -1
  543. package/out/zero-protocol/src/ast.js.map +1 -1
  544. package/out/zero-protocol/src/change-desired-queries.js +1 -0
  545. package/out/zero-protocol/src/change-desired-queries.js.map +1 -1
  546. package/out/zero-protocol/src/client-schema.js.map +1 -1
  547. package/out/zero-protocol/src/close-connection.js.map +1 -1
  548. package/out/zero-protocol/src/connect.js +7 -0
  549. package/out/zero-protocol/src/connect.js.map +1 -1
  550. package/out/zero-protocol/src/custom-queries.js.map +1 -1
  551. package/out/zero-protocol/src/data.js.map +1 -1
  552. package/out/zero-protocol/src/delete-clients.js.map +1 -1
  553. package/out/zero-protocol/src/down.js.map +1 -1
  554. package/out/zero-protocol/src/error.js +7 -0
  555. package/out/zero-protocol/src/error.js.map +1 -1
  556. package/out/zero-protocol/src/inspect-down.js.map +1 -1
  557. package/out/zero-protocol/src/inspect-up.js +1 -0
  558. package/out/zero-protocol/src/inspect-up.js.map +1 -1
  559. package/out/zero-protocol/src/mutate-server.js.map +1 -1
  560. package/out/zero-protocol/src/mutation-id.js.map +1 -1
  561. package/out/zero-protocol/src/mutation.js.map +1 -1
  562. package/out/zero-protocol/src/mutations-patch.js.map +1 -1
  563. package/out/zero-protocol/src/ping.js.map +1 -1
  564. package/out/zero-protocol/src/poke.js +4 -0
  565. package/out/zero-protocol/src/poke.js.map +1 -1
  566. package/out/zero-protocol/src/pong.js.map +1 -1
  567. package/out/zero-protocol/src/primary-key.js.map +1 -1
  568. package/out/zero-protocol/src/protocol-version.js.map +1 -1
  569. package/out/zero-protocol/src/pull.js.map +1 -1
  570. package/out/zero-protocol/src/push.js +16 -0
  571. package/out/zero-protocol/src/push.js.map +1 -1
  572. package/out/zero-protocol/src/queries-patch.js.map +1 -1
  573. package/out/zero-protocol/src/query-hash.js.map +1 -1
  574. package/out/zero-protocol/src/query-server.js.map +1 -1
  575. package/out/zero-protocol/src/row-patch.js.map +1 -1
  576. package/out/zero-protocol/src/up.js.map +1 -1
  577. package/out/zero-protocol/src/update-auth.js.map +1 -1
  578. package/out/zero-protocol/src/version.js.map +1 -1
  579. package/out/zero-react/src/use-connection-state.js +4 -2
  580. package/out/zero-react/src/use-connection-state.js.map +1 -1
  581. package/out/zero-react/src/use-query.js +6 -4
  582. package/out/zero-react/src/use-query.js.map +1 -1
  583. package/out/zero-react/src/use-zero-online.js +4 -2
  584. package/out/zero-react/src/use-zero-online.js.map +1 -1
  585. package/out/zero-react/src/zero-provider.js +15 -12
  586. package/out/zero-react/src/zero-provider.js.map +1 -1
  587. package/out/zero-schema/src/builder/relationship-builder.js.map +1 -1
  588. package/out/zero-schema/src/builder/schema-builder.js.map +1 -1
  589. package/out/zero-schema/src/builder/table-builder.js.map +1 -1
  590. package/out/zero-schema/src/compiled-permissions.js.map +1 -1
  591. package/out/zero-schema/src/name-mapper.js.map +1 -1
  592. package/out/zero-schema/src/permissions.js.map +1 -1
  593. package/out/zero-schema/src/schema-config.js.map +1 -1
  594. package/out/zero-server/src/adapters/drizzle.js.map +1 -1
  595. package/out/zero-server/src/adapters/kysely.js.map +1 -1
  596. package/out/zero-server/src/adapters/pg.js +1 -1
  597. package/out/zero-server/src/adapters/pg.js.map +1 -1
  598. package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
  599. package/out/zero-server/src/adapters/prisma.js.map +1 -1
  600. package/out/zero-server/src/custom.js +2 -1
  601. package/out/zero-server/src/custom.js.map +1 -1
  602. package/out/zero-server/src/logging.js.map +1 -1
  603. package/out/zero-server/src/pg-query-executor.js.map +1 -1
  604. package/out/zero-server/src/process-mutations.js.map +1 -1
  605. package/out/zero-server/src/push-processor.js.map +1 -1
  606. package/out/zero-server/src/queries/process-queries.js.map +1 -1
  607. package/out/zero-server/src/schema.js.map +1 -1
  608. package/out/zero-server/src/zql-database.js.map +1 -1
  609. package/out/zero-solid/src/solid-view.js +1 -1
  610. package/out/zero-solid/src/solid-view.js.map +1 -1
  611. package/out/zero-solid/src/use-connection-state.js +1 -1
  612. package/out/zero-solid/src/use-connection-state.js.map +1 -1
  613. package/out/zero-solid/src/use-query.js +2 -2
  614. package/out/zero-solid/src/use-query.js.map +1 -1
  615. package/out/zero-solid/src/use-zero-online.js +1 -1
  616. package/out/zero-solid/src/use-zero-online.js.map +1 -1
  617. package/out/zero-solid/src/use-zero.js +1 -1
  618. package/out/zero-solid/src/use-zero.js.map +1 -1
  619. package/out/zero-types/src/format.js.map +1 -1
  620. package/out/zero-types/src/name-mapper.js.map +1 -1
  621. package/out/zql/src/builder/builder.d.ts.map +1 -1
  622. package/out/zql/src/builder/builder.js +18 -7
  623. package/out/zql/src/builder/builder.js.map +1 -1
  624. package/out/zql/src/builder/debug-delegate.d.ts +5 -0
  625. package/out/zql/src/builder/debug-delegate.d.ts.map +1 -1
  626. package/out/zql/src/builder/debug-delegate.js +10 -1
  627. package/out/zql/src/builder/debug-delegate.js.map +1 -1
  628. package/out/zql/src/builder/filter.js.map +1 -1
  629. package/out/zql/src/builder/like.js.map +1 -1
  630. package/out/zql/src/error.js.map +1 -1
  631. package/out/zql/src/ivm/array-view.js.map +1 -1
  632. package/out/zql/src/ivm/cap.d.ts +32 -0
  633. package/out/zql/src/ivm/cap.d.ts.map +1 -0
  634. package/out/zql/src/ivm/cap.js +205 -0
  635. package/out/zql/src/ivm/cap.js.map +1 -0
  636. package/out/zql/src/ivm/change.js.map +1 -1
  637. package/out/zql/src/ivm/constraint.js +1 -1
  638. package/out/zql/src/ivm/constraint.js.map +1 -1
  639. package/out/zql/src/ivm/data.js.map +1 -1
  640. package/out/zql/src/ivm/exists.js.map +1 -1
  641. package/out/zql/src/ivm/fan-in.js.map +1 -1
  642. package/out/zql/src/ivm/fan-out.js.map +1 -1
  643. package/out/zql/src/ivm/filter-operators.js.map +1 -1
  644. package/out/zql/src/ivm/filter-push.js.map +1 -1
  645. package/out/zql/src/ivm/filter.js.map +1 -1
  646. package/out/zql/src/ivm/flipped-join.d.ts +4 -8
  647. package/out/zql/src/ivm/flipped-join.d.ts.map +1 -1
  648. package/out/zql/src/ivm/flipped-join.js +59 -63
  649. package/out/zql/src/ivm/flipped-join.js.map +1 -1
  650. package/out/zql/src/ivm/join-utils.js.map +1 -1
  651. package/out/zql/src/ivm/join.js.map +1 -1
  652. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  653. package/out/zql/src/ivm/memory-source.js +1 -1
  654. package/out/zql/src/ivm/memory-source.js.map +1 -1
  655. package/out/zql/src/ivm/memory-storage.js.map +1 -1
  656. package/out/zql/src/ivm/operator.d.ts +1 -1
  657. package/out/zql/src/ivm/operator.js.map +1 -1
  658. package/out/zql/src/ivm/push-accumulated.js.map +1 -1
  659. package/out/zql/src/ivm/schema.d.ts +0 -8
  660. package/out/zql/src/ivm/schema.d.ts.map +1 -1
  661. package/out/zql/src/ivm/skip-yields.js.map +1 -1
  662. package/out/zql/src/ivm/skip.js.map +1 -1
  663. package/out/zql/src/ivm/source.js.map +1 -1
  664. package/out/zql/src/ivm/stream.js.map +1 -1
  665. package/out/zql/src/ivm/take.js +2 -2
  666. package/out/zql/src/ivm/take.js.map +1 -1
  667. package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
  668. package/out/zql/src/ivm/union-fan-in.js +3 -1
  669. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  670. package/out/zql/src/ivm/union-fan-out.js.map +1 -1
  671. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  672. package/out/zql/src/mutate/crud.js.map +1 -1
  673. package/out/zql/src/mutate/custom.js.map +1 -1
  674. package/out/zql/src/mutate/mutator-registry.js.map +1 -1
  675. package/out/zql/src/mutate/mutator.d.ts +12 -3
  676. package/out/zql/src/mutate/mutator.d.ts.map +1 -1
  677. package/out/zql/src/mutate/mutator.js.map +1 -1
  678. package/out/zql/src/planner/planner-builder.js.map +1 -1
  679. package/out/zql/src/planner/planner-connection.js.map +1 -1
  680. package/out/zql/src/planner/planner-constraint.js.map +1 -1
  681. package/out/zql/src/planner/planner-debug.js.map +1 -1
  682. package/out/zql/src/planner/planner-fan-in.js.map +1 -1
  683. package/out/zql/src/planner/planner-fan-out.js.map +1 -1
  684. package/out/zql/src/planner/planner-graph.js.map +1 -1
  685. package/out/zql/src/planner/planner-join.d.ts.map +1 -1
  686. package/out/zql/src/planner/planner-join.js +2 -1
  687. package/out/zql/src/planner/planner-join.js.map +1 -1
  688. package/out/zql/src/planner/planner-node.js.map +1 -1
  689. package/out/zql/src/planner/planner-source.js.map +1 -1
  690. package/out/zql/src/planner/planner-terminus.js.map +1 -1
  691. package/out/zql/src/query/complete-ordering.js.map +1 -1
  692. package/out/zql/src/query/create-builder.js.map +1 -1
  693. package/out/zql/src/query/error.js.map +1 -1
  694. package/out/zql/src/query/escape-like.js.map +1 -1
  695. package/out/zql/src/query/expression.js.map +1 -1
  696. package/out/zql/src/query/measure-push-operator.js.map +1 -1
  697. package/out/zql/src/query/metrics-delegate.js.map +1 -1
  698. package/out/zql/src/query/named.js.map +1 -1
  699. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  700. package/out/zql/src/query/query-impl.js +1 -1
  701. package/out/zql/src/query/query-impl.js.map +1 -1
  702. package/out/zql/src/query/query-internals.js.map +1 -1
  703. package/out/zql/src/query/query-registry.d.ts +10 -3
  704. package/out/zql/src/query/query-registry.d.ts.map +1 -1
  705. package/out/zql/src/query/query-registry.js.map +1 -1
  706. package/out/zql/src/query/runnable-query-impl.js.map +1 -1
  707. package/out/zql/src/query/static-query.js.map +1 -1
  708. package/out/zql/src/query/ttl.js.map +1 -1
  709. package/out/zql/src/query/validate-input.js.map +1 -1
  710. package/out/zqlite/src/database-storage.js.map +1 -1
  711. package/out/zqlite/src/db.js.map +1 -1
  712. package/out/zqlite/src/explain-queries.js.map +1 -1
  713. package/out/zqlite/src/internal/sql-inline.js.map +1 -1
  714. package/out/zqlite/src/internal/sql.js.map +1 -1
  715. package/out/zqlite/src/internal/statement-cache.js.map +1 -1
  716. package/out/zqlite/src/query-builder.js.map +1 -1
  717. package/out/zqlite/src/query-delegate.js.map +1 -1
  718. package/out/zqlite/src/resolve-scalar-subqueries.js.map +1 -1
  719. package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
  720. package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
  721. package/out/zqlite/src/table-source.d.ts.map +1 -1
  722. package/out/zqlite/src/table-source.js +7 -7
  723. package/out/zqlite/src/table-source.js.map +1 -1
  724. package/package.json +23 -23
  725. package/out/zero-client/src/util/socket.d.ts +0 -3
  726. package/out/zero-client/src/util/socket.d.ts.map +0 -1
  727. package/out/zero-client/src/util/socket.js +0 -8
  728. package/out/zero-client/src/util/socket.js.map +0 -1
@@ -3,14 +3,10 @@ import type { Read, Store, Write } from './store.ts';
3
3
  import { WriteImplBase } from './write-impl-base.ts';
4
4
  /**
5
5
  * A SQLite prepared statement.
6
- *
7
- * `run` executes the statement with optional parameters.
8
- * `all` executes the statement and returns the result rows.
9
- * `finalize` releases the statement.
10
6
  */
11
7
  export interface PreparedStatement {
12
- firstValue(params: string[]): Promise<unknown>;
13
8
  exec(params: string[]): Promise<void>;
9
+ all(params: string[]): Promise<unknown[][]>;
14
10
  }
15
11
  export interface SQLiteDatabase {
16
12
  /**
@@ -47,6 +43,8 @@ export declare function safeFilename(name: string): string;
47
43
  export type PreparedStatements = {
48
44
  has: PreparedStatement;
49
45
  get: PreparedStatement;
46
+ hasMany: PreparedStatement;
47
+ getMany: PreparedStatement;
50
48
  put: PreparedStatement;
51
49
  del: PreparedStatement;
52
50
  };
@@ -55,6 +53,8 @@ export interface SQLiteStoreOptions {
55
53
  journalMode?: 'WAL' | 'DELETE';
56
54
  synchronous?: 'NORMAL' | 'FULL';
57
55
  readUncommitted?: boolean;
56
+ /** Directory in which to create the SQLite file. Defaults to the process CWD. */
57
+ directory?: string | undefined;
58
58
  }
59
59
  /**
60
60
  * Common database setup logic shared between expo-sqlite and op-sqlite implementations.
@@ -77,5 +77,5 @@ export declare class SQLiteWrite extends WriteImplBase implements Write {
77
77
  get closed(): boolean;
78
78
  }
79
79
  export declare function clearAllNamedStoresForTesting(): void;
80
- export declare function dropStore(name: string, createDelegate: (filename: string, opts?: SQLiteStoreOptions) => SQLiteDatabase): Promise<void>;
80
+ export declare function dropStore(name: string, createDelegate: (filename: string, opts?: SQLiteStoreOptions) => SQLiteDatabase, opts?: SQLiteStoreOptions): Promise<void>;
81
81
  //# sourceMappingURL=sqlite-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite-store.d.ts","sourceRoot":"","sources":["../../../../../replicache/src/kv/sqlite-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sqlite-store.d.ts","sourceRoot":"","sources":["../../../../../replicache/src/kv/sqlite-store.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { deepFreeze } from "../frozen-json.js";
2
- import { throwIfStoreClosed, throwIfTransactionClosed, transactionIsClosedRejection } from "./throw-if-closed.js";
2
+ import { maybeTransactionIsClosedRejection, throwIfStoreClosed, transactionError } from "./throw-if-closed.js";
3
3
  import { WriteImplBase, deleteSentinel } from "./write-impl-base.js";
4
4
  import { RWLock } from "@rocicorp/lock";
5
5
  //#region ../replicache/src/kv/sqlite-store.ts
@@ -14,8 +14,8 @@ var SQLiteStore = class {
14
14
  #entry;
15
15
  #closed = false;
16
16
  constructor(name, create, opts) {
17
- this.#filename = safeFilename(name);
18
- this.#entry = getOrCreateEntry(name, create, opts);
17
+ this.#filename = resolveFilename(name, opts);
18
+ this.#entry = getOrCreateEntry(this.#filename, create, opts);
19
19
  }
20
20
  async read() {
21
21
  throwIfStoreClosed(this);
@@ -52,6 +52,11 @@ var SQLiteStore = class {
52
52
  function safeFilename(name) {
53
53
  return name.replace(/[^a-zA-Z0-9]/g, "_");
54
54
  }
55
+ function resolveFilename(name, opts) {
56
+ const safe = safeFilename(name);
57
+ const dir = opts?.directory;
58
+ return dir ? `${dir}/${safe}` : safe;
59
+ }
55
60
  /**
56
61
  * Common database setup logic shared between expo-sqlite and op-sqlite implementations.
57
62
  * Configures SQLite pragmas, creates the entry table, and prepares common statements.
@@ -70,28 +75,110 @@ function setupDatabase(delegate, opts) {
70
75
  return {
71
76
  has: delegate.prepare(`SELECT 1 FROM entry WHERE key = ? LIMIT 1`),
72
77
  get: delegate.prepare("SELECT value FROM entry WHERE key = ?"),
78
+ hasMany: delegate.prepare(`SELECT key FROM entry WHERE key IN (SELECT value FROM json_each(?))`),
79
+ getMany: delegate.prepare(`SELECT key, value FROM entry WHERE key IN (SELECT value FROM json_each(?))`),
73
80
  put: delegate.prepare(`INSERT OR REPLACE INTO entry (key, value)
74
81
  SELECT e.value->>0, e.value->1 FROM json_each(?) e`),
75
82
  del: delegate.prepare(`DELETE FROM entry WHERE key IN (SELECT value FROM json_each(?))`)
76
83
  };
77
84
  }
85
+ var CB_STRIDE = 2;
86
+ var CB_RESOLVE = 0;
87
+ var CB_REJECT = 1;
88
+ function rejectAll(callbacks, e) {
89
+ for (let i = CB_REJECT; i < callbacks.length; i += CB_STRIDE) callbacks[i](e);
90
+ }
91
+ function parseRawValue(raw) {
92
+ return raw === void 0 ? void 0 : deepFreeze(JSON.parse(raw));
93
+ }
94
+ function resolveGet(resolve, reject, raw) {
95
+ try {
96
+ resolve(parseRawValue(raw));
97
+ } catch (e) {
98
+ reject(e);
99
+ }
100
+ }
101
+ async function flushGets(keys, callbacks, ps) {
102
+ let rows;
103
+ try {
104
+ rows = keys.length === 1 ? await ps.get.all([keys[0]]) : await ps.getMany.all([JSON.stringify(keys)]);
105
+ } catch (e) {
106
+ rejectAll(callbacks, e);
107
+ return;
108
+ }
109
+ if (keys.length === 1) {
110
+ resolveGet(callbacks[CB_RESOLVE], callbacks[CB_REJECT], rows[0]?.[0]);
111
+ return;
112
+ }
113
+ const resultMap = new Map(rows);
114
+ for (let i = 0; i < keys.length; i++) resolveGet(callbacks[i * CB_STRIDE + CB_RESOLVE], callbacks[i * CB_STRIDE + CB_REJECT], resultMap.get(keys[i]));
115
+ }
116
+ async function flushHas(keys, callbacks, ps) {
117
+ let rows;
118
+ try {
119
+ rows = keys.length === 1 ? await ps.has.all([keys[0]]) : await ps.hasMany.all([JSON.stringify(keys)]);
120
+ } catch (e) {
121
+ rejectAll(callbacks, e);
122
+ return;
123
+ }
124
+ if (keys.length === 1) {
125
+ callbacks[CB_RESOLVE](rows.length > 0);
126
+ return;
127
+ }
128
+ const existingKeys = new Set(rows.map((row) => row[0]));
129
+ for (let i = 0; i < keys.length; i++) callbacks[i * CB_STRIDE + CB_RESOLVE](existingKeys.has(keys[i]));
130
+ }
78
131
  var SQLiteStoreRead = class {
79
132
  #release;
80
- #closed = false;
81
133
  #preparedStatements;
134
+ #closed = false;
135
+ #pendingGetKeys = [];
136
+ #pendingGetCallbacks = [];
137
+ #pendingHasKeys = [];
138
+ #pendingHasCallbacks = [];
139
+ #scheduled = false;
82
140
  constructor(release, preparedStatements) {
83
141
  this.#release = release;
84
142
  this.#preparedStatements = preparedStatements;
85
143
  }
86
- async has(key) {
87
- throwIfTransactionClosed(this);
88
- return await this.#preparedStatements.has.firstValue([key]) !== void 0;
144
+ has(key) {
145
+ return maybeTransactionIsClosedRejection(this) ?? new Promise((resolve, reject) => {
146
+ this.#pendingHasKeys.push(key);
147
+ this.#pendingHasCallbacks.push(resolve, reject);
148
+ this.#scheduleLookup();
149
+ });
89
150
  }
90
- async get(key) {
91
- throwIfTransactionClosed(this);
92
- const value = await this.#preparedStatements.get.firstValue([key]);
93
- if (!value) return;
94
- return deepFreeze(JSON.parse(value));
151
+ get(key) {
152
+ return maybeTransactionIsClosedRejection(this) ?? new Promise((resolve, reject) => {
153
+ this.#pendingGetKeys.push(key);
154
+ this.#pendingGetCallbacks.push(resolve, reject);
155
+ this.#scheduleLookup();
156
+ });
157
+ }
158
+ #scheduleLookup() {
159
+ if (!this.#scheduled) {
160
+ this.#scheduled = true;
161
+ queueMicrotask(() => {
162
+ this.#scheduled = false;
163
+ const ps = this.#preparedStatements;
164
+ const getKeys = this.#pendingGetKeys;
165
+ this.#pendingGetKeys = [];
166
+ const getCallbacks = this.#pendingGetCallbacks;
167
+ this.#pendingGetCallbacks = [];
168
+ const hasKeys = this.#pendingHasKeys;
169
+ this.#pendingHasKeys = [];
170
+ const hasCallbacks = this.#pendingHasCallbacks;
171
+ this.#pendingHasCallbacks = [];
172
+ if (this.#closed) {
173
+ const e = transactionError();
174
+ rejectAll(getCallbacks, e);
175
+ rejectAll(hasCallbacks, e);
176
+ return;
177
+ }
178
+ if (getKeys.length > 0) flushGets(getKeys, getCallbacks, ps);
179
+ if (hasKeys.length > 0) flushHas(hasKeys, hasCallbacks, ps);
180
+ });
181
+ }
95
182
  }
96
183
  release() {
97
184
  if (!this.#closed) {
@@ -116,17 +203,16 @@ var SQLiteWrite = class extends WriteImplBase {
116
203
  this.#preparedStatements = preparedStatements;
117
204
  }
118
205
  async commit() {
119
- if (this.#closed) return transactionIsClosedRejection();
206
+ if (this.#closed) throw transactionError();
120
207
  const deleteKeys = [];
121
208
  for (const entry of this._pending) if (entry[1] === deleteSentinel) {
122
209
  deleteKeys.push(entry[0]);
123
210
  this._pending.delete(entry[0]);
124
211
  }
125
212
  const delP = deleteKeys.length > 0 ? this.#preparedStatements.del.exec([JSON.stringify(deleteKeys)]) : void 0;
126
- const upP = this._pending.size > 0 ? this.#preparedStatements.put.exec([JSON.stringify([...this._pending])]) : void 0;
127
- if (delP && upP) await Promise.all([delP, upP]);
128
- else if (delP) await delP;
129
- else if (upP) await upP;
213
+ const putP = this._pending.size > 0 ? this.#preparedStatements.put.exec([JSON.stringify([...this._pending])]) : void 0;
214
+ if (putP) await putP;
215
+ if (delP) await delP;
130
216
  this.#dbDelegate.execSync("COMMIT");
131
217
  this._pending.clear();
132
218
  this.#committed = true;
@@ -155,8 +241,7 @@ var stores = /* @__PURE__ */ new Map();
155
241
  * This implements the shared connection pattern where multiple stores with the same
156
242
  * name share the same database connection, lock, and delegate.
157
243
  */
158
- function getOrCreateEntry(name, create, opts) {
159
- const filename = safeFilename(name);
244
+ function getOrCreateEntry(filename, create, opts) {
160
245
  const entry = stores.get(filename);
161
246
  if (entry) {
162
247
  entry.refCount++;
@@ -192,8 +277,8 @@ function clearAllNamedStoresForTesting() {
192
277
  for (const entry of stores.values()) entry.db.close();
193
278
  stores.clear();
194
279
  }
195
- function dropStore(name, createDelegate) {
196
- const filename = safeFilename(name);
280
+ function dropStore(name, createDelegate, opts) {
281
+ const filename = resolveFilename(name, opts);
197
282
  const entry = stores.get(filename);
198
283
  if (entry) {
199
284
  try {
@@ -201,7 +286,7 @@ function dropStore(name, createDelegate) {
201
286
  } catch {}
202
287
  stores.delete(filename);
203
288
  }
204
- const tempDelegate = createDelegate(filename);
289
+ const tempDelegate = createDelegate(filename, opts);
205
290
  try {
206
291
  tempDelegate.close();
207
292
  } catch {}
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite-store.js","names":["#filename","#entry","#closed","#release","#preparedStatements","#dbDelegate","#committed"],"sources":["../../../../../replicache/src/kv/sqlite-store.ts"],"sourcesContent":["import {RWLock} from '@rocicorp/lock';\nimport type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {deepFreeze} from '../frozen-json.ts';\nimport type {Read, Store, Write} from './store.ts';\nimport {\n throwIfStoreClosed,\n throwIfTransactionClosed,\n transactionIsClosedRejection,\n} from './throw-if-closed.ts';\nimport {deleteSentinel, WriteImplBase} from './write-impl-base.ts';\n\n/**\n * A SQLite prepared statement.\n *\n * `run` executes the statement with optional parameters.\n * `all` executes the statement and returns the result rows.\n * `finalize` releases the statement.\n */\nexport interface PreparedStatement {\n firstValue(params: string[]): Promise<unknown>;\n exec(params: string[]): Promise<void>;\n}\n\nexport interface SQLiteDatabase {\n /**\n * Close the database connection.\n */\n close(): void;\n\n /**\n * Destroy or delete the database (e.g. delete file).\n */\n destroy(): void;\n\n /**\n * Prepare a SQL string, returning a statement you can execute.\n * E.g. `const stmt = db.prepare(\"SELECT * FROM todos WHERE id=?\");`\n */\n prepare(sql: string): PreparedStatement;\n\n // for PRAGMA statements, schema creation and transaction control.\n execSync(sql: string): void;\n}\n\nexport type CreateSQLiteDatabase = (\n filename: string,\n opts?: SQLiteStoreOptions,\n) => SQLiteDatabase;\n\n/**\n * SQLite-based implementation of the Store interface using a configurable delegate.\n * Supports shared connections between multiple store instances with the same name,\n * providing efficient resource utilization and proper transaction isolation.\n * Uses parameterized queries for safety and performance.\n */\nexport class SQLiteStore implements Store {\n readonly #filename: string;\n readonly #entry: StoreEntry;\n\n #closed = false;\n\n constructor(\n name: string,\n create: CreateSQLiteDatabase,\n opts?: SQLiteStoreOptions,\n ) {\n this.#filename = safeFilename(name);\n this.#entry = getOrCreateEntry(name, create, opts);\n }\n\n async read(): Promise<Read> {\n throwIfStoreClosed(this);\n\n const entry = this.#entry;\n const {db, lock, preparedStatements} = entry;\n const release = await lock.read();\n\n // Start shared read transaction if this is the first reader\n // This ensures consistent reads across all concurrent readers\n if (entry.activeReaders === 0) {\n db.execSync('BEGIN');\n }\n entry.activeReaders++;\n\n return new SQLiteStoreRead(() => {\n entry.activeReaders--;\n // Commit shared read transaction when last reader finishes\n if (entry.activeReaders === 0) {\n db.execSync('COMMIT');\n }\n release();\n }, preparedStatements);\n }\n\n async write(): Promise<Write> {\n throwIfStoreClosed(this);\n\n const {lock, db, preparedStatements} = this.#entry;\n const release = await lock.write();\n\n // At this point, RWLock guarantees no active readers\n // The last reader would have already committed the shared transaction\n\n db.execSync('BEGIN IMMEDIATE');\n\n return new SQLiteWrite(release, db, preparedStatements);\n }\n\n async close(): Promise<void> {\n if (this.#closed) {\n return;\n }\n\n const {lock, db} = this.#entry;\n // Wait for all readers and writers to finish.\n const writeRelease = await lock.write();\n\n // Handle reference counting for shared stores - only close database\n // when this is the last store instance using it\n decrementStoreRefCount(this.#filename, db);\n\n this.#closed = true;\n writeRelease();\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n}\n\nexport function safeFilename(name: string): string {\n return name.replace(/[^a-zA-Z0-9]/g, '_');\n}\n\nexport type PreparedStatements = {\n has: PreparedStatement;\n get: PreparedStatement;\n put: PreparedStatement;\n del: PreparedStatement;\n};\n\nexport interface SQLiteStoreOptions {\n // Common options\n busyTimeout?: number;\n journalMode?: 'WAL' | 'DELETE';\n synchronous?: 'NORMAL' | 'FULL';\n readUncommitted?: boolean;\n}\n\n/**\n * Common database setup logic shared between expo-sqlite and op-sqlite implementations.\n * Configures SQLite pragmas, creates the entry table, and prepares common statements.\n */\n\nexport function setupDatabase(\n delegate: SQLiteDatabase,\n opts?: SQLiteStoreOptions,\n): PreparedStatements {\n // Configure SQLite pragmas for optimal performance\n delegate.execSync(`PRAGMA busy_timeout = ${opts?.busyTimeout ?? 200}`);\n delegate.execSync(`PRAGMA journal_mode = '${opts?.journalMode ?? 'WAL'}'`);\n delegate.execSync(`PRAGMA synchronous = '${opts?.synchronous ?? 'NORMAL'}'`);\n delegate.execSync(\n `PRAGMA read_uncommitted = ${Boolean(opts?.readUncommitted)}`,\n );\n\n // Create the entry table\n delegate.execSync(`\n CREATE TABLE IF NOT EXISTS entry (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n ) WITHOUT ROWID\n `);\n\n // Prepare common statements\n return {\n has: delegate.prepare(`SELECT 1 FROM entry WHERE key = ? LIMIT 1`),\n get: delegate.prepare('SELECT value FROM entry WHERE key = ?'),\n put: delegate.prepare(\n `INSERT OR REPLACE INTO entry (key, value)\n SELECT e.value->>0, e.value->1 FROM json_each(?) e`,\n ),\n del: delegate.prepare(\n `DELETE FROM entry WHERE key IN (SELECT value FROM json_each(?))`,\n ),\n };\n}\n\nexport class SQLiteStoreRead implements Read {\n #release: () => void;\n #closed = false;\n #preparedStatements: PreparedStatements;\n\n constructor(release: () => void, preparedStatements: PreparedStatements) {\n this.#release = release;\n this.#preparedStatements = preparedStatements;\n }\n\n async has(key: string): Promise<boolean> {\n throwIfTransactionClosed(this);\n const value = await this.#preparedStatements.has.firstValue([key]);\n return value !== undefined;\n }\n\n async get(key: string): Promise<ReadonlyJSONValue | undefined> {\n throwIfTransactionClosed(this);\n const value = await this.#preparedStatements.get.firstValue([key]);\n if (!value) {\n return undefined;\n }\n\n const parsedValue = JSON.parse(value as string) as ReadonlyJSONValue;\n return deepFreeze(parsedValue);\n }\n\n release(): void {\n if (!this.#closed) {\n this.#closed = true;\n this.#release();\n }\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n}\n\nexport class SQLiteWrite extends WriteImplBase implements Write {\n readonly #release: () => void;\n readonly #dbDelegate: SQLiteDatabase;\n readonly #preparedStatements: PreparedStatements;\n #committed = false;\n #closed = false;\n\n constructor(\n release: () => void,\n dbDelegate: SQLiteDatabase,\n preparedStatements: PreparedStatements,\n ) {\n super(new SQLiteStoreRead(() => undefined, preparedStatements));\n this.#release = release;\n this.#dbDelegate = dbDelegate;\n this.#preparedStatements = preparedStatements;\n }\n\n async commit(): Promise<void> {\n if (this.#closed) {\n return transactionIsClosedRejection();\n }\n\n const deleteKeys: string[] = [];\n for (const entry of this._pending) {\n if (entry[1] === deleteSentinel) {\n deleteKeys.push(entry[0]);\n this._pending.delete(entry[0]);\n }\n }\n\n const delP =\n deleteKeys.length > 0\n ? this.#preparedStatements.del.exec([JSON.stringify(deleteKeys)])\n : undefined;\n const upP =\n this._pending.size > 0\n ? this.#preparedStatements.put.exec([\n JSON.stringify([...this._pending]),\n ])\n : undefined;\n\n if (delP && upP) {\n await Promise.all([delP, upP]);\n } else if (delP) {\n await delP;\n } else if (upP) {\n await upP;\n }\n\n this.#dbDelegate.execSync('COMMIT');\n this._pending.clear();\n this.#committed = true;\n }\n\n release(): void {\n if (!this.#closed) {\n this.#closed = true;\n super.release();\n let rollbackError: unknown;\n if (!this.#committed) {\n try {\n this.#dbDelegate.execSync('ROLLBACK');\n } catch (e) {\n rollbackError = e;\n }\n }\n\n this.#release();\n if (rollbackError !== undefined) {\n throw rollbackError;\n }\n }\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n}\n\ntype StoreEntry = {\n readonly lock: RWLock;\n readonly db: SQLiteDatabase;\n refCount: number;\n activeReaders: number;\n preparedStatements: PreparedStatements;\n};\n\n// Global map to share database connections between multiple store instances with the same name\nconst stores = new Map<string, StoreEntry>();\n\n/**\n * Gets an existing store entry or creates a new one if it doesn't exist.\n * This implements the shared connection pattern where multiple stores with the same\n * name share the same database connection, lock, and delegate.\n */\nfunction getOrCreateEntry(\n name: string,\n create: (filename: string, opts?: SQLiteStoreOptions) => SQLiteDatabase,\n opts?: SQLiteStoreOptions,\n): StoreEntry {\n const filename = safeFilename(name);\n const entry = stores.get(filename);\n\n if (entry) {\n entry.refCount++;\n return entry;\n }\n\n const dbDelegate = create(filename, opts);\n const preparedStatements = setupDatabase(dbDelegate, opts);\n\n const lock = new RWLock();\n\n const newEntry: StoreEntry = {\n lock,\n db: dbDelegate,\n refCount: 1,\n activeReaders: 0,\n preparedStatements,\n };\n stores.set(filename, newEntry);\n return newEntry;\n}\n\n/**\n * Decrements the reference count for a shared store and cleans up resources\n * when the last reference is released.\n */\n\nfunction decrementStoreRefCount(\n filename: string,\n dbDelegate: SQLiteDatabase,\n): void {\n const entry = stores.get(filename);\n if (entry) {\n entry.refCount--;\n if (entry.refCount <= 0) {\n dbDelegate.close();\n stores.delete(filename);\n }\n }\n}\nexport function clearAllNamedStoresForTesting(): void {\n for (const entry of stores.values()) {\n entry.db.close();\n }\n stores.clear();\n}\n\nexport function dropStore(\n name: string,\n createDelegate: (\n filename: string,\n opts?: SQLiteStoreOptions,\n ) => SQLiteDatabase,\n): Promise<void> {\n const filename = safeFilename(name);\n const entry = stores.get(filename);\n if (entry) {\n try {\n entry.db.close();\n } catch {\n // Ignore close errors\n }\n stores.delete(filename);\n }\n\n // Create a temporary delegate to handle database deletion\n const tempDelegate = createDelegate(filename);\n try {\n // we close the db before destroying it - this\n // caused an issue with expo-sqlite since it requires this\n tempDelegate.close();\n } catch {\n // Ignore close errors\n }\n try {\n tempDelegate.destroy();\n } catch {\n // Destroy errors shouldn't be fatal; the file may already be gone or locked\n }\n\n return Promise.resolve();\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sqlite-store.js","names":["#filename","#entry","#closed","#release","#preparedStatements","#pendingHasKeys","#pendingHasCallbacks","#scheduleLookup","#pendingGetKeys","#pendingGetCallbacks","#scheduled","#dbDelegate","#committed"],"sources":["../../../../../replicache/src/kv/sqlite-store.ts"],"sourcesContent":["import {RWLock} from '@rocicorp/lock';\nimport type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {deepFreeze} from '../frozen-json.ts';\nimport type {Read, Store, Write} from './store.ts';\nimport {\n maybeTransactionIsClosedRejection,\n throwIfStoreClosed,\n transactionError,\n} from './throw-if-closed.ts';\nimport {deleteSentinel, WriteImplBase} from './write-impl-base.ts';\n\n/**\n * A SQLite prepared statement.\n */\nexport interface PreparedStatement {\n exec(params: string[]): Promise<void>;\n all(params: string[]): Promise<unknown[][]>;\n}\n\nexport interface SQLiteDatabase {\n /**\n * Close the database connection.\n */\n close(): void;\n\n /**\n * Destroy or delete the database (e.g. delete file).\n */\n destroy(): void;\n\n /**\n * Prepare a SQL string, returning a statement you can execute.\n * E.g. `const stmt = db.prepare(\"SELECT * FROM todos WHERE id=?\");`\n */\n prepare(sql: string): PreparedStatement;\n\n // for PRAGMA statements, schema creation and transaction control.\n execSync(sql: string): void;\n}\n\nexport type CreateSQLiteDatabase = (\n filename: string,\n opts?: SQLiteStoreOptions,\n) => SQLiteDatabase;\n\n/**\n * SQLite-based implementation of the Store interface using a configurable delegate.\n * Supports shared connections between multiple store instances with the same name,\n * providing efficient resource utilization and proper transaction isolation.\n * Uses parameterized queries for safety and performance.\n */\nexport class SQLiteStore implements Store {\n readonly #filename: string;\n readonly #entry: StoreEntry;\n\n #closed = false;\n\n constructor(\n name: string,\n create: CreateSQLiteDatabase,\n opts?: SQLiteStoreOptions,\n ) {\n this.#filename = resolveFilename(name, opts);\n this.#entry = getOrCreateEntry(this.#filename, create, opts);\n }\n\n async read(): Promise<Read> {\n throwIfStoreClosed(this);\n\n const entry = this.#entry;\n const {db, lock, preparedStatements} = entry;\n const release = await lock.read();\n\n // Start shared read transaction if this is the first reader\n // This ensures consistent reads across all concurrent readers\n if (entry.activeReaders === 0) {\n db.execSync('BEGIN');\n }\n entry.activeReaders++;\n\n return new SQLiteStoreRead(() => {\n entry.activeReaders--;\n // Commit shared read transaction when last reader finishes\n if (entry.activeReaders === 0) {\n db.execSync('COMMIT');\n }\n release();\n }, preparedStatements);\n }\n\n async write(): Promise<Write> {\n throwIfStoreClosed(this);\n\n const {lock, db, preparedStatements} = this.#entry;\n const release = await lock.write();\n\n // At this point, RWLock guarantees no active readers\n // The last reader would have already committed the shared transaction\n\n db.execSync('BEGIN IMMEDIATE');\n\n return new SQLiteWrite(release, db, preparedStatements);\n }\n\n async close(): Promise<void> {\n if (this.#closed) {\n return;\n }\n\n const {lock, db} = this.#entry;\n // Wait for all readers and writers to finish.\n const writeRelease = await lock.write();\n\n // Handle reference counting for shared stores - only close database\n // when this is the last store instance using it\n decrementStoreRefCount(this.#filename, db);\n\n this.#closed = true;\n writeRelease();\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n}\n\nexport function safeFilename(name: string): string {\n return name.replace(/[^a-zA-Z0-9]/g, '_');\n}\n\nfunction resolveFilename(name: string, opts?: SQLiteStoreOptions): string {\n const safe = safeFilename(name);\n const dir = opts?.directory;\n return dir ? `${dir}/${safe}` : safe;\n}\n\nexport type PreparedStatements = {\n has: PreparedStatement;\n get: PreparedStatement;\n hasMany: PreparedStatement;\n getMany: PreparedStatement;\n put: PreparedStatement;\n del: PreparedStatement;\n};\n\nexport interface SQLiteStoreOptions {\n // Common options\n busyTimeout?: number;\n journalMode?: 'WAL' | 'DELETE';\n synchronous?: 'NORMAL' | 'FULL';\n readUncommitted?: boolean;\n /** Directory in which to create the SQLite file. Defaults to the process CWD. */\n directory?: string | undefined;\n}\n\n/**\n * Common database setup logic shared between expo-sqlite and op-sqlite implementations.\n * Configures SQLite pragmas, creates the entry table, and prepares common statements.\n */\n\nexport function setupDatabase(\n delegate: SQLiteDatabase,\n opts?: SQLiteStoreOptions,\n): PreparedStatements {\n // Configure SQLite pragmas for optimal performance\n delegate.execSync(`PRAGMA busy_timeout = ${opts?.busyTimeout ?? 200}`);\n delegate.execSync(`PRAGMA journal_mode = '${opts?.journalMode ?? 'WAL'}'`);\n delegate.execSync(`PRAGMA synchronous = '${opts?.synchronous ?? 'NORMAL'}'`);\n delegate.execSync(\n `PRAGMA read_uncommitted = ${Boolean(opts?.readUncommitted)}`,\n );\n\n // Create the entry table\n delegate.execSync(`\n CREATE TABLE IF NOT EXISTS entry (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n ) WITHOUT ROWID\n `);\n\n // Prepare common statements\n return {\n has: delegate.prepare(`SELECT 1 FROM entry WHERE key = ? LIMIT 1`),\n get: delegate.prepare('SELECT value FROM entry WHERE key = ?'),\n hasMany: delegate.prepare(\n `SELECT key FROM entry WHERE key IN (SELECT value FROM json_each(?))`,\n ),\n getMany: delegate.prepare(\n `SELECT key, value FROM entry WHERE key IN (SELECT value FROM json_each(?))`,\n ),\n put: delegate.prepare(\n `INSERT OR REPLACE INTO entry (key, value)\n SELECT e.value->>0, e.value->1 FROM json_each(?) e`,\n ),\n del: delegate.prepare(\n `DELETE FROM entry WHERE key IN (SELECT value FROM json_each(?))`,\n ),\n };\n}\n\n// Callbacks are stored as striped pairs: [resolve, reject, resolve, reject, ...]\nconst CB_STRIDE = 2;\nconst CB_RESOLVE = 0;\nconst CB_REJECT = 1;\n\ntype GetResolve = (v: ReadonlyJSONValue | undefined) => void;\ntype HasResolve = (v: boolean) => void;\ntype Reject = (e: unknown) => void;\n\nfunction rejectAll(callbacks: unknown[], e: unknown): void {\n for (let i = CB_REJECT; i < callbacks.length; i += CB_STRIDE) {\n (callbacks[i] as Reject)(e);\n }\n}\n\nfunction parseRawValue(raw: string | undefined): ReadonlyJSONValue | undefined {\n return raw === undefined\n ? undefined\n : deepFreeze(JSON.parse(raw) as ReadonlyJSONValue);\n}\n\nfunction resolveGet(\n resolve: GetResolve,\n reject: Reject,\n raw: string | undefined,\n): void {\n try {\n resolve(parseRawValue(raw));\n } catch (e) {\n reject(e);\n }\n}\n\nasync function flushGets(\n keys: string[],\n callbacks: unknown[],\n ps: PreparedStatements,\n): Promise<void> {\n let rows: unknown[][];\n try {\n rows =\n keys.length === 1\n ? await ps.get.all([keys[0]])\n : await ps.getMany.all([JSON.stringify(keys)]);\n } catch (e) {\n rejectAll(callbacks, e);\n return;\n }\n if (keys.length === 1) {\n resolveGet(\n callbacks[CB_RESOLVE] as GetResolve,\n callbacks[CB_REJECT] as Reject,\n rows[0]?.[0] as string | undefined,\n );\n return;\n }\n const resultMap = new Map(rows as [string, string][]);\n for (let i = 0; i < keys.length; i++) {\n resolveGet(\n callbacks[i * CB_STRIDE + CB_RESOLVE] as GetResolve,\n callbacks[i * CB_STRIDE + CB_REJECT] as Reject,\n resultMap.get(keys[i]),\n );\n }\n}\n\nasync function flushHas(\n keys: string[],\n callbacks: unknown[],\n ps: PreparedStatements,\n): Promise<void> {\n let rows: unknown[][];\n try {\n rows =\n keys.length === 1\n ? await ps.has.all([keys[0]])\n : await ps.hasMany.all([JSON.stringify(keys)]);\n } catch (e) {\n rejectAll(callbacks, e);\n return;\n }\n if (keys.length === 1) {\n (callbacks[CB_RESOLVE] as HasResolve)(rows.length > 0);\n return;\n }\n const existingKeys = new Set(rows.map(row => row[0] as string));\n for (let i = 0; i < keys.length; i++) {\n (callbacks[i * CB_STRIDE + CB_RESOLVE] as HasResolve)(\n existingKeys.has(keys[i]),\n );\n }\n}\n\nexport class SQLiteStoreRead implements Read {\n readonly #release: () => void;\n readonly #preparedStatements: PreparedStatements;\n #closed = false;\n #pendingGetKeys: string[] = [];\n #pendingGetCallbacks: unknown[] = [];\n #pendingHasKeys: string[] = [];\n #pendingHasCallbacks: unknown[] = [];\n #scheduled = false;\n\n constructor(release: () => void, preparedStatements: PreparedStatements) {\n this.#release = release;\n this.#preparedStatements = preparedStatements;\n }\n\n has(key: string): Promise<boolean> {\n return (\n maybeTransactionIsClosedRejection(this) ??\n new Promise((resolve, reject) => {\n this.#pendingHasKeys.push(key);\n this.#pendingHasCallbacks.push(resolve, reject);\n this.#scheduleLookup();\n })\n );\n }\n\n get(key: string): Promise<ReadonlyJSONValue | undefined> {\n return (\n maybeTransactionIsClosedRejection(this) ??\n new Promise((resolve, reject) => {\n this.#pendingGetKeys.push(key);\n this.#pendingGetCallbacks.push(resolve, reject);\n this.#scheduleLookup();\n })\n );\n }\n\n #scheduleLookup(): void {\n if (!this.#scheduled) {\n this.#scheduled = true;\n queueMicrotask(() => {\n this.#scheduled = false;\n\n const ps = this.#preparedStatements;\n const getKeys = this.#pendingGetKeys;\n this.#pendingGetKeys = [];\n const getCallbacks = this.#pendingGetCallbacks;\n this.#pendingGetCallbacks = [];\n const hasKeys = this.#pendingHasKeys;\n this.#pendingHasKeys = [];\n const hasCallbacks = this.#pendingHasCallbacks;\n this.#pendingHasCallbacks = [];\n\n if (this.#closed) {\n const e = transactionError();\n rejectAll(getCallbacks, e);\n rejectAll(hasCallbacks, e);\n return;\n }\n\n if (getKeys.length > 0) {\n void flushGets(getKeys, getCallbacks, ps);\n }\n if (hasKeys.length > 0) {\n void flushHas(hasKeys, hasCallbacks, ps);\n }\n });\n }\n }\n\n release(): void {\n if (!this.#closed) {\n this.#closed = true;\n this.#release();\n }\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n}\n\nexport class SQLiteWrite extends WriteImplBase implements Write {\n readonly #release: () => void;\n readonly #dbDelegate: SQLiteDatabase;\n readonly #preparedStatements: PreparedStatements;\n #committed = false;\n #closed = false;\n\n constructor(\n release: () => void,\n dbDelegate: SQLiteDatabase,\n preparedStatements: PreparedStatements,\n ) {\n super(new SQLiteStoreRead(() => undefined, preparedStatements));\n this.#release = release;\n this.#dbDelegate = dbDelegate;\n this.#preparedStatements = preparedStatements;\n }\n\n async commit(): Promise<void> {\n if (this.#closed) {\n throw transactionError();\n }\n\n const deleteKeys: string[] = [];\n for (const entry of this._pending) {\n if (entry[1] === deleteSentinel) {\n deleteKeys.push(entry[0]);\n this._pending.delete(entry[0]);\n }\n }\n\n const delP =\n deleteKeys.length > 0\n ? this.#preparedStatements.del.exec([JSON.stringify(deleteKeys)])\n : undefined;\n const putP =\n this._pending.size > 0\n ? this.#preparedStatements.put.exec([\n JSON.stringify([...this._pending]),\n ])\n : undefined;\n\n if (putP) await putP;\n if (delP) await delP;\n\n this.#dbDelegate.execSync('COMMIT');\n this._pending.clear();\n this.#committed = true;\n }\n\n release(): void {\n if (!this.#closed) {\n this.#closed = true;\n super.release();\n let rollbackError: unknown;\n if (!this.#committed) {\n try {\n this.#dbDelegate.execSync('ROLLBACK');\n } catch (e) {\n rollbackError = e;\n }\n }\n this.#release();\n if (rollbackError !== undefined) {\n throw rollbackError;\n }\n }\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n}\n\ntype StoreEntry = {\n readonly lock: RWLock;\n readonly db: SQLiteDatabase;\n refCount: number;\n activeReaders: number;\n preparedStatements: PreparedStatements;\n};\n\n// Global map to share database connections between multiple store instances with the same name\nconst stores = new Map<string, StoreEntry>();\n\n/**\n * Gets an existing store entry or creates a new one if it doesn't exist.\n * This implements the shared connection pattern where multiple stores with the same\n * name share the same database connection, lock, and delegate.\n */\nfunction getOrCreateEntry(\n filename: string,\n create: (filename: string, opts?: SQLiteStoreOptions) => SQLiteDatabase,\n opts?: SQLiteStoreOptions,\n): StoreEntry {\n const entry = stores.get(filename);\n\n if (entry) {\n entry.refCount++;\n return entry;\n }\n\n const dbDelegate = create(filename, opts);\n const preparedStatements = setupDatabase(dbDelegate, opts);\n\n const lock = new RWLock();\n\n const newEntry: StoreEntry = {\n lock,\n db: dbDelegate,\n refCount: 1,\n activeReaders: 0,\n preparedStatements,\n };\n stores.set(filename, newEntry);\n return newEntry;\n}\n\n/**\n * Decrements the reference count for a shared store and cleans up resources\n * when the last reference is released.\n */\n\nfunction decrementStoreRefCount(\n filename: string,\n dbDelegate: SQLiteDatabase,\n): void {\n const entry = stores.get(filename);\n if (entry) {\n entry.refCount--;\n if (entry.refCount <= 0) {\n dbDelegate.close();\n stores.delete(filename);\n }\n }\n}\nexport function clearAllNamedStoresForTesting(): void {\n for (const entry of stores.values()) {\n entry.db.close();\n }\n stores.clear();\n}\n\nexport function dropStore(\n name: string,\n createDelegate: (\n filename: string,\n opts?: SQLiteStoreOptions,\n ) => SQLiteDatabase,\n opts?: SQLiteStoreOptions,\n): Promise<void> {\n const filename = resolveFilename(name, opts);\n const entry = stores.get(filename);\n if (entry) {\n try {\n entry.db.close();\n } catch {\n // Ignore close errors\n }\n stores.delete(filename);\n }\n\n // Create a temporary delegate to handle database deletion\n const tempDelegate = createDelegate(filename, opts);\n try {\n // we close the db before destroying it - this\n // caused an issue with expo-sqlite since it requires this\n tempDelegate.close();\n } catch {\n // Ignore close errors\n }\n try {\n tempDelegate.destroy();\n } catch {\n // Destroy errors shouldn't be fatal; the file may already be gone or locked\n }\n\n return Promise.resolve();\n}\n"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ export declare function transactionError(): Error;
1
2
  export declare function throwIfStoreClosed(store: {
2
3
  readonly closed: boolean;
3
4
  }): void;
@@ -1 +1 @@
1
- {"version":3,"file":"throw-if-closed.d.ts","sourceRoot":"","sources":["../../../../../replicache/src/kv/throw-if-closed.ts"],"names":[],"mappings":"AAQA,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CAAC,GAAG,IAAI,CAI1E;AAED,wBAAgB,wBAAwB,CAAC,WAAW,EAAE;IACpD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B,GAAG,IAAI,CAIP;AAED,wBAAgB,4BAA4B,mBAE3C;AAED,wBAAgB,iCAAiC,CAAC,WAAW,EAAE;IAC7D,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,SAAS,CAE7B;AAED,wBAAgB,sBAAsB,mBAErC"}
1
+ {"version":3,"file":"throw-if-closed.d.ts","sourceRoot":"","sources":["../../../../../replicache/src/kv/throw-if-closed.ts"],"names":[],"mappings":"AAIA,wBAAgB,gBAAgB,IAAI,KAAK,CAExC;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CAAC,GAAG,IAAI,CAI1E;AAED,wBAAgB,wBAAwB,CAAC,WAAW,EAAE;IACpD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B,GAAG,IAAI,CAIP;AAED,wBAAgB,4BAA4B,mBAE3C;AAED,wBAAgB,iCAAiC,CAAC,WAAW,EAAE;IAC7D,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,SAAS,CAE7B;AAED,wBAAgB,sBAAsB,mBAErC"}
@@ -8,9 +8,6 @@ function transactionError() {
8
8
  function throwIfStoreClosed(store) {
9
9
  if (store.closed) throw storeError();
10
10
  }
11
- function throwIfTransactionClosed(transaction) {
12
- if (transaction.closed) throw transactionError();
13
- }
14
11
  function transactionIsClosedRejection() {
15
12
  return Promise.reject(transactionError());
16
13
  }
@@ -21,6 +18,6 @@ function storeIsClosedRejection() {
21
18
  return Promise.reject(storeError());
22
19
  }
23
20
  //#endregion
24
- export { maybeTransactionIsClosedRejection, storeIsClosedRejection, throwIfStoreClosed, throwIfTransactionClosed, transactionIsClosedRejection };
21
+ export { maybeTransactionIsClosedRejection, storeIsClosedRejection, throwIfStoreClosed, transactionError, transactionIsClosedRejection };
25
22
 
26
23
  //# sourceMappingURL=throw-if-closed.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"throw-if-closed.js","names":[],"sources":["../../../../../replicache/src/kv/throw-if-closed.ts"],"sourcesContent":["function storeError(): Error {\n return new Error('Store is closed');\n}\n\nfunction transactionError(): Error {\n return new Error('Transaction is closed');\n}\n\nexport function throwIfStoreClosed(store: {readonly closed: boolean}): void {\n if (store.closed) {\n throw storeError();\n }\n}\n\nexport function throwIfTransactionClosed(transaction: {\n readonly closed: boolean;\n}): void {\n if (transaction.closed) {\n throw transactionError();\n }\n}\n\nexport function transactionIsClosedRejection() {\n return Promise.reject(transactionError());\n}\n\nexport function maybeTransactionIsClosedRejection(transaction: {\n readonly closed: boolean;\n}): Promise<never> | undefined {\n return transaction.closed ? transactionIsClosedRejection() : undefined;\n}\n\nexport function storeIsClosedRejection() {\n return Promise.reject(storeError());\n}\n"],"mappings":";AAAA,SAAS,aAAoB;AAC3B,wBAAO,IAAI,MAAM,kBAAkB;;AAGrC,SAAS,mBAA0B;AACjC,wBAAO,IAAI,MAAM,wBAAwB;;AAG3C,SAAgB,mBAAmB,OAAyC;AAC1E,KAAI,MAAM,OACR,OAAM,YAAY;;AAItB,SAAgB,yBAAyB,aAEhC;AACP,KAAI,YAAY,OACd,OAAM,kBAAkB;;AAI5B,SAAgB,+BAA+B;AAC7C,QAAO,QAAQ,OAAO,kBAAkB,CAAC;;AAG3C,SAAgB,kCAAkC,aAEnB;AAC7B,QAAO,YAAY,SAAS,8BAA8B,GAAG,KAAA;;AAG/D,SAAgB,yBAAyB;AACvC,QAAO,QAAQ,OAAO,YAAY,CAAC"}
1
+ {"version":3,"file":"throw-if-closed.js","names":[],"sources":["../../../../../replicache/src/kv/throw-if-closed.ts"],"sourcesContent":["function storeError(): Error {\n return new Error('Store is closed');\n}\n\nexport function transactionError(): Error {\n return new Error('Transaction is closed');\n}\n\nexport function throwIfStoreClosed(store: {readonly closed: boolean}): void {\n if (store.closed) {\n throw storeError();\n }\n}\n\nexport function throwIfTransactionClosed(transaction: {\n readonly closed: boolean;\n}): void {\n if (transaction.closed) {\n throw transactionError();\n }\n}\n\nexport function transactionIsClosedRejection() {\n return Promise.reject(transactionError());\n}\n\nexport function maybeTransactionIsClosedRejection(transaction: {\n readonly closed: boolean;\n}): Promise<never> | undefined {\n return transaction.closed ? transactionIsClosedRejection() : undefined;\n}\n\nexport function storeIsClosedRejection() {\n return Promise.reject(storeError());\n}\n"],"mappings":";AAAA,SAAS,aAAoB;CAC3B,uBAAO,IAAI,MAAM,iBAAiB;AACpC;AAEA,SAAgB,mBAA0B;CACxC,uBAAO,IAAI,MAAM,uBAAuB;AAC1C;AAEA,SAAgB,mBAAmB,OAAyC;CAC1E,IAAI,MAAM,QACR,MAAM,WAAW;AAErB;AAUA,SAAgB,+BAA+B;CAC7C,OAAO,QAAQ,OAAO,iBAAiB,CAAC;AAC1C;AAEA,SAAgB,kCAAkC,aAEnB;CAC7B,OAAO,YAAY,SAAS,6BAA6B,IAAI,KAAA;AAC/D;AAEA,SAAgB,yBAAyB;CACvC,OAAO,QAAQ,OAAO,WAAW,CAAC;AACpC"}
@@ -1 +1 @@
1
- {"version":3,"file":"write-impl-base.js","names":["#read"],"sources":["../../../../../replicache/src/kv/write-impl-base.ts"],"sourcesContent":["import type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {\n promiseFalse,\n promiseTrue,\n promiseVoid,\n} from '../../../shared/src/resolved-promises.ts';\nimport {\n type FrozenJSONValue,\n deepFreeze,\n deepFreezeAllowUndefined,\n} from '../frozen-json.ts';\nimport type {Read} from './store.ts';\nimport {\n maybeTransactionIsClosedRejection,\n transactionIsClosedRejection,\n} from './throw-if-closed.ts';\n\nexport const deleteSentinel = Symbol();\ntype DeleteSentinel = typeof deleteSentinel;\n\nexport class WriteImplBase {\n protected readonly _pending: Map<string, FrozenJSONValue | DeleteSentinel> =\n new Map();\n readonly #read: Read;\n\n constructor(read: Read) {\n this.#read = read;\n }\n\n has(key: string): Promise<boolean> {\n if (this.#read.closed) {\n return transactionIsClosedRejection();\n }\n switch (this._pending.get(key)) {\n case undefined:\n return this.#read.has(key);\n case deleteSentinel:\n return promiseFalse;\n default:\n return promiseTrue;\n }\n }\n\n async get(key: string): Promise<FrozenJSONValue | undefined> {\n if (this.#read.closed) {\n return transactionIsClosedRejection();\n }\n const v = this._pending.get(key);\n switch (v) {\n case deleteSentinel:\n return undefined;\n case undefined: {\n const v = await this.#read.get(key);\n return deepFreezeAllowUndefined(v);\n }\n default:\n return v;\n }\n }\n\n put(key: string, value: ReadonlyJSONValue) {\n return (\n maybeTransactionIsClosedRejection(this.#read) ??\n (this._pending.set(key, deepFreeze(value)), promiseVoid)\n );\n }\n\n del(key: string): Promise<void> {\n return (\n maybeTransactionIsClosedRejection(this.#read) ??\n (this._pending.set(key, deleteSentinel), promiseVoid)\n );\n }\n\n release(): void {\n this.#read.release();\n }\n\n get closed(): boolean {\n return this.#read.closed;\n }\n}\n"],"mappings":";;;;AAiBA,IAAa,iBAAiB,QAAQ;AAGtC,IAAa,gBAAb,MAA2B;CACzB,2BACE,IAAI,KAAK;CACX;CAEA,YAAY,MAAY;AACtB,QAAA,OAAa;;CAGf,IAAI,KAA+B;AACjC,MAAI,MAAA,KAAW,OACb,QAAO,8BAA8B;AAEvC,UAAQ,KAAK,SAAS,IAAI,IAAI,EAA9B;GACE,KAAK,KAAA,EACH,QAAO,MAAA,KAAW,IAAI,IAAI;GAC5B,KAAK,eACH,QAAO;GACT,QACE,QAAO;;;CAIb,MAAM,IAAI,KAAmD;AAC3D,MAAI,MAAA,KAAW,OACb,QAAO,8BAA8B;EAEvC,MAAM,IAAI,KAAK,SAAS,IAAI,IAAI;AAChC,UAAQ,GAAR;GACE,KAAK,eACH;GACF,KAAK,KAAA,EAEH,QAAO,yBADG,MAAM,MAAA,KAAW,IAAI,IAAI,CACD;GAEpC,QACE,QAAO;;;CAIb,IAAI,KAAa,OAA0B;AACzC,SACE,kCAAkC,MAAA,KAAW,KAC5C,KAAK,SAAS,IAAI,KAAK,WAAW,MAAM,CAAC,EAAE;;CAIhD,IAAI,KAA4B;AAC9B,SACE,kCAAkC,MAAA,KAAW,KAC5C,KAAK,SAAS,IAAI,KAAK,eAAe,EAAE;;CAI7C,UAAgB;AACd,QAAA,KAAW,SAAS;;CAGtB,IAAI,SAAkB;AACpB,SAAO,MAAA,KAAW"}
1
+ {"version":3,"file":"write-impl-base.js","names":["#read"],"sources":["../../../../../replicache/src/kv/write-impl-base.ts"],"sourcesContent":["import type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {\n promiseFalse,\n promiseTrue,\n promiseVoid,\n} from '../../../shared/src/resolved-promises.ts';\nimport {\n type FrozenJSONValue,\n deepFreeze,\n deepFreezeAllowUndefined,\n} from '../frozen-json.ts';\nimport type {Read} from './store.ts';\nimport {\n maybeTransactionIsClosedRejection,\n transactionIsClosedRejection,\n} from './throw-if-closed.ts';\n\nexport const deleteSentinel = Symbol();\ntype DeleteSentinel = typeof deleteSentinel;\n\nexport class WriteImplBase {\n protected readonly _pending: Map<string, FrozenJSONValue | DeleteSentinel> =\n new Map();\n readonly #read: Read;\n\n constructor(read: Read) {\n this.#read = read;\n }\n\n has(key: string): Promise<boolean> {\n if (this.#read.closed) {\n return transactionIsClosedRejection();\n }\n switch (this._pending.get(key)) {\n case undefined:\n return this.#read.has(key);\n case deleteSentinel:\n return promiseFalse;\n default:\n return promiseTrue;\n }\n }\n\n async get(key: string): Promise<FrozenJSONValue | undefined> {\n if (this.#read.closed) {\n return transactionIsClosedRejection();\n }\n const v = this._pending.get(key);\n switch (v) {\n case deleteSentinel:\n return undefined;\n case undefined: {\n const v = await this.#read.get(key);\n return deepFreezeAllowUndefined(v);\n }\n default:\n return v;\n }\n }\n\n put(key: string, value: ReadonlyJSONValue) {\n return (\n maybeTransactionIsClosedRejection(this.#read) ??\n (this._pending.set(key, deepFreeze(value)), promiseVoid)\n );\n }\n\n del(key: string): Promise<void> {\n return (\n maybeTransactionIsClosedRejection(this.#read) ??\n (this._pending.set(key, deleteSentinel), promiseVoid)\n );\n }\n\n release(): void {\n this.#read.release();\n }\n\n get closed(): boolean {\n return this.#read.closed;\n }\n}\n"],"mappings":";;;;AAiBA,IAAa,iBAAiB,OAAO;AAGrC,IAAa,gBAAb,MAA2B;CACzB,2BACE,IAAI,IAAI;CACV;CAEA,YAAY,MAAY;EACtB,KAAKA,QAAQ;CACf;CAEA,IAAI,KAA+B;EACjC,IAAI,KAAKA,MAAM,QACb,OAAO,6BAA6B;EAEtC,QAAQ,KAAK,SAAS,IAAI,GAAG,GAA7B;GACE,KAAK,KAAA,GACH,OAAO,KAAKA,MAAM,IAAI,GAAG;GAC3B,KAAK,gBACH,OAAO;GACT,SACE,OAAO;EACX;CACF;CAEA,MAAM,IAAI,KAAmD;EAC3D,IAAI,KAAKA,MAAM,QACb,OAAO,6BAA6B;EAEtC,MAAM,IAAI,KAAK,SAAS,IAAI,GAAG;EAC/B,QAAQ,GAAR;GACE,KAAK,gBACH;GACF,KAAK,KAAA,GAEH,OAAO,yBAAyB,MADhB,KAAKA,MAAM,IAAI,GAAG,CACD;GAEnC,SACE,OAAO;EACX;CACF;CAEA,IAAI,KAAa,OAA0B;EACzC,OACE,kCAAkC,KAAKA,KAAK,MAC3C,KAAK,SAAS,IAAI,KAAK,WAAW,KAAK,CAAC,GAAG;CAEhD;CAEA,IAAI,KAA4B;EAC9B,OACE,kCAAkC,KAAKA,KAAK,MAC3C,KAAK,SAAS,IAAI,KAAK,cAAc,GAAG;CAE7C;CAEA,UAAgB;EACd,KAAKA,MAAM,QAAQ;CACrB;CAEA,IAAI,SAAkB;EACpB,OAAO,KAAKA,MAAM;CACpB;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"write-impl.js","names":["#map"],"sources":["../../../../../replicache/src/kv/write-impl.ts"],"sourcesContent":["import {promiseVoid} from '../../../shared/src/resolved-promises.ts';\nimport type {FrozenJSONValue} from '../frozen-json.ts';\nimport {ReadImpl} from './read-impl.ts';\nimport type {Write} from './store.ts';\nimport {transactionIsClosedRejection} from './throw-if-closed.ts';\nimport {deleteSentinel, WriteImplBase} from './write-impl-base.ts';\n\nexport class WriteImpl extends WriteImplBase implements Write {\n readonly #map: Map<string, FrozenJSONValue>;\n\n constructor(map: Map<string, FrozenJSONValue>, release: () => void) {\n super(new ReadImpl(map, release));\n this.#map = map;\n }\n\n commit(): Promise<void> {\n if (this.closed) {\n return transactionIsClosedRejection();\n }\n\n // HOT. Do not allocate entry tuple and destructure.\n this._pending.forEach((value, key) => {\n if (value === deleteSentinel) {\n this.#map.delete(key);\n } else {\n this.#map.set(key, value);\n }\n });\n this._pending.clear();\n this.release();\n return promiseVoid;\n }\n}\n"],"mappings":";;;;;AAOA,IAAa,YAAb,cAA+B,cAA+B;CAC5D;CAEA,YAAY,KAAmC,SAAqB;AAClE,QAAM,IAAI,SAAS,KAAK,QAAQ,CAAC;AACjC,QAAA,MAAY;;CAGd,SAAwB;AACtB,MAAI,KAAK,OACP,QAAO,8BAA8B;AAIvC,OAAK,SAAS,SAAS,OAAO,QAAQ;AACpC,OAAI,UAAU,eACZ,OAAA,IAAU,OAAO,IAAI;OAErB,OAAA,IAAU,IAAI,KAAK,MAAM;IAE3B;AACF,OAAK,SAAS,OAAO;AACrB,OAAK,SAAS;AACd,SAAO"}
1
+ {"version":3,"file":"write-impl.js","names":["#map"],"sources":["../../../../../replicache/src/kv/write-impl.ts"],"sourcesContent":["import {promiseVoid} from '../../../shared/src/resolved-promises.ts';\nimport type {FrozenJSONValue} from '../frozen-json.ts';\nimport {ReadImpl} from './read-impl.ts';\nimport type {Write} from './store.ts';\nimport {transactionIsClosedRejection} from './throw-if-closed.ts';\nimport {deleteSentinel, WriteImplBase} from './write-impl-base.ts';\n\nexport class WriteImpl extends WriteImplBase implements Write {\n readonly #map: Map<string, FrozenJSONValue>;\n\n constructor(map: Map<string, FrozenJSONValue>, release: () => void) {\n super(new ReadImpl(map, release));\n this.#map = map;\n }\n\n commit(): Promise<void> {\n if (this.closed) {\n return transactionIsClosedRejection();\n }\n\n // HOT. Do not allocate entry tuple and destructure.\n this._pending.forEach((value, key) => {\n if (value === deleteSentinel) {\n this.#map.delete(key);\n } else {\n this.#map.set(key, value);\n }\n });\n this._pending.clear();\n this.release();\n return promiseVoid;\n }\n}\n"],"mappings":";;;;;AAOA,IAAa,YAAb,cAA+B,cAA+B;CAC5D;CAEA,YAAY,KAAmC,SAAqB;EAClE,MAAM,IAAI,SAAS,KAAK,OAAO,CAAC;EAChC,KAAKA,OAAO;CACd;CAEA,SAAwB;EACtB,IAAI,KAAK,QACP,OAAO,6BAA6B;EAItC,KAAK,SAAS,SAAS,OAAO,QAAQ;GACpC,IAAI,UAAU,gBACZ,KAAKA,KAAK,OAAO,GAAG;QAEpB,KAAKA,KAAK,IAAI,KAAK,KAAK;EAE5B,CAAC;EACD,KAAK,SAAS,MAAM;EACpB,KAAK,QAAQ;EACb,OAAO;CACT;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"lazy.js","names":[],"sources":["../../../../replicache/src/lazy.ts"],"sourcesContent":["export function lazy<T>(factory: () => T): () => T {\n let value: T | undefined;\n return () => {\n if (value === undefined) {\n value = factory();\n }\n return value;\n };\n}\n"],"mappings":";AAAA,SAAgB,KAAQ,SAA2B;CACjD,IAAI;AACJ,cAAa;AACX,MAAI,UAAU,KAAA,EACZ,SAAQ,SAAS;AAEnB,SAAO"}
1
+ {"version":3,"file":"lazy.js","names":[],"sources":["../../../../replicache/src/lazy.ts"],"sourcesContent":["export function lazy<T>(factory: () => T): () => T {\n let value: T | undefined;\n return () => {\n if (value === undefined) {\n value = factory();\n }\n return value;\n };\n}\n"],"mappings":";AAAA,SAAgB,KAAQ,SAA2B;CACjD,IAAI;CACJ,aAAa;EACX,IAAI,UAAU,KAAA,GACZ,QAAQ,QAAQ;EAElB,OAAO;CACT;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"log-options.js","names":[],"sources":["../../../../replicache/src/log-options.ts"],"sourcesContent":["import {\n consoleLogSink,\n LogContext,\n TeeLogSink,\n type Context,\n type LogLevel,\n type LogSink,\n} from '@rocicorp/logger';\n\n/**\n * Creates a LogContext\n * @param logLevel The log level to use. Default is `'info'`.\n * @param logSinks Destination for logs. Default is `[consoleLogSink]`.\n * @param context Optional: Additional information that can be associated with logs.\n * @returns A LogContext instance configured with the provided options.\n */\nexport function createLogContext(\n logLevel: LogLevel = 'info',\n logSinks: LogSink[] = [consoleLogSink],\n context?: Context,\n): LogContext {\n const logSink =\n logSinks.length === 1 ? logSinks[0] : new TeeLogSink(logSinks);\n return new LogContext(logLevel, context, logSink);\n}\n"],"mappings":";;;;;;;;;AAgBA,SAAgB,iBACd,WAAqB,QACrB,WAAsB,CAAC,eAAe,EACtC,SACY;AAGZ,QAAO,IAAI,WAAW,UAAU,SAD9B,SAAS,WAAW,IAAI,SAAS,KAAK,IAAI,WAAW,SAAS,CACf"}
1
+ {"version":3,"file":"log-options.js","names":[],"sources":["../../../../replicache/src/log-options.ts"],"sourcesContent":["import {\n consoleLogSink,\n LogContext,\n TeeLogSink,\n type Context,\n type LogLevel,\n type LogSink,\n} from '@rocicorp/logger';\n\n/**\n * Creates a LogContext\n * @param logLevel The log level to use. Default is `'info'`.\n * @param logSinks Destination for logs. Default is `[consoleLogSink]`.\n * @param context Optional: Additional information that can be associated with logs.\n * @returns A LogContext instance configured with the provided options.\n */\nexport function createLogContext(\n logLevel: LogLevel = 'info',\n logSinks: LogSink[] = [consoleLogSink],\n context?: Context,\n): LogContext {\n const logSink =\n logSinks.length === 1 ? logSinks[0] : new TeeLogSink(logSinks);\n return new LogContext(logLevel, context, logSink);\n}\n"],"mappings":";;;;;;;;;AAgBA,SAAgB,iBACd,WAAqB,QACrB,WAAsB,CAAC,cAAc,GACrC,SACY;CAGZ,OAAO,IAAI,WAAW,UAAU,SAD9B,SAAS,WAAW,IAAI,SAAS,KAAK,IAAI,WAAW,QAAQ,CACf;AAClD"}
@@ -1 +1 @@
1
- {"version":3,"file":"make-idb-name.js","names":[],"sources":["../../../../replicache/src/make-idb-name.ts"],"sourcesContent":["import * as FormatVersion from './format-version-enum.ts';\n\n/**\n * Returns the name of the IDB database that will be used for a particular Replicache instance.\n * @param name The name of the Replicache instance (i.e., the `name` field of `ReplicacheOptions`).\n * @param schemaVersion The schema version of the database (i.e., the `schemaVersion` field of `ReplicacheOptions`).\n * @returns\n */\n\nexport function makeIDBName(name: string, schemaVersion?: string): string {\n return makeIDBNameInternal(name, schemaVersion, FormatVersion.Latest);\n}\n\nfunction makeIDBNameInternal(\n name: string,\n schemaVersion: string | undefined,\n formatVersion: number,\n): string {\n const n = `rep:${name}:${formatVersion}`;\n return schemaVersion ? `${n}:${schemaVersion}` : n;\n}\n\nexport {makeIDBNameInternal as makeIDBNameForTesting};\n"],"mappings":";;;;;;;AASA,SAAgB,YAAY,MAAc,eAAgC;AACxE,QAAO,oBAAoB,MAAM,eAAe,EAAqB;;AAGvE,SAAS,oBACP,MACA,eACA,eACQ;CACR,MAAM,IAAI,OAAO,KAAK,GAAG;AACzB,QAAO,gBAAgB,GAAG,EAAE,GAAG,kBAAkB"}
1
+ {"version":3,"file":"make-idb-name.js","names":[],"sources":["../../../../replicache/src/make-idb-name.ts"],"sourcesContent":["import * as FormatVersion from './format-version-enum.ts';\n\n/**\n * Returns the name of the IDB database that will be used for a particular Replicache instance.\n * @param name The name of the Replicache instance (i.e., the `name` field of `ReplicacheOptions`).\n * @param schemaVersion The schema version of the database (i.e., the `schemaVersion` field of `ReplicacheOptions`).\n * @returns\n */\n\nexport function makeIDBName(name: string, schemaVersion?: string): string {\n return makeIDBNameInternal(name, schemaVersion, FormatVersion.Latest);\n}\n\nfunction makeIDBNameInternal(\n name: string,\n schemaVersion: string | undefined,\n formatVersion: number,\n): string {\n const n = `rep:${name}:${formatVersion}`;\n return schemaVersion ? `${n}:${schemaVersion}` : n;\n}\n\nexport {makeIDBNameInternal as makeIDBNameForTesting};\n"],"mappings":";;;;;;;AASA,SAAgB,YAAY,MAAc,eAAgC;CACxE,OAAO,oBAAoB,MAAM,eAAe,CAAoB;AACtE;AAEA,SAAS,oBACP,MACA,eACA,eACQ;CACR,MAAM,IAAI,OAAO,KAAK,GAAG;CACzB,OAAO,gBAAgB,GAAG,EAAE,GAAG,kBAAkB;AACnD"}
@@ -1 +1 @@
1
- {"version":3,"file":"new-client-channel.js","names":[],"sources":["../../../../replicache/src/new-client-channel.ts"],"sourcesContent":["import {BroadcastChannel} from '../../shared/src/broadcast-channel.ts';\nimport type {Read, Store} from './dag/store.ts';\nimport {getClientGroup} from './persist/client-groups.ts';\nimport {withRead} from './with-transactions.ts';\n\n// Older clients (<= replicache@13.0.1), listened on this channel name\n// and *asserted* that the messages received were an array containing exactly\n// one string.\nfunction makeChannelNameV0(replicacheName: string): string {\n return `replicache-new-client-group:${replicacheName}`;\n}\n\n// This channel name was introduced when we first needed to change the message\n// format. The design of the messages sent on this channel allows for\n// the message content to be extended in the future in a way that is\n// forward and backwards compatible. The message format can be extended\n// by adding new *optional* fields.\nfunction makeChannelNameV1(replicacheName: string): string {\n return `replicache-new-client-group-v1:${replicacheName}`;\n}\n\nexport {\n makeChannelNameV0 as makeChannelNameV0ForTesting,\n makeChannelNameV1 as makeChannelNameV1ForTesting,\n};\n\n// This message type can be extended with optional properties.\ntype NewClientChannelMessageV1 = {clientGroupID: string; idbName: string};\n\nfunction isNewClientChannelMessageV1(\n message: unknown,\n): message is NewClientChannelMessageV1 {\n return (\n typeof message === 'object' &&\n typeof (message as {clientGroupID: unknown}).clientGroupID === 'string' &&\n typeof (message as {idbName: unknown}).idbName === 'string'\n );\n}\n\nexport function initNewClientChannel(\n replicacheName: string,\n idbName: string,\n signal: AbortSignal,\n clientGroupID: string,\n isNewClientGroup: boolean,\n onUpdateNeeded: () => void,\n perdag: Store,\n) {\n if (signal.aborted) {\n return;\n }\n\n const channelV1 = new BroadcastChannel(makeChannelNameV1(replicacheName));\n if (isNewClientGroup) {\n channelV1.postMessage({clientGroupID, idbName});\n // Send expected format to V0 channel for old clients.\n const channelV0 = new BroadcastChannel(makeChannelNameV0(replicacheName));\n channelV0.postMessage([clientGroupID]);\n channelV0.close();\n }\n\n channelV1.onmessage = async (e: MessageEvent) => {\n const {data} = e;\n if (isNewClientChannelMessageV1(data)) {\n const {clientGroupID: newClientGroupID, idbName: newClientIDBName} = data;\n if (newClientGroupID !== clientGroupID) {\n if (newClientIDBName === idbName) {\n // Check if this client can see the new client's newClientGroupID in its\n // perdag. It should be able to if the clients share persistent\n // storage. However, with `ReplicacheOption.kvStore`\n // and `IDBStoreWithMemFallback` clients may not actually share\n // persistent storage. If storage is not shared, then there is no point\n // in updating, since clients cannot sync locally. If clients do update\n // in this case, they can continually cause each other to update, since\n // on each update the clients get assigned a new client group.\n const updateNeeded = await withRead(\n perdag,\n async (perdagRead: Read) =>\n (await getClientGroup(newClientGroupID, perdagRead)) !==\n undefined,\n );\n if (updateNeeded) {\n onUpdateNeeded();\n }\n } else {\n // Idb name is different, indicating new schema or format version.\n // Update to get assigned to newClientIDBName, and hopefully\n // newClientGroupID.\n // If storage is not actually shared (i.e. due to\n // `ReplicacheOption.kvStore`\n // or `IDBStoreWithMemFallback`) the new client will not\n // get assigned to newClientGroupID, but should get the\n // newClientIDBName.\n // Note: we don't try to read from newClientIDBName to see\n // if this client shares storage with the new client, because\n // the newClientIDBName may have a format version this client\n // cannot read.\n onUpdateNeeded();\n return;\n }\n }\n }\n };\n\n signal.addEventListener('abort', () => channelV1.close(), {once: true});\n}\n"],"mappings":";;;;AAQA,SAAS,kBAAkB,gBAAgC;AACzD,QAAO,+BAA+B;;AAQxC,SAAS,kBAAkB,gBAAgC;AACzD,QAAO,kCAAkC;;AAW3C,SAAS,4BACP,SACsC;AACtC,QACE,OAAO,YAAY,YACnB,OAAQ,QAAqC,kBAAkB,YAC/D,OAAQ,QAA+B,YAAY;;AAIvD,SAAgB,qBACd,gBACA,SACA,QACA,eACA,kBACA,gBACA,QACA;AACA,KAAI,OAAO,QACT;CAGF,MAAM,YAAY,IAAI,GAAiB,kBAAkB,eAAe,CAAC;AACzE,KAAI,kBAAkB;AACpB,YAAU,YAAY;GAAC;GAAe;GAAQ,CAAC;EAE/C,MAAM,YAAY,IAAI,GAAiB,kBAAkB,eAAe,CAAC;AACzE,YAAU,YAAY,CAAC,cAAc,CAAC;AACtC,YAAU,OAAO;;AAGnB,WAAU,YAAY,OAAO,MAAoB;EAC/C,MAAM,EAAC,SAAQ;AACf,MAAI,4BAA4B,KAAK,EAAE;GACrC,MAAM,EAAC,eAAe,kBAAkB,SAAS,qBAAoB;AACrE,OAAI,qBAAqB,cACvB,KAAI,qBAAqB;QASF,MAAM,SACzB,QACA,OAAO,eACJ,MAAM,eAAe,kBAAkB,WAAW,KACnD,KAAA,EACH,CAEC,iBAAgB;UAEb;AAaL,oBAAgB;AAChB;;;;AAMR,QAAO,iBAAiB,eAAe,UAAU,OAAO,EAAE,EAAC,MAAM,MAAK,CAAC"}
1
+ {"version":3,"file":"new-client-channel.js","names":[],"sources":["../../../../replicache/src/new-client-channel.ts"],"sourcesContent":["import {BroadcastChannel} from '../../shared/src/broadcast-channel.ts';\nimport type {Read, Store} from './dag/store.ts';\nimport {getClientGroup} from './persist/client-groups.ts';\nimport {withRead} from './with-transactions.ts';\n\n// Older clients (<= replicache@13.0.1), listened on this channel name\n// and *asserted* that the messages received were an array containing exactly\n// one string.\nfunction makeChannelNameV0(replicacheName: string): string {\n return `replicache-new-client-group:${replicacheName}`;\n}\n\n// This channel name was introduced when we first needed to change the message\n// format. The design of the messages sent on this channel allows for\n// the message content to be extended in the future in a way that is\n// forward and backwards compatible. The message format can be extended\n// by adding new *optional* fields.\nfunction makeChannelNameV1(replicacheName: string): string {\n return `replicache-new-client-group-v1:${replicacheName}`;\n}\n\nexport {\n makeChannelNameV0 as makeChannelNameV0ForTesting,\n makeChannelNameV1 as makeChannelNameV1ForTesting,\n};\n\n// This message type can be extended with optional properties.\ntype NewClientChannelMessageV1 = {clientGroupID: string; idbName: string};\n\nfunction isNewClientChannelMessageV1(\n message: unknown,\n): message is NewClientChannelMessageV1 {\n return (\n typeof message === 'object' &&\n typeof (message as {clientGroupID: unknown}).clientGroupID === 'string' &&\n typeof (message as {idbName: unknown}).idbName === 'string'\n );\n}\n\nexport function initNewClientChannel(\n replicacheName: string,\n idbName: string,\n signal: AbortSignal,\n clientGroupID: string,\n isNewClientGroup: boolean,\n onUpdateNeeded: () => void,\n perdag: Store,\n) {\n if (signal.aborted) {\n return;\n }\n\n const channelV1 = new BroadcastChannel(makeChannelNameV1(replicacheName));\n if (isNewClientGroup) {\n channelV1.postMessage({clientGroupID, idbName});\n // Send expected format to V0 channel for old clients.\n const channelV0 = new BroadcastChannel(makeChannelNameV0(replicacheName));\n channelV0.postMessage([clientGroupID]);\n channelV0.close();\n }\n\n channelV1.onmessage = async (e: MessageEvent) => {\n const {data} = e;\n if (isNewClientChannelMessageV1(data)) {\n const {clientGroupID: newClientGroupID, idbName: newClientIDBName} = data;\n if (newClientGroupID !== clientGroupID) {\n if (newClientIDBName === idbName) {\n // Check if this client can see the new client's newClientGroupID in its\n // perdag. It should be able to if the clients share persistent\n // storage. However, with `ReplicacheOption.kvStore`\n // and `IDBStoreWithMemFallback` clients may not actually share\n // persistent storage. If storage is not shared, then there is no point\n // in updating, since clients cannot sync locally. If clients do update\n // in this case, they can continually cause each other to update, since\n // on each update the clients get assigned a new client group.\n const updateNeeded = await withRead(\n perdag,\n async (perdagRead: Read) =>\n (await getClientGroup(newClientGroupID, perdagRead)) !==\n undefined,\n );\n if (updateNeeded) {\n onUpdateNeeded();\n }\n } else {\n // Idb name is different, indicating new schema or format version.\n // Update to get assigned to newClientIDBName, and hopefully\n // newClientGroupID.\n // If storage is not actually shared (i.e. due to\n // `ReplicacheOption.kvStore`\n // or `IDBStoreWithMemFallback`) the new client will not\n // get assigned to newClientGroupID, but should get the\n // newClientIDBName.\n // Note: we don't try to read from newClientIDBName to see\n // if this client shares storage with the new client, because\n // the newClientIDBName may have a format version this client\n // cannot read.\n onUpdateNeeded();\n return;\n }\n }\n }\n };\n\n signal.addEventListener('abort', () => channelV1.close(), {once: true});\n}\n"],"mappings":";;;;AAQA,SAAS,kBAAkB,gBAAgC;CACzD,OAAO,+BAA+B;AACxC;AAOA,SAAS,kBAAkB,gBAAgC;CACzD,OAAO,kCAAkC;AAC3C;AAUA,SAAS,4BACP,SACsC;CACtC,OACE,OAAO,YAAY,YACnB,OAAQ,QAAqC,kBAAkB,YAC/D,OAAQ,QAA+B,YAAY;AAEvD;AAEA,SAAgB,qBACd,gBACA,SACA,QACA,eACA,kBACA,gBACA,QACA;CACA,IAAI,OAAO,SACT;CAGF,MAAM,YAAY,IAAI,GAAiB,kBAAkB,cAAc,CAAC;CACxE,IAAI,kBAAkB;EACpB,UAAU,YAAY;GAAC;GAAe;EAAO,CAAC;EAE9C,MAAM,YAAY,IAAI,GAAiB,kBAAkB,cAAc,CAAC;EACxE,UAAU,YAAY,CAAC,aAAa,CAAC;EACrC,UAAU,MAAM;CAClB;CAEA,UAAU,YAAY,OAAO,MAAoB;EAC/C,MAAM,EAAC,SAAQ;EACf,IAAI,4BAA4B,IAAI,GAAG;GACrC,MAAM,EAAC,eAAe,kBAAkB,SAAS,qBAAoB;GACrE,IAAI,qBAAqB,eACvB,IAAI,qBAAqB;QAenB,MANuB,SACzB,QACA,OAAO,eACJ,MAAM,eAAe,kBAAkB,UAAU,MAClD,KAAA,CACJ,GAEE,eAAe;GAAA,OAEZ;IAaL,eAAe;IACf;GACF;EAEJ;CACF;CAEA,OAAO,iBAAiB,eAAe,UAAU,MAAM,GAAG,EAAC,MAAM,KAAI,CAAC;AACxE"}
@@ -1 +1 @@
1
- {"version":3,"file":"on-persist-channel.js","names":[],"sources":["../../../../replicache/src/on-persist-channel.ts"],"sourcesContent":["import {assertObject, assertString} from '../../shared/src/asserts.ts';\nimport {BroadcastChannel} from '../../shared/src/broadcast-channel.ts';\nimport type {ClientGroupID, ClientID} from './sync/ids.ts';\n\nfunction makeChannelName(replicacheName: string): string {\n return `replicache-on-persist:${replicacheName}`;\n}\n\nexport type PersistInfo = {\n clientGroupID: ClientGroupID;\n clientID: ClientID;\n};\n\nexport type OnPersist = (persistInfo: PersistInfo) => void;\n\ntype HandlePersist = OnPersist;\n\nfunction assertPersistInfo(value: unknown): asserts value is PersistInfo {\n assertObject(value);\n assertString(value.clientGroupID);\n assertString(value.clientID);\n}\n\nexport function initOnPersistChannel(\n replicacheName: string,\n signal: AbortSignal,\n handlePersist: HandlePersist,\n): OnPersist {\n if (signal.aborted) {\n return () => undefined;\n }\n const channel = new BroadcastChannel(makeChannelName(replicacheName));\n\n channel.onmessage = e => {\n const {data} = e;\n assertPersistInfo(data);\n handlePersist({\n clientGroupID: data.clientGroupID,\n clientID: data.clientID,\n });\n };\n\n signal.addEventListener('abort', () => channel.close(), {once: true});\n\n return (persistInfo: PersistInfo) => {\n if (signal.aborted) {\n return;\n }\n channel.postMessage(persistInfo);\n handlePersist(persistInfo);\n };\n}\n"],"mappings":";;;AAIA,SAAS,gBAAgB,gBAAgC;AACvD,QAAO,yBAAyB;;AAYlC,SAAS,kBAAkB,OAA8C;AACvE,cAAa,MAAM;AACnB,cAAa,MAAM,cAAc;AACjC,cAAa,MAAM,SAAS;;AAG9B,SAAgB,qBACd,gBACA,QACA,eACW;AACX,KAAI,OAAO,QACT,cAAa,KAAA;CAEf,MAAM,UAAU,IAAI,GAAiB,gBAAgB,eAAe,CAAC;AAErE,SAAQ,aAAY,MAAK;EACvB,MAAM,EAAC,SAAQ;AACf,oBAAkB,KAAK;AACvB,gBAAc;GACZ,eAAe,KAAK;GACpB,UAAU,KAAK;GAChB,CAAC;;AAGJ,QAAO,iBAAiB,eAAe,QAAQ,OAAO,EAAE,EAAC,MAAM,MAAK,CAAC;AAErE,SAAQ,gBAA6B;AACnC,MAAI,OAAO,QACT;AAEF,UAAQ,YAAY,YAAY;AAChC,gBAAc,YAAY"}
1
+ {"version":3,"file":"on-persist-channel.js","names":[],"sources":["../../../../replicache/src/on-persist-channel.ts"],"sourcesContent":["import {assertObject, assertString} from '../../shared/src/asserts.ts';\nimport {BroadcastChannel} from '../../shared/src/broadcast-channel.ts';\nimport type {ClientGroupID, ClientID} from './sync/ids.ts';\n\nfunction makeChannelName(replicacheName: string): string {\n return `replicache-on-persist:${replicacheName}`;\n}\n\nexport type PersistInfo = {\n clientGroupID: ClientGroupID;\n clientID: ClientID;\n};\n\nexport type OnPersist = (persistInfo: PersistInfo) => void;\n\ntype HandlePersist = OnPersist;\n\nfunction assertPersistInfo(value: unknown): asserts value is PersistInfo {\n assertObject(value);\n assertString(value.clientGroupID);\n assertString(value.clientID);\n}\n\nexport function initOnPersistChannel(\n replicacheName: string,\n signal: AbortSignal,\n handlePersist: HandlePersist,\n): OnPersist {\n if (signal.aborted) {\n return () => undefined;\n }\n const channel = new BroadcastChannel(makeChannelName(replicacheName));\n\n channel.onmessage = e => {\n const {data} = e;\n assertPersistInfo(data);\n handlePersist({\n clientGroupID: data.clientGroupID,\n clientID: data.clientID,\n });\n };\n\n signal.addEventListener('abort', () => channel.close(), {once: true});\n\n return (persistInfo: PersistInfo) => {\n if (signal.aborted) {\n return;\n }\n channel.postMessage(persistInfo);\n handlePersist(persistInfo);\n };\n}\n"],"mappings":";;;AAIA,SAAS,gBAAgB,gBAAgC;CACvD,OAAO,yBAAyB;AAClC;AAWA,SAAS,kBAAkB,OAA8C;CACvE,aAAa,KAAK;CAClB,aAAa,MAAM,aAAa;CAChC,aAAa,MAAM,QAAQ;AAC7B;AAEA,SAAgB,qBACd,gBACA,QACA,eACW;CACX,IAAI,OAAO,SACT,aAAa,KAAA;CAEf,MAAM,UAAU,IAAI,GAAiB,gBAAgB,cAAc,CAAC;CAEpE,QAAQ,aAAY,MAAK;EACvB,MAAM,EAAC,SAAQ;EACf,kBAAkB,IAAI;EACtB,cAAc;GACZ,eAAe,KAAK;GACpB,UAAU,KAAK;EACjB,CAAC;CACH;CAEA,OAAO,iBAAiB,eAAe,QAAQ,MAAM,GAAG,EAAC,MAAM,KAAI,CAAC;CAEpE,QAAQ,gBAA6B;EACnC,IAAI,OAAO,SACT;EAEF,QAAQ,YAAY,WAAW;EAC/B,cAAc,WAAW;CAC3B;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"patch-operation.js","names":[],"sources":["../../../../replicache/src/patch-operation.ts"],"sourcesContent":["import {\n assertArray,\n assertObject,\n assertString,\n} from '../../shared/src/asserts.ts';\nimport {\n type ReadonlyJSONObject,\n type ReadonlyJSONValue,\n assertJSONObject,\n assertJSONValue,\n} from '../../shared/src/json.ts';\n\nexport type PatchOperationInternal =\n | {\n readonly op: 'put';\n readonly key: string;\n readonly value: ReadonlyJSONValue;\n }\n | {\n readonly op: 'update';\n readonly key: string;\n readonly merge?: ReadonlyJSONObject | undefined;\n readonly constrain?: readonly string[] | undefined;\n }\n | {\n readonly op: 'del';\n readonly key: string;\n }\n | {\n readonly op: 'clear';\n };\n\n/**\n * This type describes the patch field in a {@link PullResponse} and it is used\n * to describe how to update the Replicache key-value store.\n */\nexport type PatchOperation =\n | {\n readonly op: 'put';\n readonly key: string;\n readonly value: ReadonlyJSONValue;\n }\n | {\n readonly op: 'del';\n readonly key: string;\n }\n | {\n readonly op: 'clear';\n };\n\nexport function assertPatchOperations(\n p: unknown,\n): asserts p is PatchOperationInternal[] {\n assertArray(p);\n for (const item of p) {\n assertPatchOperation(item);\n }\n}\n\nfunction assertPatchOperation(p: unknown): asserts p is PatchOperationInternal {\n assertObject(p);\n switch (p.op) {\n case 'put':\n assertString(p.key);\n assertJSONValue(p.value);\n break;\n case 'update':\n assertString(p.key);\n if (p.merge !== undefined) {\n assertJSONObject(p.merge);\n }\n if (p.constrain !== undefined) {\n assertArray(p.constrain);\n for (const key of p.constrain) {\n assertString(key);\n }\n }\n break;\n case 'del':\n assertString(p.key);\n break;\n case 'clear':\n break;\n default:\n throw new Error(\n `unknown patch op \\`${p.op}\\`, expected one of \\`put\\`, \\`del\\`, \\`clear\\``,\n );\n }\n}\n"],"mappings":";;;AAkDA,SAAgB,sBACd,GACuC;AACvC,aAAY,EAAE;AACd,MAAK,MAAM,QAAQ,EACjB,sBAAqB,KAAK;;AAI9B,SAAS,qBAAqB,GAAiD;AAC7E,cAAa,EAAE;AACf,SAAQ,EAAE,IAAV;EACE,KAAK;AACH,gBAAa,EAAE,IAAI;AACnB,mBAAgB,EAAE,MAAM;AACxB;EACF,KAAK;AACH,gBAAa,EAAE,IAAI;AACnB,OAAI,EAAE,UAAU,KAAA,EACd,kBAAiB,EAAE,MAAM;AAE3B,OAAI,EAAE,cAAc,KAAA,GAAW;AAC7B,gBAAY,EAAE,UAAU;AACxB,SAAK,MAAM,OAAO,EAAE,UAClB,cAAa,IAAI;;AAGrB;EACF,KAAK;AACH,gBAAa,EAAE,IAAI;AACnB;EACF,KAAK,QACH;EACF,QACE,OAAM,IAAI,MACR,sBAAsB,EAAE,GAAG,iDAC5B"}
1
+ {"version":3,"file":"patch-operation.js","names":[],"sources":["../../../../replicache/src/patch-operation.ts"],"sourcesContent":["import {\n assertArray,\n assertObject,\n assertString,\n} from '../../shared/src/asserts.ts';\nimport {\n type ReadonlyJSONObject,\n type ReadonlyJSONValue,\n assertJSONObject,\n assertJSONValue,\n} from '../../shared/src/json.ts';\n\nexport type PatchOperationInternal =\n | {\n readonly op: 'put';\n readonly key: string;\n readonly value: ReadonlyJSONValue;\n }\n | {\n readonly op: 'update';\n readonly key: string;\n readonly merge?: ReadonlyJSONObject | undefined;\n readonly constrain?: readonly string[] | undefined;\n }\n | {\n readonly op: 'del';\n readonly key: string;\n }\n | {\n readonly op: 'clear';\n };\n\n/**\n * This type describes the patch field in a {@link PullResponse} and it is used\n * to describe how to update the Replicache key-value store.\n */\nexport type PatchOperation =\n | {\n readonly op: 'put';\n readonly key: string;\n readonly value: ReadonlyJSONValue;\n }\n | {\n readonly op: 'del';\n readonly key: string;\n }\n | {\n readonly op: 'clear';\n };\n\nexport function assertPatchOperations(\n p: unknown,\n): asserts p is PatchOperationInternal[] {\n assertArray(p);\n for (const item of p) {\n assertPatchOperation(item);\n }\n}\n\nfunction assertPatchOperation(p: unknown): asserts p is PatchOperationInternal {\n assertObject(p);\n switch (p.op) {\n case 'put':\n assertString(p.key);\n assertJSONValue(p.value);\n break;\n case 'update':\n assertString(p.key);\n if (p.merge !== undefined) {\n assertJSONObject(p.merge);\n }\n if (p.constrain !== undefined) {\n assertArray(p.constrain);\n for (const key of p.constrain) {\n assertString(key);\n }\n }\n break;\n case 'del':\n assertString(p.key);\n break;\n case 'clear':\n break;\n default:\n throw new Error(\n `unknown patch op \\`${p.op}\\`, expected one of \\`put\\`, \\`del\\`, \\`clear\\``,\n );\n }\n}\n"],"mappings":";;;AAkDA,SAAgB,sBACd,GACuC;CACvC,YAAY,CAAC;CACb,KAAK,MAAM,QAAQ,GACjB,qBAAqB,IAAI;AAE7B;AAEA,SAAS,qBAAqB,GAAiD;CAC7E,aAAa,CAAC;CACd,QAAQ,EAAE,IAAV;EACE,KAAK;GACH,aAAa,EAAE,GAAG;GAClB,gBAAgB,EAAE,KAAK;GACvB;EACF,KAAK;GACH,aAAa,EAAE,GAAG;GAClB,IAAI,EAAE,UAAU,KAAA,GACd,iBAAiB,EAAE,KAAK;GAE1B,IAAI,EAAE,cAAc,KAAA,GAAW;IAC7B,YAAY,EAAE,SAAS;IACvB,KAAK,MAAM,OAAO,EAAE,WAClB,aAAa,GAAG;GAEpB;GACA;EACF,KAAK;GACH,aAAa,EAAE,GAAG;GAClB;EACF,KAAK,SACH;EACF,SACE,MAAM,IAAI,MACR,sBAAsB,EAAE,GAAG,gDAC7B;CACJ;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"pending-mutations.js","names":[],"sources":["../../../../replicache/src/pending-mutations.ts"],"sourcesContent":["import type {ReadonlyJSONValue} from '../../shared/src/json.ts';\nimport {mustGetHeadHash, type Read} from './dag/store.ts';\nimport {DEFAULT_HEAD_NAME, localMutationsDD31} from './db/commit.ts';\nimport type {ClientID} from './sync/ids.ts';\n\nexport type PendingMutation = {\n readonly name: string;\n readonly id: number;\n readonly args: ReadonlyJSONValue;\n readonly clientID: ClientID;\n};\n\n/**\n * This returns the pending changes with the oldest mutations first.\n */\nexport async function pendingMutationsForAPI(\n dagRead: Read,\n): Promise<readonly PendingMutation[]> {\n const mainHeadHash = await mustGetHeadHash(DEFAULT_HEAD_NAME, dagRead);\n const pending = await localMutationsDD31(mainHeadHash, dagRead);\n return pending\n .map(p => ({\n id: p.meta.mutationID,\n name: p.meta.mutatorName,\n args: p.meta.mutatorArgsJSON,\n clientID: p.meta.clientID,\n }))\n .reverse();\n}\n"],"mappings":";;;;;;AAeA,eAAsB,uBACpB,SACqC;AAGrC,SADgB,MAAM,mBADD,MAAM,gBAAgB,mBAAmB,QAAQ,EACf,QAAQ,EAE5D,KAAI,OAAM;EACT,IAAI,EAAE,KAAK;EACX,MAAM,EAAE,KAAK;EACb,MAAM,EAAE,KAAK;EACb,UAAU,EAAE,KAAK;EAClB,EAAE,CACF,SAAS"}
1
+ {"version":3,"file":"pending-mutations.js","names":[],"sources":["../../../../replicache/src/pending-mutations.ts"],"sourcesContent":["import type {ReadonlyJSONValue} from '../../shared/src/json.ts';\nimport {mustGetHeadHash, type Read} from './dag/store.ts';\nimport {DEFAULT_HEAD_NAME, localMutationsDD31} from './db/commit.ts';\nimport type {ClientID} from './sync/ids.ts';\n\nexport type PendingMutation = {\n readonly name: string;\n readonly id: number;\n readonly args: ReadonlyJSONValue;\n readonly clientID: ClientID;\n};\n\n/**\n * This returns the pending changes with the oldest mutations first.\n */\nexport async function pendingMutationsForAPI(\n dagRead: Read,\n): Promise<readonly PendingMutation[]> {\n const mainHeadHash = await mustGetHeadHash(DEFAULT_HEAD_NAME, dagRead);\n const pending = await localMutationsDD31(mainHeadHash, dagRead);\n return pending\n .map(p => ({\n id: p.meta.mutationID,\n name: p.meta.mutatorName,\n args: p.meta.mutatorArgsJSON,\n clientID: p.meta.clientID,\n }))\n .reverse();\n}\n"],"mappings":";;;;;;AAeA,eAAsB,uBACpB,SACqC;CAGrC,QAAO,MADe,mBAAmB,MADd,gBAAgB,mBAAmB,OAAO,GACd,OAAO,GAE3D,KAAI,OAAM;EACT,IAAI,EAAE,KAAK;EACX,MAAM,EAAE,KAAK;EACb,MAAM,EAAE,KAAK;EACb,UAAU,EAAE,KAAK;CACnB,EAAE,EACD,QAAQ;AACb"}
@@ -1 +1 @@
1
- {"version":3,"file":"client-gc.js","names":[],"sources":["../../../../../replicache/src/persist/client-gc.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {initBgIntervalProcess} from '../bg-interval.ts';\nimport type {Store} from '../dag/store.ts';\nimport {\n addDeletedClients,\n type WritableDeletedClients,\n} from '../deleted-clients.ts';\nimport type {ClientID} from '../sync/ids.ts';\nimport {withWrite} from '../with-transactions.ts';\nimport type {Client, OnClientsDeleted} from './clients.ts';\nimport {type ClientMap, getClients, setClients} from './clients.ts';\n\n/**\n * The maximum time a client can be inactive before it is garbage collected.\n * This means that this is the maximum time a tab can be in the background\n * (frozen) and still be able to sync when it comes back to the foreground.\n */\nexport const CLIENT_MAX_INACTIVE_TIME = 24 * 60 * 60 * 1000; // 24 hours\n\n/**\n * How frequently to try to garbage collect clients.\n */\nexport const GC_INTERVAL = 5 * 60 * 1000; // 5 minutes\n\nlet latestGCUpdate: Promise<ClientMap> | undefined;\nexport function getLatestGCUpdate(): Promise<ClientMap> | undefined {\n return latestGCUpdate;\n}\n\nexport function initClientGC(\n clientID: ClientID,\n dagStore: Store,\n clientMaxInactiveTime: number,\n gcInterval: number,\n onClientsDeleted: OnClientsDeleted,\n lc: LogContext,\n signal: AbortSignal,\n): void {\n initBgIntervalProcess(\n 'ClientGC',\n () => {\n latestGCUpdate = gcClients(\n clientID,\n dagStore,\n clientMaxInactiveTime,\n onClientsDeleted,\n );\n return latestGCUpdate;\n },\n () => gcInterval,\n lc,\n signal,\n );\n}\n\nfunction gcClients(\n clientID: ClientID,\n dagStore: Store,\n clientMaxInactiveTime: number,\n onClientsDeleted: OnClientsDeleted,\n): Promise<ClientMap> {\n return withWrite(dagStore, async dagWrite => {\n const now = Date.now();\n const clients = await getClients(dagWrite);\n const deletedClients: WritableDeletedClients = [];\n const newClients: Map<ClientID, Client> = new Map();\n for (const [id, client] of clients) {\n if (\n id === clientID /* never collect ourself */ ||\n now - client.heartbeatTimestampMs <= clientMaxInactiveTime\n ) {\n newClients.set(id, client);\n } else {\n deletedClients.push({\n clientGroupID: client.clientGroupID,\n clientID: id,\n });\n }\n }\n\n if (newClients.size === clients.size) {\n return clients;\n }\n await setClients(newClients, dagWrite);\n const normalizedDeletedClients = await addDeletedClients(\n dagWrite,\n deletedClients,\n );\n await onClientsDeleted(normalizedDeletedClients);\n return newClients;\n });\n}\n"],"mappings":";;;;;;;;;;AAiBA,IAAa,2BAA2B,OAAU,KAAK;;;;AAKvD,IAAa,cAAc,MAAS;AAEpC,IAAI;AAKJ,SAAgB,aACd,UACA,UACA,uBACA,YACA,kBACA,IACA,QACM;AACN,uBACE,kBACM;AACJ,mBAAiB,UACf,UACA,UACA,uBACA,iBACD;AACD,SAAO;UAEH,YACN,IACA,OACD;;AAGH,SAAS,UACP,UACA,UACA,uBACA,kBACoB;AACpB,QAAO,UAAU,UAAU,OAAM,aAAY;EAC3C,MAAM,MAAM,KAAK,KAAK;EACtB,MAAM,UAAU,MAAM,WAAW,SAAS;EAC1C,MAAM,iBAAyC,EAAE;EACjD,MAAM,6BAAoC,IAAI,KAAK;AACnD,OAAK,MAAM,CAAC,IAAI,WAAW,QACzB,KACE,OAAO,YACP,MAAM,OAAO,wBAAwB,sBAErC,YAAW,IAAI,IAAI,OAAO;MAE1B,gBAAe,KAAK;GAClB,eAAe,OAAO;GACtB,UAAU;GACX,CAAC;AAIN,MAAI,WAAW,SAAS,QAAQ,KAC9B,QAAO;AAET,QAAM,WAAW,YAAY,SAAS;AAKtC,QAAM,iBAJ2B,MAAM,kBACrC,UACA,eACD,CAC+C;AAChD,SAAO;GACP"}
1
+ {"version":3,"file":"client-gc.js","names":[],"sources":["../../../../../replicache/src/persist/client-gc.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {initBgIntervalProcess} from '../bg-interval.ts';\nimport type {Store} from '../dag/store.ts';\nimport {\n addDeletedClients,\n type WritableDeletedClients,\n} from '../deleted-clients.ts';\nimport type {ClientID} from '../sync/ids.ts';\nimport {withWrite} from '../with-transactions.ts';\nimport type {Client, OnClientsDeleted} from './clients.ts';\nimport {type ClientMap, getClients, setClients} from './clients.ts';\n\n/**\n * The maximum time a client can be inactive before it is garbage collected.\n * This means that this is the maximum time a tab can be in the background\n * (frozen) and still be able to sync when it comes back to the foreground.\n */\nexport const CLIENT_MAX_INACTIVE_TIME = 24 * 60 * 60 * 1000; // 24 hours\n\n/**\n * How frequently to try to garbage collect clients.\n */\nexport const GC_INTERVAL = 5 * 60 * 1000; // 5 minutes\n\nlet latestGCUpdate: Promise<ClientMap> | undefined;\nexport function getLatestGCUpdate(): Promise<ClientMap> | undefined {\n return latestGCUpdate;\n}\n\nexport function initClientGC(\n clientID: ClientID,\n dagStore: Store,\n clientMaxInactiveTime: number,\n gcInterval: number,\n onClientsDeleted: OnClientsDeleted,\n lc: LogContext,\n signal: AbortSignal,\n): void {\n initBgIntervalProcess(\n 'ClientGC',\n () => {\n latestGCUpdate = gcClients(\n clientID,\n dagStore,\n clientMaxInactiveTime,\n onClientsDeleted,\n );\n return latestGCUpdate;\n },\n () => gcInterval,\n lc,\n signal,\n );\n}\n\nfunction gcClients(\n clientID: ClientID,\n dagStore: Store,\n clientMaxInactiveTime: number,\n onClientsDeleted: OnClientsDeleted,\n): Promise<ClientMap> {\n return withWrite(dagStore, async dagWrite => {\n const now = Date.now();\n const clients = await getClients(dagWrite);\n const deletedClients: WritableDeletedClients = [];\n const newClients: Map<ClientID, Client> = new Map();\n for (const [id, client] of clients) {\n if (\n id === clientID /* never collect ourself */ ||\n now - client.heartbeatTimestampMs <= clientMaxInactiveTime\n ) {\n newClients.set(id, client);\n } else {\n deletedClients.push({\n clientGroupID: client.clientGroupID,\n clientID: id,\n });\n }\n }\n\n if (newClients.size === clients.size) {\n return clients;\n }\n await setClients(newClients, dagWrite);\n const normalizedDeletedClients = await addDeletedClients(\n dagWrite,\n deletedClients,\n );\n await onClientsDeleted(normalizedDeletedClients);\n return newClients;\n });\n}\n"],"mappings":";;;;;;;;;;AAiBA,IAAa,2BAA2B,OAAU,KAAK;;;;AAKvD,IAAa,cAAc,MAAS;AAEpC,IAAI;AAKJ,SAAgB,aACd,UACA,UACA,uBACA,YACA,kBACA,IACA,QACM;CACN,sBACE,kBACM;EACJ,iBAAiB,UACf,UACA,UACA,uBACA,gBACF;EACA,OAAO;CACT,SACM,YACN,IACA,MACF;AACF;AAEA,SAAS,UACP,UACA,UACA,uBACA,kBACoB;CACpB,OAAO,UAAU,UAAU,OAAM,aAAY;EAC3C,MAAM,MAAM,KAAK,IAAI;EACrB,MAAM,UAAU,MAAM,WAAW,QAAQ;EACzC,MAAM,iBAAyC,CAAC;EAChD,MAAM,6BAAoC,IAAI,IAAI;EAClD,KAAK,MAAM,CAAC,IAAI,WAAW,SACzB,IACE,OAAO,YACP,MAAM,OAAO,wBAAwB,uBAErC,WAAW,IAAI,IAAI,MAAM;OAEzB,eAAe,KAAK;GAClB,eAAe,OAAO;GACtB,UAAU;EACZ,CAAC;EAIL,IAAI,WAAW,SAAS,QAAQ,MAC9B,OAAO;EAET,MAAM,WAAW,YAAY,QAAQ;EAKrC,MAAM,iBAAiB,MAJgB,kBACrC,UACA,cACF,CAC+C;EAC/C,OAAO;CACT,CAAC;AACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"client-group-gc.js","names":[],"sources":["../../../../../replicache/src/persist/client-group-gc.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {initBgIntervalProcess} from '../bg-interval.ts';\nimport type {Store} from '../dag/store.ts';\nimport type {ClientGroupID} from '../sync/ids.ts';\nimport {withWrite} from '../with-transactions.ts';\nimport {\n clientGroupHasPendingMutations,\n getClientGroups,\n setClientGroups,\n type ClientGroupMap,\n} from './client-groups.ts';\nimport {getClients} from './clients.ts';\n\nconst GC_INTERVAL_MS = 5 * 60 * 1000; // 5 minutes\n\nlet latestGCUpdate: Promise<ClientGroupMap> | undefined;\nexport function getLatestGCUpdate(): Promise<ClientGroupMap> | undefined {\n return latestGCUpdate;\n}\n\nexport function initClientGroupGC(\n dagStore: Store,\n enableMutationRecovery: boolean,\n lc: LogContext,\n signal: AbortSignal,\n): void {\n initBgIntervalProcess(\n 'ClientGroupGC',\n () => {\n latestGCUpdate = gcClientGroups(dagStore, enableMutationRecovery);\n return latestGCUpdate;\n },\n () => GC_INTERVAL_MS,\n lc,\n signal,\n );\n}\n\n/**\n * This removes client groups that have no clients and no pending mutations.\n * If {@linkcode enableMutationRecovery} is true, it will keep client groups with\n * pending mutations. If it is false, it will remove client groups even when they\n * have pending mutations.\n */\nexport function gcClientGroups(\n dagStore: Store,\n enableMutationRecovery: boolean,\n): Promise<ClientGroupMap> {\n return withWrite(dagStore, async tx => {\n const clients = await getClients(tx);\n const clientGroupIDs = new Set();\n for (const client of clients.values()) {\n clientGroupIDs.add(client.clientGroupID);\n }\n const clientGroups = new Map();\n const removeClientGroups: Set<ClientGroupID> = new Set();\n for (const [clientGroupID, clientGroup] of await getClientGroups(tx)) {\n if (\n clientGroupIDs.has(clientGroupID) ||\n (enableMutationRecovery && clientGroupHasPendingMutations(clientGroup))\n ) {\n clientGroups.set(clientGroupID, clientGroup);\n } else {\n removeClientGroups.add(clientGroupID);\n }\n }\n await setClientGroups(clientGroups, tx);\n // Client group GC doesn't delete individual clients, so we don't call onClientsDeleted\n return clientGroups;\n });\n}\n"],"mappings":";;;;;AAaA,IAAM,iBAAiB,MAAS;AAEhC,IAAI;AAKJ,SAAgB,kBACd,UACA,wBACA,IACA,QACM;AACN,uBACE,uBACM;AACJ,mBAAiB,eAAe,UAAU,uBAAuB;AACjE,SAAO;UAEH,gBACN,IACA,OACD;;;;;;;;AASH,SAAgB,eACd,UACA,wBACyB;AACzB,QAAO,UAAU,UAAU,OAAM,OAAM;EACrC,MAAM,UAAU,MAAM,WAAW,GAAG;EACpC,MAAM,iCAAiB,IAAI,KAAK;AAChC,OAAK,MAAM,UAAU,QAAQ,QAAQ,CACnC,gBAAe,IAAI,OAAO,cAAc;EAE1C,MAAM,+BAAe,IAAI,KAAK;EAC9B,MAAM,qCAAyC,IAAI,KAAK;AACxD,OAAK,MAAM,CAAC,eAAe,gBAAgB,MAAM,gBAAgB,GAAG,CAClE,KACE,eAAe,IAAI,cAAc,IAChC,0BAA0B,+BAA+B,YAAY,CAEtE,cAAa,IAAI,eAAe,YAAY;MAE5C,oBAAmB,IAAI,cAAc;AAGzC,QAAM,gBAAgB,cAAc,GAAG;AAEvC,SAAO;GACP"}
1
+ {"version":3,"file":"client-group-gc.js","names":[],"sources":["../../../../../replicache/src/persist/client-group-gc.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {initBgIntervalProcess} from '../bg-interval.ts';\nimport type {Store} from '../dag/store.ts';\nimport type {ClientGroupID} from '../sync/ids.ts';\nimport {withWrite} from '../with-transactions.ts';\nimport {\n clientGroupHasPendingMutations,\n getClientGroups,\n setClientGroups,\n type ClientGroupMap,\n} from './client-groups.ts';\nimport {getClients} from './clients.ts';\n\nconst GC_INTERVAL_MS = 5 * 60 * 1000; // 5 minutes\n\nlet latestGCUpdate: Promise<ClientGroupMap> | undefined;\nexport function getLatestGCUpdate(): Promise<ClientGroupMap> | undefined {\n return latestGCUpdate;\n}\n\nexport function initClientGroupGC(\n dagStore: Store,\n enableMutationRecovery: boolean,\n lc: LogContext,\n signal: AbortSignal,\n): void {\n initBgIntervalProcess(\n 'ClientGroupGC',\n () => {\n latestGCUpdate = gcClientGroups(dagStore, enableMutationRecovery);\n return latestGCUpdate;\n },\n () => GC_INTERVAL_MS,\n lc,\n signal,\n );\n}\n\n/**\n * This removes client groups that have no clients and no pending mutations.\n * If {@linkcode enableMutationRecovery} is true, it will keep client groups with\n * pending mutations. If it is false, it will remove client groups even when they\n * have pending mutations.\n */\nexport function gcClientGroups(\n dagStore: Store,\n enableMutationRecovery: boolean,\n): Promise<ClientGroupMap> {\n return withWrite(dagStore, async tx => {\n const clients = await getClients(tx);\n const clientGroupIDs = new Set();\n for (const client of clients.values()) {\n clientGroupIDs.add(client.clientGroupID);\n }\n const clientGroups = new Map();\n const removeClientGroups: Set<ClientGroupID> = new Set();\n for (const [clientGroupID, clientGroup] of await getClientGroups(tx)) {\n if (\n clientGroupIDs.has(clientGroupID) ||\n (enableMutationRecovery && clientGroupHasPendingMutations(clientGroup))\n ) {\n clientGroups.set(clientGroupID, clientGroup);\n } else {\n removeClientGroups.add(clientGroupID);\n }\n }\n await setClientGroups(clientGroups, tx);\n // Client group GC doesn't delete individual clients, so we don't call onClientsDeleted\n return clientGroups;\n });\n}\n"],"mappings":";;;;;AAaA,IAAM,iBAAiB,MAAS;AAEhC,IAAI;AAKJ,SAAgB,kBACd,UACA,wBACA,IACA,QACM;CACN,sBACE,uBACM;EACJ,iBAAiB,eAAe,UAAU,sBAAsB;EAChE,OAAO;CACT,SACM,gBACN,IACA,MACF;AACF;;;;;;;AAQA,SAAgB,eACd,UACA,wBACyB;CACzB,OAAO,UAAU,UAAU,OAAM,OAAM;EACrC,MAAM,UAAU,MAAM,WAAW,EAAE;EACnC,MAAM,iCAAiB,IAAI,IAAI;EAC/B,KAAK,MAAM,UAAU,QAAQ,OAAO,GAClC,eAAe,IAAI,OAAO,aAAa;EAEzC,MAAM,+BAAe,IAAI,IAAI;EAC7B,MAAM,qCAAyC,IAAI,IAAI;EACvD,KAAK,MAAM,CAAC,eAAe,gBAAgB,MAAM,gBAAgB,EAAE,GACjE,IACE,eAAe,IAAI,aAAa,KAC/B,0BAA0B,+BAA+B,WAAW,GAErE,aAAa,IAAI,eAAe,WAAW;OAE3C,mBAAmB,IAAI,aAAa;EAGxC,MAAM,gBAAgB,cAAc,EAAE;EAEtC,OAAO;CACT,CAAC;AACH"}
@@ -6,11 +6,51 @@ import { toRefs } from "../dag/chunk.js";
6
6
  import { indexDefinitionsEqual, indexDefinitionsSchema } from "../index-defs.js";
7
7
  //#region ../replicache/src/persist/client-groups.ts
8
8
  var clientGroupSchema = readonlyObject({
9
+ /**
10
+ * The hash of the commit in the perdag last persisted to this client group.
11
+ * Should only be updated by clients assigned to this client group.
12
+ */
9
13
  headHash: hashSchema,
14
+ /**
15
+ * Set of mutator names common to all clients assigned to this client group.
16
+ */
10
17
  mutatorNames: readonlyArray(valita_exports.string()),
18
+ /**
19
+ * Index definitions common to all clients assigned to this client group.
20
+ */
11
21
  indexes: indexDefinitionsSchema,
22
+ /**
23
+ * The highest mutation ID of every client assigned to this client group.
24
+ * Should only be updated by clients assigned to this client group. Read by
25
+ * other clients to determine if there are unacknowledged pending mutations
26
+ * for them to try to recover. This is redundant with information in the
27
+ * commit graph at `headHash`, but allows other clients to determine if there
28
+ * are unacknowledged pending mutations without having to load the commit
29
+ * graph.
30
+ */
12
31
  mutationIDs: readonlyRecord(valita_exports.number()),
32
+ /**
33
+ * The highest lastMutationID received from the server for every client
34
+ * assigned to this client group.
35
+ *
36
+ * Should be updated by the clients assigned to this client group whenever
37
+ * they persist to this client group. Read by other clients to determine if
38
+ * there are unacknowledged pending mutations for them to recover and
39
+ * *updated* by other clients upon successfully recovering pending mutations
40
+ * to avoid redundant pushes of pending mutations.
41
+ *
42
+ * Note: This will be the same as the `lastMutationIDs` of the base snapshot
43
+ * of the client group's commit graph when written by clients assigned to this
44
+ * client group. However, when written by another client recovering mutations
45
+ * it may be different because the other client does not update the commit
46
+ * graph.
47
+ */
13
48
  lastServerAckdMutationIDs: valita_exports.record(valita_exports.number()),
49
+ /**
50
+ * If the server deletes this client group it can signal that the client group
51
+ * was deleted. If that happens we mark this client group as disabled so that
52
+ * we do not use it again when creating new clients.
53
+ */
14
54
  disabled: valita_exports.boolean()
15
55
  });
16
56
  var CLIENT_GROUPS_HEAD_NAME = "client-groups";