@rocicorp/zero 1.11.0 → 1.11.1

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 (737) hide show
  1. package/out/_virtual/{_@oxc-project_runtime@0.130.0/helpers → _@oxc-project_runtime@0.154.0/helpers/esm}/usingCtx.js +2 -2
  2. package/out/analyze-query/src/analyze-cli.js +2 -1
  3. package/out/analyze-query/src/analyze-cli.js.map +1 -1
  4. package/out/analyze-query/src/bin-analyze.js +5 -3
  5. package/out/analyze-query/src/bin-analyze.js.map +1 -1
  6. package/out/analyze-query/src/bin-transform.js +3 -2
  7. package/out/analyze-query/src/bin-transform.js.map +1 -1
  8. package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
  9. package/out/ast-to-zql/src/bin.js +3 -2
  10. package/out/ast-to-zql/src/bin.js.map +1 -1
  11. package/out/ast-to-zql/src/format.js.map +1 -1
  12. package/out/datadog/src/datadog-log-sink.js +5 -4
  13. package/out/datadog/src/datadog-log-sink.js.map +1 -1
  14. package/out/otel/src/log-options.js.map +1 -1
  15. package/out/replicache/src/btree/node.js +13 -11
  16. package/out/replicache/src/btree/node.js.map +1 -1
  17. package/out/replicache/src/btree/read.js +4 -2
  18. package/out/replicache/src/btree/read.js.map +1 -1
  19. package/out/replicache/src/btree/splice.js.map +1 -1
  20. package/out/replicache/src/btree/write.js +9 -5
  21. package/out/replicache/src/btree/write.js.map +1 -1
  22. package/out/replicache/src/config.js +1 -2
  23. package/out/replicache/src/connection-loop.js.map +1 -1
  24. package/out/replicache/src/dag/chunk.js +1 -1
  25. package/out/replicache/src/dag/gc.js.map +1 -1
  26. package/out/replicache/src/dag/lazy-store.js +8 -7
  27. package/out/replicache/src/dag/lazy-store.js.map +1 -1
  28. package/out/replicache/src/dag/store-impl.js +1 -1
  29. package/out/replicache/src/dag/store-impl.js.map +1 -1
  30. package/out/replicache/src/dag/visitor.js.map +1 -1
  31. package/out/replicache/src/db/commit.js +5 -3
  32. package/out/replicache/src/db/commit.js.map +1 -1
  33. package/out/replicache/src/db/read.js +1 -1
  34. package/out/replicache/src/db/read.js.map +1 -1
  35. package/out/replicache/src/db/rebase.js.map +1 -1
  36. package/out/replicache/src/db/write.js +5 -2
  37. package/out/replicache/src/db/write.js.map +1 -1
  38. package/out/replicache/src/deleted-clients.js +3 -2
  39. package/out/replicache/src/deleted-clients.js.map +1 -1
  40. package/out/replicache/src/expo-sqlite.js +1 -2
  41. package/out/replicache/src/frozen-json.js +1 -1
  42. package/out/replicache/src/frozen-json.js.map +1 -1
  43. package/out/replicache/src/get-default-puller.js +1 -1
  44. package/out/replicache/src/hash.js +1 -1
  45. package/out/replicache/src/hash.js.map +1 -1
  46. package/out/replicache/src/impl.js +1 -2
  47. package/out/replicache/src/index-defs.js +5 -3
  48. package/out/replicache/src/index-defs.js.map +1 -1
  49. package/out/replicache/src/kv/expo-sqlite/store.js +1 -1
  50. package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
  51. package/out/replicache/src/kv/idb-store.js +1 -1
  52. package/out/replicache/src/kv/idb-store.js.map +1 -1
  53. package/out/replicache/src/kv/mem-fallback-store.js +1 -1
  54. package/out/replicache/src/kv/mem-fallback-store.js.map +1 -1
  55. package/out/replicache/src/kv/mem-store.js.map +1 -1
  56. package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
  57. package/out/replicache/src/kv/op-sqlite/types.js.map +1 -1
  58. package/out/replicache/src/kv/read-impl.js.map +1 -1
  59. package/out/replicache/src/kv/sqlite-store.js +1 -1
  60. package/out/replicache/src/kv/sqlite-store.js.map +1 -1
  61. package/out/replicache/src/kv/write-impl-base.js +4 -1
  62. package/out/replicache/src/kv/write-impl-base.js.map +1 -1
  63. package/out/replicache/src/kv/write-impl.js.map +1 -1
  64. package/out/replicache/src/log-options.js +2 -1
  65. package/out/replicache/src/log-options.js.map +1 -1
  66. package/out/replicache/src/make-idb-name.js +1 -1
  67. package/out/replicache/src/new-client-channel.js +9 -7
  68. package/out/replicache/src/new-client-channel.js.map +1 -1
  69. package/out/replicache/src/on-persist-channel.js +1 -1
  70. package/out/replicache/src/on-persist-channel.js.map +1 -1
  71. package/out/replicache/src/op-sqlite.js +1 -2
  72. package/out/replicache/src/pending-mutations.js +2 -1
  73. package/out/replicache/src/pending-mutations.js.map +1 -1
  74. package/out/replicache/src/persist/client-gc.js +2 -2
  75. package/out/replicache/src/persist/client-gc.js.map +1 -1
  76. package/out/replicache/src/persist/client-group-gc.js +2 -2
  77. package/out/replicache/src/persist/client-group-gc.js.map +1 -1
  78. package/out/replicache/src/persist/client-groups.js +1 -1
  79. package/out/replicache/src/persist/client-groups.js.map +1 -1
  80. package/out/replicache/src/persist/clients.js +1 -1
  81. package/out/replicache/src/persist/clients.js.map +1 -1
  82. package/out/replicache/src/persist/collect-idb-databases.js +5 -4
  83. package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
  84. package/out/replicache/src/persist/gather-mem-only-visitor.js.map +1 -1
  85. package/out/replicache/src/persist/gather-not-cached-visitor.js.map +1 -1
  86. package/out/replicache/src/persist/heartbeat.js +2 -2
  87. package/out/replicache/src/persist/heartbeat.js.map +1 -1
  88. package/out/replicache/src/persist/idb-databases-store.js +1 -1
  89. package/out/replicache/src/persist/idb-databases-store.js.map +1 -1
  90. package/out/replicache/src/persist/make-client-id.js +1 -1
  91. package/out/replicache/src/persist/make-client-id.js.map +1 -1
  92. package/out/replicache/src/persist/persist.js +3 -2
  93. package/out/replicache/src/persist/persist.js.map +1 -1
  94. package/out/replicache/src/persist/refresh.js +8 -5
  95. package/out/replicache/src/persist/refresh.js.map +1 -1
  96. package/out/replicache/src/process-scheduler.js.map +1 -1
  97. package/out/replicache/src/replicache-impl.js +3 -3
  98. package/out/replicache/src/replicache-impl.js.map +1 -1
  99. package/out/replicache/src/scan-iterator.js.map +1 -1
  100. package/out/replicache/src/scan-options.js +7 -6
  101. package/out/replicache/src/scan-options.js.map +1 -1
  102. package/out/replicache/src/sqlite.js +1 -2
  103. package/out/replicache/src/subscriptions.js +1 -1
  104. package/out/replicache/src/subscriptions.js.map +1 -1
  105. package/out/replicache/src/sync/diff.js +3 -1
  106. package/out/replicache/src/sync/diff.js.map +1 -1
  107. package/out/replicache/src/sync/ids.js.map +1 -1
  108. package/out/replicache/src/sync/patch.js +2 -4
  109. package/out/replicache/src/sync/patch.js.map +1 -1
  110. package/out/replicache/src/sync/pull.js +3 -1
  111. package/out/replicache/src/sync/pull.js.map +1 -1
  112. package/out/replicache/src/sync/push.js.map +1 -1
  113. package/out/replicache/src/sync/request-id.js +1 -1
  114. package/out/replicache/src/sync/request-id.js.map +1 -1
  115. package/out/replicache/src/transactions.js +1 -1
  116. package/out/replicache/src/transactions.js.map +1 -1
  117. package/out/shared/src/arrays.js +4 -1
  118. package/out/shared/src/arrays.js.map +1 -1
  119. package/out/shared/src/asserts.js +1 -1
  120. package/out/shared/src/bigint-json.js.map +1 -1
  121. package/out/shared/src/broadcast-channel.js +1 -1
  122. package/out/shared/src/btree-set.js +11 -8
  123. package/out/shared/src/btree-set.js.map +1 -1
  124. package/out/shared/src/cache.js.map +1 -1
  125. package/out/shared/src/config.js +1 -1
  126. package/out/shared/src/custom-key-map.js.map +1 -1
  127. package/out/shared/src/custom-key-set.js.map +1 -1
  128. package/out/shared/src/deep-clone.js +1 -1
  129. package/out/shared/src/document-visible.js.map +1 -1
  130. package/out/shared/src/dotenv.js.map +1 -1
  131. package/out/shared/src/error.js +1 -1
  132. package/out/shared/src/error.js.map +1 -1
  133. package/out/shared/src/hash.js +2 -2
  134. package/out/shared/src/hash.js.map +1 -1
  135. package/out/shared/src/iterables.js.map +1 -1
  136. package/out/shared/src/json-schema.js.map +1 -1
  137. package/out/shared/src/json.js.map +1 -1
  138. package/out/shared/src/logging-test-utils.js +1 -1
  139. package/out/shared/src/logging.js +1 -1
  140. package/out/shared/src/logging.js.map +1 -1
  141. package/out/shared/src/navigator.js +1 -1
  142. package/out/shared/src/options.js +9 -12
  143. package/out/shared/src/options.js.map +1 -1
  144. package/out/shared/src/promise-race.js.map +1 -1
  145. package/out/shared/src/queue.js.map +1 -1
  146. package/out/shared/src/record-proxy.js.map +1 -1
  147. package/out/shared/src/ring-buffer.js.map +1 -1
  148. package/out/shared/src/size-of-value.js +7 -10
  149. package/out/shared/src/size-of-value.js.map +1 -1
  150. package/out/shared/src/sorted-entries.js.map +1 -1
  151. package/out/shared/src/tdigest-schema.js.map +1 -1
  152. package/out/shared/src/tdigest.js.map +1 -1
  153. package/out/shared/src/valita.js +1 -1
  154. package/out/shared/src/valita.js.map +1 -1
  155. package/out/z2s/src/compiler.js +2 -4
  156. package/out/z2s/src/compiler.js.map +1 -1
  157. package/out/z2s/src/sql.js +1 -1
  158. package/out/z2s/src/sql.js.map +1 -1
  159. package/out/zero/package.js +212 -189
  160. package/out/zero/package.js.map +1 -1
  161. package/out/zero/src/adapters/drizzle.js +1 -2
  162. package/out/zero/src/adapters/kysely.js +1 -2
  163. package/out/zero/src/adapters/pg.js +1 -2
  164. package/out/zero/src/adapters/postgresjs.js +1 -2
  165. package/out/zero/src/adapters/prisma.js +1 -2
  166. package/out/zero/src/analyze.js +1 -2
  167. package/out/zero/src/change-protocol/v0.js +1 -2
  168. package/out/zero/src/expo-sqlite.js +1 -2
  169. package/out/zero/src/op-sqlite.js +1 -2
  170. package/out/zero/src/react-native.js.map +1 -1
  171. package/out/zero/src/sqlite.js +1 -2
  172. package/out/zero/src/zero-cache-dev.js +10 -9
  173. package/out/zero/src/zero-cache-dev.js.map +1 -1
  174. package/out/zero/src/zero-out.js +2 -1
  175. package/out/zero/src/zero-out.js.map +1 -1
  176. package/out/zero-cache/src/auth/auth.js +1 -1
  177. package/out/zero-cache/src/auth/auth.js.map +1 -1
  178. package/out/zero-cache/src/auth/jwt.js +4 -1
  179. package/out/zero-cache/src/auth/jwt.js.map +1 -1
  180. package/out/zero-cache/src/auth/load-permissions.js.map +1 -1
  181. package/out/zero-cache/src/auth/read-authorizer.js +3 -2
  182. package/out/zero-cache/src/auth/read-authorizer.js.map +1 -1
  183. package/out/zero-cache/src/auth/write-authorizer.js +5 -16
  184. package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
  185. package/out/zero-cache/src/config/network.js +1 -1
  186. package/out/zero-cache/src/config/network.js.map +1 -1
  187. package/out/zero-cache/src/config/server-context.js.map +1 -1
  188. package/out/zero-cache/src/config/zero-config.js +2 -2
  189. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  190. package/out/zero-cache/src/custom/fetch.js +1 -1
  191. package/out/zero-cache/src/custom/fetch.js.map +1 -1
  192. package/out/zero-cache/src/custom-queries/transform-query.js.map +1 -1
  193. package/out/zero-cache/src/db/create.js.map +1 -1
  194. package/out/zero-cache/src/db/index-predicate.js.map +1 -1
  195. package/out/zero-cache/src/db/lite-tables.js.map +1 -1
  196. package/out/zero-cache/src/db/migration-lite.js +1 -1
  197. package/out/zero-cache/src/db/migration-lite.js.map +1 -1
  198. package/out/zero-cache/src/db/migration.js +5 -3
  199. package/out/zero-cache/src/db/migration.js.map +1 -1
  200. package/out/zero-cache/src/db/pg-copy-binary.js +4 -3
  201. package/out/zero-cache/src/db/pg-copy-binary.js.map +1 -1
  202. package/out/zero-cache/src/db/pg-copy.js +0 -1
  203. package/out/zero-cache/src/db/pg-copy.js.map +1 -1
  204. package/out/zero-cache/src/db/pg-to-lite.js +1 -1
  205. package/out/zero-cache/src/db/pg-to-lite.js.map +1 -1
  206. package/out/zero-cache/src/db/run-transaction.js.map +1 -1
  207. package/out/zero-cache/src/db/specs.js +7 -5
  208. package/out/zero-cache/src/db/specs.js.map +1 -1
  209. package/out/zero-cache/src/db/sqlite-corruption.js.map +1 -1
  210. package/out/zero-cache/src/db/transaction-pool.js +5 -3
  211. package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
  212. package/out/zero-cache/src/db/warmup.js.map +1 -1
  213. package/out/zero-cache/src/observability/events.js.map +1 -1
  214. package/out/zero-cache/src/observability/log-throttle.js.map +1 -1
  215. package/out/zero-cache/src/observability/metrics.js.map +1 -1
  216. package/out/zero-cache/src/scripts/deploy-permissions.js +4 -2
  217. package/out/zero-cache/src/scripts/deploy-permissions.js.map +1 -1
  218. package/out/zero-cache/src/scripts/permissions.js.map +1 -1
  219. package/out/zero-cache/src/server/anonymous-otel-start.js +2 -1
  220. package/out/zero-cache/src/server/anonymous-otel-start.js.map +1 -1
  221. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  222. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  223. package/out/zero-cache/src/server/logging.js +1 -1
  224. package/out/zero-cache/src/server/logging.js.map +1 -1
  225. package/out/zero-cache/src/server/main.js.map +1 -1
  226. package/out/zero-cache/src/server/otel-log-sink.js.map +1 -1
  227. package/out/zero-cache/src/server/otel-start.js.map +1 -1
  228. package/out/zero-cache/src/server/reaper.js +2 -2
  229. package/out/zero-cache/src/server/reaper.js.map +1 -1
  230. package/out/zero-cache/src/server/replicator.js.map +1 -1
  231. package/out/zero-cache/src/server/runner/run-worker.js +2 -1
  232. package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
  233. package/out/zero-cache/src/server/runner/runtime.js +2 -1
  234. package/out/zero-cache/src/server/runner/runtime.js.map +1 -1
  235. package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
  236. package/out/zero-cache/src/server/shadow-syncer.js +1 -1
  237. package/out/zero-cache/src/server/shadow-syncer.js.map +1 -1
  238. package/out/zero-cache/src/server/slot-keeper.js.map +1 -1
  239. package/out/zero-cache/src/server/syncer-assigner.js.map +1 -1
  240. package/out/zero-cache/src/server/syncer.js.map +1 -1
  241. package/out/zero-cache/src/server/worker-dispatcher.js +1 -1
  242. package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
  243. package/out/zero-cache/src/server/worker-urls.js.map +1 -1
  244. package/out/zero-cache/src/services/analyze.js +1 -1
  245. package/out/zero-cache/src/services/analyze.js.map +1 -1
  246. package/out/zero-cache/src/services/change-source/common/backfill-manager.js +1 -1
  247. package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
  248. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
  249. package/out/zero-cache/src/services/change-source/common/init-cleanup.js.map +1 -1
  250. package/out/zero-cache/src/services/change-source/common/replica-restore.js.map +1 -1
  251. package/out/zero-cache/src/services/change-source/common/replica-schema.js +3 -3
  252. package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
  253. package/out/zero-cache/src/services/change-source/custom/change-source.js +1 -1
  254. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  255. package/out/zero-cache/src/services/change-source/pg/backfill-metadata.js.map +1 -1
  256. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +3 -3
  257. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
  258. package/out/zero-cache/src/services/change-source/pg/change-source-init.js +1 -1
  259. package/out/zero-cache/src/services/change-source/pg/change-source-init.js.map +1 -1
  260. package/out/zero-cache/src/services/change-source/pg/change-source.js +4 -6
  261. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  262. package/out/zero-cache/src/services/change-source/pg/decommission.js +2 -1
  263. package/out/zero-cache/src/services/change-source/pg/decommission.js.map +1 -1
  264. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +5 -3
  265. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  266. package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.js.map +1 -1
  267. package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.js.map +1 -1
  268. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +3 -2
  269. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
  270. package/out/zero-cache/src/services/change-source/pg/lsn.js.map +1 -1
  271. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js +2 -2
  272. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js.map +1 -1
  273. package/out/zero-cache/src/services/change-source/pg/replication-slot-health.js +1 -1
  274. package/out/zero-cache/src/services/change-source/pg/replication-slot-health.js.map +1 -1
  275. package/out/zero-cache/src/services/change-source/pg/replication-slots.js +3 -3
  276. package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
  277. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +1 -1
  278. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
  279. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js +13 -12
  280. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js.map +1 -1
  281. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  282. package/out/zero-cache/src/services/change-source/pg/schema/published.js +1 -1
  283. package/out/zero-cache/src/services/change-source/pg/schema/published.js.map +1 -1
  284. package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js.map +1 -1
  285. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +9 -6
  286. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  287. package/out/zero-cache/src/services/change-source/pg/schema/validation.js +1 -1
  288. package/out/zero-cache/src/services/change-source/pg/schema/validation.js.map +1 -1
  289. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js +1 -1
  290. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js.map +1 -1
  291. package/out/zero-cache/src/services/change-source/protocol/current/control.js.map +1 -1
  292. package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
  293. package/out/zero-cache/src/services/change-source/protocol/current/downstream.js.map +1 -1
  294. package/out/zero-cache/src/services/change-source/protocol/current/status.js.map +1 -1
  295. package/out/zero-cache/src/services/change-source/protocol/current/upstream.js.map +1 -1
  296. package/out/zero-cache/src/services/change-source/protocol/current.js +1 -1
  297. package/out/zero-cache/src/services/change-source/protocol/mod.js +1 -2
  298. package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.js.map +1 -1
  299. package/out/zero-cache/src/services/change-streamer/backfill-state.js +1 -1
  300. package/out/zero-cache/src/services/change-streamer/backfill-state.js.map +1 -1
  301. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js.map +1 -1
  302. package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
  303. package/out/zero-cache/src/services/change-streamer/broadcast.js +1 -1
  304. package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
  305. package/out/zero-cache/src/services/change-streamer/change-log-initializer.js +2 -2
  306. package/out/zero-cache/src/services/change-streamer/change-log-initializer.js.map +1 -1
  307. package/out/zero-cache/src/services/change-streamer/change-log-transaction-hash.js.map +1 -1
  308. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +4 -2
  309. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  310. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +21 -21
  311. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  312. package/out/zero-cache/src/services/change-streamer/change-streamer.js +1 -1
  313. package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
  314. package/out/zero-cache/src/services/change-streamer/drain-tracker.js.map +1 -1
  315. package/out/zero-cache/src/services/change-streamer/forwarder.js +11 -10
  316. package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
  317. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js +1 -1
  318. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js.map +1 -1
  319. package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js +3 -3
  320. package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js.map +1 -1
  321. package/out/zero-cache/src/services/change-streamer/replica-poller.js +1 -1
  322. package/out/zero-cache/src/services/change-streamer/replica-poller.js.map +1 -1
  323. package/out/zero-cache/src/services/change-streamer/restore-admission.js +12 -1
  324. package/out/zero-cache/src/services/change-streamer/restore-admission.js.map +1 -1
  325. package/out/zero-cache/src/services/change-streamer/schema/init.js +1 -1
  326. package/out/zero-cache/src/services/change-streamer/schema/init.js.map +1 -1
  327. package/out/zero-cache/src/services/change-streamer/schema/tables.js +1 -1
  328. package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
  329. package/out/zero-cache/src/services/change-streamer/snapshot-message.js +1 -1
  330. package/out/zero-cache/src/services/change-streamer/snapshot-message.js.map +1 -1
  331. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js.map +1 -1
  332. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js +1 -1
  333. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js.map +1 -1
  334. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.js +1 -1
  335. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.js.map +1 -1
  336. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-purge-scheduler.js.map +1 -1
  337. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.js.map +1 -1
  338. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js +1 -1
  339. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js.map +1 -1
  340. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js +1 -3
  341. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js.map +1 -1
  342. package/out/zero-cache/src/services/change-streamer/storer.js +1 -1
  343. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  344. package/out/zero-cache/src/services/change-streamer/subscribe.js +1 -1
  345. package/out/zero-cache/src/services/change-streamer/subscribe.js.map +1 -1
  346. package/out/zero-cache/src/services/change-streamer/subscriber.js +2 -2
  347. package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
  348. package/out/zero-cache/src/services/change-streamer/upstream-acker.js +0 -1
  349. package/out/zero-cache/src/services/change-streamer/upstream-acker.js.map +1 -1
  350. package/out/zero-cache/src/services/heapz.js +2 -1
  351. package/out/zero-cache/src/services/heapz.js.map +1 -1
  352. package/out/zero-cache/src/services/http-service.js.map +1 -1
  353. package/out/zero-cache/src/services/life-cycle.js +1 -1
  354. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  355. package/out/zero-cache/src/services/limiter/sliding-window-limiter.js +4 -2
  356. package/out/zero-cache/src/services/limiter/sliding-window-limiter.js.map +1 -1
  357. package/out/zero-cache/src/services/litestream/commands.js +1 -1
  358. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  359. package/out/zero-cache/src/services/litestream/litestream-checkpointer.js +2 -2
  360. package/out/zero-cache/src/services/litestream/litestream-checkpointer.js.map +1 -1
  361. package/out/zero-cache/src/services/litestream/litestream-controller.js.map +1 -1
  362. package/out/zero-cache/src/services/litestream/metrics.js.map +1 -1
  363. package/out/zero-cache/src/services/litestream/restore-progress.js.map +1 -1
  364. package/out/zero-cache/src/services/mutagen/mutagen.js +1 -1
  365. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  366. package/out/zero-cache/src/services/mutagen/pusher.js +3 -2
  367. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  368. package/out/zero-cache/src/services/plannerz.js +4 -3
  369. package/out/zero-cache/src/services/plannerz.js.map +1 -1
  370. package/out/zero-cache/src/services/profz.js +5 -3
  371. package/out/zero-cache/src/services/profz.js.map +1 -1
  372. package/out/zero-cache/src/services/replicator/change-log-cookies.js.map +1 -1
  373. package/out/zero-cache/src/services/replicator/change-log-db.js +3 -2
  374. package/out/zero-cache/src/services/replicator/change-log-db.js.map +1 -1
  375. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js +1 -1
  376. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js.map +1 -1
  377. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  378. package/out/zero-cache/src/services/replicator/drain-handler.js.map +1 -1
  379. package/out/zero-cache/src/services/replicator/incremental-sync.js +1 -1
  380. package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
  381. package/out/zero-cache/src/services/replicator/notifier.js.map +1 -1
  382. package/out/zero-cache/src/services/replicator/replication-status.js +4 -3
  383. package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
  384. package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
  385. package/out/zero-cache/src/services/replicator/reporter/recorder.js +1 -1
  386. package/out/zero-cache/src/services/replicator/reporter/recorder.js.map +1 -1
  387. package/out/zero-cache/src/services/replicator/reporter/report-schema.js +1 -1
  388. package/out/zero-cache/src/services/replicator/reporter/report-schema.js.map +1 -1
  389. package/out/zero-cache/src/services/replicator/schema/backfilling.js +1 -1
  390. package/out/zero-cache/src/services/replicator/schema/backfilling.js.map +1 -1
  391. package/out/zero-cache/src/services/replicator/schema/change-log.js.map +1 -1
  392. package/out/zero-cache/src/services/replicator/schema/column-metadata.js +1 -1
  393. package/out/zero-cache/src/services/replicator/schema/column-metadata.js.map +1 -1
  394. package/out/zero-cache/src/services/replicator/schema/replication-state.js +10 -7
  395. package/out/zero-cache/src/services/replicator/schema/replication-state.js.map +1 -1
  396. package/out/zero-cache/src/services/replicator/schema/table-metadata.js.map +1 -1
  397. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js +1 -1
  398. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js.map +1 -1
  399. package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.js +1 -1
  400. package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.js.map +1 -1
  401. package/out/zero-cache/src/services/replicator/write-worker-client.js +1 -1
  402. package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
  403. package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
  404. package/out/zero-cache/src/services/run-ast.js.map +1 -1
  405. package/out/zero-cache/src/services/runner.js.map +1 -1
  406. package/out/zero-cache/src/services/running-state.js.map +1 -1
  407. package/out/zero-cache/src/services/shadow-sync/shadow-sync-service.js.map +1 -1
  408. package/out/zero-cache/src/services/statz.js +2 -1
  409. package/out/zero-cache/src/services/statz.js.map +1 -1
  410. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js +2 -2
  411. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js.map +1 -1
  412. package/out/zero-cache/src/services/view-syncer/advancement-metrics.js.map +1 -1
  413. package/out/zero-cache/src/services/view-syncer/batch-pacer.js.map +1 -1
  414. package/out/zero-cache/src/services/view-syncer/client-handler.js +4 -2
  415. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  416. package/out/zero-cache/src/services/view-syncer/client-schema.js.map +1 -1
  417. package/out/zero-cache/src/services/view-syncer/connection-context-manager.js.map +1 -1
  418. package/out/zero-cache/src/services/view-syncer/cvr-purger.js +2 -2
  419. package/out/zero-cache/src/services/view-syncer/cvr-purger.js.map +1 -1
  420. package/out/zero-cache/src/services/view-syncer/cvr-store.js +9 -5
  421. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  422. package/out/zero-cache/src/services/view-syncer/cvr.js +3 -2
  423. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  424. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js +1 -1
  425. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js.map +1 -1
  426. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
  427. package/out/zero-cache/src/services/view-syncer/e2e-serving-lag.js.map +1 -1
  428. package/out/zero-cache/src/services/view-syncer/hydration-budget.js.map +1 -1
  429. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js +2 -2
  430. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js.map +1 -1
  431. package/out/zero-cache/src/services/view-syncer/inspect-handler.js +5 -3
  432. package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
  433. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +6 -4
  434. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  435. package/out/zero-cache/src/services/view-syncer/plan-warnings.js.map +1 -1
  436. package/out/zero-cache/src/services/view-syncer/push-cost.js.map +1 -1
  437. package/out/zero-cache/src/services/view-syncer/push-cutoff.js.map +1 -1
  438. package/out/zero-cache/src/services/view-syncer/query-covering.js.map +1 -1
  439. package/out/zero-cache/src/services/view-syncer/query-shape.js.map +1 -1
  440. package/out/zero-cache/src/services/view-syncer/query-stats.js +1 -1
  441. package/out/zero-cache/src/services/view-syncer/query-stats.js.map +1 -1
  442. package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
  443. package/out/zero-cache/src/services/view-syncer/schema/cvr.js +1 -1
  444. package/out/zero-cache/src/services/view-syncer/schema/types.js +1 -1
  445. package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
  446. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js +7 -1
  447. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js.map +1 -1
  448. package/out/zero-cache/src/services/view-syncer/snapshotter.js +3 -2
  449. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  450. package/out/zero-cache/src/services/view-syncer/ttl-clock.js.map +1 -1
  451. package/out/zero-cache/src/services/view-syncer/view-syncer.js +4 -6
  452. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  453. package/out/zero-cache/src/types/error-with-level.js.map +1 -1
  454. package/out/zero-cache/src/types/lexi-version.js.map +1 -1
  455. package/out/zero-cache/src/types/lite.js +1 -1
  456. package/out/zero-cache/src/types/lite.js.map +1 -1
  457. package/out/zero-cache/src/types/pg-data-type.js +1 -1
  458. package/out/zero-cache/src/types/pg-data-type.js.map +1 -1
  459. package/out/zero-cache/src/types/pg.js +6 -4
  460. package/out/zero-cache/src/types/pg.js.map +1 -1
  461. package/out/zero-cache/src/types/poke-chunk.js +2 -2
  462. package/out/zero-cache/src/types/poke-chunk.js.map +1 -1
  463. package/out/zero-cache/src/types/processes.js +1 -1
  464. package/out/zero-cache/src/types/processes.js.map +1 -1
  465. package/out/zero-cache/src/types/profiler.js.map +1 -1
  466. package/out/zero-cache/src/types/row-key.js.map +1 -1
  467. package/out/zero-cache/src/types/sql.js.map +1 -1
  468. package/out/zero-cache/src/types/streams.js +10 -9
  469. package/out/zero-cache/src/types/streams.js.map +1 -1
  470. package/out/zero-cache/src/types/strings.js.map +1 -1
  471. package/out/zero-cache/src/types/subscription.js.map +1 -1
  472. package/out/zero-cache/src/types/timeout.js +1 -1
  473. package/out/zero-cache/src/types/websocket-handoff.js +1 -1
  474. package/out/zero-cache/src/types/ws.js +1 -1
  475. package/out/zero-cache/src/workers/connection.js +2 -3
  476. package/out/zero-cache/src/workers/connection.js.map +1 -1
  477. package/out/zero-cache/src/workers/mutator.js.map +1 -1
  478. package/out/zero-cache/src/workers/replicator.js +5 -4
  479. package/out/zero-cache/src/workers/replicator.js.map +1 -1
  480. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  481. package/out/zero-cache/src/workers/syncer.js +2 -2
  482. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  483. package/out/zero-client/src/client/active-clients-manager.js +1 -1
  484. package/out/zero-client/src/client/active-clients-manager.js.map +1 -1
  485. package/out/zero-client/src/client/bindings.js +11 -11
  486. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  487. package/out/zero-client/src/client/connection.js +1 -1
  488. package/out/zero-client/src/client/connection.js.map +1 -1
  489. package/out/zero-client/src/client/context.js.map +1 -1
  490. package/out/zero-client/src/client/crud-impl.js +1 -1
  491. package/out/zero-client/src/client/crud-impl.js.map +1 -1
  492. package/out/zero-client/src/client/crud.js +1 -1
  493. package/out/zero-client/src/client/crud.js.map +1 -1
  494. package/out/zero-client/src/client/custom.js +1 -1
  495. package/out/zero-client/src/client/custom.js.map +1 -1
  496. package/out/zero-client/src/client/delete-clients-manager.js.map +1 -1
  497. package/out/zero-client/src/client/enable-analytics.js +1 -1
  498. package/out/zero-client/src/client/enable-analytics.js.map +1 -1
  499. package/out/zero-client/src/client/error.js.map +1 -1
  500. package/out/zero-client/src/client/inspector/client-group.js.map +1 -1
  501. package/out/zero-client/src/client/inspector/client.js.map +1 -1
  502. package/out/zero-client/src/client/inspector/html-dialog-prompt.js +1 -1
  503. package/out/zero-client/src/client/inspector/html-dialog-prompt.js.map +1 -1
  504. package/out/zero-client/src/client/inspector/inspector.js.map +1 -1
  505. package/out/zero-client/src/client/inspector/lazy-inspector.js.map +1 -1
  506. package/out/zero-client/src/client/inspector/query.js.map +1 -1
  507. package/out/zero-client/src/client/ivm-branch.js +1 -3
  508. package/out/zero-client/src/client/ivm-branch.js.map +1 -1
  509. package/out/zero-client/src/client/keys.js +2 -1
  510. package/out/zero-client/src/client/keys.js.map +1 -1
  511. package/out/zero-client/src/client/log-options.js.map +1 -1
  512. package/out/zero-client/src/client/make-replicache-mutators.js +5 -3
  513. package/out/zero-client/src/client/make-replicache-mutators.js.map +1 -1
  514. package/out/zero-client/src/client/metrics.js +3 -5
  515. package/out/zero-client/src/client/metrics.js.map +1 -1
  516. package/out/zero-client/src/client/mutation-tracker.js.map +1 -1
  517. package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
  518. package/out/zero-client/src/client/options.js.map +1 -1
  519. package/out/zero-client/src/client/query-manager.js +2 -2
  520. package/out/zero-client/src/client/query-manager.js.map +1 -1
  521. package/out/zero-client/src/client/reload-error-handler.js +4 -3
  522. package/out/zero-client/src/client/reload-error-handler.js.map +1 -1
  523. package/out/zero-client/src/client/version.js +1 -1
  524. package/out/zero-client/src/client/zero-poke-handler.js +1 -1
  525. package/out/zero-client/src/client/zero-poke-handler.js.map +1 -1
  526. package/out/zero-client/src/client/zero-rep.js.map +1 -1
  527. package/out/zero-client/src/client/zero.js +19 -11
  528. package/out/zero-client/src/client/zero.js.map +1 -1
  529. package/out/zero-client/src/mod.js +23 -23
  530. package/out/zero-client/src/util/nanoid.js.map +1 -1
  531. package/out/zero-permissions/src/permissions.js +3 -2
  532. package/out/zero-permissions/src/permissions.js.map +1 -1
  533. package/out/zero-pg/src/mod.js +9 -9
  534. package/out/zero-protocol/src/analyze-query-result.js +1 -1
  535. package/out/zero-protocol/src/analyze-query-result.js.map +1 -1
  536. package/out/zero-protocol/src/application-error.js.map +1 -1
  537. package/out/zero-protocol/src/ast.js +19 -9
  538. package/out/zero-protocol/src/ast.js.map +1 -1
  539. package/out/zero-protocol/src/change-desired-queries.js.map +1 -1
  540. package/out/zero-protocol/src/client-schema.js +1 -1
  541. package/out/zero-protocol/src/client-schema.js.map +1 -1
  542. package/out/zero-protocol/src/close-connection.js +1 -1
  543. package/out/zero-protocol/src/close-connection.js.map +1 -1
  544. package/out/zero-protocol/src/connect.js +1 -1
  545. package/out/zero-protocol/src/connect.js.map +1 -1
  546. package/out/zero-protocol/src/custom-queries.js +1 -1
  547. package/out/zero-protocol/src/custom-queries.js.map +1 -1
  548. package/out/zero-protocol/src/data.js +4 -2
  549. package/out/zero-protocol/src/data.js.map +1 -1
  550. package/out/zero-protocol/src/delete-clients.js.map +1 -1
  551. package/out/zero-protocol/src/down.js.map +1 -1
  552. package/out/zero-protocol/src/error.js.map +1 -1
  553. package/out/zero-protocol/src/inspect-down.d.ts +81 -81
  554. package/out/zero-protocol/src/inspect-down.js +1 -1
  555. package/out/zero-protocol/src/inspect-down.js.map +1 -1
  556. package/out/zero-protocol/src/inspect-up.js +1 -1
  557. package/out/zero-protocol/src/inspect-up.js.map +1 -1
  558. package/out/zero-protocol/src/mutate-server.js +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 +1 -1
  562. package/out/zero-protocol/src/mutation.js.map +1 -1
  563. package/out/zero-protocol/src/mutations-patch.js +1 -1
  564. package/out/zero-protocol/src/mutations-patch.js.map +1 -1
  565. package/out/zero-protocol/src/ping.js +1 -1
  566. package/out/zero-protocol/src/ping.js.map +1 -1
  567. package/out/zero-protocol/src/poke.js +1 -1
  568. package/out/zero-protocol/src/poke.js.map +1 -1
  569. package/out/zero-protocol/src/pong.js +1 -1
  570. package/out/zero-protocol/src/pong.js.map +1 -1
  571. package/out/zero-protocol/src/primary-key.js.map +1 -1
  572. package/out/zero-protocol/src/protocol-version.js +1 -0
  573. package/out/zero-protocol/src/protocol-version.js.map +1 -1
  574. package/out/zero-protocol/src/pull.js +1 -1
  575. package/out/zero-protocol/src/pull.js.map +1 -1
  576. package/out/zero-protocol/src/push.js +1 -1
  577. package/out/zero-protocol/src/push.js.map +1 -1
  578. package/out/zero-protocol/src/queries-patch.js +1 -1
  579. package/out/zero-protocol/src/queries-patch.js.map +1 -1
  580. package/out/zero-protocol/src/query-hash-visitor.js.map +1 -1
  581. package/out/zero-protocol/src/query-hash.js +2 -2
  582. package/out/zero-protocol/src/query-server.js +1 -1
  583. package/out/zero-protocol/src/query-server.js.map +1 -1
  584. package/out/zero-protocol/src/row-patch.js.map +1 -1
  585. package/out/zero-protocol/src/up.js.map +1 -1
  586. package/out/zero-protocol/src/update-auth.js.map +1 -1
  587. package/out/zero-protocol/src/version.js.map +1 -1
  588. package/out/zero-react/src/bindings.js +11 -11
  589. package/out/zero-react/src/mod.js +5 -5
  590. package/out/zero-react/src/use-query.js +1 -1
  591. package/out/zero-react/src/use-query.js.map +1 -1
  592. package/out/zero-react/src/zero-provider.d.ts +1 -1
  593. package/out/zero-react/src/zero-provider.d.ts.map +1 -1
  594. package/out/zero-react/src/zero-provider.js +2 -1
  595. package/out/zero-react/src/zero-provider.js.map +1 -1
  596. package/out/zero-react/src/zero.js +23 -23
  597. package/out/zero-schema/src/builder/schema-builder.js +3 -2
  598. package/out/zero-schema/src/builder/schema-builder.js.map +1 -1
  599. package/out/zero-schema/src/builder/table-builder.js +1 -1
  600. package/out/zero-schema/src/builder/table-builder.js.map +1 -1
  601. package/out/zero-schema/src/compiled-permissions.js.map +1 -1
  602. package/out/zero-schema/src/name-mapper.js +7 -5
  603. package/out/zero-schema/src/name-mapper.js.map +1 -1
  604. package/out/zero-schema/src/schema-config.js +1 -1
  605. package/out/zero-schema/src/schema-config.js.map +1 -1
  606. package/out/zero-server/src/adapters/drizzle.js.map +1 -1
  607. package/out/zero-server/src/adapters/kysely.js.map +1 -1
  608. package/out/zero-server/src/adapters/pg.js.map +1 -1
  609. package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
  610. package/out/zero-server/src/adapters/prisma.js.map +1 -1
  611. package/out/zero-server/src/closable-db-transaction.js.map +1 -1
  612. package/out/zero-server/src/custom.js +1 -1
  613. package/out/zero-server/src/custom.js.map +1 -1
  614. package/out/zero-server/src/mod.js +8 -8
  615. package/out/zero-server/src/process-mutations.js.map +1 -1
  616. package/out/zero-server/src/push-processor.js.map +1 -1
  617. package/out/zero-server/src/queries/process-queries.js +2 -1
  618. package/out/zero-server/src/queries/process-queries.js.map +1 -1
  619. package/out/zero-server/src/schema.js +7 -7
  620. package/out/zero-server/src/schema.js.map +1 -1
  621. package/out/zero-server/src/zql-database.js.map +1 -1
  622. package/out/zero-solid/src/bindings.js +11 -11
  623. package/out/zero-solid/src/mod.js +5 -5
  624. package/out/zero-solid/src/solid-view.js +1 -1
  625. package/out/zero-solid/src/solid-view.js.map +1 -1
  626. package/out/zero-solid/src/use-connection-state.js +2 -1
  627. package/out/zero-solid/src/use-connection-state.js.map +1 -1
  628. package/out/zero-solid/src/use-query.js.map +1 -1
  629. package/out/zero-solid/src/use-zero-online.js +2 -1
  630. package/out/zero-solid/src/use-zero-online.js.map +1 -1
  631. package/out/zero-solid/src/use-zero.js +3 -2
  632. package/out/zero-solid/src/use-zero.js.map +1 -1
  633. package/out/zero-solid/src/zero.js +23 -23
  634. package/out/zero-types/src/name-mapper.js.map +1 -1
  635. package/out/zql/src/builder/builder.js +15 -13
  636. package/out/zql/src/builder/builder.js.map +1 -1
  637. package/out/zql/src/builder/correlated-predicate-pushdown.js.map +1 -1
  638. package/out/zql/src/builder/debug-delegate.js.map +1 -1
  639. package/out/zql/src/builder/like.js +0 -1
  640. package/out/zql/src/builder/like.js.map +1 -1
  641. package/out/zql/src/ivm/array-view.js.map +1 -1
  642. package/out/zql/src/ivm/cap.js.map +1 -1
  643. package/out/zql/src/ivm/constraint.js +1 -1
  644. package/out/zql/src/ivm/constraint.js.map +1 -1
  645. package/out/zql/src/ivm/data.js.map +1 -1
  646. package/out/zql/src/ivm/deferred-input.js.map +1 -1
  647. package/out/zql/src/ivm/exists.js +20 -18
  648. package/out/zql/src/ivm/exists.js.map +1 -1
  649. package/out/zql/src/ivm/fan-in.js.map +1 -1
  650. package/out/zql/src/ivm/fan-out.js.map +1 -1
  651. package/out/zql/src/ivm/filter-operators.js +1 -1
  652. package/out/zql/src/ivm/filter-operators.js.map +1 -1
  653. package/out/zql/src/ivm/filter-push.js.map +1 -1
  654. package/out/zql/src/ivm/filter.js.map +1 -1
  655. package/out/zql/src/ivm/flipped-join.js +1 -3
  656. package/out/zql/src/ivm/flipped-join.js.map +1 -1
  657. package/out/zql/src/ivm/join-index-tap.js.map +1 -1
  658. package/out/zql/src/ivm/join-index.js.map +1 -1
  659. package/out/zql/src/ivm/join-utils.js +11 -13
  660. package/out/zql/src/ivm/join-utils.js.map +1 -1
  661. package/out/zql/src/ivm/join.js.map +1 -1
  662. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  663. package/out/zql/src/ivm/memory-source.js +26 -22
  664. package/out/zql/src/ivm/memory-source.js.map +1 -1
  665. package/out/zql/src/ivm/memory-storage.js.map +1 -1
  666. package/out/zql/src/ivm/operator.js +2 -2
  667. package/out/zql/src/ivm/push-accumulated.js +0 -1
  668. package/out/zql/src/ivm/push-accumulated.js.map +1 -1
  669. package/out/zql/src/ivm/skip-yields.js.map +1 -1
  670. package/out/zql/src/ivm/skip.js.map +1 -1
  671. package/out/zql/src/ivm/take-gate.js.map +1 -1
  672. package/out/zql/src/ivm/take.js +1 -1
  673. package/out/zql/src/ivm/take.js.map +1 -1
  674. package/out/zql/src/ivm/union-fan-in.js +1 -1
  675. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  676. package/out/zql/src/ivm/union-fan-out.js.map +1 -1
  677. package/out/zql/src/ivm/view-apply-change.js +1 -1
  678. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  679. package/out/zql/src/mutate/crud.js +3 -2
  680. package/out/zql/src/mutate/crud.js.map +1 -1
  681. package/out/zql/src/planner/planner-builder.js +1 -1
  682. package/out/zql/src/planner/planner-builder.js.map +1 -1
  683. package/out/zql/src/planner/planner-connection.js.map +1 -1
  684. package/out/zql/src/planner/planner-debug.js.map +1 -1
  685. package/out/zql/src/planner/planner-fan-in.js.map +1 -1
  686. package/out/zql/src/planner/planner-fan-out.js.map +1 -1
  687. package/out/zql/src/planner/planner-filter.js.map +1 -1
  688. package/out/zql/src/planner/planner-graph.js +1 -5
  689. package/out/zql/src/planner/planner-graph.js.map +1 -1
  690. package/out/zql/src/planner/planner-join.js +1 -1
  691. package/out/zql/src/planner/planner-join.js.map +1 -1
  692. package/out/zql/src/planner/planner-source.js.map +1 -1
  693. package/out/zql/src/planner/planner-terminus.js.map +1 -1
  694. package/out/zql/src/query/create-builder.js +2 -1
  695. package/out/zql/src/query/create-builder.js.map +1 -1
  696. package/out/zql/src/query/expression.js +1 -1
  697. package/out/zql/src/query/expression.js.map +1 -1
  698. package/out/zql/src/query/measure-push-operator.js.map +1 -1
  699. package/out/zql/src/query/named.js +2 -1
  700. package/out/zql/src/query/named.js.map +1 -1
  701. package/out/zql/src/query/query-delegate-base.js +1 -1
  702. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  703. package/out/zql/src/query/query-impl.js +3 -2
  704. package/out/zql/src/query/query-impl.js.map +1 -1
  705. package/out/zql/src/query/query-registry.js +1 -1
  706. package/out/zql/src/query/query-registry.js.map +1 -1
  707. package/out/zql/src/query/query-transitions.js +1 -1
  708. package/out/zql/src/query/query-transitions.js.map +1 -1
  709. package/out/zql/src/query/runnable-query-impl.js +3 -2
  710. package/out/zql/src/query/runnable-query-impl.js.map +1 -1
  711. package/out/zql/src/query/static-query.js.map +1 -1
  712. package/out/zql/src/query/ttl.js +8 -8
  713. package/out/zql/src/query/ttl.js.map +1 -1
  714. package/out/zql/src/query/validate-input.js.map +1 -1
  715. package/out/zqlite/src/database-storage.js +2 -2
  716. package/out/zqlite/src/database-storage.js.map +1 -1
  717. package/out/zqlite/src/db.js +2 -2
  718. package/out/zqlite/src/db.js.map +1 -1
  719. package/out/zqlite/src/explain-queries.js.map +1 -1
  720. package/out/zqlite/src/index-usage.js.map +1 -1
  721. package/out/zqlite/src/internal/sql-inline.js.map +1 -1
  722. package/out/zqlite/src/internal/sql.js.map +1 -1
  723. package/out/zqlite/src/internal/statement-cache.js +1 -1
  724. package/out/zqlite/src/internal/statement-cache.js.map +1 -1
  725. package/out/zqlite/src/mod.js +5 -5
  726. package/out/zqlite/src/pending-delta.js.map +1 -1
  727. package/out/zqlite/src/query-builder.js +1 -1
  728. package/out/zqlite/src/query-builder.js.map +1 -1
  729. package/out/zqlite/src/query-delegate.js.map +1 -1
  730. package/out/zqlite/src/resolve-scalar-subqueries.js +2 -5
  731. package/out/zqlite/src/resolve-scalar-subqueries.js.map +1 -1
  732. package/out/zqlite/src/sqlite-cost-model.js +3 -2
  733. package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
  734. package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
  735. package/out/zqlite/src/table-source.js +1 -1
  736. package/out/zqlite/src/table-source.js.map +1 -1
  737. package/package.json +16 -14
