@powersync/web 0.0.0-dev-20260708104358 → 0.0.0-dev-20260917074240

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 (267) hide show
  1. package/README.md +1 -11
  2. package/bin/powersync.cjs +1 -1
  3. package/dist/index.react_native_web.js +2095 -0
  4. package/dist/index.react_native_web.js.map +1 -0
  5. package/dist/worker/AccessHandlePoolVFS-BPUHfZME.js +2 -0
  6. package/dist/worker/AccessHandlePoolVFS-BPUHfZME.js.map +1 -0
  7. package/dist/worker/FacadeVFS-d1ZDvud7.js +2 -0
  8. package/dist/worker/FacadeVFS-d1ZDvud7.js.map +1 -0
  9. package/dist/worker/IDBBatchAtomicVFS-DbkDb777.js +2 -0
  10. package/dist/worker/IDBBatchAtomicVFS-DbkDb777.js.map +1 -0
  11. package/dist/worker/MemoryVFS-DVJL5F8j.js +2 -0
  12. package/dist/worker/MemoryVFS-DVJL5F8j.js.map +1 -0
  13. package/dist/worker/OPFSCoopSyncVFS-BgTiWPfa.js +2 -0
  14. package/dist/worker/OPFSCoopSyncVFS-BgTiWPfa.js.map +1 -0
  15. package/dist/worker/OPFSWriteAheadVFS-Rt5CGCZP.js +2 -0
  16. package/dist/worker/OPFSWriteAheadVFS-Rt5CGCZP.js.map +1 -0
  17. package/dist/worker/assets/mc-wa-sqlite-BHScYYZw.wasm +0 -0
  18. package/dist/worker/assets/mc-wa-sqlite-async-DdlQmAUV.wasm +0 -0
  19. package/dist/worker/assets/wa-sqlite-CIxTmRHQ.wasm +0 -0
  20. package/dist/worker/assets/wa-sqlite-async-zc68fxQq.wasm +0 -0
  21. package/dist/worker/mc-wa-sqlite-PubB6u8c.js +2 -0
  22. package/dist/worker/mc-wa-sqlite-PubB6u8c.js.map +1 -0
  23. package/dist/worker/mc-wa-sqlite-async-DJG_ANKO.js +2 -0
  24. package/dist/worker/mc-wa-sqlite-async-DJG_ANKO.js.map +1 -0
  25. package/dist/worker/wa-sqlite-D1_4mGs8.js +2 -0
  26. package/dist/worker/wa-sqlite-D1_4mGs8.js.map +1 -0
  27. package/dist/worker/wa-sqlite-async-BxkwNY-2.js +2 -0
  28. package/dist/worker/wa-sqlite-async-BxkwNY-2.js.map +1 -0
  29. package/dist/worker/websockets-Q8W_lerF.js +9 -0
  30. package/dist/worker/websockets-Q8W_lerF.js.map +1 -0
  31. package/dist/worker/worker.js +7 -0
  32. package/dist/worker/worker.js.map +1 -0
  33. package/lib/attachments/IndexDBFileSystemAdapter.js.map +1 -0
  34. package/lib/{src/db → db}/NavigatorTriggerClaimManager.d.ts +1 -1
  35. package/lib/db/NavigatorTriggerClaimManager.js.map +1 -0
  36. package/lib/db/PowerSyncDatabase.d.ts +66 -0
  37. package/lib/{src/db → db}/PowerSyncDatabase.js +60 -79
  38. package/lib/db/PowerSyncDatabase.js.map +1 -0
  39. package/lib/db/adapters/AsyncWebAdapter.d.ts +32 -0
  40. package/lib/{src/db → db}/adapters/AsyncWebAdapter.js +18 -69
  41. package/lib/db/adapters/AsyncWebAdapter.js.map +1 -0
  42. package/lib/db/adapters/SSRDBAdapter.d.ts +17 -0
  43. package/lib/db/adapters/SSRDBAdapter.js +37 -0
  44. package/lib/db/adapters/SSRDBAdapter.js.map +1 -0
  45. package/lib/{src/db → db}/adapters/WebDBAdapter.d.ts +1 -1
  46. package/lib/db/adapters/WebDBAdapter.js.map +1 -0
  47. package/lib/db/adapters/acquireFromPool.d.ts +7 -0
  48. package/lib/db/adapters/acquireFromPool.js +60 -0
  49. package/lib/db/adapters/acquireFromPool.js.map +1 -0
  50. package/lib/db/adapters/memory-pool/client.d.ts +70 -0
  51. package/lib/db/adapters/memory-pool/client.js +269 -0
  52. package/lib/db/adapters/memory-pool/client.js.map +1 -0
  53. package/lib/db/adapters/memory-pool/shared.d.ts +51 -0
  54. package/lib/db/adapters/memory-pool/shared.js +16 -0
  55. package/lib/db/adapters/memory-pool/shared.js.map +1 -0
  56. package/lib/db/adapters/memory-pool/vfs.d.ts +19 -0
  57. package/lib/db/adapters/memory-pool/vfs.js +247 -0
  58. package/lib/db/adapters/memory-pool/vfs.js.map +1 -0
  59. package/lib/db/adapters/memory-pool/worker.js +45 -0
  60. package/lib/db/adapters/memory-pool/worker.js.map +1 -0
  61. package/lib/db/adapters/options.d.ts +94 -0
  62. package/lib/db/adapters/options.js +6 -0
  63. package/lib/db/adapters/options.js.map +1 -0
  64. package/lib/db/adapters/resolveAndValidateOptions.d.ts +13 -0
  65. package/lib/db/adapters/resolveAndValidateOptions.js +41 -0
  66. package/lib/db/adapters/resolveAndValidateOptions.js.map +1 -0
  67. package/lib/{src/db → db}/adapters/wa-sqlite/ConcurrentConnection.d.ts +3 -4
  68. package/lib/{src/db → db}/adapters/wa-sqlite/ConcurrentConnection.js +2 -2
  69. package/lib/db/adapters/wa-sqlite/ConcurrentConnection.js.map +1 -0
  70. package/lib/{src/db → db}/adapters/wa-sqlite/DatabaseClient.d.ts +4 -4
  71. package/lib/{src/db → db}/adapters/wa-sqlite/DatabaseClient.js +11 -37
  72. package/lib/db/adapters/wa-sqlite/DatabaseClient.js.map +1 -0
  73. package/lib/{src/db → db}/adapters/wa-sqlite/DatabaseServer.d.ts +5 -5
  74. package/lib/{src/db → db}/adapters/wa-sqlite/DatabaseServer.js +14 -7
  75. package/lib/db/adapters/wa-sqlite/DatabaseServer.js.map +1 -0
  76. package/lib/{src/db → db}/adapters/wa-sqlite/RawSqliteConnection.d.ts +30 -12
  77. package/lib/{src/db → db}/adapters/wa-sqlite/RawSqliteConnection.js +70 -16
  78. package/lib/db/adapters/wa-sqlite/RawSqliteConnection.js.map +1 -0
  79. package/lib/db/adapters/wa-sqlite/StatementCache.d.ts +16 -0
  80. package/lib/db/adapters/wa-sqlite/StatementCache.js +44 -0
  81. package/lib/db/adapters/wa-sqlite/StatementCache.js.map +1 -0
  82. package/lib/db/adapters/wa-sqlite/WASQLiteOpenFactory.d.ts +18 -0
  83. package/lib/db/adapters/wa-sqlite/WASQLiteOpenFactory.js +140 -0
  84. package/lib/db/adapters/wa-sqlite/WASQLiteOpenFactory.js.map +1 -0
  85. package/lib/{src/db → db}/adapters/wa-sqlite/vfs.d.ts +9 -2
  86. package/lib/{src/db → db}/adapters/wa-sqlite/vfs.js +6 -6
  87. package/lib/db/adapters/wa-sqlite/vfs.js.map +1 -0
  88. package/lib/{src/db → db}/sync/SSRWebStreamingSyncImplementation.d.ts +5 -16
  89. package/lib/{src/db → db}/sync/SSRWebStreamingSyncImplementation.js +7 -23
  90. package/lib/db/sync/SSRWebStreamingSyncImplementation.js.map +1 -0
  91. package/lib/{src/db → db}/sync/SharedWebStreamingSyncImplementation.d.ts +15 -15
  92. package/lib/{src/db → db}/sync/SharedWebStreamingSyncImplementation.js +38 -70
  93. package/lib/db/sync/SharedWebStreamingSyncImplementation.js.map +1 -0
  94. package/lib/db/sync/TabLocalStreamingSyncImplementation.d.ts +19 -0
  95. package/lib/db/sync/TabLocalStreamingSyncImplementation.js +70 -0
  96. package/lib/db/sync/TabLocalStreamingSyncImplementation.js.map +1 -0
  97. package/lib/db/sync/WebRemote.d.ts +10 -0
  98. package/lib/db/sync/WebRemote.js +33 -0
  99. package/lib/db/sync/WebRemote.js.map +1 -0
  100. package/lib/{src/db → db}/sync/WebStreamingSyncImplementation.d.ts +2 -4
  101. package/lib/{src/db → db}/sync/WebStreamingSyncImplementation.js +3 -2
  102. package/lib/db/sync/WebStreamingSyncImplementation.js.map +1 -0
  103. package/lib/db/sync/userAgent.js.map +1 -0
  104. package/lib/{src/index.d.ts → index.d.ts} +1 -3
  105. package/lib/{src/index.js → index.js} +1 -3
  106. package/lib/index.js.map +1 -0
  107. package/lib/shared/navigator.js.map +1 -0
  108. package/lib/shared/tab_close_signal.js.map +1 -0
  109. package/lib/worker/SharedWorkerConnectionRequest.d.ts +5 -0
  110. package/lib/worker/SharedWorkerConnectionRequest.js +2 -0
  111. package/lib/worker/SharedWorkerConnectionRequest.js.map +1 -0
  112. package/lib/worker/client.d.ts +17 -0
  113. package/lib/worker/client.js +90 -0
  114. package/lib/worker/client.js.map +1 -0
  115. package/lib/worker/db/MultiDatabaseServer.d.ts +21 -0
  116. package/lib/{src/worker → worker}/db/MultiDatabaseServer.js +45 -24
  117. package/lib/worker/db/MultiDatabaseServer.js.map +1 -0
  118. package/lib/worker/sync/AbstractSharedSyncClientProvider.d.ts +14 -0
  119. package/lib/worker/sync/AbstractSharedSyncClientProvider.js.map +1 -0
  120. package/lib/worker/sync/BroadcastLogger.d.ts +27 -0
  121. package/lib/worker/sync/BroadcastLogger.js +65 -0
  122. package/lib/worker/sync/BroadcastLogger.js.map +1 -0
  123. package/lib/{src/worker → worker}/sync/SharedSyncImplementation.d.ts +14 -25
  124. package/lib/{src/worker → worker}/sync/SharedSyncImplementation.js +140 -107
  125. package/lib/worker/sync/SharedSyncImplementation.js.map +1 -0
  126. package/lib/{src/worker → worker}/sync/WorkerClient.d.ts +4 -4
  127. package/lib/{src/worker → worker}/sync/WorkerClient.js +5 -5
  128. package/lib/worker/sync/WorkerClient.js.map +1 -0
  129. package/lib/worker/worker.d.ts +1 -0
  130. package/lib/worker/worker.js +34 -0
  131. package/lib/worker/worker.js.map +1 -0
  132. package/package.json +31 -32
  133. package/src/db/NavigatorTriggerClaimManager.ts +1 -1
  134. package/src/db/PowerSyncDatabase.ts +96 -144
  135. package/src/db/adapters/AsyncWebAdapter.ts +29 -86
  136. package/src/db/adapters/SSRDBAdapter.ts +14 -64
  137. package/src/db/adapters/WebDBAdapter.ts +1 -1
  138. package/src/db/adapters/acquireFromPool.ts +73 -0
  139. package/src/db/adapters/memory-pool/client.ts +367 -0
  140. package/src/db/adapters/memory-pool/shared.ts +79 -0
  141. package/src/db/adapters/memory-pool/vfs.ts +293 -0
  142. package/src/db/adapters/memory-pool/worker.ts +53 -0
  143. package/src/db/adapters/options.ts +108 -0
  144. package/src/db/adapters/resolveAndValidateOptions.ts +49 -0
  145. package/src/db/adapters/wa-sqlite/ConcurrentConnection.ts +4 -5
  146. package/src/db/adapters/wa-sqlite/DatabaseClient.ts +20 -56
  147. package/src/db/adapters/wa-sqlite/DatabaseServer.ts +18 -12
  148. package/src/db/adapters/wa-sqlite/RawSqliteConnection.ts +108 -30
  149. package/src/db/adapters/wa-sqlite/StatementCache.ts +50 -0
  150. package/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.ts +82 -125
  151. package/src/db/adapters/wa-sqlite/vfs.ts +13 -8
  152. package/src/db/sync/SSRWebStreamingSyncImplementation.ts +8 -36
  153. package/src/db/sync/SharedWebStreamingSyncImplementation.ts +47 -82
  154. package/src/db/sync/TabLocalStreamingSyncImplementation.ts +90 -0
  155. package/src/db/sync/WebRemote.ts +23 -26
  156. package/src/db/sync/WebStreamingSyncImplementation.ts +4 -5
  157. package/src/index.ts +1 -3
  158. package/src/worker/SharedWorkerConnectionRequest.ts +6 -0
  159. package/src/worker/client.ts +121 -0
  160. package/src/worker/db/MultiDatabaseServer.ts +59 -33
  161. package/src/worker/sync/AbstractSharedSyncClientProvider.ts +5 -10
  162. package/src/worker/sync/BroadcastLogger.ts +35 -103
  163. package/src/worker/sync/SharedSyncImplementation.ts +197 -138
  164. package/src/worker/sync/WorkerClient.ts +8 -8
  165. package/src/worker/worker.ts +38 -0
  166. package/dist/2075a31bb151adbb9767.wasm +0 -0
  167. package/dist/3322bc84de986b63c2cd.wasm +0 -0
  168. package/dist/8e97452e297be23b5e50.wasm +0 -0
  169. package/dist/fbc178b70d530e8ce02b.wasm +0 -0
  170. package/dist/index.umd.js +0 -7821
  171. package/dist/index.umd.js.map +0 -1
  172. package/dist/worker/SharedSyncImplementation.umd.js +0 -16139
  173. package/dist/worker/SharedSyncImplementation.umd.js.map +0 -1
  174. package/dist/worker/WASQLiteDB.umd.js +0 -17434
  175. package/dist/worker/WASQLiteDB.umd.js.map +0 -1
  176. package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_dist_mc-wa-s-9af0a7.umd.js +0 -31
  177. package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_dist_mc-wa-s-9af0a7.umd.js.map +0 -1
  178. package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_dist_mc-wa-s-bbf5a9.umd.js +0 -31
  179. package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_dist_mc-wa-s-bbf5a9.umd.js.map +0 -1
  180. package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_dist_wa-sqli-c26e0f.umd.js +0 -31
  181. package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_dist_wa-sqli-c26e0f.umd.js.map +0 -1
  182. package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_dist_wa-sqlite_mjs.umd.js +0 -31
  183. package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_dist_wa-sqlite_mjs.umd.js.map +0 -1
  184. package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-2fb422.umd.js +0 -3562
  185. package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-2fb422.umd.js.map +0 -1
  186. package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-833585.umd.js +0 -1400
  187. package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-833585.umd.js.map +0 -1
  188. package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-96fb23.umd.js +0 -2478
  189. package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-96fb23.umd.js.map +0 -1
  190. package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-c89911.umd.js +0 -1681
  191. package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-c89911.umd.js.map +0 -1
  192. package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-ec4eb1.umd.js +0 -1820
  193. package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-ec4eb1.umd.js.map +0 -1
  194. package/lib/package.json +0 -91
  195. package/lib/src/attachments/IndexDBFileSystemAdapter.js.map +0 -1
  196. package/lib/src/db/NavigatorTriggerClaimManager.js.map +0 -1
  197. package/lib/src/db/PowerSyncDatabase.d.ts +0 -78
  198. package/lib/src/db/PowerSyncDatabase.js.map +0 -1
  199. package/lib/src/db/adapters/AbstractWebPowerSyncDatabaseOpenFactory.d.ts +0 -23
  200. package/lib/src/db/adapters/AbstractWebPowerSyncDatabaseOpenFactory.js +0 -27
  201. package/lib/src/db/adapters/AbstractWebPowerSyncDatabaseOpenFactory.js.map +0 -1
  202. package/lib/src/db/adapters/AsyncWebAdapter.d.ts +0 -50
  203. package/lib/src/db/adapters/AsyncWebAdapter.js.map +0 -1
  204. package/lib/src/db/adapters/SSRDBAdapter.d.ts +0 -30
  205. package/lib/src/db/adapters/SSRDBAdapter.js +0 -69
  206. package/lib/src/db/adapters/SSRDBAdapter.js.map +0 -1
  207. package/lib/src/db/adapters/WebDBAdapter.js.map +0 -1
  208. package/lib/src/db/adapters/wa-sqlite/ConcurrentConnection.js.map +0 -1
  209. package/lib/src/db/adapters/wa-sqlite/DatabaseClient.js.map +0 -1
  210. package/lib/src/db/adapters/wa-sqlite/DatabaseServer.js.map +0 -1
  211. package/lib/src/db/adapters/wa-sqlite/RawSqliteConnection.js.map +0 -1
  212. package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.d.ts +0 -45
  213. package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.js +0 -146
  214. package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.js.map +0 -1
  215. package/lib/src/db/adapters/wa-sqlite/WASQLitePowerSyncDatabaseOpenFactory.d.ts +0 -15
  216. package/lib/src/db/adapters/wa-sqlite/WASQLitePowerSyncDatabaseOpenFactory.js +0 -22
  217. package/lib/src/db/adapters/wa-sqlite/WASQLitePowerSyncDatabaseOpenFactory.js.map +0 -1
  218. package/lib/src/db/adapters/wa-sqlite/vfs.js.map +0 -1
  219. package/lib/src/db/adapters/web-sql-flags.d.ts +0 -92
  220. package/lib/src/db/adapters/web-sql-flags.js +0 -37
  221. package/lib/src/db/adapters/web-sql-flags.js.map +0 -1
  222. package/lib/src/db/sync/SSRWebStreamingSyncImplementation.js.map +0 -1
  223. package/lib/src/db/sync/SharedWebStreamingSyncImplementation.js.map +0 -1
  224. package/lib/src/db/sync/WebRemote.d.ts +0 -7
  225. package/lib/src/db/sync/WebRemote.js +0 -33
  226. package/lib/src/db/sync/WebRemote.js.map +0 -1
  227. package/lib/src/db/sync/WebStreamingSyncImplementation.js.map +0 -1
  228. package/lib/src/db/sync/userAgent.js.map +0 -1
  229. package/lib/src/index.js.map +0 -1
  230. package/lib/src/shared/navigator.js.map +0 -1
  231. package/lib/src/shared/tab_close_signal.js.map +0 -1
  232. package/lib/src/worker/db/MultiDatabaseServer.d.ts +0 -17
  233. package/lib/src/worker/db/MultiDatabaseServer.js.map +0 -1
  234. package/lib/src/worker/db/WASQLiteDB.worker.d.ts +0 -4
  235. package/lib/src/worker/db/WASQLiteDB.worker.js +0 -31
  236. package/lib/src/worker/db/WASQLiteDB.worker.js.map +0 -1
  237. package/lib/src/worker/db/open-worker-database.d.ts +0 -14
  238. package/lib/src/worker/db/open-worker-database.js +0 -53
  239. package/lib/src/worker/db/open-worker-database.js.map +0 -1
  240. package/lib/src/worker/sync/AbstractSharedSyncClientProvider.d.ts +0 -19
  241. package/lib/src/worker/sync/AbstractSharedSyncClientProvider.js.map +0 -1
  242. package/lib/src/worker/sync/BroadcastLogger.d.ts +0 -47
  243. package/lib/src/worker/sync/BroadcastLogger.js +0 -129
  244. package/lib/src/worker/sync/BroadcastLogger.js.map +0 -1
  245. package/lib/src/worker/sync/SharedSyncImplementation.js.map +0 -1
  246. package/lib/src/worker/sync/SharedSyncImplementation.worker.js +0 -12
  247. package/lib/src/worker/sync/SharedSyncImplementation.worker.js.map +0 -1
  248. package/lib/src/worker/sync/WorkerClient.js.map +0 -1
  249. package/lib/tsconfig.tsbuildinfo +0 -1
  250. package/src/db/adapters/AbstractWebPowerSyncDatabaseOpenFactory.ts +0 -47
  251. package/src/db/adapters/wa-sqlite/WASQLitePowerSyncDatabaseOpenFactory.ts +0 -24
  252. package/src/db/adapters/web-sql-flags.ts +0 -141
  253. package/src/worker/db/WASQLiteDB.worker.ts +0 -35
  254. package/src/worker/db/open-worker-database.ts +0 -62
  255. package/src/worker/sync/SharedSyncImplementation.worker.ts +0 -14
  256. /package/lib/{src/attachments → attachments}/IndexDBFileSystemAdapter.d.ts +0 -0
  257. /package/lib/{src/attachments → attachments}/IndexDBFileSystemAdapter.js +0 -0
  258. /package/lib/{src/db → db}/NavigatorTriggerClaimManager.js +0 -0
  259. /package/lib/{src/db → db}/adapters/WebDBAdapter.js +0 -0
  260. /package/lib/{src/worker/sync/SharedSyncImplementation.worker.d.ts → db/adapters/memory-pool/worker.d.ts} +0 -0
  261. /package/lib/{src/db → db}/sync/userAgent.d.ts +0 -0
  262. /package/lib/{src/db → db}/sync/userAgent.js +0 -0
  263. /package/lib/{src/shared → shared}/navigator.d.ts +0 -0
  264. /package/lib/{src/shared → shared}/navigator.js +0 -0
  265. /package/lib/{src/shared → shared}/tab_close_signal.d.ts +0 -0
  266. /package/lib/{src/shared → shared}/tab_close_signal.js +0 -0
  267. /package/lib/{src/worker → worker}/sync/AbstractSharedSyncClientProvider.js +0 -0
