@powersync/common 1.46.0 → 1.47.0

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 (55) hide show
  1. package/README.md +5 -1
  2. package/dist/bundle.cjs +1266 -360
  3. package/dist/bundle.cjs.map +1 -1
  4. package/dist/bundle.mjs +1259 -361
  5. package/dist/bundle.mjs.map +1 -1
  6. package/dist/bundle.node.cjs +1266 -360
  7. package/dist/bundle.node.cjs.map +1 -1
  8. package/dist/bundle.node.mjs +1259 -361
  9. package/dist/bundle.node.mjs.map +1 -1
  10. package/dist/index.d.cts +530 -29
  11. package/lib/attachments/AttachmentContext.d.ts +86 -0
  12. package/lib/attachments/AttachmentContext.js +229 -0
  13. package/lib/attachments/AttachmentContext.js.map +1 -0
  14. package/lib/attachments/AttachmentErrorHandler.d.ts +31 -0
  15. package/lib/attachments/AttachmentErrorHandler.js +2 -0
  16. package/lib/attachments/AttachmentErrorHandler.js.map +1 -0
  17. package/lib/attachments/AttachmentQueue.d.ts +149 -0
  18. package/lib/attachments/AttachmentQueue.js +362 -0
  19. package/lib/attachments/AttachmentQueue.js.map +1 -0
  20. package/lib/attachments/AttachmentService.d.ts +29 -0
  21. package/lib/attachments/AttachmentService.js +56 -0
  22. package/lib/attachments/AttachmentService.js.map +1 -0
  23. package/lib/attachments/LocalStorageAdapter.d.ts +62 -0
  24. package/lib/attachments/LocalStorageAdapter.js +6 -0
  25. package/lib/attachments/LocalStorageAdapter.js.map +1 -0
  26. package/lib/attachments/RemoteStorageAdapter.d.ts +27 -0
  27. package/lib/attachments/RemoteStorageAdapter.js +2 -0
  28. package/lib/attachments/RemoteStorageAdapter.js.map +1 -0
  29. package/lib/attachments/Schema.d.ts +50 -0
  30. package/lib/attachments/Schema.js +62 -0
  31. package/lib/attachments/Schema.js.map +1 -0
  32. package/lib/attachments/SyncingService.d.ts +62 -0
  33. package/lib/attachments/SyncingService.js +168 -0
  34. package/lib/attachments/SyncingService.js.map +1 -0
  35. package/lib/attachments/WatchedAttachmentItem.d.ts +17 -0
  36. package/lib/attachments/WatchedAttachmentItem.js +2 -0
  37. package/lib/attachments/WatchedAttachmentItem.js.map +1 -0
  38. package/lib/index.d.ts +10 -0
  39. package/lib/index.js +10 -0
  40. package/lib/index.js.map +1 -1
  41. package/lib/utils/mutex.d.ts +1 -1
  42. package/lib/utils/mutex.js.map +1 -1
  43. package/package.json +1 -1
  44. package/src/attachments/AttachmentContext.ts +279 -0
  45. package/src/attachments/AttachmentErrorHandler.ts +34 -0
  46. package/src/attachments/AttachmentQueue.ts +472 -0
  47. package/src/attachments/AttachmentService.ts +62 -0
  48. package/src/attachments/LocalStorageAdapter.ts +72 -0
  49. package/src/attachments/README.md +718 -0
  50. package/src/attachments/RemoteStorageAdapter.ts +30 -0
  51. package/src/attachments/Schema.ts +87 -0
  52. package/src/attachments/SyncingService.ts +193 -0
  53. package/src/attachments/WatchedAttachmentItem.ts +19 -0
  54. package/src/index.ts +11 -0
  55. package/src/utils/mutex.ts +1 -1