@@ -1 +1 @@
1
- {"version":3,"file":"deleted-clients.js","names":[],"sources":["../../../../replicache/src/deleted-clients.ts"],"sourcesContent":["import {stringCompare} from '../../shared/src/string-compare.ts';\nimport * as v from '../../shared/src/valita.ts';\nimport type {Read, Write} from './dag/store.ts';\nimport {deepFreeze} from './frozen-json.ts';\nimport {getClients, setClients} from './persist/clients.ts';\nimport {\n clientGroupIDSchema,\n clientIDSchema,\n type ClientGroupID,\n type ClientID,\n} from './sync/ids.ts';\n\n/**\n * We keep track of deleted clients in the {@link DELETED_CLIENTS_HEAD_NAME}\n * head.\n */\nexport const DELETED_CLIENTS_HEAD_NAME = 'deleted-clients-v2';\n\ntype ClientIDPair = {\n clientGroupID: ClientGroupID;\n clientID: ClientID;\n};\n\nexport type DeletedClients = readonly Readonly<ClientIDPair>[];\n\nexport type WritableDeletedClients = ClientIDPair[];\n\nexport const deletedClientsSchema: v.Type<DeletedClients> = v.readonlyArray(\n v.readonlyObject({\n clientGroupID: clientGroupIDSchema,\n clientID: clientIDSchema,\n }),\n);\n\nfunction compare(a: ClientIDPair, b: ClientIDPair): number {\n const cg = stringCompare(a.clientGroupID, b.clientGroupID);\n if (cg !== 0) {\n return cg;\n }\n return stringCompare(a.clientID, b.clientID);\n}\n\nexport function normalizeDeletedClients(\n deletedClients: DeletedClients,\n): DeletedClients {\n return deletedClients\n .toSorted(compare)\n .filter((item, i, arr) => i === 0 || compare(item, arr[i - 1]) !== 0);\n}\n\nexport function mergeDeletedClients(\n a: DeletedClients,\n b: DeletedClients,\n): DeletedClients {\n const merged: WritableDeletedClients = [];\n a = normalizeDeletedClients(a);\n b = normalizeDeletedClients(b);\n for (let i = 0, j = 0; i < a.length || j < b.length;) {\n if (i < a.length && (j >= b.length || compare(a[i], b[j]) < 0)) {\n merged.push(a[i]);\n i++;\n } else if (j < b.length && (i >= a.length || compare(b[j], a[i]) < 0)) {\n merged.push(b[j]);\n j++;\n } else {\n // equal\n merged.push(a[i]);\n i++;\n j++;\n }\n }\n return merged;\n}\n\nexport function removeFromDeletedClients(\n old: DeletedClients,\n toRemove: DeletedClients,\n): DeletedClients {\n old = normalizeDeletedClients(old);\n toRemove = normalizeDeletedClients(toRemove);\n const result: WritableDeletedClients = [];\n for (let i = 0, j = 0; i < old.length;) {\n if (j >= toRemove.length || compare(old[i], toRemove[j]) < 0) {\n result.push(old[i]);\n i++;\n } else if (j < toRemove.length && compare(old[i], toRemove[j]) === 0) {\n // equal, skip\n i++;\n j++;\n } else {\n // old[i] > toRemove[j]\n j++;\n }\n }\n return result;\n}\n\nexport async function setDeletedClients(\n dagWrite: Write,\n deletedClients: DeletedClients,\n): Promise<DeletedClients> {\n // sort and dedupe\n\n const data = normalizeDeletedClients(deletedClients);\n\n const chunkData = deepFreeze(data);\n const chunk = dagWrite.createChunk(chunkData, []);\n await dagWrite.putChunk(chunk);\n await dagWrite.setHead(DELETED_CLIENTS_HEAD_NAME, chunk.hash);\n return data;\n}\n\nexport async function getDeletedClients(\n dagRead: Read,\n): Promise<DeletedClients> {\n const hash = await dagRead.getHead(DELETED_CLIENTS_HEAD_NAME);\n if (hash === undefined) {\n return [];\n }\n const chunk = await dagRead.mustGetChunk(hash);\n\n const res = v.test(chunk.data, deletedClientsSchema);\n if (!res.ok) {\n // If not ok then we ignore this. It might be in the old format but we do\n // not know the clientGroupID of the old clients.\n return [];\n }\n\n return res.value;\n}\n\n/**\n * Adds deleted clients to the {@link DELETED_CLIENTS_HEAD_NAME} head.\n * @returns the new list of deleted clients (sorted and deduped).\n */\nexport async function addDeletedClients(\n dagWrite: Write,\n deletedClientsToAdd: DeletedClients,\n): Promise<DeletedClients> {\n const oldDeletedClients = await getDeletedClients(dagWrite);\n\n return setDeletedClients(\n dagWrite,\n mergeDeletedClients(oldDeletedClients, deletedClientsToAdd),\n );\n}\n\nexport async function removeDeletedClients(\n dagWrite: Write,\n deletedClientsToRemove: DeletedClients,\n): Promise<DeletedClients> {\n const oldDeletedClients = await getDeletedClients(dagWrite);\n return setDeletedClients(\n dagWrite,\n removeFromDeletedClients(oldDeletedClients, deletedClientsToRemove),\n );\n}\n\nexport async function confirmDeletedClients(\n dagWrite: Write,\n deletedClientIds: readonly ClientID[],\n deletedClientGroupIds: readonly ClientGroupID[],\n): Promise<DeletedClients> {\n const deletedClientIDSet = new Set(deletedClientIds);\n const deletedClientGroupIDSet = new Set(deletedClientGroupIds);\n const oldDeletedClients = await getDeletedClients(dagWrite);\n const clients = new Map(await getClients(dagWrite));\n for (const clientID of deletedClientIds) {\n clients.delete(clientID);\n }\n for (const clientGroupID of deletedClientGroupIds) {\n for (const [clientID, client] of clients) {\n if (client.clientGroupID === clientGroupID) {\n clients.delete(clientID);\n }\n }\n }\n\n await setClients(clients, dagWrite);\n\n return setDeletedClients(\n dagWrite,\n oldDeletedClients.filter(\n ({clientGroupID, clientID}) =>\n !deletedClientGroupIDSet.has(clientGroupID) &&\n !deletedClientIDSet.has(clientID),\n ),\n );\n}\n"],"mappings":";;;;;;;;;;AAgBA,IAAa,4BAA4B;AAWzC,IAAa,uBAA+C,cAC1D,eAAiB;CACf,eAAe;CACf,UAAU;AACZ,CAAC,CACH;AAEA,SAAS,QAAQ,GAAiB,GAAyB;CACzD,MAAM,KAAK,cAAc,EAAE,eAAe,EAAE,aAAa;CACzD,IAAI,OAAO,GACT,OAAO;CAET,OAAO,cAAc,EAAE,UAAU,EAAE,QAAQ;AAC7C;AAEA,SAAgB,wBACd,gBACgB;CAChB,OAAO,eACJ,SAAS,OAAO,EAChB,QAAQ,MAAM,GAAG,QAAQ,MAAM,KAAK,QAAQ,MAAM,IAAI,IAAI,EAAE,MAAM,CAAC;AACxE;AAEA,SAAgB,oBACd,GACA,GACgB;CAChB,MAAM,SAAiC,CAAC;CACxC,IAAI,wBAAwB,CAAC;CAC7B,IAAI,wBAAwB,CAAC;CAC7B,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,UAAU,IAAI,EAAE,SAC3C,IAAI,IAAI,EAAE,WAAW,KAAK,EAAE,UAAU,QAAQ,EAAE,IAAI,EAAE,EAAE,IAAI,IAAI;EAC9D,OAAO,KAAK,EAAE,EAAE;EAChB;CACF,OAAO,IAAI,IAAI,EAAE,WAAW,KAAK,EAAE,UAAU,QAAQ,EAAE,IAAI,EAAE,EAAE,IAAI,IAAI;EACrE,OAAO,KAAK,EAAE,EAAE;EAChB;CACF,OAAO;EAEL,OAAO,KAAK,EAAE,EAAE;EAChB;EACA;CACF;CAEF,OAAO;AACT;AAyBA,eAAsB,kBACpB,UACA,gBACyB;CAGzB,MAAM,OAAO,wBAAwB,cAAc;CAEnD,MAAM,YAAY,WAAW,IAAI;CACjC,MAAM,QAAQ,SAAS,YAAY,WAAW,CAAC,CAAC;CAChD,MAAM,SAAS,SAAS,KAAK;CAC7B,MAAM,SAAS,QAAQ,2BAA2B,MAAM,IAAI;CAC5D,OAAO;AACT;AAEA,eAAsB,kBACpB,SACyB;CACzB,MAAM,OAAO,MAAM,QAAQ,QAAQ,yBAAyB;CAC5D,IAAI,SAAS,KAAA,GACX,OAAO,CAAC;CAIV,MAAM,MAAM,MAAO,MAFC,QAAQ,aAAa,IAAI,GAEpB,MAAM,oBAAoB;CACnD,IAAI,CAAC,IAAI,IAGP,OAAO,CAAC;CAGV,OAAO,IAAI;AACb;;;;;AAMA,eAAsB,kBACpB,UACA,qBACyB;CAGzB,OAAO,kBACL,UACA,oBAAoB,MAJU,kBAAkB,QAAQ,GAIjB,mBAAmB,CAC5D;AACF;AAaA,eAAsB,sBACpB,UACA,kBACA,uBACyB;CACzB,MAAM,qBAAqB,IAAI,IAAI,gBAAgB;CACnD,MAAM,0BAA0B,IAAI,IAAI,qBAAqB;CAC7D,MAAM,oBAAoB,MAAM,kBAAkB,QAAQ;CAC1D,MAAM,UAAU,IAAI,IAAI,MAAM,WAAW,QAAQ,CAAC;CAClD,KAAK,MAAM,YAAY,kBACrB,QAAQ,OAAO,QAAQ;CAEzB,KAAK,MAAM,iBAAiB,uBAC1B,KAAK,MAAM,CAAC,UAAU,WAAW,SAC/B,IAAI,OAAO,kBAAkB,eAC3B,QAAQ,OAAO,QAAQ;CAK7B,MAAM,WAAW,SAAS,QAAQ;CAElC,OAAO,kBACL,UACA,kBAAkB,QACf,EAAC,eAAe,eACf,CAAC,wBAAwB,IAAI,aAAa,KAC1C,CAAC,mBAAmB,IAAI,QAAQ,CACpC,CACF;AACF"}
1
+ {"version":3,"file":"deleted-clients.js","names":["v.readonlyArray","v.readonlyObject","v.test"],"sources":["../../../../replicache/src/deleted-clients.ts"],"sourcesContent":["import {stringCompare} from '../../shared/src/string-compare.ts';\nimport * as v from '../../shared/src/valita.ts';\nimport type {Read, Write} from './dag/store.ts';\nimport {deepFreeze} from './frozen-json.ts';\nimport {getClients, setClients} from './persist/clients.ts';\nimport {\n clientGroupIDSchema,\n clientIDSchema,\n type ClientGroupID,\n type ClientID,\n} from './sync/ids.ts';\n\n/**\n * We keep track of deleted clients in the {@link DELETED_CLIENTS_HEAD_NAME}\n * head.\n */\nexport const DELETED_CLIENTS_HEAD_NAME = 'deleted-clients-v2';\n\ntype ClientIDPair = {\n clientGroupID: ClientGroupID;\n clientID: ClientID;\n};\n\nexport type DeletedClients = readonly Readonly<ClientIDPair>[];\n\nexport type WritableDeletedClients = ClientIDPair[];\n\nexport const deletedClientsSchema: v.Type<DeletedClients> = v.readonlyArray(\n v.readonlyObject({\n clientGroupID: clientGroupIDSchema,\n clientID: clientIDSchema,\n }),\n);\n\nfunction compare(a: ClientIDPair, b: ClientIDPair): number {\n const cg = stringCompare(a.clientGroupID, b.clientGroupID);\n if (cg !== 0) {\n return cg;\n }\n return stringCompare(a.clientID, b.clientID);\n}\n\nexport function normalizeDeletedClients(\n deletedClients: DeletedClients,\n): DeletedClients {\n return deletedClients\n .toSorted(compare)\n .filter((item, i, arr) => i === 0 || compare(item, arr[i - 1]) !== 0);\n}\n\nexport function mergeDeletedClients(\n a: DeletedClients,\n b: DeletedClients,\n): DeletedClients {\n const merged: WritableDeletedClients = [];\n a = normalizeDeletedClients(a);\n b = normalizeDeletedClients(b);\n for (let i = 0, j = 0; i < a.length || j < b.length;) {\n if (i < a.length && (j >= b.length || compare(a[i], b[j]) < 0)) {\n merged.push(a[i]);\n i++;\n } else if (j < b.length && (i >= a.length || compare(b[j], a[i]) < 0)) {\n merged.push(b[j]);\n j++;\n } else {\n // equal\n merged.push(a[i]);\n i++;\n j++;\n }\n }\n return merged;\n}\n\nexport function removeFromDeletedClients(\n old: DeletedClients,\n toRemove: DeletedClients,\n): DeletedClients {\n old = normalizeDeletedClients(old);\n toRemove = normalizeDeletedClients(toRemove);\n const result: WritableDeletedClients = [];\n for (let i = 0, j = 0; i < old.length;) {\n if (j >= toRemove.length || compare(old[i], toRemove[j]) < 0) {\n result.push(old[i]);\n i++;\n } else if (j < toRemove.length && compare(old[i], toRemove[j]) === 0) {\n // equal, skip\n i++;\n j++;\n } else {\n // old[i] > toRemove[j]\n j++;\n }\n }\n return result;\n}\n\nexport async function setDeletedClients(\n dagWrite: Write,\n deletedClients: DeletedClients,\n): Promise<DeletedClients> {\n // sort and dedupe\n\n const data = normalizeDeletedClients(deletedClients);\n\n const chunkData = deepFreeze(data);\n const chunk = dagWrite.createChunk(chunkData, []);\n await dagWrite.putChunk(chunk);\n await dagWrite.setHead(DELETED_CLIENTS_HEAD_NAME, chunk.hash);\n return data;\n}\n\nexport async function getDeletedClients(\n dagRead: Read,\n): Promise<DeletedClients> {\n const hash = await dagRead.getHead(DELETED_CLIENTS_HEAD_NAME);\n if (hash === undefined) {\n return [];\n }\n const chunk = await dagRead.mustGetChunk(hash);\n\n const res = v.test(chunk.data, deletedClientsSchema);\n if (!res.ok) {\n // If not ok then we ignore this. It might be in the old format but we do\n // not know the clientGroupID of the old clients.\n return [];\n }\n\n return res.value;\n}\n\n/**\n * Adds deleted clients to the {@link DELETED_CLIENTS_HEAD_NAME} head.\n * @returns the new list of deleted clients (sorted and deduped).\n */\nexport async function addDeletedClients(\n dagWrite: Write,\n deletedClientsToAdd: DeletedClients,\n): Promise<DeletedClients> {\n const oldDeletedClients = await getDeletedClients(dagWrite);\n\n return setDeletedClients(\n dagWrite,\n mergeDeletedClients(oldDeletedClients, deletedClientsToAdd),\n );\n}\n\nexport async function removeDeletedClients(\n dagWrite: Write,\n deletedClientsToRemove: DeletedClients,\n): Promise<DeletedClients> {\n const oldDeletedClients = await getDeletedClients(dagWrite);\n return setDeletedClients(\n dagWrite,\n removeFromDeletedClients(oldDeletedClients, deletedClientsToRemove),\n );\n}\n\nexport async function confirmDeletedClients(\n dagWrite: Write,\n deletedClientIds: readonly ClientID[],\n deletedClientGroupIds: readonly ClientGroupID[],\n): Promise<DeletedClients> {\n const deletedClientIDSet = new Set(deletedClientIds);\n const deletedClientGroupIDSet = new Set(deletedClientGroupIds);\n const oldDeletedClients = await getDeletedClients(dagWrite);\n const clients = new Map(await getClients(dagWrite));\n for (const clientID of deletedClientIds) {\n clients.delete(clientID);\n }\n for (const clientGroupID of deletedClientGroupIds) {\n for (const [clientID, client] of clients) {\n if (client.clientGroupID === clientGroupID) {\n clients.delete(clientID);\n }\n }\n }\n\n await setClients(clients, dagWrite);\n\n return setDeletedClients(\n dagWrite,\n oldDeletedClients.filter(\n ({clientGroupID, clientID}) =>\n !deletedClientGroupIDSet.has(clientGroupID) &&\n !deletedClientIDSet.has(clientID),\n ),\n );\n}\n"],"mappings":";;;;;;;;;;AAgBA,IAAa,4BAA4B;AAWzC,IAAa,uBAA+CA,cAC1DC,eAAiB;CACf,eAAe;CACf,UAAU;AACZ,CAAC,CACH;AAEA,SAAS,QAAQ,GAAiB,GAAyB;CACzD,MAAM,KAAK,cAAc,EAAE,eAAe,EAAE,aAAa;CACzD,IAAI,OAAO,GACT,OAAO;CAET,OAAO,cAAc,EAAE,UAAU,EAAE,QAAQ;AAC7C;AAEA,SAAgB,wBACd,gBACgB;CAChB,OAAO,eACJ,SAAS,OAAO,CAAC,CACjB,QAAQ,MAAM,GAAG,QAAQ,MAAM,KAAK,QAAQ,MAAM,IAAI,IAAI,EAAE,MAAM,CAAC;AACxE;AAEA,SAAgB,oBACd,GACA,GACgB;CAChB,MAAM,SAAiC,CAAC;CACxC,IAAI,wBAAwB,CAAC;CAC7B,IAAI,wBAAwB,CAAC;CAC7B,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,UAAU,IAAI,EAAE,SAC3C,IAAI,IAAI,EAAE,WAAW,KAAK,EAAE,UAAU,QAAQ,EAAE,IAAI,EAAE,EAAE,IAAI,IAAI;EAC9D,OAAO,KAAK,EAAE,EAAE;EAChB;CACF,OAAO,IAAI,IAAI,EAAE,WAAW,KAAK,EAAE,UAAU,QAAQ,EAAE,IAAI,EAAE,EAAE,IAAI,IAAI;EACrE,OAAO,KAAK,EAAE,EAAE;EAChB;CACF,OAAO;EAEL,OAAO,KAAK,EAAE,EAAE;EAChB;EACA;CACF;CAEF,OAAO;AACT;AAyBA,eAAsB,kBACpB,UACA,gBACyB;CAGzB,MAAM,OAAO,wBAAwB,cAAc;CAEnD,MAAM,YAAY,WAAW,IAAI;CACjC,MAAM,QAAQ,SAAS,YAAY,WAAW,CAAC,CAAC;CAChD,MAAM,SAAS,SAAS,KAAK;CAC7B,MAAM,SAAS,QAAQ,2BAA2B,MAAM,IAAI;CAC5D,OAAO;AACT;AAEA,eAAsB,kBACpB,SACyB;CACzB,MAAM,OAAO,MAAM,QAAQ,QAAQ,yBAAyB;CAC5D,IAAI,SAAS,KAAA,GACX,OAAO,CAAC;CAEV,MAAM,QAAQ,MAAM,QAAQ,aAAa,IAAI;CAE7C,MAAM,MAAMC,KAAO,MAAM,MAAM,oBAAoB;CACnD,IAAI,CAAC,IAAI,IAGP,OAAO,CAAC;CAGV,OAAO,IAAI;AACb;;;;;AAMA,eAAsB,kBACpB,UACA,qBACyB;CAGzB,OAAO,kBACL,UACA,oBAAoB,MAJU,kBAAkB,QAAQ,GAIjB,mBAAmB,CAC5D;AACF;AAaA,eAAsB,sBACpB,UACA,kBACA,uBACyB;CACzB,MAAM,qBAAqB,IAAI,IAAI,gBAAgB;CACnD,MAAM,0BAA0B,IAAI,IAAI,qBAAqB;CAC7D,MAAM,oBAAoB,MAAM,kBAAkB,QAAQ;CAC1D,MAAM,UAAU,IAAI,IAAI,MAAM,WAAW,QAAQ,CAAC;CAClD,KAAK,MAAM,YAAY,kBACrB,QAAQ,OAAO,QAAQ;CAEzB,KAAK,MAAM,iBAAiB,uBAC1B,KAAK,MAAM,CAAC,UAAU,WAAW,SAC/B,IAAI,OAAO,kBAAkB,eAC3B,QAAQ,OAAO,QAAQ;CAK7B,MAAM,WAAW,SAAS,QAAQ;CAElC,OAAO,kBACL,UACA,kBAAkB,QACf,EAAC,eAAe,eACf,CAAC,wBAAwB,IAAI,aAAa,KAC1C,CAAC,mBAAmB,IAAI,QAAQ,CACpC,CACF;AACF"}
@@ -1,2 +1 @@
1
- import "./kv/expo-sqlite/store.js";
2
- export {};
1
+ export { expoSQLiteStoreProvider } from "./kv/expo-sqlite/store.js";
@@ -86,6 +86,6 @@ function deepFreezeAllowUndefined(v) {
86
86
  return deepFreeze(v);
87
87
  }
