@powersync/service-module-mongodb 0.0.0-dev-20250825132649 → 0.0.0-dev-20250827072023

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.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @powersync/service-module-mongodb
2
2
 
3
- ## 0.0.0-dev-20250825132649
3
+ ## 0.0.0-dev-20250827072023
4
4
 
5
5
  ### Patch Changes
6
6
 
@@ -11,15 +11,17 @@
11
11
  - Updated dependencies [29a368e]
12
12
  - Updated dependencies [f1d187b]
13
13
  - Updated dependencies [0fad466]
14
+ - Updated dependencies [5284fb5]
15
+ - Updated dependencies [5284fb5]
14
16
  - Updated dependencies [a700ec9]
15
17
  - Updated dependencies [060b829]
16
18
  - Updated dependencies [d49bebe]
17
- - @powersync/service-sync-rules@0.0.0-dev-20250825132649
18
- - @powersync/service-core@0.0.0-dev-20250825132649
19
- - @powersync/service-types@0.0.0-dev-20250825132649
20
- - @powersync/lib-services-framework@0.0.0-dev-20250825132649
21
- - @powersync/lib-service-mongodb@0.0.0-dev-20250825132649
22
- - @powersync/service-jsonbig@0.0.0-dev-20250825132649
19
+ - @powersync/service-sync-rules@0.0.0-dev-20250827072023
20
+ - @powersync/service-core@0.0.0-dev-20250827072023
21
+ - @powersync/service-types@0.0.0-dev-20250827072023
22
+ - @powersync/lib-services-framework@0.0.0-dev-20250827072023
23
+ - @powersync/lib-service-mongodb@0.0.0-dev-20250827072023
24
+ - @powersync/service-jsonbig@0.0.0-dev-20250827072023
23
25
 
24
26
  ## 0.11.0
25
27
 
@@ -1,7 +1,7 @@
1
1
  import { mongo } from '@powersync/lib-service-mongodb';
2
2
  import { DatabaseConnectionError, Logger } from '@powersync/lib-services-framework';
3
3
  import { MetricsEngine, SourceEntityDescriptor, SourceTable, storage } from '@powersync/service-core';
4
- import { DatabaseInputRow, SqliteRow, SqlSyncRules, TablePattern } from '@powersync/service-sync-rules';
4
+ import { DatabaseInputRow, SqliteInputRow, SqlSyncRules, TablePattern } from '@powersync/service-sync-rules';
5
5
  import { MongoManager } from './MongoManager.js';