@@ -1,26 +1,24 @@
1
1
  import {
2
- AbortOperation,
3
2
  BaseObserver,
4
- ConnectionManager,
5
- ConnectionPool,
6
3
  DBAdapter,
7
- DBAdapterDefaultMixin,
8
- DBAdapterListener,
9
4
  DBLockOptions,
10
5
  LockContext,
11
6
  PowerSyncBackendConnector,
7
+ SyncStatus,
8
+ LogLevels,
9
+ SyncStreamConnectionMethod
10
+ } from '@powersync/common';
11
+ import {
12
+ AbortOperation,
13
+ ConnectionManager,
12
14
  SqliteBucketStorage,
13
15
  SubscribedStream,
14
- SyncStatus,
15
- createLogger,
16
- Mutex,
17
- type ILogLevel,
18
- type ILogger,
19
- type PowerSyncConnectionOptions,
20
16
  type StreamingSyncImplementation,
21
17
  type StreamingSyncImplementationListener,
22
- type SyncStatusOptions
23
- } from '@powersync/common';
18
+ Mutex,
19
+ ResolvedSyncOptions,
20
+ SyncStatusSnapshot
21
+ } from '@powersync/shared-internals';
24
22
  import * as Comlink from 'comlink';
25
23
  import { WebRemote } from '../../db/sync/WebRemote.js';