88
88
  //#endregion
89
- export { assertDeepFrozen, deepFreeze, deepFreezeAllowUndefined };
89
+ export { assertDeepFrozen, deepFreeze, deepFreezeAllowUndefined, isDeepFrozen };
90
90
 
91
91
  //# sourceMappingURL=frozen-json.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"frozen-json.js","names":[],"sources":["../../../../replicache/src/frozen-json.ts"],"sourcesContent":["import {throwInvalidType} from '../../shared/src/asserts.ts';\nimport {skipAssertJSONValue} from '../../shared/src/config.ts';\nimport {hasOwn} from '../../shared/src/has-own.ts';\nimport type {\n ReadonlyJSONObject,\n ReadonlyJSONValue,\n} from '../../shared/src/json.ts';\nimport {skipFreeze, skipFrozenAsserts} from './config.ts';\nimport type {Cookie, FrozenCookie} from './cookies.ts';\n\ndeclare const frozenJSONTag: unique symbol;\n\n/**\n * Used to mark a type as having been frozen.\n */\nexport type FrozenTag<T> = T & {readonly [frozenJSONTag]: true};\n\nexport type FrozenJSONValue =\n | null\n | string\n | boolean\n | number\n | FrozenJSONArray\n | FrozenJSONObject;\n\ntype FrozenJSONArray = FrozenTag<ReadonlyArray<FrozenJSONValue>>;\n\nexport type FrozenJSONObject = FrozenTag<{\n readonly [key: string]: FrozenJSONValue;\n}>;\n\n/**\n * We tag deep frozen objects in debug mode so that we do not have to deep\n * freeze an object more than once.\n */\nconst deepFrozenObjects = new WeakSet<object>();\n\n/**\n * Recursively freezes the passed in value (mutates it) and returns it.\n *\n * This is controlled by `skipFreeze` which is true in release mode.\n */\nexport function deepFreeze(v: Cookie): FrozenCookie;\nexport function deepFreeze(v: ReadonlyJSONValue): FrozenJSONValue;\nexport function deepFreeze(v: ReadonlyJSONValue): FrozenJSONValue {\n if (skipFreeze) {\n return v as FrozenJSONValue;\n }\n\n deepFreezeInternal(v, []);\n return v as FrozenJSONValue;\n}\n\nfunction deepFreezeInternal(\n v: ReadonlyJSONValue | undefined,\n seen: object[],\n): void {\n switch (typeof v) {\n case 'undefined':\n throw new TypeError('Unexpected value undefined');\n case 'boolean':\n case 'number':\n case 'string':\n return;\n case 'object': {\n if (v === null) {\n return;\n }\n\n if (deepFrozenObjects.has(v)) {\n return;\n }\n deepFrozenObjects.add(v);\n\n if (seen.includes(v)) {\n throwInvalidType(v, 'Cyclic JSON object');\n }\n\n seen.push(v);\n\n Object.freeze(v);\n if (Array.isArray(v)) {\n deepFreezeArray(v, seen);\n } else {\n deepFreezeObject(v as ReadonlyJSONObject, seen);\n }\n seen.pop();\n return;\n }\n\n default:\n throwInvalidType(v, 'JSON value');\n }\n}\n\nfunction deepFreezeArray(\n v: ReadonlyArray<ReadonlyJSONValue>,\n seen: object[],\n): void {\n for (const item of v) {\n deepFreezeInternal(item, seen);\n }\n}\n\nfunction deepFreezeObject(v: ReadonlyJSONObject, seen: object[]): void {\n for (const k in v) {\n if (hasOwn(v, k)) {\n const value = v[k];\n if (value !== undefined) {\n deepFreezeInternal(value, seen);\n }\n }\n }\n}\n\nexport function assertFrozenJSONValue(\n v: unknown,\n): asserts v is FrozenJSONValue {\n if (skipFrozenAsserts || skipAssertJSONValue) {\n return;\n }\n\n switch (typeof v) {\n case 'boolean':\n case 'number':\n case 'string':\n return;\n case 'object':\n if (v === null) {\n return;\n }\n\n if (isDeepFrozen(v, [])) {\n return;\n }\n }\n throwInvalidType(v, 'JSON value');\n}\n\nexport function assertDeepFrozen<V>(v: V): asserts v is Readonly<V> {\n if (skipFrozenAsserts) {\n return;\n }\n\n if (!isDeepFrozen(v, [])) {\n throw new Error('Expected frozen object');\n }\n}\n\n/**\n * Recursive deep frozen check.\n *\n * It adds frozen objects to the {@link deepFrozenObjects} WeakSet so that we do\n * not have to check the same object more than once.\n */\nexport function isDeepFrozen(v: unknown, seen: object[]): boolean {\n switch (typeof v) {\n case 'boolean':\n case 'number':\n case 'string':\n return true;\n case 'object':\n if (v === null) {\n return true;\n }\n\n if (deepFrozenObjects.has(v)) {\n return true;\n }\n\n if (!Object.isFrozen(v)) {\n return false;\n }\n\n if (seen.includes(v)) {\n throwInvalidType(v, 'Cyclic JSON object');\n }\n\n seen.push(v);\n\n if (Array.isArray(v)) {\n for (const item of v) {\n if (!isDeepFrozen(item, seen)) {\n seen.pop();\n return false;\n }\n }\n } else {\n for (const k in v) {\n if (hasOwn(v, k)) {\n const value = (v as Record<string, unknown>)[k];\n if (value !== undefined && !isDeepFrozen(value, seen)) {\n seen.pop();\n return false;\n }\n }\n }\n }\n\n deepFrozenObjects.add(v);\n seen.pop();\n return true;\n\n default:\n throwInvalidType(v, 'JSON value');\n }\n}\n\nexport type P = Parameters<typeof deepFreeze>[0];\nexport type R = ReturnType<typeof deepFreeze>;\nexport function deepFreezeAllowUndefined(v: P | undefined): R | undefined {\n if (v === undefined) {\n return undefined;\n }\n return deepFreeze(v) as R;\n}\n"],"mappings":";;;;;;;;;AAmCA,IAAM,oCAAoB,IAAI,QAAgB;AAS9C,SAAgB,WAAW,GAAuC;CAChE,IAAI,QACF,OAAO;CAGT,mBAAmB,GAAG,CAAC,CAAC;CACxB,OAAO;AACT;AAEA,SAAS,mBACP,GACA,MACM;CACN,QAAQ,OAAO,GAAf;EACE,KAAK,aACH,MAAM,IAAI,UAAU,4BAA4B;EAClD,KAAK;EACL,KAAK;EACL,KAAK,UACH;EACF,KAAK;GACH,IAAI,MAAM,MACR;GAGF,IAAI,kBAAkB,IAAI,CAAC,GACzB;GAEF,kBAAkB,IAAI,CAAC;GAEvB,IAAI,KAAK,SAAS,CAAC,GACjB,iBAAiB,GAAG,oBAAoB;GAG1C,KAAK,KAAK,CAAC;GAEX,OAAO,OAAO,CAAC;GACf,IAAI,MAAM,QAAQ,CAAC,GACjB,gBAAgB,GAAG,IAAI;QAEvB,iBAAiB,GAAyB,IAAI;GAEhD,KAAK,IAAI;GACT;EAGF,SACE,iBAAiB,GAAG,YAAY;CACpC;AACF;AAEA,SAAS,gBACP,GACA,MACM;CACN,KAAK,MAAM,QAAQ,GACjB,mBAAmB,MAAM,IAAI;AAEjC;AAEA,SAAS,iBAAiB,GAAuB,MAAsB;CACrE,KAAK,MAAM,KAAK,GACd,IAAI,OAAO,GAAG,CAAC,GAAG;EAChB,MAAM,QAAQ,EAAE;EAChB,IAAI,UAAU,KAAA,GACZ,mBAAmB,OAAO,IAAI;CAElC;AAEJ;AA0BA,SAAgB,iBAAoB,GAAgC;CAClE,IAAI,QACF;CAGF,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,GACrB,MAAM,IAAI,MAAM,wBAAwB;AAE5C;;;;;;;AAQA,SAAgB,aAAa,GAAY,MAAyB;CAChE,QAAQ,OAAO,GAAf;EACE,KAAK;EACL,KAAK;EACL,KAAK,UACH,OAAO;EACT,KAAK;GACH,IAAI,MAAM,MACR,OAAO;GAGT,IAAI,kBAAkB,IAAI,CAAC,GACzB,OAAO;GAGT,IAAI,CAAC,OAAO,SAAS,CAAC,GACpB,OAAO;GAGT,IAAI,KAAK,SAAS,CAAC,GACjB,iBAAiB,GAAG,oBAAoB;GAG1C,KAAK,KAAK,CAAC;GAEX,IAAI,MAAM,QAAQ,CAAC;SACZ,MAAM,QAAQ,GACjB,IAAI,CAAC,aAAa,MAAM,IAAI,GAAG;KAC7B,KAAK,IAAI;KACT,OAAO;IACT;UAGF,KAAK,MAAM,KAAK,GACd,IAAI,OAAO,GAAG,CAAC,GAAG;IAChB,MAAM,QAAS,EAA8B;IAC7C,IAAI,UAAU,KAAA,KAAa,CAAC,aAAa,OAAO,IAAI,GAAG;KACrD,KAAK,IAAI;KACT,OAAO;IACT;GACF;GAIJ,kBAAkB,IAAI,CAAC;GACvB,KAAK,IAAI;GACT,OAAO;EAET,SACE,iBAAiB,GAAG,YAAY;CACpC;AACF;AAIA,SAAgB,yBAAyB,GAAiC;CACxE,IAAI,MAAM,KAAA,GACR;CAEF,OAAO,WAAW,CAAC;AACrB"}