@@ -0,0 +1,62 @@
1
+ import { column } from '../db/schema/Column.js';
2
+ import { Table } from '../db/schema/Table.js';
3
+ export const ATTACHMENT_TABLE = 'attachments';
4
+ /**
5
+ * Maps a database row to an AttachmentRecord.
6
+ *
7
+ * @param row - The database row object
8
+ * @returns The corresponding AttachmentRecord
9
+ *
10
+ * @experimental
11
+ */
12
+ export function attachmentFromSql(row) {
13
+ return {
14
+ id: row.id,
15
+ filename: row.filename,
16
+ localUri: row.local_uri,
17
+ size: row.size,
18
+ mediaType: row.media_type,
19
+ timestamp: row.timestamp,
20
+ metaData: row.meta_data,
21
+ hasSynced: row.has_synced === 1,
22
+ state: row.state
23
+ };
24
+ }
25
+ /**
26
+ * AttachmentState represents the current synchronization state of an attachment.
27
+ *
28
+ * @experimental
29
+ */
30
+ export var AttachmentState;
31
+ (function (AttachmentState) {
32
+ AttachmentState[AttachmentState["QUEUED_UPLOAD"] = 0] = "QUEUED_UPLOAD";
33
+ AttachmentState[AttachmentState["QUEUED_DOWNLOAD"] = 1] = "QUEUED_DOWNLOAD";
34
+ AttachmentState[AttachmentState["QUEUED_DELETE"] = 2] = "QUEUED_DELETE";
35
+ AttachmentState[AttachmentState["SYNCED"] = 3] = "SYNCED";
36
+ AttachmentState[AttachmentState["ARCHIVED"] = 4] = "ARCHIVED"; // Attachment has been orphaned, i.e. the associated record has been deleted
37
+ })(AttachmentState || (AttachmentState = {}));
38
+ /**
39
+ * AttachmentTable defines the schema for the attachment queue table.
40
+ *
41
+ * @internal
42
+ */
43
+ export class AttachmentTable extends Table {
44
+ constructor(options) {
45
+ super({
46
+ filename: column.text,
47
+ local_uri: column.text,
48
+ timestamp: column.integer,
49
+ size: column.integer,
50
+ media_type: column.text,
51
+ state: column.integer, // Corresponds to AttachmentState
52
+ has_synced: column.integer,
53
+ meta_data: column.text
54
+ }, {
55
+ ...options,
56
+ viewName: options?.viewName ?? ATTACHMENT_TABLE,
57
+ localOnly: true,
58
+ insertOnly: false
59
+ });
60
+ }
61
+ }
62
+ //# sourceMappingURL=Schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Schema.js","sourceRoot":"","sources":["../../src/attachments/Schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAG9C,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAAC;AAmB9C;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAQ;IACxC,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,QAAQ,EAAE,GAAG,CAAC,SAAS;QACvB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,SAAS,EAAE,GAAG,CAAC,UAAU;QACzB,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,QAAQ,EAAE,GAAG,CAAC,SAAS;QACvB,SAAS,EAAE,GAAG,CAAC,UAAU,KAAK,CAAC;QAC/B,KAAK,EAAE,GAAG,CAAC,KAAK;KACjB,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAN,IAAY,eAMX;AAND,WAAY,eAAe;IACzB,uEAAiB,CAAA;IACjB,2EAAmB,CAAA;IACnB,uEAAiB,CAAA;IACjB,yDAAU,CAAA;IACV,6DAAY,CAAA,CAAC,4EAA4E;AAC3F,CAAC,EANW,eAAe,KAAf,eAAe,QAM1B;AAID;;;;GAIG;AACH,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxC,YAAY,OAAgC;QAC1C,KAAK,CACH;YACE,QAAQ,EAAE,MAAM,CAAC,IAAI;YACrB,SAAS,EAAE,MAAM,CAAC,IAAI;YACtB,SAAS,EAAE,MAAM,CAAC,OAAO;YACzB,IAAI,EAAE,MAAM,CAAC,OAAO;YACpB,UAAU,EAAE,MAAM,CAAC,IAAI;YACvB,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,iCAAiC;YACxD,UAAU,EAAE,MAAM,CAAC,OAAO;YAC1B,SAAS,EAAE,MAAM,CAAC,IAAI;SACvB,EACD;YACE,GAAG,OAAO;YACV,QAAQ,EAAE,OAAO,EAAE,QAAQ,IAAI,gBAAgB;YAC/C,SAAS,EAAE,IAAI;YACf,UAAU,EAAE,KAAK;SAClB,CACF,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,62 @@
1
+ import { ILogger } from '../utils/Logger.js';
2
+ import { AttachmentService } from './AttachmentService.js';
3
+ import { LocalStorageAdapter } from './LocalStorageAdapter.js';
4
+ import { RemoteStorageAdapter } from './RemoteStorageAdapter.js';
5
+ import { AttachmentRecord } from './Schema.js';
6
+ import { AttachmentErrorHandler } from './AttachmentErrorHandler.js';
7
+ import { AttachmentContext } from './AttachmentContext.js';
8
+ /**
9
+ * Orchestrates attachment synchronization between local and remote storage.
10
+ * Handles uploads, downloads, deletions, and state transitions.
11
+ *
12
+ * @internal
13
+ */
14
+ export declare class SyncingService {
15
+ private attachmentService;
16
+ private localStorage;
17
+ private remoteStorage;
18
+ private logger;
19
+ private errorHandler?;
20
+ constructor(attachmentService: AttachmentService, localStorage: LocalStorageAdapter, remoteStorage: RemoteStorageAdapter, logger: ILogger, errorHandler?: AttachmentErrorHandler);
21
+ /**
22
+ * Processes attachments based on their state (upload, download, or delete).
23
+ * All updates are saved in a single batch after processing.
24
+ *
25
+ * @param attachments - Array of attachment records to process
26
+ * @param context - Attachment context for database operations
27
+ * @returns Promise that resolves when all attachments have been processed and saved
28
+ */
29
+ processAttachments(attachments: AttachmentRecord[], context: AttachmentContext): Promise<void>;
30
+ /**
31
+ * Uploads an attachment from local storage to remote storage.
32
+ * On success, marks as SYNCED. On failure, defers to error handler or archives.
33
+ *
34
+ * @param attachment - The attachment record to upload
35
+ * @returns Updated attachment record with new state
36
+ * @throws Error if the attachment has no localUri
37
+ */
38
+ uploadAttachment(attachment: AttachmentRecord): Promise<AttachmentRecord>;
39
+ /**
40
+ * Downloads an attachment from remote storage to local storage.
41
+ * Retrieves the file, converts to base64, and saves locally.
42
+ * On success, marks as SYNCED. On failure, defers to error handler or archives.
43
+ *
44
+ * @param attachment - The attachment record to download
45
+ * @returns Updated attachment record with local URI and new state
46
+ */
47
+ downloadAttachment(attachment: AttachmentRecord): Promise<AttachmentRecord>;
48
+ /**
49
+ * Deletes an attachment from both remote and local storage.
50
+ * Removes the remote file, local file (if exists), and the attachment record.
51
+ * On failure, defers to error handler or archives.
52
+ *
53
+ * @param attachment - The attachment record to delete
54
+ * @returns Updated attachment record
55
+ */
56
+ deleteAttachment(attachment: AttachmentRecord): Promise<AttachmentRecord>;
57
+ /**
58
+ * Performs cleanup of archived attachments by removing their local files and records.
59
+ * Errors during local file deletion are logged but do not prevent record deletion.
60
+ */
61
+ deleteArchivedAttachments(context: AttachmentContext): Promise<boolean>;
62
+ }
@@ -0,0 +1,168 @@
1
+ import { AttachmentState } from './Schema.js';
2
+ /**
3
+ * Orchestrates attachment synchronization between local and remote storage.
4
+ * Handles uploads, downloads, deletions, and state transitions.
5
+ *
6
+ * @internal
7
+ */
8
+ export class SyncingService {
9
+ attachmentService;
10
+ localStorage;
11
+ remoteStorage;
12
+ logger;
13
+ errorHandler;
14
+ constructor(attachmentService, localStorage, remoteStorage, logger, errorHandler) {
15
+ this.attachmentService = attachmentService;
16
+ this.localStorage = localStorage;
17
+ this.remoteStorage = remoteStorage;
18
+ this.logger = logger;
19
+ this.errorHandler = errorHandler;
20
+ }
21
+ /**
22
+ * Processes attachments based on their state (upload, download, or delete).
23
+ * All updates are saved in a single batch after processing.
24
+ *
25
+ * @param attachments - Array of attachment records to process
26
+ * @param context - Attachment context for database operations
27
+ * @returns Promise that resolves when all attachments have been processed and saved
28
+ */
29
+ async processAttachments(attachments, context) {
30
+ const updatedAttachments = [];
31
+ for (const attachment of attachments) {
32
+ switch (attachment.state) {
33
+ case AttachmentState.QUEUED_UPLOAD:
34
+ const uploaded = await this.uploadAttachment(attachment);
35
+ updatedAttachments.push(uploaded);
36
+ break;
37
+ case AttachmentState.QUEUED_DOWNLOAD:
38
+ const downloaded = await this.downloadAttachment(attachment);
39
+ updatedAttachments.push(downloaded);
40
+ break;
41
+ case AttachmentState.QUEUED_DELETE:
42
+ const deleted = await this.deleteAttachment(attachment);
43
+ updatedAttachments.push(deleted);
44
+ break;
45
+ default:
46
+ break;
47
+ }
48
+ }
49
+ await context.saveAttachments(updatedAttachments);
50
+ }
51
+ /**
52
+ * Uploads an attachment from local storage to remote storage.
53
+ * On success, marks as SYNCED. On failure, defers to error handler or archives.
54
+ *
55
+ * @param attachment - The attachment record to upload
56
+ * @returns Updated attachment record with new state
57
+ * @throws Error if the attachment has no localUri
58
+ */
59
+ async uploadAttachment(attachment) {
60
+ this.logger.info(`Uploading attachment ${attachment.filename}`);
61
+ try {
62
+ if (attachment.localUri == null) {
63
+ throw new Error(`No localUri for attachment ${attachment.id}`);
64
+ }
65
+ const fileBlob = await this.localStorage.readFile(attachment.localUri);
66
+ await this.remoteStorage.uploadFile(fileBlob, attachment);
67
+ return {
68
+ ...attachment,
69
+ state: AttachmentState.SYNCED,
70
+ hasSynced: true
71
+ };
72
+ }
73
+ catch (error) {
74
+ const shouldRetry = (await this.errorHandler?.onUploadError(attachment, error)) ?? true;
75
+ if (!shouldRetry) {
76
+ return {
77
+ ...attachment,
78
+ state: AttachmentState.ARCHIVED
79
+ };
80
+ }
81
+ return attachment;
82
+ }
83
+ }
84
+ /**
85
+ * Downloads an attachment from remote storage to local storage.
86
+ * Retrieves the file, converts to base64, and saves locally.
87
+ * On success, marks as SYNCED. On failure, defers to error handler or archives.
88
+ *
89
+ * @param attachment - The attachment record to download
90
+ * @returns Updated attachment record with local URI and new state
91
+ */
92
+ async downloadAttachment(attachment) {
93
+ this.logger.info(`Downloading attachment ${attachment.filename}`);
94
+ try {
95
+ const fileData = await this.remoteStorage.downloadFile(attachment);
96
+ const localUri = this.localStorage.getLocalUri(attachment.filename);
97
+ await this.localStorage.saveFile(localUri, fileData);
98
+ return {
99
+ ...attachment,
100
+ state: AttachmentState.SYNCED,
101
+ localUri: localUri,
102
+ hasSynced: true
103
+ };
104
+ }
105
+ catch (error) {
106
+ const shouldRetry = (await this.errorHandler?.onDownloadError(attachment, error)) ?? true;
107
+ if (!shouldRetry) {
108
+ return {
109
+ ...attachment,
110
+ state: AttachmentState.ARCHIVED
111
+ };
112
+ }
113
+ return attachment;
114
+ }
115
+ }
116
+ /**
117
+ * Deletes an attachment from both remote and local storage.
118
+ * Removes the remote file, local file (if exists), and the attachment record.
119
+ * On failure, defers to error handler or archives.
120
+ *
121
+ * @param attachment - The attachment record to delete
122
+ * @returns Updated attachment record
123
+ */
124
+ async deleteAttachment(attachment) {
125
+ try {
126
+ await this.remoteStorage.deleteFile(attachment);
127
+ if (attachment.localUri) {
128
+ await this.localStorage.deleteFile(attachment.localUri);
129
+ }
130
+ await this.attachmentService.withContext(async (ctx) => {
131
+ await ctx.deleteAttachment(attachment.id);
132
+ });
133
+ return {
134
+ ...attachment,
135
+ state: AttachmentState.ARCHIVED
136
+ };
137
+ }
138
+ catch (error) {
139
+ const shouldRetry = (await this.errorHandler?.onDeleteError(attachment, error)) ?? true;
140
+ if (!shouldRetry) {
141
+ return {
142
+ ...attachment,
143
+ state: AttachmentState.ARCHIVED
144
+ };
145
+ }
146
+ return attachment;
147
+ }
148
+ }
149
+ /**
150
+ * Performs cleanup of archived attachments by removing their local files and records.
151
+ * Errors during local file deletion are logged but do not prevent record deletion.
152
+ */
153
+ async deleteArchivedAttachments(context) {
154
+ return await context.deleteArchivedAttachments(async (archivedAttachments) => {
155
+ for (const attachment of archivedAttachments) {
156
+ if (attachment.localUri) {
157
+ try {
158
+ await this.localStorage.deleteFile(attachment.localUri);
159
+ }
160
+ catch (error) {
161
+ this.logger.error('Error deleting local file for archived attachment', error);
162
+ }
163
+ }
164
+ }
165
+ });
166
+ }
167
+ }
168
+ //# sourceMappingURL=SyncingService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SyncingService.js","sourceRoot":"","sources":["../../src/attachments/SyncingService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * WatchedAttachmentItem represents an attachment reference in your application's data model.
3
+ * Use either filename OR fileExtension (not both).
4
+ *
5
+ * @experimental
6
+ */
7
+ export type WatchedAttachmentItem = {
8
+ id: string;
9
+ filename: string;
10
+ fileExtension?: never;
11
+ metaData?: string;
12
+ } | {
13
+ id: string;
14
+ fileExtension: string;
15
+ filename?: never;
16
+ metaData?: string;
17
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=WatchedAttachmentItem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WatchedAttachmentItem.js","sourceRoot":"","sources":["../../src/attachments/WatchedAttachmentItem.ts"],"names":[],"mappings":""}
package/lib/index.d.ts CHANGED
@@ -1,3 +1,12 @@
1
+ export * from './attachments/AttachmentContext.js';
2
+ export * from './attachments/AttachmentErrorHandler.js';
3
+ export * from './attachments/AttachmentQueue.js';
4
+ export * from './attachments/AttachmentService.js';
5
+ export * from './attachments/LocalStorageAdapter.js';
6
+ export * from './attachments/RemoteStorageAdapter.js';
7
+ export * from './attachments/Schema.js';
8
+ export * from './attachments/SyncingService.js';
9
+ export * from './attachments/WatchedAttachmentItem.js';
1
10
  export * from './client/AbstractPowerSyncDatabase.js';
2
11
  export * from './client/AbstractPowerSyncOpenFactory.js';
3
12
  export { compilableQueryWatch, CompilableQueryWatchHandler } from './client/compilableQueryWatch.js';
@@ -48,5 +57,6 @@ export * from './utils/BaseObserver.js';
48
57
  export * from './utils/ControlledExecutor.js';
49
58
  export * from './utils/DataStream.js';
50
59
  export * from './utils/Logger.js';
60
+ export * from './utils/mutex.js';
51
61
  export * from './utils/parseQuery.js';
52
62
  export * from './types/types.js';
package/lib/index.js CHANGED
@@ -1,3 +1,12 @@
1
+ export * from './attachments/AttachmentContext.js';
2
+ export * from './attachments/AttachmentErrorHandler.js';
3
+ export * from './attachments/AttachmentQueue.js';
4
+ export * from './attachments/AttachmentService.js';
5
+ export * from './attachments/LocalStorageAdapter.js';
6
+ export * from './attachments/RemoteStorageAdapter.js';
7
+ export * from './attachments/Schema.js';
8
+ export * from './attachments/SyncingService.js';
9
+ export * from './attachments/WatchedAttachmentItem.js';
1
10
  export * from './client/AbstractPowerSyncDatabase.js';
2
11
  export * from './client/AbstractPowerSyncOpenFactory.js';
3
12
  export { compilableQueryWatch } from './client/compilableQueryWatch.js';
@@ -48,6 +57,7 @@ export * from './utils/BaseObserver.js';
48
57
  export * from './utils/ControlledExecutor.js';
49
58
  export * from './utils/DataStream.js';
50
59
  export * from './utils/Logger.js';
60
+ export * from './utils/mutex.js';
51
61
  export * from './utils/parseQuery.js';
52
62
  export * from './types/types.js';
53
63
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uCAAuC,CAAC;AACtD,cAAc,0CAA0C,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAA+B,MAAM,kCAAkC,CAAC;AACrG,cAAc,kDAAkD,CAAC;AACjE,cAAc,6CAA6C,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8CAA8C,CAAC;AAC7D,cAAc,mCAAmC,CAAC;AAClD,OAAO,EAAE,SAAS,EAAQ,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAChF,cAAc,yCAAyC,CAAC;AACxD,cAAc,oCAAoC,CAAC;AACnD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,uCAAuC,CAAC;AACtD,cAAc,wCAAwC,CAAC;AACvD,cAAc,wCAAwC,CAAC;AACvD,cAAc,6DAA6D,CAAC;AAC5E,cAAc,8CAA8C,CAAC;AAC7D,cAAc,+BAA+B,CAAC;AAE9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,OAAO,EAA0B,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACjF,cAAc,yBAAyB,CAAC;AACxC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AAEvC,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,4BAA4B,EAAE,MAAM,gDAAgD,CAAC;AAC9F,cAAc,kCAAkC,CAAC;AACjD,cAAc,qCAAqC,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,cAAc,iCAAiC,CAAC;AAChD,cAAc,uDAAuD,CAAC;AACtE,cAAc,4CAA4C,CAAC;AAC3D,cAAc,2DAA2D,CAAC;AAC1E,cAAc,uDAAuD,CAAC;AACtE,cAAc,kCAAkC,CAAC;AAEjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AAEtC,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oCAAoC,CAAC;AACnD,cAAc,yCAAyC,CAAC;AACxD,cAAc,kCAAkC,CAAC;AACjD,cAAc,oCAAoC,CAAC;AACnD,cAAc,sCAAsC,CAAC;AACrD,cAAc,uCAAuC,CAAC;AACtD,cAAc,yBAAyB,CAAC;AACxC,cAAc,iCAAiC,CAAC;AAChD,cAAc,wCAAwC,CAAC;AAEvD,cAAc,uCAAuC,CAAC;AACtD,cAAc,0CAA0C,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAA+B,MAAM,kCAAkC,CAAC;AACrG,cAAc,kDAAkD,CAAC;AACjE,cAAc,6CAA6C,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8CAA8C,CAAC;AAC7D,cAAc,mCAAmC,CAAC;AAClD,OAAO,EAAE,SAAS,EAAQ,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAChF,cAAc,yCAAyC,CAAC;AACxD,cAAc,oCAAoC,CAAC;AACnD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,uCAAuC,CAAC;AACtD,cAAc,wCAAwC,CAAC;AACvD,cAAc,wCAAwC,CAAC;AACvD,cAAc,6DAA6D,CAAC;AAC5E,cAAc,8CAA8C,CAAC;AAC7D,cAAc,+BAA+B,CAAC;AAE9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,OAAO,EAA0B,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACjF,cAAc,yBAAyB,CAAC;AACxC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AAEvC,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,4BAA4B,EAAE,MAAM,gDAAgD,CAAC;AAC9F,cAAc,kCAAkC,CAAC;AACjD,cAAc,qCAAqC,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,cAAc,iCAAiC,CAAC;AAChD,cAAc,uDAAuD,CAAC;AACtE,cAAc,4CAA4C,CAAC;AAC3D,cAAc,2DAA2D,CAAC;AAC1E,cAAc,uDAAuD,CAAC;AACtE,cAAc,kCAAkC,CAAC;AAEjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AAEtC,cAAc,kBAAkB,CAAC"}
@@ -3,5 +3,5 @@ import { Mutex } from 'async-mutex';
3
3
  * Wrapper for async-mutex runExclusive, which allows for a timeout on each exclusive lock.
4
4
  */
5
5
  export declare function mutexRunExclusive<T>(mutex: Mutex, callback: () => Promise<T>, options?: {
6
- timeoutMs: number;
6
+ timeoutMs?: number;
7
7
  }): Promise<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"mutex.js","sourceRoot":"","sources":["../../src/utils/mutex.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,KAAY,EACZ,QAA0B,EAC1B,OAA+B;IAE/B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,OAAO,GAAG,OAAO,EAAE,SAAS,CAAC;QACnC,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,MAAM,SAAS,GAAG,OAAO;YACvB,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE;gBACd,QAAQ,GAAG,IAAI,CAAC;gBAChB,MAAM,CAAC,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC;YAChD,CAAC,EAAE,OAAO,CAAC;YACb,CAAC,CAAC,SAAS,CAAC;QAEd,KAAK,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YAC5B,IAAI,SAAS,EAAE,CAAC;gBACd,YAAY,CAAC,SAAS,CAAC,CAAC;YAC1B,CAAC;YACD,IAAI,QAAQ;gBAAE,OAAO;YAErB,IAAI,CAAC;gBACH,OAAO,CAAC,MAAM,QAAQ,EAAE,CAAC,CAAC;YAC5B,CAAC;YAAC,OAAO,EAAE,EAAE,CAAC;gBACZ,MAAM,CAAC,EAAE,CAAC,CAAC;YACb,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"mutex.js","sourceRoot":"","sources":["../../src/utils/mutex.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,KAAY,EACZ,QAA0B,EAC1B,OAAgC;IAEhC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,OAAO,GAAG,OAAO,EAAE,SAAS,CAAC;QACnC,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,MAAM,SAAS,GAAG,OAAO;YACvB,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE;gBACd,QAAQ,GAAG,IAAI,CAAC;gBAChB,MAAM,CAAC,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC;YAChD,CAAC,EAAE,OAAO,CAAC;YACb,CAAC,CAAC,SAAS,CAAC;QAEd,KAAK,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YAC5B,IAAI,SAAS,EAAE,CAAC;gBACd,YAAY,CAAC,SAAS,CAAC,CAAC;YAC1B,CAAC;YACD,IAAI,QAAQ;gBAAE,OAAO;YAErB,IAAI,CAAC;gBACH,OAAO,CAAC,MAAM,QAAQ,EAAE,CAAC,CAAC;YAC5B,CAAC;YAAC,OAAO,EAAE,EAAE,CAAC;gBACZ,MAAM,CAAC,EAAE,CAAC,CAAC;YACb,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@powersync/common",
3
- "version": "1.46.0",
3
+ "version": "1.47.0",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"