26
24
  import {
@@ -28,11 +26,11 @@ import {
28
26
  WebStreamingSyncImplementationOptions
29
27
  } from '../../db/sync/WebStreamingSyncImplementation.js';
30
28
 
31
- import { ResolvedWebSQLOpenOptions } from '../../db/adapters/web-sql-flags.js';
32
29
  import { AbstractSharedSyncClientProvider } from './AbstractSharedSyncClientProvider.js';
33
30
  import { BroadcastLogger } from './BroadcastLogger.js';
34
31
  import { DatabaseClient, OpenWorkerConnection } from '../../db/adapters/wa-sqlite/DatabaseClient.js';
35
32
  import { generateTabCloseSignal } from '../../shared/tab_close_signal.js';
33
+ import { ResolvedWebSQLOpenOptions } from '../../db/adapters/options.js';
36
34
 
37
35
  /**
38
36
  * @internal
@@ -60,8 +58,12 @@ export type ManualSharedSyncPayload = {
60
58
  * @internal
61
59
  */
62
60
  export type SharedSyncInitOptions = {
63
- streamOptions: Omit<WebStreamingSyncImplementationOptions, 'adapter' | 'uploadCrud' | 'remote' | 'subscriptions'>;
61
+ streamOptions: Omit<
62
+ WebStreamingSyncImplementationOptions,
63
+ 'adapter' | 'uploadCrud' | 'postCheckpointRequest' | 'remote' | 'subscriptions' | 'logger'
64
+ >;
64
65
  dbParams: ResolvedWebSQLOpenOptions;
66
+ enableBroadcastLogs: boolean;
65
67
  };
66
68
 
67
69
  /**
@@ -83,14 +85,6 @@ export type WrappedSyncPort = {
83
85
  isClosing: boolean;
84
86
  };
85
87
 
86
- /**
87
- * @internal
88
- */
89
- export type RemoteOperationAbortController = {
90
- controller: AbortController;
91
- activePort: WrappedSyncPort;
92
- };
93
-
94
88
  /**
95
89
  * HACK: The shared implementation wraps and provides its own
96
90
  * PowerSyncBackendConnector when generating the streaming sync implementation.
@@ -98,6 +92,23 @@ export type RemoteOperationAbortController = {
98
92
  */
99
93
  const CONNECTOR_PLACEHOLDER = {} as PowerSyncBackendConnector;
100
94
 
95
+ /**
96
+ * How long to wait for a client tab to answer a call before giving up on it.
97
+ */
98
+ const CONNECTOR_CALL_TIMEOUT_MS = 30_000;
99
+
100
+ type UseConnectorOptions = {
101
+ /**
102
+ * Aborted when the sync client disconnects.
103
+ */
104
+ signal?: AbortSignal;
105
+ /**
106
+ * Fail the call if the tab has not responded within this many milliseconds. `null` waits indefinitely, which is only
107
+ * appropriate for calls that are unbounded by nature and already covered by {@link UseConnectorOptions.signal}.
108
+ */
109
+ timeoutMs?: number | null;
110
+ };
111
+
101
112
  /**
102
113
  * @internal
103
114
  * Shared sync implementation which runs inside a shared webworker
@@ -108,25 +119,22 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
108
119
  protected isInitialized: Promise<void>;
109
120
  protected statusListener?: () => void;
110
121
 
111
- protected fetchCredentialsController?: RemoteOperationAbortController;
112
- protected uploadDataController?: RemoteOperationAbortController;
113
-
114
122
  protected syncParams: SharedSyncInitOptions | null;
115
- protected logger: ILogger;
116
- protected lastConnectOptions: PowerSyncConnectionOptions | undefined;
123
+ protected lastConnectOptions: ResolvedSyncOptions | undefined;
117
124
  protected portMutex: Mutex;
118
125
  private subscriptions: SubscribedStream[] = [];
119
126
 
120
127
  protected connectionManager: ConnectionManager;
121
- syncStatus: SyncStatus;
122
- broadCastLogger: ILogger;
128
+ private syncStatus?: SyncStatusSnapshot;
129
+ logger: BroadcastLogger;
123
130
  protected readonly database = this.generateReconnectableDatabase();
124
131
 
132
+ private sharedCloseSignal = generateTabCloseSignal();
133
+
125
134
  constructor() {
126
135
  super();
127
136
  this.ports = [];
128
137
  this.syncParams = null;
129
- this.logger = createLogger('shared-sync');
130
138
  this.lastConnectOptions = undefined;
131
139
  this.portMutex = new Mutex();
132
140
 
@@ -139,26 +147,37 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
139
147
  });
140
148
  });
141
149
 
142
- this.syncStatus = new SyncStatus({});
143
- this.broadCastLogger = new BroadcastLogger(this.ports);
150
+ this.logger = new BroadcastLogger('shared-sync', this.ports);
144
151
 
145
152
  this.connectionManager = new ConnectionManager({
146
153
  createSyncImplementation: async () => {
147
154
  await this.waitForReady();
148
155
 
149
156
  const sync = this.generateStreamingImplementation();
150
- const onDispose = sync.registerListener({
151
- statusChanged: (status) => {
152
- this.updateAllStatuses(status.toJSON());
157
+ const removeStatusListener = sync.registerListener({
158
+ statusChanged: (snapshot) => {
159
+ this.syncStatus = snapshot;
160
+ const json = snapshot.toJSON();
161
+ this.ports.forEach((p) => p.clientProvider.statusChanged(json));
153
162
  }
154
163
  });
155
164
 
156
165
  return {
157
166
  sync,
158
- onDispose
167
+ onDispose: () => {
168
+ removeStatusListener();
169
+
170
+ // Drop the JavaScript state along with the implementation that produced it: it describes in-flight work of
171
+ // a sync client that no longer exists. `addPort` hands this status to every tab that connects afterwards,
172
+ // so a `downloadError` left here is shown by tabs that never saw the failure, and nothing can clear it
173
+ // because only a completed sync does. The core status is kept - `hasSynced` and `lastSyncedAt` are
174
+ // persisted facts that remain true while disconnected.
175
+ this.syncStatus &&= new SyncStatusSnapshot(this.syncStatus.core, {});
176
+ }
159
177
  };
160
178
  },
161
- logger: this.logger
179
+ logger: this.logger,
180
+ defaultConnectionMethod: SyncStreamConnectionMethod.HTTP
162
181
  });
163
182
  }
164
183
 
@@ -192,12 +211,6 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
192
211
  });
193
212
  }
194
213
 
195
- async waitForStatus(status: SyncStatusOptions): Promise<void> {
196
- return this.withSyncImplementation(async (sync) => {
197
- return sync.waitForStatus(status);
198
- });
199
- }
200
-
201
214
  async waitUntilStatusMatches(predicate: (status: SyncStatus) => boolean): Promise<void> {
202
215
  return this.withSyncImplementation(async (sync) => {
203
216
  return sync.waitUntilStatusMatches(predicate);
@@ -209,7 +222,7 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
209
222
  }
210
223
 
211
224
  private collectActiveSubscriptions() {
212
- this.logger.debug('Collecting active stream subscriptions across tabs');
225
+ this.logger.log({ level: LogLevels.debug, message: 'Collecting active stream subscriptions across tabs' });
213
226
  const active = new Map<string, SubscribedStream>();
214
227
  for (const port of this.ports) {
215
228
  for (const stream of port.currentSubscriptions) {
@@ -218,7 +231,10 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
218
231
  }
219
232
  }
220
233
  this.subscriptions = [...active.values()];
221
- this.logger.debug('Collected stream subscriptions', this.subscriptions);
234
+ this.logger.log({
235
+ level: LogLevels.debug,
236
+ message: `Collected stream subscriptions, ${JSON.stringify(this.subscriptions)}`
237
+ });
222
238
  this.connectionManager.syncStreamImplementation?.updateSubscriptions(this.subscriptions);
223
239
  }
224
240
 
@@ -227,9 +243,8 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
227
243
  this.collectActiveSubscriptions();
228
244
  }
229
245
 
230
- setLogLevel(level: ILogLevel) {
246
+ setLogLevel(level: number) {
231
247
  this.logger.setLevel(level);
232
- this.broadCastLogger.setLevel(level);
233
248
  }
234
249
 
235
250
  /**
@@ -247,16 +262,18 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
247
262
 
248
263
  // First time setting params
249
264
  this.syncParams = params;
250
- if (params.streamOptions?.flags?.broadcastLogs) {
251
- this.logger = this.broadCastLogger;
252
- }
265
+ this.logger.sendBroadcasts = params.enableBroadcastLogs;
253
266
 
254
267
  // Ensure we have a usable database connection, the reconnectable database will connect lazily on first use.
255
268
  await this.database.readLock(async () => {});
256
269
 
257
270
  self.onerror = (event) => {
258
271
  // Share any uncaught events on the broadcast logger
259
- this.logger.error('Uncaught exception in PowerSync shared sync worker', event);
272
+ this.logger.log({
273
+ level: LogLevels.error,
274
+ message: 'Uncaught exception in PowerSync shared sync worker',
275
+ error: event
276
+ });
260
277
  };
261
278
 
262
279
  this.iterateListeners((l) => l.initialized?.());
@@ -274,9 +291,9 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
274
291
  * The connection will simply be reconnected whenever a new tab
275
292
  * connects.
276
293
  */
277
- async connect(options?: PowerSyncConnectionOptions) {
294
+ async connect(options: ResolvedSyncOptions, serializedSchema: any) {
278
295
  this.lastConnectOptions = options;
279
- return this.connectionManager.connect(CONNECTOR_PLACEHOLDER, options ?? {});
296
+ return this.connectionManager.connect(CONNECTOR_PLACEHOLDER, options ?? {}, serializedSchema);
280
297
  }
281
298
 
282
299
  async disconnect() {
@@ -298,7 +315,7 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
298
315
  this.ports.push(portProvider);
299
316
 
300
317
  // Give the newly connected client the latest status
301
- const status = this.connectionManager.syncStreamImplementation?.syncStatus;
318
+ const status = this.syncStatus;
302
319
  if (status) {
303
320
  portProvider.clientProvider.statusChanged(status.toJSON());
304
321
  }
@@ -321,7 +338,10 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
321
338
  return await this.portMutex.runExclusive(async () => {
322
339
  const index = this.ports.findIndex((p) => p == port);
323
340
  if (index < 0) {
324
- this.logger.warn(`Could not remove port ${port} since it is not present in active ports.`);
341
+ this.logger.log({
342
+ level: LogLevels.warn,
343
+ message: `Could not remove port ${port} since it is not present in active ports.`
344
+ });
325
345
  return () => {};
326
346
  }
327
347
 
@@ -329,18 +349,6 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
329
349
  // Remove from the list of active ports
330
350
  this.ports.splice(index, 1);
331
351
 
332
- /**
333
- * The port might currently be in use. Any active functions might
334
- * not resolve. Abort them here.
335
- */
336
- [this.fetchCredentialsController, this.uploadDataController].forEach((abortController) => {
337
- if (abortController?.activePort == port) {
338
- abortController!.controller.abort(
339
- new AbortOperation('Closing pending requests after client port is removed')
340
- );
341
- }
342
- });
343
-
344
352
  // Close the worker wrapped database connection, we can't accurately rely on this connection
345
353
  for (const closeListener of trackedPort.closeListeners) {
346
354
  await closeListener();
@@ -358,10 +366,8 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
358
366
  });
359
367
  }
360
368
 
361
- async getWriteCheckpoint(): Promise<string> {
362
- return this.withSyncImplementation(async (sync) => {
363
- return sync.getWriteCheckpoint();
364
- });
369
+ requestCheckpoint() {
370
+ return this.withSyncImplementation((sync) => sync.requestCheckpoint());
365
371
  }
366
372
 
367
373
  protected async withSyncImplementation<T>(callback: (sync: StreamingSyncImplementation) => Promise<T>): Promise<T> {
@@ -397,62 +403,48 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
397
403
  throw new Error('No client port found to invalidate credentials');
398
404
  }
399
405
  try {
400
- this.logger.log('calling the last port client provider to invalidate credentials');
406
+ this.logger.log({
407
+ level: LogLevels.info,
408
+ message: 'calling the last port client provider to invalidate credentials'
409
+ });
401
410
  lastPort.clientProvider.invalidateCredentials();
402
- } catch (ex) {
403
- this.logger.error('error invalidating credentials', ex);
411
+ } catch (error) {
412
+ this.logger.log({ level: LogLevels.error, message: 'error invalidating credentials', error });
404
413
  }
405
414
  },
406
- fetchCredentials: async () => {
407
- const lastPort = await this.getLastWrappedPort();
408
- if (!lastPort) {
409
- throw new Error('No client port found to fetch credentials');
410
- }
411
- return new Promise(async (resolve, reject) => {
412
- const abortController = new AbortController();
413
- this.fetchCredentialsController = {
414
- controller: abortController,
415
- activePort: lastPort
416
- };
417
-
418
- abortController.signal.onabort = reject;
419
- try {
420
- this.logger.log('calling the last port client provider for credentials');
421
- resolve(await lastPort.clientProvider.fetchCredentials());
422
- } catch (ex) {
423
- reject(ex);
424
- } finally {
425
- this.fetchCredentialsController = undefined;
426
- }
427
- });
415
+ fetchCredentials: () => {
416
+ return this.#useConnector(
417
+ (port) => {
418
+ this.logger.log({
419
+ level: LogLevels.info,
420
+ message: 'calling the last port client provider for credentials'
421
+ });
422
+
423
+ return port.clientProvider.fetchCredentials();
424
+ },
425
+ 'fetchCredentials',
426
+ // No sync abort signal reaches the remote, so this relies on the timeout alone.
427
+ { timeoutMs: CONNECTOR_CALL_TIMEOUT_MS }
428
+ );
428
429
  }
429
430
  },
430
431
  this.logger
431
432
  ),
432
- uploadCrud: async () => {
433
- const lastPort = await this.getLastWrappedPort();
434
- if (!lastPort) {
435
- throw new Error('No client port found to upload crud');
436
- }
437
-
438
- return new Promise(async (resolve, reject) => {
439
- const abortController = new AbortController();
440
- this.uploadDataController = {
441
- controller: abortController,
442
- activePort: lastPort
443
- };
444
-
445
- // Resolving will make it retry
446
- abortController.signal.onabort = () => resolve();
447
- try {
448
- resolve(await lastPort.clientProvider.uploadCrud());
449
- } catch (ex) {
450
- reject(ex);
451
- } finally {
452
- this.uploadDataController = undefined;
453
- }
433
+ uploadCrud: (signal) => {
434
+ return this.#useConnector((port) => port.clientProvider.uploadCrud(), 'uploadCrud', {
435
+ signal,
436
+ // Uploads are user-defined and legitimately unbounded (large batches over slow connections), so a timeout
437
+ // would cut valid work short. Disconnecting aborts the signal, which is what releases this.
438
+ timeoutMs: null
454
439
  });
455
440
  },
441
+ postCheckpointRequest: (clientId, requestId, signal) => {
442
+ return this.#useConnector(
443
+ (port) => port.clientProvider.postCheckpointRequest(clientId, requestId),
444
+ 'postCheckpointRequest',
445
+ { signal, timeoutMs: CONNECTOR_CALL_TIMEOUT_MS }
446
+ );
447
+ },
456
448
  ...syncParams.streamOptions,
457
449
  subscriptions: this.subscriptions,
458
450
  // Logger cannot be transferred just yet
@@ -460,6 +452,79 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
460
452
  });