1
+ {"version":3,"file":"frozen-json.js","names":["skipFreeze","skipFrozenAsserts"],"sources":["../../../../replicache/src/frozen-json.ts"],"sourcesContent":["import {throwInvalidType} from '../../shared/src/asserts.ts';\nimport {skipAssertJSONValue} from '../../shared/src/config.ts';\nimport {hasOwn} from '../../shared/src/has-own.ts';\nimport type {\n ReadonlyJSONObject,\n ReadonlyJSONValue,\n} from '../../shared/src/json.ts';\nimport {skipFreeze, skipFrozenAsserts} from './config.ts';\nimport type {Cookie, FrozenCookie} from './cookies.ts';\n\ndeclare const frozenJSONTag: unique symbol;\n\n/**\n * Used to mark a type as having been frozen.\n */\nexport type FrozenTag<T> = T & {readonly [frozenJSONTag]: true};\n\nexport type FrozenJSONValue =\n | null\n | string\n | boolean\n | number\n | FrozenJSONArray\n | FrozenJSONObject;\n\ntype FrozenJSONArray = FrozenTag<ReadonlyArray<FrozenJSONValue>>;\n\nexport type FrozenJSONObject = FrozenTag<{\n readonly [key: string]: FrozenJSONValue;\n}>;\n\n/**\n * We tag deep frozen objects in debug mode so that we do not have to deep\n * freeze an object more than once.\n */\nconst deepFrozenObjects = new WeakSet<object>();\n\n/**\n * Recursively freezes the passed in value (mutates it) and returns it.\n *\n * This is controlled by `skipFreeze` which is true in release mode.\n */\nexport function deepFreeze(v: Cookie): FrozenCookie;\nexport function deepFreeze(v: ReadonlyJSONValue): FrozenJSONValue;\nexport function deepFreeze(v: ReadonlyJSONValue): FrozenJSONValue {\n if (skipFreeze) {\n return v as FrozenJSONValue;\n }\n\n deepFreezeInternal(v, []);\n return v as FrozenJSONValue;\n}\n\nfunction deepFreezeInternal(\n v: ReadonlyJSONValue | undefined,\n seen: object[],\n): void {\n switch (typeof v) {\n case 'undefined':\n throw new TypeError('Unexpected value undefined');\n case 'boolean':\n case 'number':\n case 'string':\n return;\n case 'object': {\n if (v === null) {\n return;\n }\n\n if (deepFrozenObjects.has(v)) {\n return;\n }\n deepFrozenObjects.add(v);\n\n if (seen.includes(v)) {\n throwInvalidType(v, 'Cyclic JSON object');\n }\n\n seen.push(v);\n\n Object.freeze(v);\n if (Array.isArray(v)) {\n deepFreezeArray(v, seen);\n } else {\n deepFreezeObject(v as ReadonlyJSONObject, seen);\n }\n seen.pop();\n return;\n }\n\n default:\n throwInvalidType(v, 'JSON value');\n }\n}\n\nfunction deepFreezeArray(\n v: ReadonlyArray<ReadonlyJSONValue>,\n seen: object[],\n): void {\n for (const item of v) {\n deepFreezeInternal(item, seen);\n }\n}\n\nfunction deepFreezeObject(v: ReadonlyJSONObject, seen: object[]): void {\n for (const k in v) {\n if (hasOwn(v, k)) {\n const value = v[k];\n if (value !== undefined) {\n deepFreezeInternal(value, seen);\n }\n }\n }\n}\n\nexport function assertFrozenJSONValue(\n v: unknown,\n): asserts v is FrozenJSONValue {\n if (skipFrozenAsserts || skipAssertJSONValue) {\n return;\n }\n\n switch (typeof v) {\n case 'boolean':\n case 'number':\n case 'string':\n return;\n case 'object':\n if (v === null) {\n return;\n }\n\n if (isDeepFrozen(v, [])) {\n return;\n }\n }\n throwInvalidType(v, 'JSON value');\n}\n\nexport function assertDeepFrozen<V>(v: V): asserts v is Readonly<V> {\n if (skipFrozenAsserts) {\n return;\n }\n\n if (!isDeepFrozen(v, [])) {\n throw new Error('Expected frozen object');\n }\n}\n\n/**\n * Recursive deep frozen check.\n *\n * It adds frozen objects to the {@link deepFrozenObjects} WeakSet so that we do\n * not have to check the same object more than once.\n */\nexport function isDeepFrozen(v: unknown, seen: object[]): boolean {\n switch (typeof v) {\n case 'boolean':\n case 'number':\n case 'string':\n return true;\n case 'object':\n if (v === null) {\n return true;\n }\n\n if (deepFrozenObjects.has(v)) {\n return true;\n }\n\n if (!Object.isFrozen(v)) {\n return false;\n }\n\n if (seen.includes(v)) {\n throwInvalidType(v, 'Cyclic JSON object');\n }\n\n seen.push(v);\n\n if (Array.isArray(v)) {\n for (const item of v) {\n if (!isDeepFrozen(item, seen)) {\n seen.pop();\n return false;\n }\n }\n } else {\n for (const k in v) {\n if (hasOwn(v, k)) {\n const value = (v as Record<string, unknown>)[k];\n if (value !== undefined && !isDeepFrozen(value, seen)) {\n seen.pop();\n return false;\n }\n }\n }\n }\n\n deepFrozenObjects.add(v);\n seen.pop();\n return true;\n\n default:\n throwInvalidType(v, 'JSON value');\n }\n}\n\nexport type P = Parameters<typeof deepFreeze>[0];\nexport type R = ReturnType<typeof deepFreeze>;\nexport function deepFreezeAllowUndefined(v: P | undefined): R | undefined {\n if (v === undefined) {\n return undefined;\n }\n return deepFreeze(v) as R;\n}\n"],"mappings":";;;;;;;;;AAmCA,IAAM,oCAAoB,IAAI,QAAgB;AAS9C,SAAgB,WAAW,GAAuC;CAChE,IAAIA,QACF,OAAO;CAGT,mBAAmB,GAAG,CAAC,CAAC;CACxB,OAAO;AACT;AAEA,SAAS,mBACP,GACA,MACM;CACN,QAAQ,OAAO,GAAf;EACE,KAAK,aACH,MAAM,IAAI,UAAU,4BAA4B;EAClD,KAAK;EACL,KAAK;EACL,KAAK,UACH;EACF,KAAK;GACH,IAAI,MAAM,MACR;GAGF,IAAI,kBAAkB,IAAI,CAAC,GACzB;GAEF,kBAAkB,IAAI,CAAC;GAEvB,IAAI,KAAK,SAAS,CAAC,GACjB,iBAAiB,GAAG,oBAAoB;GAG1C,KAAK,KAAK,CAAC;GAEX,OAAO,OAAO,CAAC;GACf,IAAI,MAAM,QAAQ,CAAC,GACjB,gBAAgB,GAAG,IAAI;QAEvB,iBAAiB,GAAyB,IAAI;GAEhD,KAAK,IAAI;GACT;EAGF,SACE,iBAAiB,GAAG,YAAY;CACpC;AACF;AAEA,SAAS,gBACP,GACA,MACM;CACN,KAAK,MAAM,QAAQ,GACjB,mBAAmB,MAAM,IAAI;AAEjC;AAEA,SAAS,iBAAiB,GAAuB,MAAsB;CACrE,KAAK,MAAM,KAAK,GACd,IAAI,OAAO,GAAG,CAAC,GAAG;EAChB,MAAM,QAAQ,EAAE;EAChB,IAAI,UAAU,KAAA,GACZ,mBAAmB,OAAO,IAAI;CAElC;AAEJ;AA0BA,SAAgB,iBAAoB,GAAgC;CAClE,IAAIC,QACF;CAGF,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,GACrB,MAAM,IAAI,MAAM,wBAAwB;AAE5C;;;;;;;AAQA,SAAgB,aAAa,GAAY,MAAyB;CAChE,QAAQ,OAAO,GAAf;EACE,KAAK;EACL,KAAK;EACL,KAAK,UACH,OAAO;EACT,KAAK;GACH,IAAI,MAAM,MACR,OAAO;GAGT,IAAI,kBAAkB,IAAI,CAAC,GACzB,OAAO;GAGT,IAAI,CAAC,OAAO,SAAS,CAAC,GACpB,OAAO;GAGT,IAAI,KAAK,SAAS,CAAC,GACjB,iBAAiB,GAAG,oBAAoB;GAG1C,KAAK,KAAK,CAAC;GAEX,IAAI,MAAM,QAAQ,CAAC,GACZ;SAAA,MAAM,QAAQ,GACjB,IAAI,CAAC,aAAa,MAAM,IAAI,GAAG;KAC7B,KAAK,IAAI;KACT,OAAO;IACT;UAGF,KAAK,MAAM,KAAK,GACd,IAAI,OAAO,GAAG,CAAC,GAAG;IAChB,MAAM,QAAS,EAA8B;IAC7C,IAAI,UAAU,KAAA,KAAa,CAAC,aAAa,OAAO,IAAI,GAAG;KACrD,KAAK,IAAI;KACT,OAAO;IACT;GACF;GAIJ,kBAAkB,IAAI,CAAC;GACvB,KAAK,IAAI;GACT,OAAO;EAET,SACE,iBAAiB,GAAG,YAAY;CACpC;AACF;AAIA,SAAgB,yBAAyB,GAAiC;CACxE,IAAI,MAAM,KAAA,GACR;CAEF,OAAO,WAAW,CAAC;AACrB"}
@@ -44,6 +44,6 @@ function assertPullerResultV1(v) {
44
44
  if (v.response !== void 0) assertPullResponseV1(v.response);
45
45
  }
46
46
  //#endregion
47
- export { assertPullerResultV1, getDefaultPuller, isDefaultPuller };
47
+ export { assertPullResponseV1, assertPullerResultV1, getDefaultPuller, isDefaultPuller };
48
48
 
49
49
  //# sourceMappingURL=get-default-puller.js.map
@@ -33,6 +33,6 @@ function assertHash(value) {
33
33
  }
34
34
  var hashSchema = valita_exports.string().assert(isHash, "Invalid hash");
35
35
  //#endregion
36
- export { assertHash, emptyHash, hashSchema, newRandomHash };
36
+ export { assertHash, emptyHash, hashSchema, isHash, newRandomHash };
37
37
 