6
6
  export interface ChangeStreamOptions {
7
7
  connections: MongoManager;
@@ -88,7 +88,7 @@ export declare class ChangeStream {
88
88
  initialReplication(snapshotLsn: string | null): Promise<void>;
89
89
  private setupCheckpointsCollection;
90
90
  private getSourceNamespaceFilters;
91
- static getQueryData(results: Iterable<DatabaseInputRow>): Generator<SqliteRow>;
91
+ static getQueryData(results: Iterable<DatabaseInputRow>): Generator<SqliteInputRow>;
92
92
  private snapshotTable;
93
93
  private getRelation;
94
94
  private getCollectionInfo;
@@ -1,13 +1,13 @@
1
1
  import { mongo } from '@powersync/lib-service-mongodb';
2
2
  import { storage } from '@powersync/service-core';
3
- import { SqliteRow, SqliteValue } from '@powersync/service-sync-rules';
3
+ import { SqliteInputRow, SqliteInputValue } from '@powersync/service-sync-rules';
4
4
  export declare function getMongoRelation(source: mongo.ChangeStreamNameSpace): storage.SourceEntityDescriptor;
5
5
  /**
6
6
  * For in-memory cache only.
7
7
  */
8
8
  export declare function getCacheIdentifier(source: storage.SourceEntityDescriptor | storage.SourceTable): string;
9
- export declare function constructAfterRecord(document: mongo.Document): SqliteRow;
10
- export declare function toMongoSyncRulesValue(data: any): SqliteValue;
9
+ export declare function constructAfterRecord(document: mongo.Document): SqliteInputRow;
10
+ export declare function toMongoSyncRulesValue(data: any): SqliteInputValue;
11
11
  /**
12
12
  * Id for checkpoints not associated with any specific replication stream.
13
13
  *
@@ -1,6 +1,7 @@
1
1
  import { mongo } from '@powersync/lib-service-mongodb';
2
2
  import { storage } from '@powersync/service-core';
3
- import { JSONBig, JsonContainer } from '@powersync/service-jsonbig';
3
+ import { JsonContainer } from '@powersync/service-jsonbig';
4
+ import { CustomArray, CustomObject, CustomSqliteValue, DateTimeValue } from '@powersync/service-sync-rules';
4
5
  import { ErrorCode, ServiceError } from '@powersync/lib-services-framework';
5
6
  import { MongoLSN } from '../common/MongoLSN.js';
6
7
  import { CHECKPOINTS_COLLECTION } from './replication-utils.js';
@@ -63,7 +64,8 @@ export function toMongoSyncRulesValue(data) {
63
64
  return data.toHexString();
64
65
  }
65
66
  else if (data instanceof Date) {
66
- return data.toISOString().replace('T', ' ');
67
+ const isoString = data.toISOString();
68
+ return new DateTimeValue(isoString);
67
69
  }
68
70
  else if (data instanceof mongo.Binary) {
69
71
  return new Uint8Array(data.buffer);
@@ -81,8 +83,7 @@ export function toMongoSyncRulesValue(data) {
81
83
  return JSON.stringify({ pattern: data.source, options: data.flags });
82
84
  }
83
85
  else if (Array.isArray(data)) {
84
- // We may be able to avoid some parse + stringify cycles here for JsonSqliteContainer.
85
- return JSONBig.stringify(data.map((element) => filterJsonData(element)));
86
+ return new CustomArray(data, filterJsonData);
86
87
  }
87
88
  else if (data instanceof Uint8Array) {
88
89
  return data;
@@ -91,18 +92,14 @@ export function toMongoSyncRulesValue(data) {
91
92
  return data.toString();
92
93
  }
93
94
  else if (typeof data == 'object') {
94
- let record = {};
95
- for (let key of Object.keys(data)) {
96
- record[key] = filterJsonData(data[key]);
97
- }
98
- return JSONBig.stringify(record);
95
+ return new CustomObject(data, filterJsonData);
99
96
  }
100
97
  else {
101
98
  return null;
102
99
  }
103
100
  }
104
101
  const DEPTH_LIMIT = 20;
105
- function filterJsonData(data, depth = 0) {
102
+ function filterJsonData(data, context, depth = 0) {
106
103
  const autoBigNum = true;
107
104
  if (depth > DEPTH_LIMIT) {
108
105
  // This is primarily to prevent infinite recursion
@@ -135,7 +132,8 @@ function filterJsonData(data, depth = 0) {
135
132
  return data;
136
133
  }
137
134
  else if (data instanceof Date) {
138
- return data.toISOString().replace('T', ' ');
135
+ const isoString = data.toISOString();
136
+ return new DateTimeValue(isoString).toSqliteValue(context);
139
137
  }
140
138
  else if (data instanceof mongo.ObjectId) {
141
139
  return data.toHexString();
@@ -159,11 +157,14 @@ function filterJsonData(data, depth = 0) {
159
157
  return { pattern: data.source, options: data.flags };
160
158
  }
161
159
  else if (Array.isArray(data)) {
162
- return data.map((element) => filterJsonData(element, depth + 1));
160
+ return data.map((element) => filterJsonData(element, context, depth + 1));
163
161
  }
164
162
  else if (ArrayBuffer.isView(data)) {
165
163
  return undefined;
166
164
  }
165
+ else if (data instanceof CustomSqliteValue) {
166
+ return data.toSqliteValue(context);
167
+ }
167
168
  else if (data instanceof JsonContainer) {
168
169
  // Can be stringified directly when using our JSONBig implementation
169
170
  return data;
@@ -171,7 +172,7 @@ function filterJsonData(data, depth = 0) {
171
172
  else if (typeof data == 'object') {
172
173
  let record = {};
173
174
  for (let key of Object.keys(data)) {
174
- record[key] = filterJsonData(data[key], depth + 1);
175
+ record[key] = filterJsonData(data[key], context, depth + 1);
175
176
  }
176
177
  return record;
177
178
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MongoRelation.js","sourceRoot":"","sources":["../../src/replication/MongoRelation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MongoRelation.js","sourceRoot":"","sources":["../../src/replication/MongoRelation.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@powersync/service-module-mongodb",
3
3
  "repository": "https://github.com/powersync-ja/powersync-service",
4
4
  "types": "dist/index.d.ts",
5
- "version": "0.0.0-dev-20250825132649",
5
+ "version": "0.0.0-dev-20250827072023",
6
6
  "main": "dist/index.js",
7
7
  "license": "FSL-1.1-ALv2",
8
8
  "type": "module",
@@ -25,17 +25,17 @@
25
25
  "bson": "^6.10.3",
26
26
  "ts-codec": "^1.3.0",
27
27
  "uuid": "^11.1.0",
28
- "@powersync/lib-services-framework": "0.0.0-dev-20250825132649",
29
- "@powersync/lib-service-mongodb": "0.0.0-dev-20250825132649",
30
- "@powersync/service-jsonbig": "0.0.0-dev-20250825132649",
31
- "@powersync/service-sync-rules": "0.0.0-dev-20250825132649",
32
- "@powersync/service-core": "0.0.0-dev-20250825132649",
33
- "@powersync/service-types": "0.0.0-dev-20250825132649"
28
+ "@powersync/lib-service-mongodb": "0.0.0-dev-20250827072023",
29
+ "@powersync/lib-services-framework": "0.0.0-dev-20250827072023",
30
+ "@powersync/service-core": "0.0.0-dev-20250827072023",
31
+ "@powersync/service-jsonbig": "0.0.0-dev-20250827072023",
32
+ "@powersync/service-sync-rules": "0.0.0-dev-20250827072023",
33
+ "@powersync/service-types": "0.0.0-dev-20250827072023"
34
34
  },
35
35
  "devDependencies": {
36
- "@powersync/service-core-tests": "0.0.0-dev-20250825132649",
37
- "@powersync/service-module-mongodb-storage": "0.0.0-dev-20250825132649",
38
- "@powersync/service-module-postgres-storage": "0.0.0-dev-20250825132649"
36
+ "@powersync/service-core-tests": "0.0.0-dev-20250827072023",
37
+ "@powersync/service-module-mongodb-storage": "0.0.0-dev-20250827072023",
38
+ "@powersync/service-module-postgres-storage": "0.0.0-dev-20250827072023"
39
39
  },
40
40
  "scripts": {
41
41
  "build": "tsc -b",
@@ -17,7 +17,7 @@ import {
17
17
  SourceTable,
18
18
  storage
19
19
  } from '@powersync/service-core';
20
- import { DatabaseInputRow, SqliteRow, SqlSyncRules, TablePattern } from '@powersync/service-sync-rules';
20
+ import { DatabaseInputRow, SqliteInputRow, SqliteRow, SqlSyncRules, TablePattern } from '@powersync/service-sync-rules';
21
21
  import { ReplicationMetric } from '@powersync/service-types';
22
22
  import { MongoLSN } from '../common/MongoLSN.js';
23
23
  import { PostImagesOption } from '../types/types.js';
@@ -439,7 +439,7 @@ export class ChangeStream {
439
439
  return { $match: { ns: { $in: $inFilters } }, multipleDatabases };
440
440
  }
441
441
 
442
- static *getQueryData(results: Iterable<DatabaseInputRow>): Generator<SqliteRow> {
442
+ static *getQueryData(results: Iterable<DatabaseInputRow>): Generator<SqliteInputRow> {
443
443
  for (let row of results) {
444
444
  yield constructAfterRecord(row);
445
445
  }
@@ -1,7 +1,18 @@
1
1
  import { mongo } from '@powersync/lib-service-mongodb';
2
2
  import { storage } from '@powersync/service-core';
3
3
  import { JSONBig, JsonContainer } from '@powersync/service-jsonbig';
4
- import { SqliteRow, SqliteValue } from '@powersync/service-sync-rules';
4
+ import {
5
+ CompatibilityContext,
6
+ CustomArray,
7
+ CustomObject,
8
+ CustomSqliteValue,
9
+ DatabaseInputValue,
10
+ SqliteInputRow,
11
+ SqliteInputValue,
12
+ SqliteRow,
13
+ SqliteValue,
14
+ DateTimeValue
15
+ } from '@powersync/service-sync-rules';
5
16
 
6
17
  import { ErrorCode, ServiceError } from '@powersync/lib-services-framework';
7
18
  import { MongoLSN } from '../common/MongoLSN.js';
@@ -27,15 +38,15 @@ export function getCacheIdentifier(source: storage.SourceEntityDescriptor | stor
27
38
  return `${source.schema}.${source.name}`;
28
39
  }
29
40
 
30
- export function constructAfterRecord(document: mongo.Document): SqliteRow {
31
- let record: SqliteRow = {};
41
+ export function constructAfterRecord(document: mongo.Document): SqliteInputRow {
42
+ let record: SqliteInputRow = {};
32
43
  for (let key of Object.keys(document)) {
33
44
  record[key] = toMongoSyncRulesValue(document[key]);
34
45
  }
35
46
  return record;
36
47
  }
37
48
 
38
- export function toMongoSyncRulesValue(data: any): SqliteValue {
49
+ export function toMongoSyncRulesValue(data: any): SqliteInputValue {
39
50
  const autoBigNum = true;
40
51
  if (data === null) {
41
52
  return null;
@@ -60,7 +71,8 @@ export function toMongoSyncRulesValue(data: any): SqliteValue {
60
71
  } else if (data instanceof mongo.UUID) {
61
72
  return data.toHexString();
62
73
  } else if (data instanceof Date) {
63
- return data.toISOString().replace('T', ' ');
74
+ const isoString = data.toISOString();
75
+ return new DateTimeValue(isoString);
64
76
  } else if (data instanceof mongo.Binary) {
65
77
  return new Uint8Array(data.buffer);
66
78
  } else if (data instanceof mongo.Long) {
@@ -72,18 +84,13 @@ export function toMongoSyncRulesValue(data: any): SqliteValue {
72
84
  } else if (data instanceof RegExp) {
73
85
  return JSON.stringify({ pattern: data.source, options: data.flags });
74
86
  } else if (Array.isArray(data)) {
75
- // We may be able to avoid some parse + stringify cycles here for JsonSqliteContainer.
76
- return JSONBig.stringify(data.map((element) => filterJsonData(element)));
87
+ return new CustomArray(data, filterJsonData);
77
88
  } else if (data instanceof Uint8Array) {
78
89
  return data;
79
90
  } else if (data instanceof JsonContainer) {
80
91
  return data.toString();
81
92
  } else if (typeof data == 'object') {
82
- let record: Record<string, any> = {};
83
- for (let key of Object.keys(data)) {
84
- record[key] = filterJsonData(data[key]);
85
- }
86
- return JSONBig.stringify(record);
93
+ return new CustomObject(data, filterJsonData);
87
94
  } else {
88
95
  return null;
89
96
  }
@@ -91,7 +98,7 @@ export function toMongoSyncRulesValue(data: any): SqliteValue {
91
98
 
92
99
  const DEPTH_LIMIT = 20;
93
100
 
94
- function filterJsonData(data: any, depth = 0): any {
101
+ function filterJsonData(data: any, context: CompatibilityContext, depth = 0): any {
95
102
  const autoBigNum = true;
96
103
  if (depth > DEPTH_LIMIT) {
97
104
  // This is primarily to prevent infinite recursion
@@ -117,7 +124,8 @@ function filterJsonData(data: any, depth = 0): any {
117
124
  } else if (typeof data == 'bigint') {
118
125
  return data;
119
126
  } else if (data instanceof Date) {
120
- return data.toISOString().replace('T', ' ');
127
+ const isoString = data.toISOString();
128
+ return new DateTimeValue(isoString).toSqliteValue(context);
121
129
  } else if (data instanceof mongo.ObjectId) {
122
130
  return data.toHexString();
123
131
  } else if (data instanceof mongo.UUID) {
@@ -133,16 +141,18 @@ function filterJsonData(data: any, depth = 0): any {
133
141
  } else if (data instanceof RegExp) {
134
142
  return { pattern: data.source, options: data.flags };
135
143
  } else if (Array.isArray(data)) {
136
- return data.map((element) => filterJsonData(element, depth + 1));
144
+ return data.map((element) => filterJsonData(element, context, depth + 1));
137
145
  } else if (ArrayBuffer.isView(data)) {
138
146
  return undefined;
147
+ } else if (data instanceof CustomSqliteValue) {
148
+ return data.toSqliteValue(context);
139
149
  } else if (data instanceof JsonContainer) {
140
150
  // Can be stringified directly when using our JSONBig implementation
141
151
  return data;
142
152
  } else if (typeof data == 'object') {
143
153
  let record: Record<string, any> = {};
144
154
  for (let key of Object.keys(data)) {
145
- record[key] = filterJsonData(data[key], depth + 1);
155
+ record[key] = filterJsonData(data[key], context, depth + 1);
146
156
  }
147
157
  return record;
148
158
  } else {
@@ -1,5 +1,11 @@
1
1
  import { mongo } from '@powersync/lib-service-mongodb';
2
- import { SqliteRow, SqlSyncRules } from '@powersync/service-sync-rules';
2
+ import {
3
+ applyRowContext,
4
+ CompatibilityContext,
5
+ CompatibilityEdition,
6
+ SqliteInputRow,
7
+ SqlSyncRules
8
+ } from '@powersync/service-sync-rules';
3
9
  import { describe, expect, test } from 'vitest';
4
10
 
5
11
  import { MongoRouteAPIAdapter } from '@module/api/MongoRouteAPIAdapter.js';
@@ -138,8 +144,10 @@ describe('mongo data types', () => {
138
144
  ]);
139
145
  }
140
146
 
141
- function checkResults(transformed: Record<string, any>[]) {
142
- expect(transformed[0]).toMatchObject({
147
+ function checkResults(transformed: SqliteInputRow[]) {
148
+ const sqliteValue = transformed.map((e) => applyRowContext(e, CompatibilityContext.FULL_BACKWARDS_COMPATIBILITY));
149
+
150
+ expect(sqliteValue[0]).toMatchObject({
143
151
  _id: 1n,
144
152
  text: 'text',
145
153
  uuid: 'baeb2514-4c57-436d-b3cc-c1256211656d',
@@ -152,17 +160,17 @@ describe('mongo data types', () => {
152
160
  null: null,
153
161
  decimal: '3.14'
154
162
  });
155
- expect(transformed[1]).toMatchObject({
163
+ expect(sqliteValue[1]).toMatchObject({
156
164
  _id: 2n,
157
165
  nested: '{"test":"thing"}'
158
166
  });
159
167
 
160
- expect(transformed[2]).toMatchObject({
168
+ expect(sqliteValue[2]).toMatchObject({
161
169
  _id: 3n,
162
170
  date: '2023-03-06 13:47:00.000Z'
163
171
  });
164
172
 
165
- expect(transformed[3]).toMatchObject({
173
+ expect(sqliteValue[3]).toMatchObject({
166
174
  _id: 4n,
167
175
  objectId: '66e834cc91d805df11fa0ecb',
168
176
  timestamp: 1958505087099n,
@@ -177,9 +185,9 @@ describe('mongo data types', () => {
177
185
  });
178
186
 
179
187
  // This must specifically be null, and not undefined.
180
- expect(transformed[4].undefined).toBeNull();
188
+ expect(sqliteValue[4].undefined).toBeNull();
181
189
 
182
- expect(transformed[5]).toMatchObject({
190
+ expect(sqliteValue[5]).toMatchObject({
183
191
  _id: 6n,
184
192
  int4: -1n,
185
193
  int8: -9007199254740993n,
@@ -188,8 +196,10 @@ describe('mongo data types', () => {
188
196
  });
189
197
  }
190
198
 
191
- function checkResultsNested(transformed: Record<string, any>[]) {
192
- expect(transformed[0]).toMatchObject({
199
+ function checkResultsNested(transformed: SqliteInputRow[]) {
200
+ const sqliteValue = transformed.map((e) => applyRowContext(e, CompatibilityContext.FULL_BACKWARDS_COMPATIBILITY));
201
+
202
+ expect(sqliteValue[0]).toMatchObject({
193
203
  _id: 1n,
194
204
  text: `["text"]`,
195
205
  uuid: '["baeb2514-4c57-436d-b3cc-c1256211656d"]',
@@ -204,22 +214,22 @@ describe('mongo data types', () => {
204
214
 
205
215
  // Note: Depending on to what extent we use the original postgres value, the whitespace may change, and order may change.
206
216
  // We do expect that decimals and big numbers are preserved.
207
- expect(transformed[1]).toMatchObject({
217
+ expect(sqliteValue[1]).toMatchObject({
208
218
  _id: 2n,
209
219
  nested: '[{"test":"thing"}]'
210
220
  });
211
221
 
212
- expect(transformed[2]).toMatchObject({
222
+ expect(sqliteValue[2]).toMatchObject({
213
223
  _id: 3n,
214
224
  date: '["2023-03-06 13:47:00.000Z"]'
215
225
  });
216
226
 
217
- expect(transformed[3]).toMatchObject({
227
+ expect(sqliteValue[3]).toMatchObject({
218
228
  _id: 5n,
219
229
  undefined: '[null]'
220
230
  });
221
231
 
222
- expect(transformed[4]).toMatchObject({
232
+ expect(sqliteValue[4]).toMatchObject({
223
233
  _id: 6n,
224
234
  int4: '[-1]',
225
235
  int8: '[-9007199254740993]',
@@ -227,7 +237,7 @@ describe('mongo data types', () => {
227
237
  decimal: '["-3.14"]'
228
238
  });
229
239
 
230
- expect(transformed[5]).toMatchObject({
240
+ expect(sqliteValue[5]).toMatchObject({
231
241
  _id: 10n,
232
242
  objectId: '["66e834cc91d805df11fa0ecb"]',
233
243
  timestamp: '[1958505087099]',
@@ -522,13 +532,45 @@ bucket_definitions:
522
532
  errors: []
523
533
  });
524
534
  });
535
+
536
+ test('date format', async () => {
537
+ const { db, client } = await connectMongoData();
538
+ const collection = db.collection('test_data');
539
+ try {
540
+ await setupTable(db);
541
+ await collection.insertOne({
542
+ fraction: new Date('2023-03-06 15:47:01.123+02'),
543
+ noFraction: new Date('2023-03-06 15:47:01+02')
544
+ });
545
+
546
+ const rawResults = await db
547
+ .collection('test_data')
548
+ .find({}, { sort: { _id: 1 } })
549
+ .toArray();
550
+ const [row] = [...ChangeStream.getQueryData(rawResults)];
551
+
552
+ const oldFormat = applyRowContext(row, CompatibilityContext.FULL_BACKWARDS_COMPATIBILITY);
553
+ expect(oldFormat).toMatchObject({
554
+ fraction: '2023-03-06 13:47:01.123Z',
555
+ noFraction: '2023-03-06 13:47:01.000Z'
556
+ });
557
+
558
+ const newFormat = applyRowContext(row, new CompatibilityContext(CompatibilityEdition.SYNC_STREAMS));
559
+ expect(newFormat).toMatchObject({
560
+ fraction: '2023-03-06T13:47:01.123Z',
561
+ noFraction: '2023-03-06T13:47:01.000Z'
562
+ });
563
+ } finally {
564
+ await client.close();
565
+ }
566
+ });
525
567
  });
526
568
 
527
569
  /**
528
570
  * Return all the inserts from the first transaction in the replication stream.
529
571
  */
530
572
  async function getReplicationTx(replicationStream: mongo.ChangeStream, count: number) {
531
- let transformed: SqliteRow[] = [];
573
+ let transformed: SqliteInputRow[] = [];
532
574
  for await (const doc of replicationStream) {
533
575
  // Specifically filter out map_input / map_output collections
534
576
  if (!(doc as any)?.ns?.coll?.startsWith('test_data')) {