461
453
  }
462
454
 
455
+ /**
456
+ * Calls into a client tab.
457
+ *
458
+ * A tab can stop servicing its message port without ever closing it: it may be frozen or in the back/forward cache,
459
+ * or its sync implementation may have been abandoned without being disposed. Comlink has no timeout of its own, so a
460
+ * call to such a port settles neither way, and the `closeListeners` below only fire for ports we know have closed.
461
+ *
462
+ * That is not a local problem. `disconnect()` awaits the sync loops, so a single call that can never settle wedges
463
+ * the disconnect, and with it every `connect()` queued behind it. Every call is therefore bounded by the caller's
464
+ * abort signal, a timeout, or both.
465
+ */
466
+ async #useConnector<T>(
467
+ inner: (port: WrappedSyncPort) => Promise<T>,
468
+ debugContext: string,
469
+ options: UseConnectorOptions = {}
470
+ ): Promise<T> {
471
+ const { signal, timeoutMs = CONNECTOR_CALL_TIMEOUT_MS } = options;
472
+
473
+ const controller = new AbortController();
474
+ const abortWith = (reason: string) => {
475
+ if (controller.signal.aborted) {
476
+ return;
477
+ }
478
+ this.logger.log({ level: LogLevels.warn, message: `Aborting ${debugContext}: ${reason}` });
479
+ controller.abort(new AbortOperation(`Aborted ${debugContext}: ${reason}`));
480
+ };
481
+
482
+ const timeout =
483
+ timeoutMs == null
484
+ ? undefined
485
+ : setTimeout(() => abortWith(`the client tab did not respond within ${timeoutMs}ms`), timeoutMs);
486
+
487
+ const onRequestedAbort = () => abortWith('the sync client disconnected');
488
+ signal?.addEventListener('abort', onRequestedAbort, { once: true });
489
+ if (signal?.aborted) {
490
+ onRequestedAbort();
491
+ }
492
+
493
+ try {
494
+ return await withAbort({
495
+ signal: controller.signal,
496
+ // Resolving the port takes the portMutex, which is held while other ports are being removed, so it has to be
497
+ // inside the guard as well.
498
+ action: async () => {
499
+ const lastPort = await this.getLastWrappedPort();
500
+ if (!lastPort) {
501
+ throw new Error(`No client port found for ${debugContext}`);
502
+ }
503
+
504
+ return await new Promise<T>((resolve, reject) => {
505
+ const portClosed = () => {
506
+ reject(new Error(`Tab closed while handling ${debugContext}`));
507
+ };
508
+
509
+ lastPort.closeListeners.push(portClosed);
510
+
511
+ inner(lastPort)
512
+ .then(resolve, reject)
513
+ .finally(() => {
514
+ const index = lastPort.closeListeners.indexOf(portClosed);
515
+ if (index >= 0) {
516
+ lastPort.closeListeners.splice(index, 1);
517
+ }
518
+ });
519
+ });
520
+ }
521
+ });
522
+ } finally {
523
+ clearTimeout(timeout);
524
+ signal?.removeEventListener('abort', onRequestedAbort);
525
+ }
526
+ }
527
+
463
528
  /**
464
529
  * Requests a random client to share its database connection with us.
465
530
  */