38
38
  //# sourceMappingURL=hash.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hash.js","names":[],"sources":["../../../../replicache/src/hash.ts"],"sourcesContent":["import {assert} from '../../shared/src/asserts.ts';\nimport {randomUint64} from '../../shared/src/random-uint64.ts';\nimport * as valita from '../../shared/src/valita.ts';\n\nexport const STRING_LENGTH = 22;\n\n// We use an opaque type so that we can make sure that a hash is always a hash.\n// TypeScript does not have direct support but we can use a trick described\n// here:\n//\n// https://evertpot.com/opaque-ts-types/\n//\n// The basic idea is to declare a type that cannot be created. We then use\n// functions that cast a string to this type.\n//\n\n// By using declare we tell the type system that there is a unique symbol.\n// However, there is no such symbol but the type system does not care.\ndeclare const hashTag: unique symbol;\n\n/**\n * Opaque type representing a hash. The only way to create one is using `parse`\n * or `hashOf` (except for static unsafe cast of course).\n */\nexport type Hash = string & {[hashTag]: true};\n\n// We are no longer using hashes but due to legacy reason we still refer to\n// them as hashes. We use UUID and counters instead.\nconst hashRe = /^[0-9a-v-]+$/;\n\nexport function parse(s: string): Hash {\n assertHash(s);\n return s;\n}\n\nconst emptyUUID = '0'.repeat(STRING_LENGTH);\nexport const emptyHash = emptyUUID as unknown as Hash;\n\n/**\n * Creates a function that generates random hashes.\n */\nexport const newRandomHash = makeNewRandomHashFunctionInternal();\n\nconst fakeHashRe = /^[0-9a-v]{0,8}$/;\n\n/**\n * Creates a function that generates UUID hashes for tests.\n */\nexport function makeNewFakeHashFunction(hashPrefix = 'fake'): () => Hash {\n assert(fakeHashRe.test(hashPrefix), `Invalid hash prefix: ${hashPrefix}`);\n let i = 0;\n return () => {\n const count = String(i++);\n return (hashPrefix +\n '0'.repeat(STRING_LENGTH - hashPrefix.length - count.length) +\n count) as Hash;\n };\n}\n\nfunction toStringAndSlice(n: number | bigint, len: number): string {\n return n.toString(32).slice(-len).padStart(len, '0');\n}\n\n/**\n * This creates an ID that looks like `<RANDOM><COUNTER>`. The random part is\n * a random number encoded with base 32 and the length is 12 characters. The\n * is 10 characters long and encoded as base 32. The total length is 22 characters.\n *\n * Do the math: https://devina.io/collision-calculator\n */\nfunction makeNewRandomHashFunctionInternal(): () => Hash {\n let base = '';\n let i = 0;\n\n return () => {\n if (!base) {\n // This needs to be lazy because the cloudflare worker environment will\n // throw an error if crypto.getRandomValues is used statically. Specifically:\n // Error: Some functionality, such as asynchronous I/O, timeouts, and\n // generating random values, can only be performed while handling a\n // request.\n base = toStringAndSlice(randomUint64(), 12);\n }\n const tail = toStringAndSlice(i++, 10);\n return (base + tail) as Hash;\n };\n}\n\n/**\n * Generates a fake hash useful for testing.\n */\nexport function fakeHash(word: string | number): Hash {\n if (typeof word === 'number') {\n word = String(word);\n }\n return ('fake' + '0'.repeat(STRING_LENGTH - 4 - word.length) + word) as Hash;\n}\n\nexport function isHash(value: unknown): value is Hash {\n return typeof value === 'string' && hashRe.test(value);\n}\n\nexport function assertHash(value: unknown): asserts value is Hash {\n valita.assert(value, hashSchema);\n}\n\nexport const hashSchema = valita.string().assert(isHash, 'Invalid hash');\n"],"mappings":";;AA4BA,IAAM,SAAS;AAQf,IAAa,YADK,IAAI,OAAA,EACG;;;;AAKzB,IAAa,gBAAgB,kCAAkC;AAkB/D,SAAS,iBAAiB,GAAoB,KAAqB;CACjE,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,GAAG,EAAE,SAAS,KAAK,GAAG;AACrD;;;;;;;;AASA,SAAS,oCAAgD;CACvD,IAAI,OAAO;CACX,IAAI,IAAI;CAER,aAAa;EACX,IAAI,CAAC,MAMH,OAAO,iBAAiB,aAAa,GAAG,EAAE;EAE5C,MAAM,OAAO,iBAAiB,KAAK,EAAE;EACrC,OAAQ,OAAO;CACjB;AACF;AAYA,SAAgB,OAAO,OAA+B;CACpD,OAAO,OAAO,UAAU,YAAY,OAAO,KAAK,KAAK;AACvD;AAEA,SAAgB,WAAW,OAAuC;CAChE,OAAc,OAAO,UAAU;AACjC;AAEA,IAAa,aAAa,eAAO,OAAO,EAAE,OAAO,QAAQ,cAAc"}
1
+ {"version":3,"file":"hash.js","names":["valita"],"sources":["../../../../replicache/src/hash.ts"],"sourcesContent":["import {assert} from '../../shared/src/asserts.ts';\nimport {randomUint64} from '../../shared/src/random-uint64.ts';\nimport * as valita from '../../shared/src/valita.ts';\n\nexport const STRING_LENGTH = 22;\n\n// We use an opaque type so that we can make sure that a hash is always a hash.\n// TypeScript does not have direct support but we can use a trick described\n// here:\n//\n// https://evertpot.com/opaque-ts-types/\n//\n// The basic idea is to declare a type that cannot be created. We then use\n// functions that cast a string to this type.\n//\n\n// By using declare we tell the type system that there is a unique symbol.\n// However, there is no such symbol but the type system does not care.\ndeclare const hashTag: unique symbol;\n\n/**\n * Opaque type representing a hash. The only way to create one is using `parse`\n * or `hashOf` (except for static unsafe cast of course).\n */\nexport type Hash = string & {[hashTag]: true};\n\n// We are no longer using hashes but due to legacy reason we still refer to\n// them as hashes. We use UUID and counters instead.\nconst hashRe = /^[0-9a-v-]+$/;\n\nexport function parse(s: string): Hash {\n assertHash(s);\n return s;\n}\n\nconst emptyUUID = '0'.repeat(STRING_LENGTH);\nexport const emptyHash = emptyUUID as unknown as Hash;\n\n/**\n * Creates a function that generates random hashes.\n */\nexport const newRandomHash = makeNewRandomHashFunctionInternal();\n\nconst fakeHashRe = /^[0-9a-v]{0,8}$/;\n\n/**\n * Creates a function that generates UUID hashes for tests.\n */\nexport function makeNewFakeHashFunction(hashPrefix = 'fake'): () => Hash {\n assert(fakeHashRe.test(hashPrefix), `Invalid hash prefix: ${hashPrefix}`);\n let i = 0;\n return () => {\n const count = String(i++);\n return (hashPrefix +\n '0'.repeat(STRING_LENGTH - hashPrefix.length - count.length) +\n count) as Hash;\n };\n}\n\nfunction toStringAndSlice(n: number | bigint, len: number): string {\n return n.toString(32).slice(-len).padStart(len, '0');\n}\n\n/**\n * This creates an ID that looks like `<RANDOM><COUNTER>`. The random part is\n * a random number encoded with base 32 and the length is 12 characters. The\n * is 10 characters long and encoded as base 32. The total length is 22 characters.\n *\n * Do the math: https://devina.io/collision-calculator\n */\nfunction makeNewRandomHashFunctionInternal(): () => Hash {\n let base = '';\n let i = 0;\n\n return () => {\n if (!base) {\n // This needs to be lazy because the cloudflare worker environment will\n // throw an error if crypto.getRandomValues is used statically. Specifically:\n // Error: Some functionality, such as asynchronous I/O, timeouts, and\n // generating random values, can only be performed while handling a\n // request.\n base = toStringAndSlice(randomUint64(), 12);\n }\n const tail = toStringAndSlice(i++, 10);\n return (base + tail) as Hash;\n };\n}\n\n/**\n * Generates a fake hash useful for testing.\n */\nexport function fakeHash(word: string | number): Hash {\n if (typeof word === 'number') {\n word = String(word);\n }\n return ('fake' + '0'.repeat(STRING_LENGTH - 4 - word.length) + word) as Hash;\n}\n\nexport function isHash(value: unknown): value is Hash {\n return typeof value === 'string' && hashRe.test(value);\n}\n\nexport function assertHash(value: unknown): asserts value is Hash {\n valita.assert(value, hashSchema);\n}\n\nexport const hashSchema = valita.string().assert(isHash, 'Invalid hash');\n"],"mappings":";;AA4BA,IAAM,SAAS;AAQf,IAAa,YADK,IAAI,OAAA,EACG;;;;AAKzB,IAAa,gBAAgB,kCAAkC;AAkB/D,SAAS,iBAAiB,GAAoB,KAAqB;CACjE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK,GAAG;AACrD;;;;;;;;AASA,SAAS,oCAAgD;CACvD,IAAI,OAAO;CACX,IAAI,IAAI;CAER,aAAa;EACX,IAAI,CAAC,MAMH,OAAO,iBAAiB,aAAa,GAAG,EAAE;EAE5C,MAAM,OAAO,iBAAiB,KAAK,EAAE;EACrC,OAAQ,OAAO;CACjB;AACF;AAYA,SAAgB,OAAO,OAA+B;CACpD,OAAO,OAAO,UAAU,YAAY,OAAO,KAAK,KAAK;AACvD;AAEA,SAAgB,WAAW,OAAuC;CAChE,OAAc,OAAO,UAAU;AACjC;AAEA,IAAa,aAAaA,eAAO,OAAO,CAAC,CAAC,OAAO,QAAQ,cAAc"}
@@ -1,2 +1 @@
1
- import "./replicache-impl.js";
2
- export {};
1
+ export { ReplicacheImpl } from "./replicache-impl.js";
@@ -1,9 +1,11 @@
1
1
  import { readonlyObject, readonlyRecord, valita_exports } from "../../shared/src/valita.js";
2
- var indexDefinitionsSchema = readonlyRecord(readonlyObject({
2
+ //#region ../replicache/src/index-defs.ts
3
+ var indexDefinitionSchema = readonlyObject({
3
4
  prefix: valita_exports.string().optional(),
4
5
  jsonPointer: valita_exports.string(),
5
6
  allowEmpty: valita_exports.boolean().optional()
6
- }));
7
+ });
8
+ var indexDefinitionsSchema = readonlyRecord(indexDefinitionSchema);
7
9
  function indexDefinitionEqual(a, b) {
8
10
  return a.jsonPointer === b.jsonPointer && (a.allowEmpty ?? false) === (b.allowEmpty ?? false) && (a.prefix ?? "") === (b.prefix ?? "");
9
11
  }
@@ -16,6 +18,6 @@ function indexDefinitionsEqual(a, b) {
16
18
  return true;
17
19
  }
18
20
  //#endregion
19
- export { indexDefinitionsEqual, indexDefinitionsSchema };
21
+ export { indexDefinitionEqual, indexDefinitionSchema, indexDefinitionsEqual, indexDefinitionsSchema };
20
22
 
21
23
  //# sourceMappingURL=index-defs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-defs.js","names":[],"sources":["../../../../replicache/src/index-defs.ts"],"sourcesContent":["import * as valita from '../../shared/src/valita.ts';\n\n/**\n * The definition of a single index.\n */\nexport type IndexDefinition = {\n /**\n * The prefix, if any, to limit the index over. If not provided the values of\n * all keys are indexed.\n */\n readonly prefix?: string | undefined;\n\n /**\n * A [JSON Pointer](https://tools.ietf.org/html/rfc6901) pointing at the sub\n * value inside each value to index over.\n *\n * For example, one might index over users' ages like so:\n * `{prefix: '/user/', jsonPointer: '/age'}`\n */\n readonly jsonPointer: string;\n\n /**\n * If `true`, indexing empty values will not emit a warning. Defaults to `false`.\n */\n readonly allowEmpty?: boolean | undefined;\n};\n\nexport const indexDefinitionSchema: valita.Type<IndexDefinition> =\n valita.readonlyObject({\n prefix: valita.string().optional(),\n jsonPointer: valita.string(),\n allowEmpty: valita.boolean().optional(),\n });\n\n/**\n * An object as a map defining the indexes. The keys are the index names and the\n * values are the index definitions.\n */\nexport type IndexDefinitions = {readonly [name: string]: IndexDefinition};\n\nexport const indexDefinitionsSchema = valita.readonlyRecord(\n indexDefinitionSchema,\n);\n\nexport function indexDefinitionEqual(\n a: IndexDefinition,\n b: IndexDefinition,\n): boolean {\n return (\n a.jsonPointer === b.jsonPointer &&\n (a.allowEmpty ?? false) === (b.allowEmpty ?? false) &&\n (a.prefix ?? '') === (b.prefix ?? '')\n );\n}\n\nexport function indexDefinitionsEqual(\n a: IndexDefinitions,\n b: IndexDefinitions,\n): boolean {\n if (Object.keys(a).length !== Object.keys(b).length) {\n return false;\n }\n for (const [aKey, aValue] of Object.entries(a)) {\n const bValue = b[aKey];\n if (!bValue || !indexDefinitionEqual(aValue, bValue)) {\n return false;\n }\n }\n return true;\n}\n\nexport function assertIndexDefinitions(\n value: unknown,\n): asserts value is IndexDefinitions {\n valita.assert(value, indexDefinitionsSchema);\n}\n"],"mappings":";AAwCA,IAAa,yBAAyB,eAZpC,eAAsB;CACpB,QAAQ,eAAO,OAAO,EAAE,SAAS;CACjC,aAAa,eAAO,OAAO;CAC3B,YAAY,eAAO,QAAQ,EAAE,SAAS;AACxC,CASA,CACF;AAEA,SAAgB,qBACd,GACA,GACS;CACT,OACE,EAAE,gBAAgB,EAAE,gBACnB,EAAE,cAAc,YAAY,EAAE,cAAc,WAC5C,EAAE,UAAU,SAAS,EAAE,UAAU;AAEtC;AAEA,SAAgB,sBACd,GACA,GACS;CACT,IAAI,OAAO,KAAK,CAAC,EAAE,WAAW,OAAO,KAAK,CAAC,EAAE,QAC3C,OAAO;CAET,KAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,CAAC,GAAG;EAC9C,MAAM,SAAS,EAAE;EACjB,IAAI,CAAC,UAAU,CAAC,qBAAqB,QAAQ,MAAM,GACjD,OAAO;CAEX;CACA,OAAO;AACT"}
1
+ {"version":3,"file":"index-defs.js","names":["valita.readonlyObject","valita","valita.readonlyRecord"],"sources":["../../../../replicache/src/index-defs.ts"],"sourcesContent":["import * as valita from '../../shared/src/valita.ts';\n\n/**\n * The definition of a single index.\n */\nexport type IndexDefinition = {\n /**\n * The prefix, if any, to limit the index over. If not provided the values of\n * all keys are indexed.\n */\n readonly prefix?: string | undefined;\n\n /**\n * A [JSON Pointer](https://tools.ietf.org/html/rfc6901) pointing at the sub\n * value inside each value to index over.\n *\n * For example, one might index over users' ages like so:\n * `{prefix: '/user/', jsonPointer: '/age'}`\n */\n readonly jsonPointer: string;\n\n /**\n * If `true`, indexing empty values will not emit a warning. Defaults to `false`.\n */\n readonly allowEmpty?: boolean | undefined;\n};\n\nexport const indexDefinitionSchema: valita.Type<IndexDefinition> =\n valita.readonlyObject({\n prefix: valita.string().optional(),\n jsonPointer: valita.string(),\n allowEmpty: valita.boolean().optional(),\n });\n\n/**\n * An object as a map defining the indexes. The keys are the index names and the\n * values are the index definitions.\n */\nexport type IndexDefinitions = {readonly [name: string]: IndexDefinition};\n\nexport const indexDefinitionsSchema = valita.readonlyRecord(\n indexDefinitionSchema,\n);\n\nexport function indexDefinitionEqual(\n a: IndexDefinition,\n b: IndexDefinition,\n): boolean {\n return (\n a.jsonPointer === b.jsonPointer &&\n (a.allowEmpty ?? false) === (b.allowEmpty ?? false) &&\n (a.prefix ?? '') === (b.prefix ?? '')\n );\n}\n\nexport function indexDefinitionsEqual(\n a: IndexDefinitions,\n b: IndexDefinitions,\n): boolean {\n if (Object.keys(a).length !== Object.keys(b).length) {\n return false;\n }\n for (const [aKey, aValue] of Object.entries(a)) {\n const bValue = b[aKey];\n if (!bValue || !indexDefinitionEqual(aValue, bValue)) {\n return false;\n }\n }\n return true;\n}\n\nexport function assertIndexDefinitions(\n value: unknown,\n): asserts value is IndexDefinitions {\n valita.assert(value, indexDefinitionsSchema);\n}\n"],"mappings":";;AA2BA,IAAa,wBACXA,eAAsB;CACpB,QAAQC,eAAO,OAAO,CAAC,CAAC,SAAS;CACjC,aAAaA,eAAO,OAAO;CAC3B,YAAYA,eAAO,QAAQ,CAAC,CAAC,SAAS;AACxC,CAAC;AAQH,IAAa,yBAAyBC,eACpC,qBACF;AAEA,SAAgB,qBACd,GACA,GACS;CACT,OACE,EAAE,gBAAgB,EAAE,gBACnB,EAAE,cAAc,YAAY,EAAE,cAAc,WAC5C,EAAE,UAAU,SAAS,EAAE,UAAU;AAEtC;AAEA,SAAgB,sBACd,GACA,GACS;CACT,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC,WAAW,OAAO,KAAK,CAAC,CAAC,CAAC,QAC3C,OAAO;CAET,KAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,CAAC,GAAG;EAC9C,MAAM,SAAS,EAAE;EACjB,IAAI,CAAC,UAAU,CAAC,qBAAqB,QAAQ,MAAM,GACjD,OAAO;CAEX;CACA,OAAO;AACT"}
@@ -75,6 +75,6 @@ var ExpoSQLiteDatabase = class {
75
75
  }
76
76
  };
77
77
  //#endregion
78
- export { expoSQLiteStoreProvider };
78
+ export { dropExpoSQLiteStore, expoSQLiteStoreProvider };
79
79
 
80
80
  //# sourceMappingURL=store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","names":["#statement","#lock","#db","#filename","#statements"],"sources":["../../../../../../replicache/src/kv/expo-sqlite/store.ts"],"sourcesContent":["import {Lock} from '@rocicorp/lock';\nimport {\n deleteDatabaseSync,\n openDatabaseSync,\n type SQLiteDatabase as DB,\n type SQLiteStatement,\n} from 'expo-sqlite';\nimport type {\n PreparedStatement,\n SQLiteDatabase,\n SQLiteStoreOptions,\n} from '../sqlite-store.ts';\nimport {dropStore, SQLiteStore} from '../sqlite-store.ts';\nimport type {StoreProvider} from '../store.ts';\n\nexport type ExpoSQLiteStoreOptions = SQLiteStoreOptions;\n\nexport function dropExpoSQLiteStore(\n name: string,\n opts?: ExpoSQLiteStoreOptions,\n): Promise<void> {\n return dropStore(name, filename => new ExpoSQLiteDatabase(filename), opts);\n}\n\n/**\n * Creates a StoreProvider for SQLite-based stores using expo-sqlite.\n * Supports shared connections between multiple store instances with the same name,\n * providing efficient resource utilization and proper transaction isolation.\n */\nexport function expoSQLiteStoreProvider(\n opts?: ExpoSQLiteStoreOptions,\n): StoreProvider {\n return {\n create: name =>\n new SQLiteStore(\n name,\n name => new ExpoSQLiteDatabase(name),\n opts,\n 'expo-sqlite',\n ),\n drop: name => dropExpoSQLiteStore(name, opts),\n };\n}\n\n/**\n * An expo-sqlite prepared statement is a stateful cursor over a single\n * `sqlite3_stmt`: `executeForRawResultAsync` resets, rebinds and steps the\n * first row, and the returned result's `getAllAsync` then steps the *remaining*\n * rows of whatever the statement is currently bound to. Both are separate\n * native round trips.\n *\n * `SQLiteStore` shares one prepared statement per SQL across all concurrent\n * readers, so without serialization reader B's `executeForRawResultAsync` can\n * rebind the statement inside reader A's await gap, and A's `getAllAsync` then\n * returns B's rows (and B is starved of them). That yields wrong or missing\n * values and, when a ref count delta is computed from such a read and written,\n * a persistently corrupted store.\n *\n * Every call on a statement is therefore run under a per-statement lock so the\n * execute + fetch pair is atomic with respect to other users of that statement.\n */\nclass ExpoSQLitePreparedStatement implements PreparedStatement {\n readonly #statement: SQLiteStatement;\n readonly #lock = new Lock();\n\n constructor(statement: SQLiteStatement) {\n this.#statement = statement;\n }\n\n exec(params: string[]): Promise<void> {\n return this.#lock.withLock(async () => {\n await this.#statement.executeForRawResultAsync(params);\n });\n }\n\n all(params: string[]): Promise<unknown[][]> {\n return this.#lock.withLock(async () => {\n const result = await this.#statement.executeForRawResultAsync(params);\n // Must be awaited inside the lock so that no other caller can reset the\n // statement before all rows have been stepped.\n return (await result.getAllAsync()) as unknown[][];\n });\n }\n}\n\nclass ExpoSQLiteDatabase implements SQLiteDatabase {\n readonly #db: DB;\n readonly #filename: string;\n readonly #statements: Set<SQLiteStatement> = new Set();\n\n constructor(filename: string) {\n this.#filename = filename;\n this.#db = openDatabaseSync(filename);\n }\n\n close(): void {\n for (const stmt of this.#statements) {\n stmt.finalizeSync();\n }\n this.#db.closeSync();\n }\n\n destroy(): void {\n deleteDatabaseSync(this.#filename);\n }\n\n prepare(sql: string): PreparedStatement {\n const statement = this.#db.prepareSync(sql);\n this.#statements.add(statement);\n return new ExpoSQLitePreparedStatement(statement);\n }\n\n execSync(sql: string): void {\n this.#db.execSync(sql);\n }\n}\n"],"mappings":";;;;AAiBA,SAAgB,oBACd,MACA,MACe;CACf,OAAO,UAAU,OAAM,aAAY,IAAI,mBAAmB,QAAQ,GAAG,IAAI;AAC3E;;;;;;AAOA,SAAgB,wBACd,MACe;CACf,OAAO;EACL,SAAQ,SACN,IAAI,YACF,OACA,SAAQ,IAAI,mBAAmB,IAAI,GACnC,MACA,aACF;EACF,OAAM,SAAQ,oBAAoB,MAAM,IAAI;CAC9C;AACF;;;;;;;;;;;;;;;;;;AAmBA,IAAM,8BAAN,MAA+D;CAC7D;CACA,QAAiB,IAAI,KAAK;CAE1B,YAAY,WAA4B;EACtC,KAAKA,aAAa;CACpB;CAEA,KAAK,QAAiC;EACpC,OAAO,KAAKC,MAAM,SAAS,YAAY;GACrC,MAAM,KAAKD,WAAW,yBAAyB,MAAM;EACvD,CAAC;CACH;CAEA,IAAI,QAAwC;EAC1C,OAAO,KAAKC,MAAM,SAAS,YAAY;GAIrC,OAAQ,OAAM,MAHO,KAAKD,WAAW,yBAAyB,MAAM,GAG/C,YAAY;EACnC,CAAC;CACH;AACF;AAEA,IAAM,qBAAN,MAAmD;CACjD;CACA;CACA,8BAA6C,IAAI,IAAI;CAErD,YAAY,UAAkB;EAC5B,KAAKG,YAAY;EACjB,KAAKD,MAAM,iBAAiB,QAAQ;CACtC;CAEA,QAAc;EACZ,KAAK,MAAM,QAAQ,KAAKE,aACtB,KAAK,aAAa;EAEpB,KAAKF,IAAI,UAAU;CACrB;CAEA,UAAgB;EACd,mBAAmB,KAAKC,SAAS;CACnC;CAEA,QAAQ,KAAgC;EACtC,MAAM,YAAY,KAAKD,IAAI,YAAY,GAAG;EAC1C,KAAKE,YAAY,IAAI,SAAS;EAC9B,OAAO,IAAI,4BAA4B,SAAS;CAClD;CAEA,SAAS,KAAmB;EAC1B,KAAKF,IAAI,SAAS,GAAG;CACvB;AACF"}
