@powersync/common 0.0.0-dev-20260503073249 → 0.0.0-dev-20260630141119

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 (284) hide show
  1. package/lib/attachments/AttachmentContext.d.ts +9 -8
  2. package/lib/attachments/AttachmentContext.js +8 -3
  3. package/lib/attachments/AttachmentContext.js.map +1 -1
  4. package/lib/attachments/AttachmentErrorHandler.d.ts +6 -6
  5. package/lib/attachments/AttachmentQueue.d.ts +85 -36
  6. package/lib/attachments/AttachmentQueue.js +19 -21
  7. package/lib/attachments/AttachmentQueue.js.map +1 -1
  8. package/lib/attachments/AttachmentService.d.ts +3 -3
  9. package/lib/attachments/AttachmentService.js +4 -3
  10. package/lib/attachments/AttachmentService.js.map +1 -1
  11. package/lib/attachments/LocalStorageAdapter.d.ts +14 -8
  12. package/lib/attachments/LocalStorageAdapter.js +3 -0
  13. package/lib/attachments/LocalStorageAdapter.js.map +1 -1
  14. package/lib/attachments/RemoteStorageAdapter.d.ts +4 -4
  15. package/lib/attachments/Schema.d.ts +14 -6
  16. package/lib/attachments/Schema.js +8 -3
  17. package/lib/attachments/Schema.js.map +1 -1
  18. package/lib/attachments/SyncingService.d.ts +2 -2
  19. package/lib/attachments/SyncingService.js +8 -3
  20. package/lib/attachments/SyncingService.js.map +1 -1
  21. package/lib/attachments/WatchedAttachmentItem.d.ts +3 -1
  22. package/lib/client/{AbstractPowerSyncDatabase.d.ts → CommonPowerSyncDatabase.d.ts} +112 -238
  23. package/lib/client/CommonPowerSyncDatabase.js +2 -0
  24. package/lib/client/CommonPowerSyncDatabase.js.map +1 -0
  25. package/lib/client/Query.d.ts +9 -0
  26. package/lib/client/SQLOpenFactory.d.ts +44 -10
  27. package/lib/client/SQLOpenFactory.js +1 -19
  28. package/lib/client/SQLOpenFactory.js.map +1 -1
  29. package/lib/client/compilableQueryWatch.d.ts +8 -2
  30. package/lib/client/compilableQueryWatch.js +4 -2
  31. package/lib/client/compilableQueryWatch.js.map +1 -1
  32. package/lib/client/connection/PowerSyncBackendConnector.d.ts +6 -3
  33. package/lib/client/connection/PowerSyncCredentials.d.ts +3 -0
  34. package/lib/client/runOnSchemaChange.d.ts +5 -2
  35. package/lib/client/runOnSchemaChange.js +3 -0
  36. package/lib/client/runOnSchemaChange.js.map +1 -1
  37. package/lib/client/sync/bucket/CrudBatch.d.ts +2 -0
  38. package/lib/client/sync/bucket/CrudBatch.js +2 -0
  39. package/lib/client/sync/bucket/CrudBatch.js.map +1 -1
  40. package/lib/client/sync/bucket/CrudEntry.d.ts +9 -31
  41. package/lib/client/sync/bucket/CrudEntry.js +2 -97
  42. package/lib/client/sync/bucket/CrudEntry.js.map +1 -1
  43. package/lib/client/sync/bucket/CrudTransaction.d.ts +3 -0
  44. package/lib/client/sync/bucket/CrudTransaction.js +3 -0
  45. package/lib/client/sync/bucket/CrudTransaction.js.map +1 -1
  46. package/lib/client/sync/options.d.ts +65 -0
  47. package/lib/client/sync/options.js +25 -0
  48. package/lib/client/sync/options.js.map +1 -0
  49. package/lib/client/sync/stream/JsonValue.d.ts +10 -0
  50. package/lib/client/sync/stream/JsonValue.js +2 -0
  51. package/lib/client/sync/stream/JsonValue.js.map +1 -0
  52. package/lib/client/sync/sync-streams.d.ts +23 -8
  53. package/lib/client/triggers/TriggerManager.d.ts +28 -56
  54. package/lib/client/triggers/TriggerManager.js +2 -1
  55. package/lib/client/triggers/TriggerManager.js.map +1 -1
  56. package/lib/client/triggers/sanitizeSQL.d.ts +4 -0
  57. package/lib/client/triggers/sanitizeSQL.js +4 -0
  58. package/lib/client/triggers/sanitizeSQL.js.map +1 -1
  59. package/lib/client/watched/GetAllQuery.d.ts +7 -3
  60. package/lib/client/watched/GetAllQuery.js +3 -1
  61. package/lib/client/watched/GetAllQuery.js.map +1 -1
  62. package/lib/client/watched/WatchedQuery.d.ts +20 -6
  63. package/lib/client/watched/WatchedQuery.js +3 -5
  64. package/lib/client/watched/WatchedQuery.js.map +1 -1
  65. package/lib/client/watched/processors/DifferentialQueryProcessor.d.ts +15 -45
  66. package/lib/client/watched/processors/DifferentialQueryProcessor.js +1 -172
  67. package/lib/client/watched/processors/DifferentialQueryProcessor.js.map +1 -1
  68. package/lib/client/watched/processors/OnChangeQueryProcessor.d.ts +4 -22
  69. package/lib/client/watched/processors/OnChangeQueryProcessor.js +1 -82
  70. package/lib/client/watched/processors/OnChangeQueryProcessor.js.map +1 -1
  71. package/lib/client/watched/processors/comparators.d.ts +8 -0
  72. package/lib/client/watched/processors/comparators.js +4 -0
  73. package/lib/client/watched/processors/comparators.js.map +1 -1
  74. package/lib/db/DBAdapter.d.ts +90 -113
  75. package/lib/db/DBAdapter.js +70 -89
  76. package/lib/db/DBAdapter.js.map +1 -1
  77. package/lib/db/QueryResult.d.ts +104 -0
  78. package/lib/db/QueryResult.js +96 -0
  79. package/lib/db/QueryResult.js.map +1 -0
  80. package/lib/db/crud/SyncProgress.d.ts +7 -14
  81. package/lib/db/crud/SyncProgress.js +1 -60
  82. package/lib/db/crud/SyncProgress.js.map +1 -1
  83. package/lib/db/crud/SyncStatus.d.ts +54 -91
  84. package/lib/db/crud/SyncStatus.js +1 -245
  85. package/lib/db/crud/SyncStatus.js.map +1 -1
  86. package/lib/db/crud/UploadQueueStatus.d.ts +3 -0
  87. package/lib/db/crud/UploadQueueStatus.js +3 -0
  88. package/lib/db/crud/UploadQueueStatus.js.map +1 -1
  89. package/lib/db/schema/Column.d.ts +22 -1
  90. package/lib/db/schema/Column.js +10 -4
  91. package/lib/db/schema/Column.js.map +1 -1
  92. package/lib/db/schema/Index.d.ts +8 -3
  93. package/lib/db/schema/Index.js +4 -1
  94. package/lib/db/schema/Index.js.map +1 -1
  95. package/lib/db/schema/IndexedColumn.d.ts +8 -3
  96. package/lib/db/schema/IndexedColumn.js +4 -1
  97. package/lib/db/schema/IndexedColumn.js.map +1 -1
  98. package/lib/db/schema/RawTable.d.ts +7 -1
  99. package/lib/db/schema/Schema.d.ts +10 -29
  100. package/lib/db/schema/Schema.js +3 -1
  101. package/lib/db/schema/Schema.js.map +1 -1
  102. package/lib/db/schema/Table.d.ts +69 -91
  103. package/lib/db/schema/Table.js +88 -87
  104. package/lib/db/schema/Table.js.map +1 -1
  105. package/lib/index.d.ts +7 -27
  106. package/lib/index.js +6 -27
  107. package/lib/index.js.map +1 -1
  108. package/lib/types/types.d.ts +6 -0
  109. package/lib/utils/BaseObserver.d.ts +12 -0
  110. package/lib/utils/BaseObserver.js +3 -0
  111. package/lib/utils/BaseObserver.js.map +1 -1
  112. package/lib/utils/Logger.d.ts +60 -22
  113. package/lib/utils/Logger.js +38 -30
  114. package/lib/utils/Logger.js.map +1 -1
  115. package/lib/utils/MetaBaseObserver.d.ts +11 -11
  116. package/lib/utils/MetaBaseObserver.js +1 -50
  117. package/lib/utils/MetaBaseObserver.js.map +1 -1
  118. package/lib/utils/mutex.d.ts +3 -45
  119. package/lib/utils/mutex.js +1 -153
  120. package/lib/utils/mutex.js.map +1 -1
  121. package/package.json +8 -42
  122. package/src/attachments/AttachmentContext.ts +15 -13
  123. package/src/attachments/AttachmentErrorHandler.ts +6 -6
  124. package/src/attachments/AttachmentQueue.ts +99 -42
  125. package/src/attachments/AttachmentService.ts +7 -6
  126. package/src/attachments/LocalStorageAdapter.ts +14 -8
  127. package/src/attachments/README.md +2 -0
  128. package/src/attachments/RemoteStorageAdapter.ts +4 -4
  129. package/src/attachments/Schema.ts +14 -6
  130. package/src/attachments/SyncingService.ts +10 -6
  131. package/src/attachments/WatchedAttachmentItem.ts +3 -1
  132. package/src/client/CommonPowerSyncDatabase.ts +540 -0
  133. package/src/client/Query.ts +9 -0
  134. package/src/client/SQLOpenFactory.ts +47 -19
  135. package/src/client/compilableQueryWatch.ts +9 -4
  136. package/src/client/connection/PowerSyncBackendConnector.ts +6 -3
  137. package/src/client/connection/PowerSyncCredentials.ts +3 -0
  138. package/src/client/runOnSchemaChange.ts +5 -2
  139. package/src/client/sync/bucket/CrudBatch.ts +2 -0
  140. package/src/client/sync/bucket/CrudEntry.ts +10 -101
  141. package/src/client/sync/bucket/CrudTransaction.ts +3 -0
  142. package/src/client/sync/options.ts +77 -0
  143. package/src/client/sync/stream/JsonValue.ts +11 -0
  144. package/src/client/sync/sync-streams.ts +23 -10
  145. package/src/client/triggers/TriggerManager.ts +29 -59
  146. package/src/client/triggers/sanitizeSQL.ts +5 -0
  147. package/src/client/watched/GetAllQuery.ts +8 -4
  148. package/src/client/watched/WatchedQuery.ts +20 -11
  149. package/src/client/watched/processors/DifferentialQueryProcessor.ts +19 -219
  150. package/src/client/watched/processors/OnChangeQueryProcessor.ts +4 -109
  151. package/src/client/watched/processors/comparators.ts +8 -0
  152. package/src/db/DBAdapter.ts +160 -175
  153. package/src/db/QueryResult.ts +195 -0
  154. package/src/db/crud/SyncProgress.ts +8 -43
  155. package/src/db/crud/SyncStatus.ts +66 -216
  156. package/src/db/crud/UploadQueueStatus.ts +3 -0
  157. package/src/db/schema/Column.ts +22 -5
  158. package/src/db/schema/Index.ts +9 -3
  159. package/src/db/schema/IndexedColumn.ts +9 -3
  160. package/src/db/schema/RawTable.ts +7 -1
  161. package/src/db/schema/Schema.ts +12 -7
  162. package/src/db/schema/Table.ts +130 -180
  163. package/src/index.ts +7 -27
  164. package/src/types/types.ts +6 -0
  165. package/src/utils/BaseObserver.ts +12 -0
  166. package/src/utils/Logger.ts +86 -31
  167. package/src/utils/MetaBaseObserver.ts +14 -60
  168. package/src/utils/mutex.ts +4 -189
  169. package/dist/bundle.cjs +0 -14781
  170. package/dist/bundle.cjs.map +0 -1
  171. package/dist/bundle.mjs +0 -14689
  172. package/dist/bundle.mjs.map +0 -1
  173. package/dist/bundle.node.cjs +0 -12258
  174. package/dist/bundle.node.cjs.map +0 -1
  175. package/dist/bundle.node.mjs +0 -12166
  176. package/dist/bundle.node.mjs.map +0 -1
  177. package/dist/index.d.cts +0 -4391
  178. package/lib/client/AbstractPowerSyncDatabase.js +0 -987
  179. package/lib/client/AbstractPowerSyncDatabase.js.map +0 -1
  180. package/lib/client/AbstractPowerSyncOpenFactory.d.ts +0 -22
  181. package/lib/client/AbstractPowerSyncOpenFactory.js +0 -25
  182. package/lib/client/AbstractPowerSyncOpenFactory.js.map +0 -1
  183. package/lib/client/ConnectionManager.d.ts +0 -112
  184. package/lib/client/ConnectionManager.js +0 -294
  185. package/lib/client/ConnectionManager.js.map +0 -1
  186. package/lib/client/CustomQuery.d.ts +0 -22
  187. package/lib/client/CustomQuery.js +0 -43
  188. package/lib/client/CustomQuery.js.map +0 -1
  189. package/lib/client/constants.d.ts +0 -1
  190. package/lib/client/constants.js +0 -2
  191. package/lib/client/constants.js.map +0 -1
  192. package/lib/client/sync/bucket/BucketStorageAdapter.d.ts +0 -102
  193. package/lib/client/sync/bucket/BucketStorageAdapter.js +0 -19
  194. package/lib/client/sync/bucket/BucketStorageAdapter.js.map +0 -1
  195. package/lib/client/sync/bucket/OpType.d.ts +0 -16
  196. package/lib/client/sync/bucket/OpType.js +0 -23
  197. package/lib/client/sync/bucket/OpType.js.map +0 -1
  198. package/lib/client/sync/bucket/OplogEntry.d.ts +0 -23
  199. package/lib/client/sync/bucket/OplogEntry.js +0 -36
  200. package/lib/client/sync/bucket/OplogEntry.js.map +0 -1
  201. package/lib/client/sync/bucket/SqliteBucketStorage.d.ts +0 -61
  202. package/lib/client/sync/bucket/SqliteBucketStorage.js +0 -324
  203. package/lib/client/sync/bucket/SqliteBucketStorage.js.map +0 -1
  204. package/lib/client/sync/bucket/SyncDataBatch.d.ts +0 -6
  205. package/lib/client/sync/bucket/SyncDataBatch.js +0 -12
  206. package/lib/client/sync/bucket/SyncDataBatch.js.map +0 -1
  207. package/lib/client/sync/bucket/SyncDataBucket.d.ts +0 -40
  208. package/lib/client/sync/bucket/SyncDataBucket.js +0 -40
  209. package/lib/client/sync/bucket/SyncDataBucket.js.map +0 -1
  210. package/lib/client/sync/stream/AbstractRemote.d.ts +0 -161
  211. package/lib/client/sync/stream/AbstractRemote.js +0 -483
  212. package/lib/client/sync/stream/AbstractRemote.js.map +0 -1
  213. package/lib/client/sync/stream/AbstractStreamingSyncImplementation.d.ts +0 -244
  214. package/lib/client/sync/stream/AbstractStreamingSyncImplementation.js +0 -990
  215. package/lib/client/sync/stream/AbstractStreamingSyncImplementation.js.map +0 -1
  216. package/lib/client/sync/stream/WebsocketClientTransport.d.ts +0 -15
  217. package/lib/client/sync/stream/WebsocketClientTransport.js +0 -61
  218. package/lib/client/sync/stream/WebsocketClientTransport.js.map +0 -1
  219. package/lib/client/sync/stream/core-instruction.d.ts +0 -72
  220. package/lib/client/sync/stream/core-instruction.js +0 -27
  221. package/lib/client/sync/stream/core-instruction.js.map +0 -1
  222. package/lib/client/sync/stream/streaming-sync-types.d.ts +0 -143
  223. package/lib/client/sync/stream/streaming-sync-types.js +0 -26
  224. package/lib/client/sync/stream/streaming-sync-types.js.map +0 -1
  225. package/lib/client/triggers/MemoryTriggerClaimManager.d.ts +0 -6
  226. package/lib/client/triggers/MemoryTriggerClaimManager.js +0 -21
  227. package/lib/client/triggers/MemoryTriggerClaimManager.js.map +0 -1
  228. package/lib/client/triggers/TriggerManagerImpl.d.ts +0 -39
  229. package/lib/client/triggers/TriggerManagerImpl.js +0 -405
  230. package/lib/client/triggers/TriggerManagerImpl.js.map +0 -1
  231. package/lib/client/watched/processors/AbstractQueryProcessor.d.ts +0 -68
  232. package/lib/client/watched/processors/AbstractQueryProcessor.js +0 -151
  233. package/lib/client/watched/processors/AbstractQueryProcessor.js.map +0 -1
  234. package/lib/db/ConnectionClosedError.d.ts +0 -10
  235. package/lib/db/ConnectionClosedError.js +0 -21
  236. package/lib/db/ConnectionClosedError.js.map +0 -1
  237. package/lib/db/schema/TableV2.d.ts +0 -9
  238. package/lib/db/schema/TableV2.js +0 -9
  239. package/lib/db/schema/TableV2.js.map +0 -1
  240. package/lib/utils/AbortOperation.d.ts +0 -9
  241. package/lib/utils/AbortOperation.js +0 -19
  242. package/lib/utils/AbortOperation.js.map +0 -1
  243. package/lib/utils/ControlledExecutor.d.ts +0 -25
  244. package/lib/utils/ControlledExecutor.js +0 -51
  245. package/lib/utils/ControlledExecutor.js.map +0 -1
  246. package/lib/utils/async.d.ts +0 -14
  247. package/lib/utils/async.js +0 -46
  248. package/lib/utils/async.js.map +0 -1
  249. package/lib/utils/parseQuery.d.ts +0 -6
  250. package/lib/utils/parseQuery.js +0 -17
  251. package/lib/utils/parseQuery.js.map +0 -1
  252. package/lib/utils/queue.d.ts +0 -16
  253. package/lib/utils/queue.js +0 -42
  254. package/lib/utils/queue.js.map +0 -1
  255. package/lib/utils/stream_transform.d.ts +0 -39
  256. package/lib/utils/stream_transform.js +0 -206
  257. package/lib/utils/stream_transform.js.map +0 -1
  258. package/src/client/AbstractPowerSyncDatabase.ts +0 -1362
  259. package/src/client/AbstractPowerSyncOpenFactory.ts +0 -39
  260. package/src/client/ConnectionManager.ts +0 -402
  261. package/src/client/CustomQuery.ts +0 -56
  262. package/src/client/constants.ts +0 -1
  263. package/src/client/sync/bucket/BucketStorageAdapter.ts +0 -118
  264. package/src/client/sync/bucket/OpType.ts +0 -23
  265. package/src/client/sync/bucket/OplogEntry.ts +0 -50
  266. package/src/client/sync/bucket/SqliteBucketStorage.ts +0 -395
  267. package/src/client/sync/bucket/SyncDataBatch.ts +0 -11
  268. package/src/client/sync/bucket/SyncDataBucket.ts +0 -49
  269. package/src/client/sync/stream/AbstractRemote.ts +0 -624
  270. package/src/client/sync/stream/AbstractStreamingSyncImplementation.ts +0 -1285
  271. package/src/client/sync/stream/WebsocketClientTransport.ts +0 -80
  272. package/src/client/sync/stream/core-instruction.ts +0 -99
  273. package/src/client/sync/stream/streaming-sync-types.ts +0 -210
  274. package/src/client/triggers/MemoryTriggerClaimManager.ts +0 -25
  275. package/src/client/triggers/TriggerManagerImpl.ts +0 -496
  276. package/src/client/watched/processors/AbstractQueryProcessor.ts +0 -226
  277. package/src/db/ConnectionClosedError.ts +0 -23
  278. package/src/db/schema/TableV2.ts +0 -9
  279. package/src/utils/AbortOperation.ts +0 -17
  280. package/src/utils/ControlledExecutor.ts +0 -72
  281. package/src/utils/async.ts +0 -50
  282. package/src/utils/parseQuery.ts +0 -25
  283. package/src/utils/queue.ts +0 -48
  284. package/src/utils/stream_transform.ts +0 -252