@@ -508,7 +573,7 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
508
573
  const remote = Comlink.wrap<OpenWorkerConnection>(workerPort);
509
574
  const identifier = this.syncParams!.dbParams.dbFilename;
510
575
 
511
- const clientLockName = await generateTabCloseSignal();
576
+ const clientLockName = await this.sharedCloseSignal;
512
577
 
513
578
  /**
514
579
  * The open could fail if the tab is closed while we're busy opening the database.
@@ -542,7 +607,7 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
542
607
  clearTimeout(timeout);
543
608
 
544
609
  client.closeListeners.push(async () => {
545
- this.logger.info('Aborting open connection because associated tab closed.');
610
+ this.logger.log({ level: LogLevels.info, message: 'Aborting open connection because associated tab closed.' });
546
611
  handleClosed(db);
547
612
  /**
548
613
  * Don't await this close operation. It might never resolve if the tab is closed.
@@ -550,7 +615,9 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
550
615
  * We then call close. The close operation is configured to fire-and-forget, the main promise will reject immediately.
551
616
  */
552
617
  db.markRemoteClosed();
553
- db.close().catch((ex) => this.logger.warn('error closing database connection', ex));
618
+ db.close().catch((error) =>
619
+ this.logger.log({ level: LogLevels.warn, message: 'error closing database connection', error })
620
+ );
554
621
  });