1
+ {"version":3,"file":"store.js","names":[],"sources":["../../../../../../replicache/src/kv/expo-sqlite/store.ts"],"sourcesContent":["import {Lock} from '@rocicorp/lock';\nimport {\n deleteDatabaseSync,\n openDatabaseSync,\n type SQLiteDatabase as DB,\n type SQLiteStatement,\n} from 'expo-sqlite';\nimport type {\n PreparedStatement,\n SQLiteDatabase,\n SQLiteStoreOptions,\n} from '../sqlite-store.ts';\nimport {dropStore, SQLiteStore} from '../sqlite-store.ts';\nimport type {StoreProvider} from '../store.ts';\n\nexport type ExpoSQLiteStoreOptions = SQLiteStoreOptions;\n\nexport function dropExpoSQLiteStore(\n name: string,\n opts?: ExpoSQLiteStoreOptions,\n): Promise<void> {\n return dropStore(name, filename => new ExpoSQLiteDatabase(filename), opts);\n}\n\n/**\n * Creates a StoreProvider for SQLite-based stores using expo-sqlite.\n * Supports shared connections between multiple store instances with the same name,\n * providing efficient resource utilization and proper transaction isolation.\n */\nexport function expoSQLiteStoreProvider(\n opts?: ExpoSQLiteStoreOptions,\n): StoreProvider {\n return {\n create: name =>\n new SQLiteStore(\n name,\n name => new ExpoSQLiteDatabase(name),\n opts,\n 'expo-sqlite',\n ),\n drop: name => dropExpoSQLiteStore(name, opts),\n };\n}\n\n/**\n * An expo-sqlite prepared statement is a stateful cursor over a single\n * `sqlite3_stmt`: `executeForRawResultAsync` resets, rebinds and steps the\n * first row, and the returned result's `getAllAsync` then steps the *remaining*\n * rows of whatever the statement is currently bound to. Both are separate\n * native round trips.\n *\n * `SQLiteStore` shares one prepared statement per SQL across all concurrent\n * readers, so without serialization reader B's `executeForRawResultAsync` can\n * rebind the statement inside reader A's await gap, and A's `getAllAsync` then\n * returns B's rows (and B is starved of them). That yields wrong or missing\n * values and, when a ref count delta is computed from such a read and written,\n * a persistently corrupted store.\n *\n * Every call on a statement is therefore run under a per-statement lock so the\n * execute + fetch pair is atomic with respect to other users of that statement.\n */\nclass ExpoSQLitePreparedStatement implements PreparedStatement {\n readonly #statement: SQLiteStatement;\n readonly #lock = new Lock();\n\n constructor(statement: SQLiteStatement) {\n this.#statement = statement;\n }\n\n exec(params: string[]): Promise<void> {\n return this.#lock.withLock(async () => {\n await this.#statement.executeForRawResultAsync(params);\n });\n }\n\n all(params: string[]): Promise<unknown[][]> {\n return this.#lock.withLock(async () => {\n const result = await this.#statement.executeForRawResultAsync(params);\n // Must be awaited inside the lock so that no other caller can reset the\n // statement before all rows have been stepped.\n return (await result.getAllAsync()) as unknown[][];\n });\n }\n}\n\nclass ExpoSQLiteDatabase implements SQLiteDatabase {\n readonly #db: DB;\n readonly #filename: string;\n readonly #statements: Set<SQLiteStatement> = new Set();\n\n constructor(filename: string) {\n this.#filename = filename;\n this.#db = openDatabaseSync(filename);\n }\n\n close(): void {\n for (const stmt of this.#statements) {\n stmt.finalizeSync();\n }\n this.#db.closeSync();\n }\n\n destroy(): void {\n deleteDatabaseSync(this.#filename);\n }\n\n prepare(sql: string): PreparedStatement {\n const statement = this.#db.prepareSync(sql);\n this.#statements.add(statement);\n return new ExpoSQLitePreparedStatement(statement);\n }\n\n execSync(sql: string): void {\n this.#db.execSync(sql);\n }\n}\n"],"mappings":";;;;AAiBA,SAAgB,oBACd,MACA,MACe;CACf,OAAO,UAAU,OAAM,aAAY,IAAI,mBAAmB,QAAQ,GAAG,IAAI;AAC3E;;;;;;AAOA,SAAgB,wBACd,MACe;CACf,OAAO;EACL,SAAQ,SACN,IAAI,YACF,OACA,SAAQ,IAAI,mBAAmB,IAAI,GACnC,MACA,aACF;EACF,OAAM,SAAQ,oBAAoB,MAAM,IAAI;CAC9C;AACF;;;;;;;;;;;;;;;;;;AAmBA,IAAM,8BAAN,MAA+D;CAC7D;CACA,QAAiB,IAAI,KAAK;CAE1B,YAAY,WAA4B;EACtC,KAAK,aAAa;CACpB;CAEA,KAAK,QAAiC;EACpC,OAAO,KAAK,MAAM,SAAS,YAAY;GACrC,MAAM,KAAK,WAAW,yBAAyB,MAAM;EACvD,CAAC;CACH;CAEA,IAAI,QAAwC;EAC1C,OAAO,KAAK,MAAM,SAAS,YAAY;GAIrC,OAAQ,OAAM,MAHO,KAAK,WAAW,yBAAyB,MAAM,EAAA,CAG/C,YAAY;EACnC,CAAC;CACH;AACF;AAEA,IAAM,qBAAN,MAAmD;CACjD;CACA;CACA,8BAA6C,IAAI,IAAI;CAErD,YAAY,UAAkB;EAC5B,KAAK,YAAY;EACjB,KAAK,MAAM,iBAAiB,QAAQ;CACtC;CAEA,QAAc;EACZ,KAAK,MAAM,QAAQ,KAAK,aACtB,KAAK,aAAa;EAEpB,KAAK,IAAI,UAAU;CACrB;CAEA,UAAgB;EACd,mBAAmB,KAAK,SAAS;CACnC;CAEA,QAAQ,KAAgC;EACtC,MAAM,YAAY,KAAK,IAAI,YAAY,GAAG;EAC1C,KAAK,YAAY,IAAI,SAAS;EAC9B,OAAO,IAAI,4BAA4B,SAAS;CAClD;CAEA,SAAS,KAAmB;EAC1B,KAAK,IAAI,SAAS,GAAG;CACvB;AACF"}
@@ -182,6 +182,6 @@ function dropIDBStore(name) {
182
182
  });
183
183
  }
184
184
  //#endregion
185
- export { IDBNotFoundError, IDBStore, dropIDBStore };
185
+ export { IDBNotFoundError, IDBOpenError, IDBStore, dropIDBStore };
186
186
 
187
187
  //# sourceMappingURL=idb-store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"idb-store.js","names":["#db","#closed","#withReopen","#idbDeleted","#tx"],"sources":["../../../../../replicache/src/kv/idb-store.ts"],"sourcesContent":["import {resolver} from '@rocicorp/resolver';\nimport {assertNotNull} from '../../../shared/src/asserts.ts';\nimport {mustGetBrowserGlobal} from '../../../shared/src/browser-env.ts';\nimport {promiseVoid} from '../../../shared/src/resolved-promises.ts';\nimport {\n type FrozenJSONValue,\n deepFreezeAllowUndefined,\n} from '../frozen-json.ts';\nimport {StorageFailureError} from '../storage-failure.ts';\nimport type {Read, Store, Write} from './store.ts';\nimport {\n storeIsClosedRejection,\n transactionIsClosedRejection,\n} from './throw-if-closed.ts';\nimport {WriteImplBase, deleteSentinel} from './write-impl-base.ts';\n\nconst RELAXED = {durability: 'relaxed'} as const;\nconst OBJECT_STORE = 'chunks';\n\nexport class IDBStore implements Store {\n #db: Promise<IDBDatabase>;\n #closed = false;\n #idbDeleted = false;\n\n constructor(name: string) {\n this.#db = openDatabase(name);\n // read() and write() surface an open failure as an IDBOpenError. Don't\n // leave an unhandled rejection when neither is called.\n this.#db.catch(() => undefined);\n }\n\n read(): Promise<Read> {\n if (this.#closed) {\n return storeIsClosedRejection();\n }\n return this.#withReopen(readImpl);\n }\n\n write(): Promise<Write> {\n if (this.#closed) {\n return storeIsClosedRejection();\n }\n return this.#withReopen(writeImpl);\n }\n\n async close(): Promise<void> {\n if (!this.#idbDeleted) {\n const db = await this.#db;\n db.close();\n }\n this.#closed = true;\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n\n get kind(): string {\n return 'idb';\n }\n\n async #withReopen<R>(fn: (db: IDBDatabase) => R): Promise<R> {\n // Tries to reopen an IndexedDB, and rejects if the database needs\n // upgrading (is missing for whatever reason).\n const reopenExistingDB = async (name: string): Promise<IDBDatabase> => {\n const {promise, resolve, reject} = resolver<IDBDatabase>();\n const req = indexedDB.open(name);\n\n req.onupgradeneeded = () => {\n const tx = req.transaction;\n assertNotNull(tx);\n tx.abort();\n this.#idbDeleted = true;\n reject(\n new IDBNotFoundError(\n `Expected IndexedDB not found: ${name}. This likely means that the user deleted IndexedDB instances while the app was running. This is non-fatal. The app will continue running in memory until reload.`,\n ),\n );\n };\n\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n\n const db = await promise;\n db.onversionchange = () => db.close();\n return db;\n };\n\n // We abstract on `readImpl` to work around an issue in Safari. Safari does\n // not allow any microtask between a transaction is created until it is\n // first used. We used to use `await read()` here instead of `await\n // this._db` but then there is a microtask between the creation of the\n // transaction and the return of this function. By doing `await this._db`\n // here we only await the db and no await is involved with the transaction.\n // See https://github.com/jakearchibald/idb-keyval/commit/1af0a00b1a70a678d2f9cf5e74c55a22e57324c5#r55989916\n const db = await this.#db;\n\n try {\n return fn(db);\n } catch (e: unknown) {\n if (!this.#closed && e instanceof DOMException) {\n if (e.name === 'InvalidStateError') {\n this.#db = reopenExistingDB(db.name);\n const reopened = await this.#db;\n return fn(reopened);\n } else if (e.name === 'NotFoundError') {\n // This edge-case can happen if the db has been deleted and the\n // user/developer has DevTools open in certain browsers.\n // See discussion at https://github.com/rocicorp/replicache-internal/pull/216\n this.#idbDeleted = true;\n mustGetBrowserGlobal('indexedDB').deleteDatabase(db.name);\n throw new IDBNotFoundError(\n `Expected IndexedDB ${db.name} missing object store. Deleting db. This is non-fatal, the app will continue working in memory until it is reloaded.`,\n );\n }\n }\n throw e;\n }\n }\n}\n\nclass ReadImpl implements Read {\n readonly #tx: IDBTransaction;\n #closed = false;\n\n constructor(tx: IDBTransaction) {\n this.#tx = tx;\n }\n\n has(key: string): Promise<boolean> {\n if (this.#closed) {\n return transactionIsClosedRejection();\n }\n return new Promise((resolve, reject) => {\n const req = objectStore(this.#tx).count(key);\n req.onsuccess = () => resolve(req.result > 0);\n req.onerror = () => reject(req.error);\n });\n }\n\n get(key: string): Promise<FrozenJSONValue | undefined> {\n if (this.#closed) {\n return transactionIsClosedRejection();\n }\n return new Promise((resolve, reject) => {\n const req = objectStore(this.#tx).get(key);\n req.onsuccess = () => resolve(deepFreezeAllowUndefined(req.result));\n req.onerror = () => reject(req.error);\n });\n }\n\n release(): void {\n this.#closed = true;\n // Do nothing. We rely on IDB locking.\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n}\n\nclass WriteImpl extends WriteImplBase {\n readonly #tx: IDBTransaction;\n #closed = false;\n\n constructor(tx: IDBTransaction) {\n super(new ReadImpl(tx));\n this.#tx = tx;\n }\n\n commit(): Promise<void> {\n if (this.#closed) {\n return transactionIsClosedRejection();\n }\n if (this._pending.size === 0) {\n return promiseVoid;\n }\n\n return new Promise((resolve, reject) => {\n const tx = this.#tx;\n const store = objectStore(tx);\n for (const [key, val] of this._pending) {\n if (val === deleteSentinel) {\n store.delete(key);\n } else {\n store.put(val, key);\n }\n }\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n release(): void {\n // We rely on IDB locking so no need to do anything here.\n this.#closed = true;\n super.release();\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n}\n\nfunction writeImpl(db: IDBDatabase): Write {\n const tx = db.transaction(OBJECT_STORE, 'readwrite', RELAXED);\n return new WriteImpl(tx);\n}\n\nfunction readImpl(db: IDBDatabase): Read {\n const tx = db.transaction(OBJECT_STORE, 'readonly');\n return new ReadImpl(tx);\n}\n\nfunction objectStore(tx: IDBTransaction): IDBObjectStore {\n return tx.objectStore(OBJECT_STORE);\n}\n\nfunction openDatabase(name: string): Promise<IDBDatabase> {\n const idb = mustGetBrowserGlobal('indexedDB');\n return new Promise((resolve, reject) => {\n const req = idb.open(name);\n req.onupgradeneeded = () => {\n req.result.createObjectStore(OBJECT_STORE);\n };\n req.onsuccess = () => {\n const db = req.result;\n // Another tab/process wants to modify the db, so release it.\n db.onversionchange = () => db.close();\n resolve(db);\n };\n req.onerror = () =>\n reject(\n new IDBOpenError(`Failed to open IndexedDB ${name}`, {\n cause: req.error,\n }),\n );\n });\n}\n\n/**\n * This error is thrown when we detect that the IndexedDB has been removed. This\n * does not normally happen but can happen during development if the user has\n * DevTools open and deletes the IndexedDB from there.\n */\nexport class IDBNotFoundError extends Error {\n name = 'IDBNotFoundError';\n}\n\nconst DISK_FULL = /database or disk is full/;\n\n/**\n * `read()` and `write()` reject with this error when the initial\n * `indexedDB.open` failed. The browser's error is the `cause`. A failure after\n * the database opened, such as a transaction error, is not wrapped.\n *\n * It is a `cannot-open` storage failure, or `full` when the browser says so\n * (WebKit's IndexedDB is SQLite underneath and reports `database or disk is\n * full`).\n */\nexport class IDBOpenError extends StorageFailureError {\n name = 'IDBOpenError';\n\n constructor(message: string, options: {cause: unknown}) {\n super(\n DISK_FULL.test(String(options.cause)) ? 'full' : 'cannot-open',\n message,\n options,\n );\n }\n}\n\nexport function dropIDBStore(name: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const req = indexedDB.deleteDatabase(name);\n req.onsuccess = () => resolve();\n req.onerror = () => reject(req.error);\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"idb-store.js","names":[],"sources":["../../../../../replicache/src/kv/idb-store.ts"],"sourcesContent":["import {resolver} from '@rocicorp/resolver';\nimport {assertNotNull} from '../../../shared/src/asserts.ts';\nimport {mustGetBrowserGlobal} from '../../../shared/src/browser-env.ts';\nimport {promiseVoid} from '../../../shared/src/resolved-promises.ts';\nimport {\n type FrozenJSONValue,\n deepFreezeAllowUndefined,\n} from '../frozen-json.ts';\nimport {StorageFailureError} from '../storage-failure.ts';\nimport type {Read, Store, Write} from './store.ts';\nimport {\n storeIsClosedRejection,\n transactionIsClosedRejection,\n} from './throw-if-closed.ts';\nimport {WriteImplBase, deleteSentinel} from './write-impl-base.ts';\n\nconst RELAXED = {durability: 'relaxed'} as const;\nconst OBJECT_STORE = 'chunks';\n\nexport class IDBStore implements Store {\n #db: Promise<IDBDatabase>;\n #closed = false;\n #idbDeleted = false;\n\n constructor(name: string) {\n this.#db = openDatabase(name);\n // read() and write() surface an open failure as an IDBOpenError. Don't\n // leave an unhandled rejection when neither is called.\n this.#db.catch(() => undefined);\n }\n\n read(): Promise<Read> {\n if (this.#closed) {\n return storeIsClosedRejection();\n }\n return this.#withReopen(readImpl);\n }\n\n write(): Promise<Write> {\n if (this.#closed) {\n return storeIsClosedRejection();\n }\n return this.#withReopen(writeImpl);\n }\n\n async close(): Promise<void> {\n if (!this.#idbDeleted) {\n const db = await this.#db;\n db.close();\n }\n this.#closed = true;\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n\n get kind(): string {\n return 'idb';\n }\n\n async #withReopen<R>(fn: (db: IDBDatabase) => R): Promise<R> {\n // Tries to reopen an IndexedDB, and rejects if the database needs\n // upgrading (is missing for whatever reason).\n const reopenExistingDB = async (name: string): Promise<IDBDatabase> => {\n const {promise, resolve, reject} = resolver<IDBDatabase>();\n const req = indexedDB.open(name);\n\n req.onupgradeneeded = () => {\n const tx = req.transaction;\n assertNotNull(tx);\n tx.abort();\n this.#idbDeleted = true;\n reject(\n new IDBNotFoundError(\n `Expected IndexedDB not found: ${name}. This likely means that the user deleted IndexedDB instances while the app was running. This is non-fatal. The app will continue running in memory until reload.`,\n ),\n );\n };\n\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n\n const db = await promise;\n db.onversionchange = () => db.close();\n return db;\n };\n\n // We abstract on `readImpl` to work around an issue in Safari. Safari does\n // not allow any microtask between a transaction is created until it is\n // first used. We used to use `await read()` here instead of `await\n // this._db` but then there is a microtask between the creation of the\n // transaction and the return of this function. By doing `await this._db`\n // here we only await the db and no await is involved with the transaction.\n // See https://github.com/jakearchibald/idb-keyval/commit/1af0a00b1a70a678d2f9cf5e74c55a22e57324c5#r55989916\n const db = await this.#db;\n\n try {\n return fn(db);\n } catch (e: unknown) {\n if (!this.#closed && e instanceof DOMException) {\n if (e.name === 'InvalidStateError') {\n this.#db = reopenExistingDB(db.name);\n const reopened = await this.#db;\n return fn(reopened);\n } else if (e.name === 'NotFoundError') {\n // This edge-case can happen if the db has been deleted and the\n // user/developer has DevTools open in certain browsers.\n // See discussion at https://github.com/rocicorp/replicache-internal/pull/216\n this.#idbDeleted = true;\n mustGetBrowserGlobal('indexedDB').deleteDatabase(db.name);\n throw new IDBNotFoundError(\n `Expected IndexedDB ${db.name} missing object store. Deleting db. This is non-fatal, the app will continue working in memory until it is reloaded.`,\n );\n }\n }\n throw e;\n }\n }\n}\n\nclass ReadImpl implements Read {\n readonly #tx: IDBTransaction;\n #closed = false;\n\n constructor(tx: IDBTransaction) {\n this.#tx = tx;\n }\n\n has(key: string): Promise<boolean> {\n if (this.#closed) {\n return transactionIsClosedRejection();\n }\n return new Promise((resolve, reject) => {\n const req = objectStore(this.#tx).count(key);\n req.onsuccess = () => resolve(req.result > 0);\n req.onerror = () => reject(req.error);\n });\n }\n\n get(key: string): Promise<FrozenJSONValue | undefined> {\n if (this.#closed) {\n return transactionIsClosedRejection();\n }\n return new Promise((resolve, reject) => {\n const req = objectStore(this.#tx).get(key);\n req.onsuccess = () => resolve(deepFreezeAllowUndefined(req.result));\n req.onerror = () => reject(req.error);\n });\n }\n\n release(): void {\n this.#closed = true;\n // Do nothing. We rely on IDB locking.\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n}\n\nclass WriteImpl extends WriteImplBase {\n readonly #tx: IDBTransaction;\n #closed = false;\n\n constructor(tx: IDBTransaction) {\n super(new ReadImpl(tx));\n this.#tx = tx;\n }\n\n commit(): Promise<void> {\n if (this.#closed) {\n return transactionIsClosedRejection();\n }\n if (this._pending.size === 0) {\n return promiseVoid;\n }\n\n return new Promise((resolve, reject) => {\n const tx = this.#tx;\n const store = objectStore(tx);\n for (const [key, val] of this._pending) {\n if (val === deleteSentinel) {\n store.delete(key);\n } else {\n store.put(val, key);\n }\n }\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n release(): void {\n // We rely on IDB locking so no need to do anything here.\n this.#closed = true;\n super.release();\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n}\n\nfunction writeImpl(db: IDBDatabase): Write {\n const tx = db.transaction(OBJECT_STORE, 'readwrite', RELAXED);\n return new WriteImpl(tx);\n}\n\nfunction readImpl(db: IDBDatabase): Read {\n const tx = db.transaction(OBJECT_STORE, 'readonly');\n return new ReadImpl(tx);\n}\n\nfunction objectStore(tx: IDBTransaction): IDBObjectStore {\n return tx.objectStore(OBJECT_STORE);\n}\n\nfunction openDatabase(name: string): Promise<IDBDatabase> {\n const idb = mustGetBrowserGlobal('indexedDB');\n return new Promise((resolve, reject) => {\n const req = idb.open(name);\n req.onupgradeneeded = () => {\n req.result.createObjectStore(OBJECT_STORE);\n };\n req.onsuccess = () => {\n const db = req.result;\n // Another tab/process wants to modify the db, so release it.\n db.onversionchange = () => db.close();\n resolve(db);\n };\n req.onerror = () =>\n reject(\n new IDBOpenError(`Failed to open IndexedDB ${name}`, {\n cause: req.error,\n }),\n );\n });\n}\n\n/**\n * This error is thrown when we detect that the IndexedDB has been removed. This\n * does not normally happen but can happen during development if the user has\n * DevTools open and deletes the IndexedDB from there.\n */\nexport class IDBNotFoundError extends Error {\n name = 'IDBNotFoundError';\n}\n\nconst DISK_FULL = /database or disk is full/;\n\n/**\n * `read()` and `write()` reject with this error when the initial\n * `indexedDB.open` failed. The browser's error is the `cause`. A failure after\n * the database opened, such as a transaction error, is not wrapped.\n *\n * It is a `cannot-open` storage failure, or `full` when the browser says so\n * (WebKit's IndexedDB is SQLite underneath and reports `database or disk is\n * full`).\n */\nexport class IDBOpenError extends StorageFailureError {\n name = 'IDBOpenError';\n\n constructor(message: string, options: {cause: unknown}) {\n super(\n DISK_FULL.test(String(options.cause)) ? 'full' : 'cannot-open',\n message,\n options,\n );\n }\n}\n\nexport function dropIDBStore(name: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const req = indexedDB.deleteDatabase(name);\n req.onsuccess = () => resolve();\n req.onerror = () => reject(req.error);\n });\n}\n"],"mappings":"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"}