@@ -1,7 +1,9 @@
1
- import { BaseListener, BaseObserver, BaseObserverInterface } from './BaseObserver.js';
1
+ import { BaseListener, BaseObserverInterface } from './BaseObserver.js';
2
2
 
3
3
  /**
4
4
  * Represents the counts of listeners for each event type in a BaseListener.
5
+ *
6
+ * @public
5
7
  */
6
8
  export type ListenerCounts<Listener extends BaseListener> = Partial<Record<keyof Listener, number>> & {
7
9
  total: number;
@@ -9,73 +11,25 @@ export type ListenerCounts<Listener extends BaseListener> = Partial<Record<keyof
9
11
 
10
12
  /**
11
13
  * Meta listener which reports the counts of listeners for each event type.
14
+ *
15
+ * @public
12
16
  */
13
17
  export interface MetaListener<ParentListener extends BaseListener> extends BaseListener {
14
18
  listenersChanged?: (counts: ListenerCounts<ParentListener>) => void;
15
19
  }
16
20
 
17
- export interface ListenerMetaManager<Listener extends BaseListener>
18
- extends BaseObserverInterface<MetaListener<Listener>> {
21
+ /**
22
+ * @public
23
+ */
24
+ export interface ListenerMetaManager<Listener extends BaseListener> extends BaseObserverInterface<
25
+ MetaListener<Listener>
26
+ > {
19
27
  counts: ListenerCounts<Listener>;
20
28
  }
21
29
 
22
- export interface MetaBaseObserverInterface<Listener extends BaseListener> extends BaseObserverInterface<Listener> {
23
- listenerMeta: ListenerMetaManager<Listener>;
24
- }
25
-
26
30
  /**
27
- * A BaseObserver that tracks the counts of listeners for each event type.
31
+ * @public
28
32
  */
29
- export class MetaBaseObserver<Listener extends BaseListener>
30
- extends BaseObserver<Listener>
31
- implements MetaBaseObserverInterface<Listener>
32
- {
33
- protected get listenerCounts(): ListenerCounts<Listener> {
34
- const counts = {} as Partial<Record<keyof Listener, number>>;
35
- let total = 0;
36
- for (const listener of this.listeners) {
37
- for (const key in listener) {
38
- if (listener[key]) {
39
- counts[key] = (counts[key] ?? 0) + 1;
40
- total++;
41
- }
42
- }
43
- }
44
- return {
45
- ...counts,
46
- total
47
- };
48
- }
49
-
50
- get listenerMeta(): ListenerMetaManager<Listener> {
51
- return {
52
- counts: this.listenerCounts,
53
- // Allows registering a meta listener that will be notified of changes in listener counts
54
- registerListener: (listener: Partial<MetaListener<Listener>>) => {
55
- return this.metaListener.registerListener(listener);
56
- }
57
- };
58
- }
59
-
60
- protected metaListener: BaseObserver<MetaListener<Listener>>;
61
-
62
- constructor() {
63
- super();
64
- this.metaListener = new BaseObserver<MetaListener<Listener>>();
65
- }
66
-
67
- registerListener(listener: Partial<Listener>): () => void {
68
- const dispose = super.registerListener(listener);
69
- const updatedCount = this.listenerCounts;
70
- this.metaListener.iterateListeners((l) => {
71
- l.listenersChanged?.(updatedCount);
72
- });
73
- return () => {
74
- dispose();
75
- const updatedCount = this.listenerCounts;
76
- this.metaListener.iterateListeners((l) => {
77
- l.listenersChanged?.(updatedCount);
78
- });
79
- };
80
- }
33
+ export interface MetaBaseObserverInterface<Listener extends BaseListener> extends BaseObserverInterface<Listener> {
34
+ listenerMeta: ListenerMetaManager<Listener>;
81
35
  }
@@ -1,192 +1,7 @@
1
- import { Queue } from './queue.js';
2
-
3
- export type UnlockFn = () => void;
4
-
5
1
  /**
6
- * An asynchronous semaphore implementation with associated items per lease.
7
- *
8
- * @internal This class is meant to be used in PowerSync SDKs only, and is not part of the public API.
2
+ * @internal This is implemented in `@powersync/shared-internals`, but we need it in the attachment service
3
+ * implementation.
9
4
  */
10
- export class Semaphore<T> {
11
- // Available items that are not currently assigned to a waiter.
12
- private readonly available: Queue<T>;
13
-
14
- readonly size: number;
15
- // Linked list of waiters. We don't expect the wait list to become particularly large, and this allows removing
16
- // aborted waiters from the middle of the list efficiently.
17
- private firstWaiter?: SemaphoreWaitNode<T>;
18
- private lastWaiter?: SemaphoreWaitNode<T>;
19
-
20
- constructor(elements: Iterable<T>) {
21
- this.available = new Queue(elements);
22
- this.size = this.available.length;
23
- }
24
-
25
- private addWaiter(requestedItems: number, onAcquire: () => void): SemaphoreWaitNode<T> {
26
- const node: SemaphoreWaitNode<T> = {
27
- isActive: true,
28
- acquiredItems: [],
29
- remainingItems: requestedItems,
30
- onAcquire,
31
- prev: this.lastWaiter
32
- };
33
- if (this.lastWaiter) {
34
- this.lastWaiter.next = node;
35
- this.lastWaiter = node;
36
- } else {
37
- // First waiter
38
- this.lastWaiter = this.firstWaiter = node;
39
- }
40
-
41
- return node;
42
- }
43
-
44
- private deactivateWaiter(waiter: SemaphoreWaitNode<T>) {
45
- const { prev, next } = waiter;
46
- waiter.isActive = false;
47
-
48
- if (prev) prev.next = next;
49
- if (next) next.prev = prev;
50
- if (waiter == this.firstWaiter) this.firstWaiter = next;
51
- if (waiter == this.lastWaiter) this.lastWaiter = prev;
52
- }
53
-
54
- private requestPermits(amount: number, abort?: AbortSignal): Promise<{ items: T[]; release: UnlockFn }> {
55
- if (amount <= 0 || amount > this.size) {
56
- throw new Error(`Invalid amount of items requested (${amount}), must be between 1 and ${this.size}`);
57
- }
58
-
59
- return new Promise((resolve, reject) => {
60
- function rejectAborted() {
61
- reject(abort?.reason ?? new Error('Semaphore acquire aborted'));
62
- }
63
- if (abort?.aborted) {
64
- return rejectAborted();
65
- }
66
-
67
- let waiter: SemaphoreWaitNode<T>;
68
-
69
- const markCompleted = () => {
70
- const items = waiter.acquiredItems;
71
- waiter.acquiredItems = []; // Avoid releasing items twice.
72
-
73
- for (const element of items) {
74
- // Give to next waiter, if possible.
75
- const nextWaiter = this.firstWaiter;
76
- if (nextWaiter) {
77
- nextWaiter.acquiredItems.push(element);
78
- nextWaiter.remainingItems--;
79
- if (nextWaiter.remainingItems == 0) {
80
- nextWaiter.onAcquire();
81
- }
82
- } else {
83
- // No pending waiter, return lease into pool.
84
- this.available.addLast(element);
85
- }
86
- }
87
- };
88
-
89
- const onAbort = () => {
90
- abort?.removeEventListener('abort', onAbort);
91
-
92
- if (waiter.isActive) {
93
- this.deactivateWaiter(waiter);
94
- rejectAborted();
95
- }
96
- };
97
-
98
- const resolvePromise = () => {
99
- this.deactivateWaiter(waiter);
100
- abort?.removeEventListener('abort', onAbort);
101
-
102
- const items = waiter.acquiredItems;
103
- resolve({ items, release: markCompleted });
104
- };
105
-
106
- waiter = this.addWaiter(amount, resolvePromise);
107
-
108
- // If there are items in the pool that haven't been assigned, we can pull them into this waiter. Note that this is
109
- // only the case if we're the first waiter (otherwise, items would have been assigned to an earlier waiter).
110
- while (!this.available.isEmpty && waiter.remainingItems > 0) {
111
- waiter.acquiredItems.push(this.available.removeFirst());
112
- waiter.remainingItems--;
113
- }
114
-
115
- if (waiter.remainingItems == 0) {
116
- return resolvePromise();
117
- }
118
-
119
- abort?.addEventListener('abort', onAbort);
120
- });
121
- }
122
-
123
- /**
124
- * Requests a single item from the pool.
125
- *
126
- * The returned `release` callback must be invoked to return the item into the pool.
127
- */
128
- async requestOne(abort?: AbortSignal): Promise<{ item: T; release: UnlockFn }> {
129
- const { items, release } = await this.requestPermits(1, abort);
130
- return { release, item: items[0] };
131
- }
132
-
133
- /**
134
- * Requests access to all items from the pool.
135
- *
136
- * The returned `release` callback must be invoked to return items into the pool.
137
- */
138
- requestAll(abort?: AbortSignal): Promise<{ items: T[]; release: UnlockFn }> {
139
- return this.requestPermits(this.size, abort);
140
- }
141
- }
142
-
143
- interface SemaphoreWaitNode<T> {
144
- /**
145
- * Whether the waiter is currently active (not aborted and not fullfilled).
146
- */
147
- isActive: boolean;
148
- acquiredItems: T[];
149
- remainingItems: number;
150
- onAcquire: () => void;
151
- prev?: SemaphoreWaitNode<T>;
152
- next?: SemaphoreWaitNode<T>;
153
- }
154
-
155
- /**
156
- * An asynchronous mutex implementation.
157
- *
158
- * @internal This class is meant to be used in PowerSync SDKs only, and is not part of the public API.
159
- */
160
- export class Mutex {
161
- private inner = new Semaphore([null]);
162
-
163
- async acquire(abort?: AbortSignal): Promise<UnlockFn> {
164
- const { release } = await this.inner.requestOne(abort);
165
- return release;
166
- }
167
-
168
- async runExclusive<T>(fn: () => PromiseLike<T> | T, abort?: AbortSignal): Promise<T> {
169
- const returnMutex = await this.acquire(abort);
170
-
171
- try {
172
- return await fn();
173
- } finally {
174
- returnMutex();
175
- }
176
- }
177
- }
178
-
179
- /**
180
- * Creates a signal aborting after the set timeout.
181
- */
182
- export function timeoutSignal(timeout: number): AbortSignal;
183
- export function timeoutSignal(timeout?: number): AbortSignal | undefined;
184
-
185
- export function timeoutSignal(timeout?: number): AbortSignal | undefined {
186
- if (timeout == null) return;
187
- if ('timeout' in AbortSignal) return AbortSignal.timeout(timeout);
188
-
189
- const controller = new AbortController();
190
- setTimeout(() => controller.abort(new Error('Timeout waiting for lock')), timeout);
191
- return controller.signal;
5
+ export interface Mutex {
6
+ runExclusive<T>(fn: () => PromiseLike<T> | T, abort?: AbortSignal): Promise<T>;
192
7
  }