555
622
  return db;
556
623
  }
@@ -559,7 +626,7 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
559
626
  const syncParams = this.syncParams;
560
627
  const sharedSync = this;
561
628
 
562
- class ReconnectPool extends BaseObserver<DBAdapterListener> implements ConnectionPool {
629
+ return new (class extends DBAdapter {
563
630
  private connectionState:
564
631
  | null
565
632
  | DatabaseClient<ResolvedWebSQLOpenOptions>
@@ -628,19 +695,7 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
628
695
  async refreshSchema(): Promise<void> {
629
696
  // Not used by sync client.
630
697
  }
631
- }
632
-
633
- const Adapter = DBAdapterDefaultMixin(ReconnectPool);
634
- return new Adapter();
635
- }
636
-
637
- /**
638
- * A method to update the all shared statuses for each
639
- * client.
640
- */
641
- private updateAllStatuses(status: SyncStatusOptions) {
642
- this.syncStatus = new SyncStatus(status);
643
- this.ports.forEach((p) => p.clientProvider.statusChanged(status));
698
+ })();
644
699
  }
645
700
  }
646
701
 
@@ -653,15 +708,19 @@ function withAbort<T>(options: {
653
708
  cleanupOnAbort?: (result: T) => void;
654
709
  }): Promise<T> {
655
710
  const { action, signal, cleanupOnAbort } = options;
711
+ // Callers that abort with an `Error` reason get it propagated, so the failure says what actually went wrong.
712
+ const abortError = () =>
713
+ signal.reason instanceof Error ? signal.reason : new AbortOperation('Operation aborted by abort controller');
714
+
656
715
  return new Promise((resolve, reject) => {
657
716
  if (signal.aborted) {
658
- reject(new AbortOperation('Operation aborted by abort controller'));
717
+ reject(abortError());
659
718
  return;
660
719
  }
661
720
 
662
721
  function handleAbort() {
663
722
  signal.removeEventListener('abort', handleAbort);
664
- reject(new AbortOperation('Operation aborted by abort controller'));
723
+ reject(abortError());
665
724
  }
666
725
 
667
726
  signal.addEventListener('abort', handleAbort, { once: true });
@@ -1,4 +1,3 @@
1
- import { ILogLevel, PowerSyncConnectionOptions, SubscribedStream } from '@powersync/common';
2
1
  import * as Comlink from 'comlink';
3
2
  import { getNavigatorLocks } from '../../shared/navigator.js';
4
3
  import {
@@ -8,6 +7,7 @@ import {
8
7
  SharedSyncInitOptions,
9
8
  WrappedSyncPort
10
9
  } from './SharedSyncImplementation.js';
10
+ import { SubscribedStream, ResolvedSyncOptions } from '@powersync/shared-internals';
11
11
 
12
12
  /**
13
13
  * A client to the shared sync worker.
@@ -65,7 +65,7 @@ export class WorkerClient {
65
65
  });
66
66
  }
67
67
 
68
- setLogLevel(level: ILogLevel) {
68
+ setLogLevel(level: number) {
69
69
  this.sync.setLogLevel(level);
70
70
  }
71
71
 
@@ -78,12 +78,8 @@ export class WorkerClient {
78
78
  return this.sync.setParams(params);
79
79
  }
80
80
 
81
- getWriteCheckpoint() {
82
- return this.sync.getWriteCheckpoint();
83
- }
84
-
85
- connect(options?: PowerSyncConnectionOptions) {
86
- return this.sync.connect(options);
81
+ connect(options: ResolvedSyncOptions, schema: any) {
82
+ return this.sync.connect(options, schema);
87
83
  }
88
84
 
89
85
  updateSubscriptions(subscriptions: SubscribedStream[]) {
@@ -92,6 +88,10 @@ export class WorkerClient {
92
88
  }
93
89
  }
94
90
 
91
+ requestCheckpoint(): Promise<bigint> {
92
+ return this.sync.requestCheckpoint();
93
+ }
94
+
95
95
  disconnect() {
96
96
  return this.sync.disconnect();
97
97
  }
@@ -0,0 +1,38 @@
1
+ import * as Comlink from 'comlink';
2
+
3
+ import { createConsoleLogger, LogLevels } from '@powersync/common';
4
+ import { isSharedWorker, MultiDatabaseServer } from './db/MultiDatabaseServer.js';
5
+ import { SharedSyncImplementation } from './sync/SharedSyncImplementation.js';
6
+ import { OpenWorkerConnection } from '../db/adapters/wa-sqlite/DatabaseClient.js';
7
+ import { SharedWorkerConnectionRequest } from './SharedWorkerConnectionRequest.js';
8
+ import { WorkerClient } from './sync/WorkerClient.js';
9
+
10
+ const server = new MultiDatabaseServer(createConsoleLogger({ prefix: 'db-worker', minLevel: LogLevels.trace }));
11
+
12
+ const exposedDatabaseFunctions: OpenWorkerConnection = {
13
+ connect: (config) => server.handleConnection(config),
14
+ connectToExisting: ({ identifier, lockName }) => server.connectToExisting(identifier, lockName)
15
+ };
16
+
17
+ if (isSharedWorker) {
18
+ const sharedSyncImplementation = new SharedSyncImplementation();
19
+
20
+ // A shared worker can either be an IndexedDB-VFS database server or a shared sync coordinator.
21
+ // To be able to know what service a client is connecting to, we let clients send an inner MessagePort through the
22
+ // top-level port along with a tag describing what they need.
23
+ const _self = self as unknown as SharedWorkerGlobalScope;
24
+ _self.onconnect = (outerEvent: MessageEvent) => {
25
+ const port = outerEvent.ports[0];
26
+ port.onmessage = (event: MessageEvent<SharedWorkerConnectionRequest>) => {
27
+ const { service, port } = event.data;
28
+ if (service === 'database') {
29
+ Comlink.expose(exposedDatabaseFunctions, port);
30
+ } else if (service === 'sync') {
31
+ new WorkerClient(sharedSyncImplementation, port);
32
+ }
33
+ };
34
+ };
35
+ } else {
36
+ // Dedicated workers are only used for databases, so we don't need an intermediate layer.
37
+ Comlink.expose(exposedDatabaseFunctions);
38
+ }
Binary file
Binary file
Binary file
Binary file