@@ -172,6 +172,6 @@ var ReportingWrite = class extends ReportingRead {
172
172
  }
173
173
  };
174
174
  //#endregion
175
- export { MemFallbackStoreProvider, fallbackStoreProvider, isFallbackStore };
175
+ export { MemFallbackStore, MemFallbackStoreProvider, fallbackStoreProvider, isFallbackStore };
176
176
 
177
177
  //# sourceMappingURL=mem-fallback-store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mem-fallback-store.js","names":["#inner","#onFallBack","#onFailureAfterOpen","#failure","#opened","#name","#provider","#store","#onMemory","#reportAndRethrow","#closed"],"sources":["../../../../../replicache/src/kv/mem-fallback-store.ts"],"sourcesContent":["import type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {\n getStorageFailure,\n type StorageFailureError,\n} from '../storage-failure.ts';\nimport {dropMemStore, MemStore} from './mem-store.ts';\nimport type {Read, Store, StoreProvider, Write} from './store.ts';\n\n/**\n * The names of the memory stores instances moved onto after a storage\n * failure, in this process. Unlike the stores of a `kvStore: 'mem'` instance,\n * these are cleared by drops whatever store they are asked to drop from.\n */\nconst fellBack = new Set<string>();\n\n/** Whether an instance moved onto a memory store of this name. */\nexport function isFallbackStore(name: string): boolean {\n return fellBack.has(name);\n}\n\n/** Creates and drops the memory stores instances fell back to. */\nexport const fallbackStoreProvider: StoreProvider = {\n create: name => new MemStore(name),\n drop: name => {\n fellBack.delete(name);\n return dropMemStore(name);\n },\n};\n\n/**\n * Wraps a {@link StoreProvider} so that the stores it creates move onto memory\n * together when their storage fails while the instance is opening (see\n * `onStorageFailure`): a store whose `create` throws a\n * {@link StorageFailureError} starts on a {@link MemStore}, and after\n * {@link fallBack} the other stores switch on their next `read()` or\n * `write()`. The memory stores keep the same names, so drops reach them too.\n *\n * Only before {@link opened}. After that the in-memory dag holds data loaded\n * from the real store and loads more on demand, which an empty memory store\n * cannot serve, so a failure is left to the caller. It is still reported, the\n * first time a transaction fails to begin or to commit on a storage failure,\n * whichever caller ran it (persist, heartbeat, garbage collection, ...).\n */\nexport class MemFallbackStoreProvider implements StoreProvider {\n readonly #inner: StoreProvider;\n readonly #onFallBack: (failure: StorageFailureError) => void;\n readonly #onFailureAfterOpen: (failure: StorageFailureError) => void;\n #failure: StorageFailureError | undefined;\n #opened = false;\n\n constructor(\n inner: StoreProvider,\n onFallBack: (failure: StorageFailureError) => void,\n onFailureAfterOpen: (failure: StorageFailureError) => void,\n ) {\n this.#inner = inner;\n this.#onFallBack = onFallBack;\n this.#onFailureAfterOpen = onFailureAfterOpen;\n }\n\n /** Set once the stores have moved onto memory. */\n get failure(): StorageFailureError | undefined {\n return this.#failure;\n }\n\n /** The open has finished; storage failures no longer move the stores. */\n opened(): void {\n this.#opened = true;\n }\n\n /**\n * Moves the stores onto memory if `error` reports a storage failure, the\n * open has not finished, and they are not on memory already. Returns\n * whether it moved them.\n */\n fallBack(error: unknown): boolean {\n if (this.#failure !== undefined || this.#opened) {\n return false;\n }\n const failure = getStorageFailure(error);\n if (failure === undefined) {\n return false;\n }\n this.#failure = failure;\n this.#onFallBack(failure);\n return true;\n }\n\n /**\n * Reports `error` if it is a storage failure after the open. Before it,\n * the open's own error handling decides whether to fall back.\n */\n report(error: unknown): void {\n if (this.#opened && this.#failure === undefined) {\n const failure = getStorageFailure(error);\n if (failure !== undefined) {\n this.#onFailureAfterOpen(failure);\n }\n }\n }\n\n create = (name: string): MemFallbackStore => {\n if (this.#failure === undefined) {\n try {\n return new MemFallbackStore(name, this.#inner.create(name), this);\n } catch (e) {\n if (!this.fallBack(e)) {\n throw e;\n }\n }\n }\n fellBack.add(name);\n return new MemFallbackStore(name, new MemStore(name), this);\n };\n\n drop = (name: string): Promise<void> =>\n this.#failure === undefined\n ? this.#inner.drop(name)\n : fallbackStoreProvider.drop(name);\n}\n\nexport class MemFallbackStore implements Store {\n readonly #name: string;\n readonly #provider: MemFallbackStoreProvider;\n #store: Store;\n #onMemory: boolean;\n #closed = false;\n\n constructor(name: string, store: Store, provider: MemFallbackStoreProvider) {\n this.#name = name;\n this.#store = store;\n this.#onMemory = store instanceof MemStore;\n this.#provider = provider;\n }\n\n async read(): Promise<Read> {\n return new ReportingRead(\n await this.backing.read().catch(this.#reportAndRethrow),\n this.#reportAndRethrow,\n );\n }\n\n async write(): Promise<Write> {\n return new ReportingWrite(\n await this.backing.write().catch(this.#reportAndRethrow),\n this.#reportAndRethrow,\n );\n }\n\n readonly #reportAndRethrow = (e: unknown): never => {\n this.#provider.report(e);\n throw e;\n };\n\n /** The store currently backing this one: the real store, or memory. */\n get backing(): Store {\n if (\n !this.#onMemory &&\n !this.#closed &&\n this.#provider.failure !== undefined\n ) {\n // Not awaited: a store whose storage failed may not complete its close.\n this.#store.close().catch(() => undefined);\n this.#store = new MemStore(this.#name);\n this.#onMemory = true;\n fellBack.add(this.#name);\n }\n return this.#store;\n }\n\n close(): Promise<void> {\n this.#closed = true;\n return this.#store.close();\n }\n\n get closed(): boolean {\n return this.#closed || this.#store.closed;\n }\n\n /** `'mem'` from the moment the stores are on memory. */\n get kind(): string | undefined {\n return this.backing.kind;\n }\n}\n\n/**\n * Reports a transaction that fails to end on a storage failure: its commit,\n * or its release (the SQLite store commits a read transaction and rolls back\n * an uncommitted write there). Not the per-key reads and writes: they are on\n * the hot path, and the SQLite store runs a write's statements in the commit.\n */\nclass ReportingRead<R extends Read> implements Read {\n protected readonly _tx: R;\n protected readonly _reportAndRethrow: (e: unknown) => never;\n\n constructor(tx: R, reportAndRethrow: (e: unknown) => never) {\n this._tx = tx;\n this._reportAndRethrow = reportAndRethrow;\n }\n\n has(key: string): Promise<boolean> {\n return this._tx.has(key);\n }\n\n get(key: string): Promise<ReadonlyJSONValue | undefined> {\n return this._tx.get(key);\n }\n\n release(): void {\n try {\n this._tx.release();\n } catch (e) {\n this._reportAndRethrow(e);\n }\n }\n\n get closed(): boolean {\n return this._tx.closed;\n }\n}\n\nclass ReportingWrite extends ReportingRead<Write> implements Write {\n put(key: string, value: ReadonlyJSONValue): Promise<void> {\n return this._tx.put(key, value);\n }\n\n del(key: string): Promise<void> {\n return this._tx.del(key);\n }\n\n commit(): Promise<void> {\n return this._tx.commit().catch(this._reportAndRethrow);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"mem-fallback-store.js","names":[],"sources":["../../../../../replicache/src/kv/mem-fallback-store.ts"],"sourcesContent":["import type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {\n getStorageFailure,\n type StorageFailureError,\n} from '../storage-failure.ts';\nimport {dropMemStore, MemStore} from './mem-store.ts';\nimport type {Read, Store, StoreProvider, Write} from './store.ts';\n\n/**\n * The names of the memory stores instances moved onto after a storage\n * failure, in this process. Unlike the stores of a `kvStore: 'mem'` instance,\n * these are cleared by drops whatever store they are asked to drop from.\n */\nconst fellBack = new Set<string>();\n\n/** Whether an instance moved onto a memory store of this name. */\nexport function isFallbackStore(name: string): boolean {\n return fellBack.has(name);\n}\n\n/** Creates and drops the memory stores instances fell back to. */\nexport const fallbackStoreProvider: StoreProvider = {\n create: name => new MemStore(name),\n drop: name => {\n fellBack.delete(name);\n return dropMemStore(name);\n },\n};\n\n/**\n * Wraps a {@link StoreProvider} so that the stores it creates move onto memory\n * together when their storage fails while the instance is opening (see\n * `onStorageFailure`): a store whose `create` throws a\n * {@link StorageFailureError} starts on a {@link MemStore}, and after\n * {@link fallBack} the other stores switch on their next `read()` or\n * `write()`. The memory stores keep the same names, so drops reach them too.\n *\n * Only before {@link opened}. After that the in-memory dag holds data loaded\n * from the real store and loads more on demand, which an empty memory store\n * cannot serve, so a failure is left to the caller. It is still reported, the\n * first time a transaction fails to begin or to commit on a storage failure,\n * whichever caller ran it (persist, heartbeat, garbage collection, ...).\n */\nexport class MemFallbackStoreProvider implements StoreProvider {\n readonly #inner: StoreProvider;\n readonly #onFallBack: (failure: StorageFailureError) => void;\n readonly #onFailureAfterOpen: (failure: StorageFailureError) => void;\n #failure: StorageFailureError | undefined;\n #opened = false;\n\n constructor(\n inner: StoreProvider,\n onFallBack: (failure: StorageFailureError) => void,\n onFailureAfterOpen: (failure: StorageFailureError) => void,\n ) {\n this.#inner = inner;\n this.#onFallBack = onFallBack;\n this.#onFailureAfterOpen = onFailureAfterOpen;\n }\n\n /** Set once the stores have moved onto memory. */\n get failure(): StorageFailureError | undefined {\n return this.#failure;\n }\n\n /** The open has finished; storage failures no longer move the stores. */\n opened(): void {\n this.#opened = true;\n }\n\n /**\n * Moves the stores onto memory if `error` reports a storage failure, the\n * open has not finished, and they are not on memory already. Returns\n * whether it moved them.\n */\n fallBack(error: unknown): boolean {\n if (this.#failure !== undefined || this.#opened) {\n return false;\n }\n const failure = getStorageFailure(error);\n if (failure === undefined) {\n return false;\n }\n this.#failure = failure;\n this.#onFallBack(failure);\n return true;\n }\n\n /**\n * Reports `error` if it is a storage failure after the open. Before it,\n * the open's own error handling decides whether to fall back.\n */\n report(error: unknown): void {\n if (this.#opened && this.#failure === undefined) {\n const failure = getStorageFailure(error);\n if (failure !== undefined) {\n this.#onFailureAfterOpen(failure);\n }\n }\n }\n\n create = (name: string): MemFallbackStore => {\n if (this.#failure === undefined) {\n try {\n return new MemFallbackStore(name, this.#inner.create(name), this);\n } catch (e) {\n if (!this.fallBack(e)) {\n throw e;\n }\n }\n }\n fellBack.add(name);\n return new MemFallbackStore(name, new MemStore(name), this);\n };\n\n drop = (name: string): Promise<void> =>\n this.#failure === undefined\n ? this.#inner.drop(name)\n : fallbackStoreProvider.drop(name);\n}\n\nexport class MemFallbackStore implements Store {\n readonly #name: string;\n readonly #provider: MemFallbackStoreProvider;\n #store: Store;\n #onMemory: boolean;\n #closed = false;\n\n constructor(name: string, store: Store, provider: MemFallbackStoreProvider) {\n this.#name = name;\n this.#store = store;\n this.#onMemory = store instanceof MemStore;\n this.#provider = provider;\n }\n\n async read(): Promise<Read> {\n return new ReportingRead(\n await this.backing.read().catch(this.#reportAndRethrow),\n this.#reportAndRethrow,\n );\n }\n\n async write(): Promise<Write> {\n return new ReportingWrite(\n await this.backing.write().catch(this.#reportAndRethrow),\n this.#reportAndRethrow,\n );\n }\n\n readonly #reportAndRethrow = (e: unknown): never => {\n this.#provider.report(e);\n throw e;\n };\n\n /** The store currently backing this one: the real store, or memory. */\n get backing(): Store {\n if (\n !this.#onMemory &&\n !this.#closed &&\n this.#provider.failure !== undefined\n ) {\n // Not awaited: a store whose storage failed may not complete its close.\n this.#store.close().catch(() => undefined);\n this.#store = new MemStore(this.#name);\n this.#onMemory = true;\n fellBack.add(this.#name);\n }\n return this.#store;\n }\n\n close(): Promise<void> {\n this.#closed = true;\n return this.#store.close();\n }\n\n get closed(): boolean {\n return this.#closed || this.#store.closed;\n }\n\n /** `'mem'` from the moment the stores are on memory. */\n get kind(): string | undefined {\n return this.backing.kind;\n }\n}\n\n/**\n * Reports a transaction that fails to end on a storage failure: its commit,\n * or its release (the SQLite store commits a read transaction and rolls back\n * an uncommitted write there). Not the per-key reads and writes: they are on\n * the hot path, and the SQLite store runs a write's statements in the commit.\n */\nclass ReportingRead<R extends Read> implements Read {\n protected readonly _tx: R;\n protected readonly _reportAndRethrow: (e: unknown) => never;\n\n constructor(tx: R, reportAndRethrow: (e: unknown) => never) {\n this._tx = tx;\n this._reportAndRethrow = reportAndRethrow;\n }\n\n has(key: string): Promise<boolean> {\n return this._tx.has(key);\n }\n\n get(key: string): Promise<ReadonlyJSONValue | undefined> {\n return this._tx.get(key);\n }\n\n release(): void {\n try {\n this._tx.release();\n } catch (e) {\n this._reportAndRethrow(e);\n }\n }\n\n get closed(): boolean {\n return this._tx.closed;\n }\n}\n\nclass ReportingWrite extends ReportingRead<Write> implements Write {\n put(key: string, value: ReadonlyJSONValue): Promise<void> {\n return this._tx.put(key, value);\n }\n\n del(key: string): Promise<void> {\n return this._tx.del(key);\n }\n\n commit(): Promise<void> {\n return this._tx.commit().catch(this._reportAndRethrow);\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"mem-store.js","names":["#map","#rwLock","#closed"],"sources":["../../../../../replicache/src/kv/mem-store.ts"],"sourcesContent":["import {RWLock} from '@rocicorp/lock';\nimport {promiseVoid} from '../../../shared/src/resolved-promises.ts';\nimport type {FrozenJSONValue} from '../frozen-json.ts';\nimport {ReadImpl} from './read-impl.ts';\nimport type {Read, Store, Write} from './store.ts';\nimport {throwIfStoreClosed} from './throw-if-closed.ts';\nimport {WriteImpl} from './write-impl.ts';\n\ntype StorageMap = Map<string, FrozenJSONValue>;\n\ntype Value = {readonly lock: RWLock; readonly map: StorageMap};\n\nconst stores = new Map<string, Value>();\n\nexport function clearAllNamedMemStoresForTesting(): void {\n stores.clear();\n}\n\nexport function dropMemStore(name: string): Promise<void> {\n stores.delete(name);\n return promiseVoid;\n}\n\nexport function hasMemStore(name: string): boolean {\n return stores.has(name);\n}\n\n/**\n * A named in-memory Store implementation.\n *\n * Two (or more) named memory stores with the same name will share the same\n * underlying storage. They will also share the same read/write locks, so that\n * only one write transaction can be running at the same time.\n *\n * @experimental This class is experimental and might be removed or changed\n * in the future without following semver versioning. Please be cautious.\n */\nexport class MemStore implements Store {\n readonly #map: StorageMap;\n readonly #rwLock: RWLock;\n #closed = false;\n\n constructor(name: string) {\n const entry = stores.get(name);\n let lock: RWLock;\n let map: StorageMap;\n if (entry) {\n ({lock, map} = entry);\n } else {\n lock = new RWLock();\n map = new Map();\n stores.set(name, {lock, map});\n }\n this.#rwLock = lock;\n this.#map = map;\n }\n\n async read(): Promise<Read> {\n throwIfStoreClosed(this);\n const release = await this.#rwLock.read();\n return new ReadImpl(this.#map, release);\n }\n\n async write(): Promise<Write> {\n throwIfStoreClosed(this);\n const release = await this.#rwLock.write();\n return new WriteImpl(this.#map, release);\n }\n\n close(): Promise<void> {\n this.#closed = true;\n return promiseVoid;\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n\n get kind(): string {\n return 'mem';\n }\n}\n"],"mappings":";;;;;;AAYA,IAAM,yBAAS,IAAI,IAAmB;AAMtC,SAAgB,aAAa,MAA6B;CACxD,OAAO,OAAO,IAAI;CAClB,OAAO;AACT;;;;;;;;;;;AAgBA,IAAa,WAAb,MAAuC;CACrC;CACA;CACA,UAAU;CAEV,YAAY,MAAc;EACxB,MAAM,QAAQ,OAAO,IAAI,IAAI;EAC7B,IAAI;EACJ,IAAI;EACJ,IAAI,OACF,CAAC,CAAC,MAAM,OAAO;OACV;GACL,OAAO,IAAI,OAAO;GAClB,sBAAM,IAAI,IAAI;GACd,OAAO,IAAI,MAAM;IAAC;IAAM;GAAG,CAAC;EAC9B;EACA,KAAKC,UAAU;EACf,KAAKD,OAAO;CACd;CAEA,MAAM,OAAsB;EAC1B,mBAAmB,IAAI;EACvB,MAAM,UAAU,MAAM,KAAKC,QAAQ,KAAK;EACxC,OAAO,IAAI,SAAS,KAAKD,MAAM,OAAO;CACxC;CAEA,MAAM,QAAwB;EAC5B,mBAAmB,IAAI;EACvB,MAAM,UAAU,MAAM,KAAKC,QAAQ,MAAM;EACzC,OAAO,IAAI,UAAU,KAAKD,MAAM,OAAO;CACzC;CAEA,QAAuB;EACrB,KAAKE,UAAU;EACf,OAAO;CACT;CAEA,IAAI,SAAkB;EACpB,OAAO,KAAKA;CACd;CAEA,IAAI,OAAe;EACjB,OAAO;CACT;AACF"}
1
+ {"version":3,"file":"mem-store.js","names":[],"sources":["../../../../../replicache/src/kv/mem-store.ts"],"sourcesContent":["import {RWLock} from '@rocicorp/lock';\nimport {promiseVoid} from '../../../shared/src/resolved-promises.ts';\nimport type {FrozenJSONValue} from '../frozen-json.ts';\nimport {ReadImpl} from './read-impl.ts';\nimport type {Read, Store, Write} from './store.ts';\nimport {throwIfStoreClosed} from './throw-if-closed.ts';\nimport {WriteImpl} from './write-impl.ts';\n\ntype StorageMap = Map<string, FrozenJSONValue>;\n\ntype Value = {readonly lock: RWLock; readonly map: StorageMap};\n\nconst stores = new Map<string, Value>();\n\nexport function clearAllNamedMemStoresForTesting(): void {\n stores.clear();\n}\n\nexport function dropMemStore(name: string): Promise<void> {\n stores.delete(name);\n return promiseVoid;\n}\n\nexport function hasMemStore(name: string): boolean {\n return stores.has(name);\n}\n\n/**\n * A named in-memory Store implementation.\n *\n * Two (or more) named memory stores with the same name will share the same\n * underlying storage. They will also share the same read/write locks, so that\n * only one write transaction can be running at the same time.\n *\n * @experimental This class is experimental and might be removed or changed\n * in the future without following semver versioning. Please be cautious.\n */\nexport class MemStore implements Store {\n readonly #map: StorageMap;\n readonly #rwLock: RWLock;\n #closed = false;\n\n constructor(name: string) {\n const entry = stores.get(name);\n let lock: RWLock;\n let map: StorageMap;\n if (entry) {\n ({lock, map} = entry);\n } else {\n lock = new RWLock();\n map = new Map();\n stores.set(name, {lock, map});\n }\n this.#rwLock = lock;\n this.#map = map;\n }\n\n async read(): Promise<Read> {\n throwIfStoreClosed(this);\n const release = await this.#rwLock.read();\n return new ReadImpl(this.#map, release);\n }\n\n async write(): Promise<Write> {\n throwIfStoreClosed(this);\n const release = await this.#rwLock.write();\n return new WriteImpl(this.#map, release);\n }\n\n close(): Promise<void> {\n this.#closed = true;\n return promiseVoid;\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n\n get kind(): string {\n return 'mem';\n }\n}\n"],"mappings":";;;;;;AAYA,IAAM,yBAAS,IAAI,IAAmB;AAMtC,SAAgB,aAAa,MAA6B;CACxD,OAAO,OAAO,IAAI;CAClB,OAAO;AACT;;;;;;;;;;;AAgBA,IAAa,WAAb,MAAuC;CACrC;CACA;CACA,UAAU;CAEV,YAAY,MAAc;EACxB,MAAM,QAAQ,OAAO,IAAI,IAAI;EAC7B,IAAI;EACJ,IAAI;EACJ,IAAI,OACF,CAAC,CAAC,MAAM,OAAO;OACV;GACL,OAAO,IAAI,OAAO;GAClB,sBAAM,IAAI,IAAI;GACd,OAAO,IAAI,MAAM;IAAC;IAAM;GAAG,CAAC;EAC9B;EACA,KAAK,UAAU;EACf,KAAK,OAAO;CACd;CAEA,MAAM,OAAsB;EAC1B,mBAAmB,IAAI;EACvB,MAAM,UAAU,MAAM,KAAK,QAAQ,KAAK;EACxC,OAAO,IAAI,SAAS,KAAK,MAAM,OAAO;CACxC;CAEA,MAAM,QAAwB;EAC5B,mBAAmB,IAAI;EACvB,MAAM,UAAU,MAAM,KAAK,QAAQ,MAAM;EACzC,OAAO,IAAI,UAAU,KAAK,MAAM,OAAO;CACzC;CAEA,QAAuB;EACrB,KAAK,UAAU;EACf,OAAO;CACT;CAEA,IAAI,SAAkB;EACpB,OAAO,KAAK;CACd;CAEA,IAAI,OAAe;EACjB,OAAO;CACT;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","names":["#db","#sql","#openOpts"],"sources":["../../../../../../replicache/src/kv/op-sqlite/store.ts"],"sourcesContent":["import type {\n PreparedStatement,\n SQLiteDatabase,\n SQLiteStoreOptions,\n} from '../sqlite-store.ts';\nimport {dropStore, SQLiteStore} from '../sqlite-store.ts';\nimport type {StoreProvider} from '../store.ts';\nimport {open, rawResultRows, type DB} from './types.ts';\n\nexport type OpSQLiteStoreOptions = SQLiteStoreOptions & {\n // OpSQLite-specific options\n location?: 'default' | 'Library' | 'Documents' | 'Temporary';\n encryptionKey?: string;\n};\n\nfunction dropOpSQLiteStore(\n name: string,\n opts?: OpSQLiteStoreOptions,\n): Promise<void> {\n return dropStore(\n name,\n (filename, options) => new OpSQLiteDatabase(filename, options),\n opts,\n );\n}\n\n/**\n * Creates a StoreProvider for SQLite-based stores using @op-engineering/op-sqlite.\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 function opSQLiteStoreProvider(\n opts?: OpSQLiteStoreOptions,\n): StoreProvider {\n return {\n create: name =>\n new SQLiteStore(\n name,\n (name, options) => new OpSQLiteDatabase(name, options),\n opts,\n 'op-sqlite',\n ),\n drop: name => dropOpSQLiteStore(name, opts),\n };\n}\n\nclass OpSQLitePreparedStatement implements PreparedStatement {\n readonly #db: DB;\n readonly #sql: string;\n\n constructor(db: DB, sql: string) {\n this.#db = db;\n this.#sql = sql;\n }\n\n async exec(params: string[]): Promise<void> {\n await this.#db.executeRaw(this.#sql, params);\n }\n\n async all(params: string[]): Promise<unknown[][]> {\n return rawResultRows(await this.#db.executeRaw(this.#sql, params));\n }\n}\n\n/** What `open()` accepts; kept so `destroy()` reopens with the same options. */\ntype OpenOptions = Parameters<typeof open>[0];\n\nclass OpSQLiteDatabase implements SQLiteDatabase {\n readonly #db: DB;\n readonly #openOpts: OpenOptions;\n\n constructor(filename: string, opts?: OpSQLiteStoreOptions) {\n const openOpts: OpenOptions = {name: filename};\n\n if (opts?.location) {\n openOpts.location = opts.location;\n }\n if (opts?.encryptionKey) {\n openOpts.encryptionKey = opts.encryptionKey;\n }\n\n this.#openOpts = openOpts;\n this.#db = open(openOpts);\n }\n\n close(): void {\n this.#db.close();\n }\n\n destroy(): void {\n // OpSQLite uses delete method on the database instance\n // We need to create a temporary connection to delete the database. It\n // must be opened with the same options as the store, or a non-default\n // `location` deletes a (freshly created, empty) file at the default path\n // and leaves the real database in place.\n try {\n const tempDb = open(this.#openOpts);\n tempDb.delete();\n tempDb.close();\n } catch (_error) {\n // Database might not exist, which is fine\n }\n }\n\n prepare(sql: string): PreparedStatement {\n return new OpSQLitePreparedStatement(this.#db, sql);\n }\n\n execSync(sql: string): void {\n this.#db.executeRawSync(sql, []);\n }\n}\n"],"mappings":";;;AAeA,SAAS,kBACP,MACA,MACe;CACf,OAAO,UACL,OACC,UAAU,YAAY,IAAI,iBAAiB,UAAU,OAAO,GAC7D,IACF;AACF;;;;;;;AAQA,SAAgB,sBACd,MACe;CACf,OAAO;EACL,SAAQ,SACN,IAAI,YACF,OACC,MAAM,YAAY,IAAI,iBAAiB,MAAM,OAAO,GACrD,MACA,WACF;EACF,OAAM,SAAQ,kBAAkB,MAAM,IAAI;CAC5C;AACF;AAEA,IAAM,4BAAN,MAA6D;CAC3D;CACA;CAEA,YAAY,IAAQ,KAAa;EAC/B,KAAKA,MAAM;EACX,KAAKC,OAAO;CACd;CAEA,MAAM,KAAK,QAAiC;EAC1C,MAAM,KAAKD,IAAI,WAAW,KAAKC,MAAM,MAAM;CAC7C;CAEA,MAAM,IAAI,QAAwC;EAChD,OAAO,cAAc,MAAM,KAAKD,IAAI,WAAW,KAAKC,MAAM,MAAM,CAAC;CACnE;AACF;AAKA,IAAM,mBAAN,MAAiD;CAC/C;CACA;CAEA,YAAY,UAAkB,MAA6B;EACzD,MAAM,WAAwB,EAAC,MAAM,SAAQ;EAE7C,IAAI,MAAM,UACR,SAAS,WAAW,KAAK;EAE3B,IAAI,MAAM,eACR,SAAS,gBAAgB,KAAK;EAGhC,KAAKC,YAAY;EACjB,KAAKF,MAAM,KAAK,QAAQ;CAC1B;CAEA,QAAc;EACZ,KAAKA,IAAI,MAAM;CACjB;CAEA,UAAgB;EAMd,IAAI;GACF,MAAM,SAAS,KAAK,KAAKE,SAAS;GAClC,OAAO,OAAO;GACd,OAAO,MAAM;EACf,SAAS,QAAQ,CAEjB;CACF;CAEA,QAAQ,KAAgC;EACtC,OAAO,IAAI,0BAA0B,KAAKF,KAAK,GAAG;CACpD;CAEA,SAAS,KAAmB;EAC1B,KAAKA,IAAI,eAAe,KAAK,CAAC,CAAC;CACjC;AACF"}
1
+ {"version":3,"file":"store.js","names":[],"sources":["../../../../../../replicache/src/kv/op-sqlite/store.ts"],"sourcesContent":["import type {\n PreparedStatement,\n SQLiteDatabase,\n SQLiteStoreOptions,\n} from '../sqlite-store.ts';\nimport {dropStore, SQLiteStore} from '../sqlite-store.ts';\nimport type {StoreProvider} from '../store.ts';\nimport {open, rawResultRows, type DB} from './types.ts';\n\nexport type OpSQLiteStoreOptions = SQLiteStoreOptions & {\n // OpSQLite-specific options\n location?: 'default' | 'Library' | 'Documents' | 'Temporary';\n encryptionKey?: string;\n};\n\nfunction dropOpSQLiteStore(\n name: string,\n opts?: OpSQLiteStoreOptions,\n): Promise<void> {\n return dropStore(\n name,\n (filename, options) => new OpSQLiteDatabase(filename, options),\n opts,\n );\n}\n\n/**\n * Creates a StoreProvider for SQLite-based stores using @op-engineering/op-sqlite.\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 function opSQLiteStoreProvider(\n opts?: OpSQLiteStoreOptions,\n): StoreProvider {\n return {\n create: name =>\n new SQLiteStore(\n name,\n (name, options) => new OpSQLiteDatabase(name, options),\n opts,\n 'op-sqlite',\n ),\n drop: name => dropOpSQLiteStore(name, opts),\n };\n}\n\nclass OpSQLitePreparedStatement implements PreparedStatement {\n readonly #db: DB;\n readonly #sql: string;\n\n constructor(db: DB, sql: string) {\n this.#db = db;\n this.#sql = sql;\n }\n\n async exec(params: string[]): Promise<void> {\n await this.#db.executeRaw(this.#sql, params);\n }\n\n async all(params: string[]): Promise<unknown[][]> {\n return rawResultRows(await this.#db.executeRaw(this.#sql, params));\n }\n}\n\n/** What `open()` accepts; kept so `destroy()` reopens with the same options. */\ntype OpenOptions = Parameters<typeof open>[0];\n\nclass OpSQLiteDatabase implements SQLiteDatabase {\n readonly #db: DB;\n readonly #openOpts: OpenOptions;\n\n constructor(filename: string, opts?: OpSQLiteStoreOptions) {\n const openOpts: OpenOptions = {name: filename};\n\n if (opts?.location) {\n openOpts.location = opts.location;\n }\n if (opts?.encryptionKey) {\n openOpts.encryptionKey = opts.encryptionKey;\n }\n\n this.#openOpts = openOpts;\n this.#db = open(openOpts);\n }\n\n close(): void {\n this.#db.close();\n }\n\n destroy(): void {\n // OpSQLite uses delete method on the database instance\n // We need to create a temporary connection to delete the database. It\n // must be opened with the same options as the store, or a non-default\n // `location` deletes a (freshly created, empty) file at the default path\n // and leaves the real database in place.\n try {\n const tempDb = open(this.#openOpts);\n tempDb.delete();\n tempDb.close();\n } catch (_error) {\n // Database might not exist, which is fine\n }\n }\n\n prepare(sql: string): PreparedStatement {\n return new OpSQLitePreparedStatement(this.#db, sql);\n }\n\n execSync(sql: string): void {\n this.#db.executeRawSync(sql, []);\n }\n}\n"],"mappings":";;;AAeA,SAAS,kBACP,MACA,MACe;CACf,OAAO,UACL,OACC,UAAU,YAAY,IAAI,iBAAiB,UAAU,OAAO,GAC7D,IACF;AACF;;;;;;;AAQA,SAAgB,sBACd,MACe;CACf,OAAO;EACL,SAAQ,SACN,IAAI,YACF,OACC,MAAM,YAAY,IAAI,iBAAiB,MAAM,OAAO,GACrD,MACA,WACF;EACF,OAAM,SAAQ,kBAAkB,MAAM,IAAI;CAC5C;AACF;AAEA,IAAM,4BAAN,MAA6D;CAC3D;CACA;CAEA,YAAY,IAAQ,KAAa;EAC/B,KAAK,MAAM;EACX,KAAK,OAAO;CACd;CAEA,MAAM,KAAK,QAAiC;EAC1C,MAAM,KAAK,IAAI,WAAW,KAAK,MAAM,MAAM;CAC7C;CAEA,MAAM,IAAI,QAAwC;EAChD,OAAO,cAAc,MAAM,KAAK,IAAI,WAAW,KAAK,MAAM,MAAM,CAAC;CACnE;AACF;AAKA,IAAM,mBAAN,MAAiD;CAC/C;CACA;CAEA,YAAY,UAAkB,MAA6B;EACzD,MAAM,WAAwB,EAAC,MAAM,SAAQ;EAE7C,IAAI,MAAM,UACR,SAAS,WAAW,KAAK;EAE3B,IAAI,MAAM,eACR,SAAS,gBAAgB,KAAK;EAGhC,KAAK,YAAY;EACjB,KAAK,MAAM,KAAK,QAAQ;CAC1B;CAEA,QAAc;EACZ,KAAK,IAAI,MAAM;CACjB;CAEA,UAAgB;EAMd,IAAI;GACF,MAAM,SAAS,KAAK,KAAK,SAAS;GAClC,OAAO,OAAO;GACd,OAAO,MAAM;EACf,SAAS,QAAQ,CAEjB;CACF;CAEA,QAAQ,KAAgC;EACtC,OAAO,IAAI,0BAA0B,KAAK,KAAK,GAAG;CACpD;CAEA,SAAS,KAAmB;EAC1B,KAAK,IAAI,eAAe,KAAK,CAAC,CAAC;CACjC;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../../../../../../replicache/src/kv/op-sqlite/types.ts"],"sourcesContent":["// Type definitions and imports for @op-engineering/op-sqlite\n// This file isolates the module resolution workarounds needed for this package\n\nimport {open as openDB} from '@op-engineering/op-sqlite';\n\n/**\n * Result of `executeRaw`/`executeRawSync`. op-sqlite changed this shape in\n * v17.0.0 (commit `4cd58b8`): `<=16` returned a bare array of row arrays, `>=17`\n * returns `{rowsAffected, insertId, rawRows, columnNames}` with rows under\n * `rawRows`. The peer range is `>=15`, so both shapes must be handled.\n */\nexport type RawResult =\n | unknown[][]\n | {\n rawRows?: unknown[][];\n columnNames?: unknown[];\n rowsAffected?: number;\n insertId?: number;\n };\n\n/** Extracts the row arrays from either {@link RawResult} shape. */\nexport function rawResultRows(result: RawResult): unknown[][] {\n return (\n Array.isArray(result) ? result : (result.rawRows ?? [])\n ) as unknown[][];\n}\n\n// Minimal type definitions for @op-engineering/op-sqlite\n// These types are used as fallback since imports have module resolution issues\nexport interface DB {\n close: () => void;\n delete: (location?: string) => void;\n executeRaw: (query: string, params?: string[]) => Promise<RawResult>;\n executeRawSync: (query: string, params?: string[]) => RawResult;\n}\n\nexport type OpenFunction = (params: {\n name: string;\n location?: string;\n encryptionKey?: string;\n}) => DB;\n\n// Export the open function with proper typing\nexport const open: OpenFunction = openDB;\n"],"mappings":";;;AAqBA,SAAgB,cAAc,QAAgC;CAC5D,OACE,MAAM,QAAQ,MAAM,IAAI,SAAU,OAAO,WAAW,CAAC;AAEzD;AAkBA,IAAa,SAAqB"}
1
+ {"version":3,"file":"types.js","names":["open","openDB"],"sources":["../../../../../../replicache/src/kv/op-sqlite/types.ts"],"sourcesContent":["// Type definitions and imports for @op-engineering/op-sqlite\n// This file isolates the module resolution workarounds needed for this package\n\nimport {open as openDB} from '@op-engineering/op-sqlite';\n\n/**\n * Result of `executeRaw`/`executeRawSync`. op-sqlite changed this shape in\n * v17.0.0 (commit `4cd58b8`): `<=16` returned a bare array of row arrays, `>=17`\n * returns `{rowsAffected, insertId, rawRows, columnNames}` with rows under\n * `rawRows`. The peer range is `>=15`, so both shapes must be handled.\n */\nexport type RawResult =\n | unknown[][]\n | {\n rawRows?: unknown[][];\n columnNames?: unknown[];\n rowsAffected?: number;\n insertId?: number;\n };\n\n/** Extracts the row arrays from either {@link RawResult} shape. */\nexport function rawResultRows(result: RawResult): unknown[][] {\n return (\n Array.isArray(result) ? result : (result.rawRows ?? [])\n ) as unknown[][];\n}\n\n// Minimal type definitions for @op-engineering/op-sqlite\n// These types are used as fallback since imports have module resolution issues\nexport interface DB {\n close: () => void;\n delete: (location?: string) => void;\n executeRaw: (query: string, params?: string[]) => Promise<RawResult>;\n executeRawSync: (query: string, params?: string[]) => RawResult;\n}\n\nexport type OpenFunction = (params: {\n name: string;\n location?: string;\n encryptionKey?: string;\n}) => DB;\n\n// Export the open function with proper typing\nexport const open: OpenFunction = openDB;\n"],"mappings":";;;AAqBA,SAAgB,cAAc,QAAgC;CAC5D,OACE,MAAM,QAAQ,MAAM,IAAI,SAAU,OAAO,WAAW,CAAC;AAEzD;AAkBA,IAAaA,SAAqBC"}
@@ -1 +1 @@
1
- {"version":3,"file":"read-impl.js","names":["#map","#release","#closed"],"sources":["../../../../../replicache/src/kv/read-impl.ts"],"sourcesContent":["import type {FrozenJSONValue} from '../frozen-json.ts';\nimport type {Read} from './store.ts';\nimport {maybeTransactionIsClosedRejection} from './throw-if-closed.ts';\n\nexport class ReadImpl implements Read {\n readonly #map: Map<string, FrozenJSONValue>;\n readonly #release: () => void;\n #closed = false;\n\n constructor(map: Map<string, FrozenJSONValue>, release: () => void) {\n this.#map = map;\n this.#release = release;\n }\n\n release() {\n this.#release();\n this.#closed = true;\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n\n has(key: string): Promise<boolean> {\n return (\n maybeTransactionIsClosedRejection(this) ??\n Promise.resolve(this.#map.has(key))\n );\n }\n\n get(key: string): Promise<FrozenJSONValue | undefined> {\n return (\n maybeTransactionIsClosedRejection(this) ??\n Promise.resolve(this.#map.get(key))\n );\n }\n}\n"],"mappings":";;AAIA,IAAa,WAAb,MAAsC;CACpC;CACA;CACA,UAAU;CAEV,YAAY,KAAmC,SAAqB;EAClE,KAAKA,OAAO;EACZ,KAAKC,WAAW;CAClB;CAEA,UAAU;EACR,KAAKA,SAAS;EACd,KAAKC,UAAU;CACjB;CAEA,IAAI,SAAkB;EACpB,OAAO,KAAKA;CACd;CAEA,IAAI,KAA+B;EACjC,OACE,kCAAkC,IAAI,KACtC,QAAQ,QAAQ,KAAKF,KAAK,IAAI,GAAG,CAAC;CAEtC;CAEA,IAAI,KAAmD;EACrD,OACE,kCAAkC,IAAI,KACtC,QAAQ,QAAQ,KAAKA,KAAK,IAAI,GAAG,CAAC;CAEtC;AACF"}
1
+ {"version":3,"file":"read-impl.js","names":[],"sources":["../../../../../replicache/src/kv/read-impl.ts"],"sourcesContent":["import type {FrozenJSONValue} from '../frozen-json.ts';\nimport type {Read} from './store.ts';\nimport {maybeTransactionIsClosedRejection} from './throw-if-closed.ts';\n\nexport class ReadImpl implements Read {\n readonly #map: Map<string, FrozenJSONValue>;\n readonly #release: () => void;\n #closed = false;\n\n constructor(map: Map<string, FrozenJSONValue>, release: () => void) {\n this.#map = map;\n this.#release = release;\n }\n\n release() {\n this.#release();\n this.#closed = true;\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n\n has(key: string): Promise<boolean> {\n return (\n maybeTransactionIsClosedRejection(this) ??\n Promise.resolve(this.#map.has(key))\n );\n }\n\n get(key: string): Promise<FrozenJSONValue | undefined> {\n return (\n maybeTransactionIsClosedRejection(this) ??\n Promise.resolve(this.#map.get(key))\n );\n }\n}\n"],"mappings":";;AAIA,IAAa,WAAb,MAAsC;CACpC;CACA;CACA,UAAU;CAEV,YAAY,KAAmC,SAAqB;EAClE,KAAK,OAAO;EACZ,KAAK,WAAW;CAClB;CAEA,UAAU;EACR,KAAK,SAAS;EACd,KAAK,UAAU;CACjB;CAEA,IAAI,SAAkB;EACpB,OAAO,KAAK;CACd;CAEA,IAAI,KAA+B;EACjC,OACE,kCAAkC,IAAI,KACtC,QAAQ,QAAQ,KAAK,KAAK,IAAI,GAAG,CAAC;CAEtC;CAEA,IAAI,KAAmD;EACrD,OACE,kCAAkC,IAAI,KACtC,QAAQ,QAAQ,KAAK,KAAK,IAAI,GAAG,CAAC;CAEtC;AACF"}
@@ -441,6 +441,6 @@ function dropStore(name, createDelegate, opts) {
441
441
  return Promise.resolve();
442
442
  }
443
443
  //#endregion
444
- export { SQLiteStore, clearAllNamedStoresForTesting, dropStore };
444
+ export { SQLiteStore, SQLiteStoreRead, SQLiteWrite, classifySQLiteError, clearAllNamedStoresForTesting, dropStore, safeFilename, setupDatabase };
445
445
 
446
446
  //# sourceMappingURL=sqlite-store.js.map