@powersync/service-module-mysql 0.7.4 → 0.9.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 (63) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/LICENSE +3 -3
  3. package/dev/docker/mysql/init-scripts/my.cnf +1 -3
  4. package/dist/api/MySQLRouteAPIAdapter.js +12 -4
  5. package/dist/api/MySQLRouteAPIAdapter.js.map +1 -1
  6. package/dist/common/ReplicatedGTID.js +4 -0
  7. package/dist/common/ReplicatedGTID.js.map +1 -1
  8. package/dist/common/common-index.d.ts +1 -2
  9. package/dist/common/common-index.js +1 -2
  10. package/dist/common/common-index.js.map +1 -1
  11. package/dist/common/mysql-to-sqlite.d.ts +1 -1
  12. package/dist/common/mysql-to-sqlite.js +4 -0
  13. package/dist/common/mysql-to-sqlite.js.map +1 -1
  14. package/dist/common/schema-utils.d.ts +20 -0
  15. package/dist/common/{get-replication-columns.js → schema-utils.js} +73 -30
  16. package/dist/common/schema-utils.js.map +1 -0
  17. package/dist/replication/BinLogReplicationJob.js +4 -1
  18. package/dist/replication/BinLogReplicationJob.js.map +1 -1
  19. package/dist/replication/BinLogStream.d.ts +9 -6
  20. package/dist/replication/BinLogStream.js +117 -73
  21. package/dist/replication/BinLogStream.js.map +1 -1
  22. package/dist/replication/zongji/BinLogListener.d.ts +60 -6
  23. package/dist/replication/zongji/BinLogListener.js +347 -89
  24. package/dist/replication/zongji/BinLogListener.js.map +1 -1
  25. package/dist/replication/zongji/zongji-utils.d.ts +4 -1
  26. package/dist/replication/zongji/zongji-utils.js +9 -0
  27. package/dist/replication/zongji/zongji-utils.js.map +1 -1
  28. package/dist/types/node-sql-parser-extended-types.d.ts +31 -0
  29. package/dist/types/node-sql-parser-extended-types.js +2 -0
  30. package/dist/types/node-sql-parser-extended-types.js.map +1 -0
  31. package/dist/utils/mysql-utils.d.ts +4 -2
  32. package/dist/utils/mysql-utils.js +15 -3
  33. package/dist/utils/mysql-utils.js.map +1 -1
  34. package/dist/utils/parser-utils.d.ts +16 -0
  35. package/dist/utils/parser-utils.js +58 -0
  36. package/dist/utils/parser-utils.js.map +1 -0
  37. package/package.json +12 -11
  38. package/src/api/MySQLRouteAPIAdapter.ts +15 -4
  39. package/src/common/ReplicatedGTID.ts +6 -1
  40. package/src/common/common-index.ts +1 -2
  41. package/src/common/mysql-to-sqlite.ts +7 -1
  42. package/src/common/{get-replication-columns.ts → schema-utils.ts} +96 -37
  43. package/src/replication/BinLogReplicationJob.ts +4 -1
  44. package/src/replication/BinLogStream.ts +139 -94
  45. package/src/replication/zongji/BinLogListener.ts +421 -100
  46. package/src/replication/zongji/zongji-utils.ts +16 -1
  47. package/src/types/node-sql-parser-extended-types.ts +25 -0
  48. package/src/utils/mysql-utils.ts +19 -4
  49. package/src/utils/parser-utils.ts +73 -0
  50. package/test/src/BinLogListener.test.ts +421 -77
  51. package/test/src/BinLogStream.test.ts +128 -52
  52. package/test/src/BinlogStreamUtils.ts +12 -2
  53. package/test/src/mysql-to-sqlite.test.ts +5 -5
  54. package/test/src/parser-utils.test.ts +24 -0
  55. package/test/src/schema-changes.test.ts +659 -0
  56. package/test/src/util.ts +87 -1
  57. package/tsconfig.tsbuildinfo +1 -1
  58. package/dist/common/get-replication-columns.d.ts +0 -12
  59. package/dist/common/get-replication-columns.js.map +0 -1
  60. package/dist/common/get-tables-from-pattern.d.ts +0 -7
  61. package/dist/common/get-tables-from-pattern.js +0 -28
  62. package/dist/common/get-tables-from-pattern.js.map +0 -1
  63. package/src/common/get-tables-from-pattern.ts +0 -44
@@ -2,36 +2,63 @@ import * as common from '../../common/common-index.js';
2
2
  import async from 'async';
3
3
  import * as zongji_utils from './zongji-utils.js';
4
4
  import { logger as defaultLogger } from '@powersync/lib-services-framework';
5
- // Maximum time the processing queue can be paused before resuming automatically
6
- // MySQL server will automatically terminate replication connections after 60 seconds of inactivity, so this guards against that.
7
- const MAX_QUEUE_PAUSE_TIME_MS = 45_000;
5
+ import timers from 'timers/promises';
6
+ import pkg from 'node-sql-parser';
7
+ import { isAlterTable, isColumnExpression, isConstraintExpression, isCreateUniqueIndex, isDropIndex, isDropTable, isRenameExpression, isRenameTable, isTruncate, matchedSchemaChangeQuery } from '../../utils/parser-utils.js';
8
+ const { Parser } = pkg;
9
+ /**
10
+ * Seconds of inactivity after which a keepalive event is sent by the MySQL server.
11
+ */
12
+ export const KEEPALIVE_INACTIVITY_THRESHOLD = 30;
13
+ /**
14
+ * Schema changes that are detectable by inspecting query events.
15
+ * Create table statements are not included here, since new tables are automatically detected when row events
16
+ * are received for them.
17
+ */
18
+ export var SchemaChangeType;
19
+ (function (SchemaChangeType) {
20
+ SchemaChangeType["RENAME_TABLE"] = "Rename Table";
21
+ SchemaChangeType["DROP_TABLE"] = "Drop Table";
22
+ SchemaChangeType["TRUNCATE_TABLE"] = "Truncate Table";
23
+ SchemaChangeType["ALTER_TABLE_COLUMN"] = "Alter Table Column";
24
+ SchemaChangeType["REPLICATION_IDENTITY"] = "Alter Replication Identity";
25
+ })(SchemaChangeType || (SchemaChangeType = {}));
8
26
  /**
9
27
  * Wrapper class for the Zongji BinLog listener. Internally handles the creation and management of the listener and posts
10
28
  * events on the provided BinLogEventHandler.
11
29
  */
12
30
  export class BinLogListener {
13
31
  options;
32
+ sqlParser;
14
33
  connectionManager;
15
34
  eventHandler;
16
35
  binLogPosition;
17
36
  currentGTID;
18
37
  logger;
38
+ listenerError;
39
+ databaseFilter;
40
+ isStopped = false;
41
+ isStopping = false;
42
+ // Flag to indicate if are currently in a transaction that involves multiple row mutation events.
43
+ isTransactionOpen = false;
19
44
  zongji;
20
45
  processingQueue;
21
46
  /**
22
47
  * The combined size in bytes of all the binlog events currently in the processing queue.
23
48
  */
24
- queueMemoryUsage;
49
+ queueMemoryUsage = 0;
25
50
  constructor(options) {
26
51
  this.options = options;
27
52
  this.logger = options.logger ?? defaultLogger;
28
53
  this.connectionManager = options.connectionManager;
29
54
  this.eventHandler = options.eventHandler;
30
- this.binLogPosition = options.startPosition;
31
- this.currentGTID = null;
32
- this.processingQueue = async.queue(this.createQueueWorker(), 1);
33
- this.queueMemoryUsage = 0;
55
+ this.binLogPosition = options.startGTID.position;
56
+ this.currentGTID = options.startGTID;
57
+ this.sqlParser = new Parser();
58
+ this.processingQueue = this.createProcessingQueue();
34
59
  this.zongji = this.createZongjiListener();
60
+ this.listenerError = null;
61
+ this.databaseFilter = this.createDatabaseFilter(options.sourceTables);
35
62
  }
36
63
  /**
37
64
  * The queue memory limit in bytes as defined in the connection options.
@@ -40,107 +67,137 @@ export class BinLogListener {
40
67
  get queueMemoryLimit() {
41
68
  return this.connectionManager.options.binlog_queue_memory_limit * 1024 * 1024;
42
69
  }
43
- async start() {
70
+ async start(isRestart = false) {
44
71
  if (this.isStopped) {
45
72
  return;
46
73
  }
47
- this.logger.info(`Starting replication. Created replica client with serverId:${this.options.serverId}`);
48
- this.zongji.start({
49
- // We ignore the unknown/heartbeat event since it currently serves no purpose other than to keep the connection alive
50
- // tablemap events always need to be included for the other row events to work
51
- includeEvents: ['tablemap', 'writerows', 'updaterows', 'deleterows', 'xid', 'rotate', 'gtidlog'],
52
- includeSchema: { [this.connectionManager.databaseName]: this.options.includedTables },
53
- filename: this.binLogPosition.filename,
54
- position: this.binLogPosition.offset,
55
- serverId: this.options.serverId
56
- });
57
- return new Promise((resolve, reject) => {
58
- // Handle an edge case where the listener has already been stopped before completing startup
59
- if (this.isStopped) {
60
- this.logger.info('BinLog listener was stopped before startup completed.');
61
- resolve();
62
- }
63
- this.zongji.on('error', (error) => {
64
- if (!this.isStopped) {
65
- this.logger.error('Binlog listener error:', error);
66
- this.stop();
67
- reject(error);
68
- }
69
- else {
70
- this.logger.warn('Binlog listener error during shutdown:', error);
71
- }
72
- });
73
- this.processingQueue.error((error) => {
74
- if (!this.isStopped) {
75
- this.logger.error('BinlogEvent processing error:', error);
76
- this.stop();
74
+ this.logger.info(`${isRestart ? 'Restarting' : 'Starting'} BinLog Listener with replica client id:${this.options.serverId}...`);
75
+ // Set a heartbeat interval for the Zongji replication connection, these events are enough to keep the connection
76
+ // alive for setTimeout to work on the socket.
77
+ // The heartbeat needs to be set before starting the listener, since the replication connection is locked once replicating
78
+ await new Promise((resolve, reject) => {
79
+ this.zongji.connection.query(
80
+ // In nanoseconds, 10^9 = 1s
81
+ `set @master_heartbeat_period=${this.options.keepAliveInactivitySeconds ?? KEEPALIVE_INACTIVITY_THRESHOLD}*1000000000`, (error, results, _fields) => {
82
+ if (error) {
77
83
  reject(error);
78
84
  }
79
85
  else {
80
- this.logger.warn('BinlogEvent processing error during shutdown:', error);
86
+ this.logger.info('Successfully set up replication connection heartbeat.');
87
+ resolve(results);
81
88
  }
82
89
  });
83
- this.zongji.on('stopped', () => {
90
+ });
91
+ // The _socket member is only set after a query is run on the connection, so we set the timeout after setting the heartbeat.
92
+ // The timeout here must be greater than the master_heartbeat_period.
93
+ const socket = this.zongji.connection._socket;
94
+ socket.setTimeout(60_000, () => {
95
+ this.logger.info('Destroying socket due to replication connection timeout.');
96
+ socket.destroy(new Error('Replication connection timeout.'));
97
+ });
98
+ this.zongji.start({
99
+ // Tablemap events always need to be included for the other row events to work
100
+ includeEvents: [
101
+ 'tablemap',
102
+ 'writerows',
103
+ 'updaterows',
104
+ 'deleterows',
105
+ 'xid',
106
+ 'rotate',
107
+ 'gtidlog',
108
+ 'query',
109
+ 'heartbeat',
110
+ 'heartbeat_v2'
111
+ ],
112
+ includeSchema: this.databaseFilter,
113
+ filename: this.binLogPosition.filename,
114
+ position: this.binLogPosition.offset,
115
+ serverId: this.options.serverId
116
+ });
117
+ return new Promise((resolve) => {
118
+ this.zongji.once('ready', () => {
119
+ this.logger.info(`BinLog Listener ${isRestart ? 'restarted' : 'started'}. Listening for events from position: ${this.binLogPosition.filename}:${this.binLogPosition.offset}`);
84
120
  resolve();
85
- this.logger.info('BinLog listener stopped. Replication ended.');
86
121
  });
87
122
  });
88
123
  }
89
- stop() {
90
- if (!this.isStopped) {
91
- this.zongji.stop();
124
+ async restartZongji() {
125
+ if (this.zongji.stopped) {
126
+ this.zongji = this.createZongjiListener();
127
+ await this.start(true);
128
+ }
129
+ }
130
+ async stopZongji() {
131
+ if (!this.zongji.stopped) {
132
+ this.logger.info('Stopping BinLog Listener...');
133
+ await new Promise((resolve) => {
134
+ this.zongji.once('stopped', () => {
135
+ resolve();
136
+ });
137
+ this.zongji.stop();
138
+ });
139
+ this.logger.info('BinLog Listener stopped.');
140
+ }
141
+ }
142
+ async stop() {
143
+ if (!(this.isStopped || this.isStopping)) {
144
+ this.isStopping = true;
145
+ await this.stopZongji();
92
146
  this.processingQueue.kill();
147
+ this.isStopped = true;
148
+ }
149
+ }
150
+ async replicateUntilStopped() {
151
+ while (!this.isStopped) {
152
+ await timers.setTimeout(1_000);
153
+ }
154
+ if (this.listenerError) {
155
+ this.logger.error('BinLog Listener stopped due to an error:', this.listenerError);
156
+ throw this.listenerError;
93
157
  }
94
158
  }
95
- get isStopped() {
96
- return this.zongji.stopped;
159
+ createProcessingQueue() {
160
+ const queue = async.queue(this.createQueueWorker(), 1);
161
+ queue.error((error) => {
162
+ if (!(this.isStopped || this.isStopping)) {
163
+ this.listenerError = error;
164
+ this.stop();
165
+ }
166
+ else {
167
+ this.logger.warn('Error processing BinLog event during shutdown:', error);
168
+ }
169
+ });
170
+ return queue;
97
171
  }
98
172
  createZongjiListener() {
99
173
  const zongji = this.connectionManager.createBinlogListener();
100
174
  zongji.on('binlog', async (evt) => {
101
- this.logger.info(`Received Binlog event:${evt.getEventName()}`);
175
+ this.logger.debug(`Received BinLog event:${evt.getEventName()}`);
102
176
  this.processingQueue.push(evt);
103
177
  this.queueMemoryUsage += evt.size;
104
178
  // When the processing queue grows past the threshold, we pause the binlog listener
105
179
  if (this.isQueueOverCapacity()) {
106
- this.logger.info(`Binlog processing queue has reached its memory limit of [${this.connectionManager.options.binlog_queue_memory_limit}MB]. Pausing Binlog listener.`);
107
- zongji.pause();
108
- const resumeTimeoutPromise = new Promise((resolve) => {
109
- setTimeout(() => resolve('timeout'), MAX_QUEUE_PAUSE_TIME_MS);
110
- });
111
- await Promise.race([this.processingQueue.empty(), resumeTimeoutPromise]);
112
- this.logger.info(`Binlog processing queue backlog cleared. Resuming Binlog listener.`);
113
- zongji.resume();
180
+ this.logger.info(`BinLog processing queue has reached its memory limit of [${this.connectionManager.options.binlog_queue_memory_limit}MB]. Pausing BinLog Listener.`);
181
+ await this.stopZongji();
182
+ await this.processingQueue.drain();
183
+ this.logger.info(`BinLog processing queue backlog cleared. Resuming BinLog Listener.`);
184
+ await this.restartZongji();
114
185
  }
115
186
  });
116
- zongji.on('ready', async () => {
117
- // Set a heartbeat interval for the Zongji replication connection
118
- // Zongji does not explicitly handle the heartbeat events - they are categorized as event:unknown
119
- // The heartbeat events are enough to keep the connection alive for setTimeout to work on the socket.
120
- await new Promise((resolve, reject) => {
121
- this.zongji.connection.query(
122
- // In nanoseconds, 10^9 = 1s
123
- 'set @master_heartbeat_period=28*1000000000', (error, results, fields) => {
124
- if (error) {
125
- reject(error);
126
- }
127
- else {
128
- this.logger.info('Successfully set up replication connection heartbeat...');
129
- resolve(results);
130
- }
131
- });
132
- });
133
- // The _socket member is only set after a query is run on the connection, so we set the timeout after setting the heartbeat.
134
- // The timeout here must be greater than the master_heartbeat_period.
135
- const socket = this.zongji.connection._socket;
136
- socket.setTimeout(60_000, () => {
137
- this.logger.info('Destroying socket due to replication connection timeout.');
138
- socket.destroy(new Error('Replication connection timeout.'));
139
- });
140
- this.logger.info(`BinLog listener setup complete. Reading binlog from: ${this.binLogPosition.filename}:${this.binLogPosition.offset}`);
187
+ zongji.on('error', (error) => {
188
+ if (!(this.isStopped || this.isStopping)) {
189
+ this.listenerError = error;
190
+ this.stop();
191
+ }
192
+ else {
193
+ this.logger.warn('Ignored BinLog Listener error during shutdown:', error);
194
+ }
141
195
  });
142
196
  return zongji;
143
197
  }
198
+ isQueueOverCapacity() {
199
+ return this.queueMemoryUsage >= this.queueMemoryLimit;
200
+ }
144
201
  createQueueWorker() {
145
202
  return async (evt) => {
146
203
  switch (true) {
@@ -155,38 +212,239 @@ export class BinLogListener {
155
212
  offset: evt.nextPosition
156
213
  }
157
214
  });
215
+ this.binLogPosition.offset = evt.nextPosition;
158
216
  await this.eventHandler.onTransactionStart({ timestamp: new Date(evt.timestamp) });
217
+ this.logger.info(`Processed GTID event: ${this.currentGTID.comparable}`);
159
218
  break;
160
219
  case zongji_utils.eventIsRotation(evt):
220
+ // The first event when starting replication is a synthetic Rotate event
221
+ // It describes the last binlog file and position that the replica client processed
161
222
  this.binLogPosition.filename = evt.binlogName;
162
- this.binLogPosition.offset = evt.position;
223
+ this.binLogPosition.offset = evt.nextPosition !== 0 ? evt.nextPosition : evt.position;
163
224
  await this.eventHandler.onRotate();
225
+ const newFile = this.binLogPosition.filename !== evt.binlogName;
226
+ if (newFile) {
227
+ this.logger.info(`Processed Rotate event. New BinLog file is: ${this.binLogPosition.filename}:${this.binLogPosition.offset}`);
228
+ }
164
229
  break;
165
230
  case zongji_utils.eventIsWriteMutation(evt):
166
- await this.eventHandler.onWrite(evt.rows, evt.tableMap[evt.tableId]);
231
+ const tableMap = evt.tableMap[evt.tableId];
232
+ await this.eventHandler.onWrite(evt.rows, tableMap);
233
+ this.binLogPosition.offset = evt.nextPosition;
234
+ this.logger.info(`Processed Write event for table [${tableMap.parentSchema}.${tableMap.tableName}]. ${evt.rows.length} row(s) inserted.`);
167
235
  break;
168
236
  case zongji_utils.eventIsUpdateMutation(evt):
169
237
  await this.eventHandler.onUpdate(evt.rows.map((row) => row.after), evt.rows.map((row) => row.before), evt.tableMap[evt.tableId]);
238
+ this.binLogPosition.offset = evt.nextPosition;
239
+ this.logger.info(`Processed Update event for table [${evt.tableMap[evt.tableId].tableName}]. ${evt.rows.length} row(s) updated.`);
170
240
  break;
171
241
  case zongji_utils.eventIsDeleteMutation(evt):
172
242
  await this.eventHandler.onDelete(evt.rows, evt.tableMap[evt.tableId]);
243
+ this.binLogPosition.offset = evt.nextPosition;
244
+ this.logger.info(`Processed Delete event for table [${evt.tableMap[evt.tableId].tableName}]. ${evt.rows.length} row(s) deleted.`);
245
+ break;
246
+ case zongji_utils.eventIsHeartbeat(evt):
247
+ case zongji_utils.eventIsHeartbeat_v2(evt):
248
+ // Heartbeats are sent by the master to keep the connection alive after a period of inactivity. They are synthetic
249
+ // so are not written to the binlog. Consequently, they have no effect on the binlog position.
250
+ // We forward these along with the current GTID to the event handler, but don't want to do this if a transaction is in progress.
251
+ if (!this.isTransactionOpen) {
252
+ await this.eventHandler.onKeepAlive(this.currentGTID.comparable);
253
+ }
254
+ this.logger.debug(`Processed Heartbeat event. Current GTID is: ${this.currentGTID.comparable}`);
173
255
  break;
174
256
  case zongji_utils.eventIsXid(evt):
257
+ this.isTransactionOpen = false;
258
+ this.binLogPosition.offset = evt.nextPosition;
175
259
  const LSN = new common.ReplicatedGTID({
176
260
  raw_gtid: this.currentGTID.raw,
177
- position: {
178
- filename: this.binLogPosition.filename,
179
- offset: evt.nextPosition
180
- }
261
+ position: this.binLogPosition
181
262
  }).comparable;
182
263
  await this.eventHandler.onCommit(LSN);
264
+ this.logger.info(`Processed Xid event - transaction complete. LSN: ${LSN}.`);
265
+ break;
266
+ case zongji_utils.eventIsQuery(evt):
267
+ await this.processQueryEvent(evt);
183
268
  break;
184
269
  }
185
270
  this.queueMemoryUsage -= evt.size;
186
271
  };
187
272
  }
188
- isQueueOverCapacity() {
189
- return this.queueMemoryUsage >= this.queueMemoryLimit;
273
+ async processQueryEvent(event) {
274
+ const { query, nextPosition } = event;
275
+ // BEGIN query events mark the start of a transaction before any row events. They are not schema changes so no further parsing is necessary.
276
+ if (query === 'BEGIN') {
277
+ this.isTransactionOpen = true;
278
+ return;
279
+ }
280
+ const schemaChanges = this.toSchemaChanges(query, event.schema);
281
+ if (schemaChanges.length > 0) {
282
+ // Handling schema changes can take a long time, so we stop the Zongji listener whilst handling them to prevent the listener from timing out.
283
+ await this.stopZongji();
284
+ for (const change of schemaChanges) {
285
+ this.logger.info(`Processing schema change ${change.type} for table [${change.schema}.${change.table}]`);
286
+ await this.eventHandler.onSchemaChange(change);
287
+ }
288
+ // DDL queries are auto commited, but do not come with a corresponding Xid event, in those cases we trigger a manual commit if we are not already in a transaction.
289
+ // Some DDL queries include row events, and in those cases will include a Xid event.
290
+ if (!this.isTransactionOpen) {
291
+ this.binLogPosition.offset = nextPosition;
292
+ const LSN = new common.ReplicatedGTID({
293
+ raw_gtid: this.currentGTID.raw,
294
+ position: this.binLogPosition
295
+ }).comparable;
296
+ await this.eventHandler.onCommit(LSN);
297
+ }
298
+ this.logger.info(`Successfully processed ${schemaChanges.length} schema change(s).`);
299
+ // If there are still events in the processing queue, we need to process those before restarting Zongji
300
+ // This avoids potentially processing the same events again after a restart.
301
+ if (!this.processingQueue.idle()) {
302
+ this.logger.info(`Processing [${this.processingQueue.length()}] events(s) before resuming...`);
303
+ this.processingQueue.drain(async () => {
304
+ await this.restartZongji();
305
+ });
306
+ }
307
+ else {
308
+ await this.restartZongji();
309
+ }
310
+ }
311
+ else if (!this.isTransactionOpen) {
312
+ this.binLogPosition.offset = nextPosition;
313
+ const LSN = new common.ReplicatedGTID({
314
+ raw_gtid: this.currentGTID.raw,
315
+ position: this.binLogPosition
316
+ }).comparable;
317
+ await this.eventHandler.onCommit(LSN);
318
+ }
319
+ }
320
+ /**
321
+ * Function that interprets a DDL query for any applicable schema changes.
322
+ * If the query does not contain any relevant schema changes, an empty array is returned.
323
+ * The defaultSchema is derived from the database set on the MySQL Node.js connection client.
324
+ * It is used as a fallback when the schema/database cannot be determined from the query DDL.
325
+ *
326
+ * @param query
327
+ * @param defaultSchema
328
+ */
329
+ toSchemaChanges(query, defaultSchema) {
330
+ let statements = [];
331
+ try {
332
+ const ast = this.sqlParser.astify(query, { database: 'MySQL' });
333
+ statements = Array.isArray(ast) ? ast : [ast];
334
+ }
335
+ catch (error) {
336
+ if (matchedSchemaChangeQuery(query, Object.values(this.databaseFilter))) {
337
+ this.logger.warn(`Failed to parse query: [${query}].
338
+ Please review for the schema changes and manually redeploy the sync rules if required.`);
339
+ }
340
+ return [];
341
+ }
342
+ const changes = [];
343
+ for (const statement of statements) {
344
+ if (isTruncate(statement)) {
345
+ const truncateStatement = statement;
346
+ // Truncate statements can apply to multiple tables
347
+ for (const entity of truncateStatement.name) {
348
+ changes.push({
349
+ type: SchemaChangeType.TRUNCATE_TABLE,
350
+ table: entity.table,
351
+ schema: entity.db ?? defaultSchema
352
+ });
353
+ }
354
+ }
355
+ else if (isDropTable(statement)) {
356
+ for (const entity of statement.name) {
357
+ changes.push({ type: SchemaChangeType.DROP_TABLE, table: entity.table, schema: entity.db ?? defaultSchema });
358
+ }
359
+ }
360
+ else if (isDropIndex(statement)) {
361
+ const dropStatement = statement;
362
+ changes.push({
363
+ type: SchemaChangeType.REPLICATION_IDENTITY,
364
+ table: dropStatement.table.table,
365
+ schema: dropStatement.table.db ?? defaultSchema
366
+ });
367
+ }
368
+ else if (isCreateUniqueIndex(statement)) {
369
+ // Potential change to the replication identity if the table has no prior unique constraint
370
+ changes.push({
371
+ type: SchemaChangeType.REPLICATION_IDENTITY,
372
+ // @ts-ignore - The type definitions for node-sql-parser do not reflect the correct structure here
373
+ table: statement.table.table,
374
+ // @ts-ignore
375
+ schema: statement.table.db ?? defaultSchema
376
+ });
377
+ }
378
+ else if (isRenameTable(statement)) {
379
+ const renameStatement = statement;
380
+ // Rename statements can apply to multiple tables
381
+ for (const table of renameStatement.table) {
382
+ const schema = table[0].db ?? defaultSchema;
383
+ const isNewTableIncluded = this.databaseFilter[schema](table[1].table);
384
+ changes.push({
385
+ type: SchemaChangeType.RENAME_TABLE,
386
+ table: table[0].table,
387
+ newTable: isNewTableIncluded ? table[1].table : undefined,
388
+ schema
389
+ });
390
+ }
391
+ }
392
+ else if (isAlterTable(statement)) {
393
+ const fromTable = statement.table[0];
394
+ for (const expression of statement.expr) {
395
+ if (isRenameExpression(expression)) {
396
+ changes.push({
397
+ type: SchemaChangeType.RENAME_TABLE,
398
+ table: fromTable.table,
399
+ newTable: expression.table,
400
+ schema: fromTable.db ?? defaultSchema
401
+ });
402
+ }
403
+ else if (isColumnExpression(expression)) {
404
+ changes.push({
405
+ type: SchemaChangeType.ALTER_TABLE_COLUMN,
406
+ table: fromTable.table,
407
+ schema: fromTable.db ?? defaultSchema
408
+ });
409
+ }
410
+ else if (isConstraintExpression(expression)) {
411
+ // Potential changes to the replication identity
412
+ changes.push({
413
+ type: SchemaChangeType.REPLICATION_IDENTITY,
414
+ table: fromTable.table,
415
+ schema: fromTable.db ?? defaultSchema
416
+ });
417
+ }
418
+ }
419
+ }
420
+ }
421
+ // Filter out schema changes that are not relevant to the included tables
422
+ return changes.filter((change) => this.isTableIncluded(change.table, change.schema) ||
423
+ (change.newTable && this.isTableIncluded(change.newTable, change.schema)));
424
+ }
425
+ isTableIncluded(tableName, schema) {
426
+ return this.databaseFilter[schema] && this.databaseFilter[schema](tableName);
427
+ }
428
+ createDatabaseFilter(sourceTables) {
429
+ // Group sync rule tables by schema
430
+ const schemaMap = new Map();
431
+ for (const table of sourceTables) {
432
+ if (!schemaMap.has(table.schema)) {
433
+ const tables = [table];
434
+ schemaMap.set(table.schema, tables);
435
+ }
436
+ else {
437
+ schemaMap.get(table.schema).push(table);
438
+ }
439
+ }
440
+ const databaseFilter = {};
441
+ for (const entry of schemaMap.entries()) {
442
+ const [schema, sourceTables] = entry;
443
+ databaseFilter[schema] = (table) => sourceTables.findIndex((sourceTable) => sourceTable.isWildcard
444
+ ? table.startsWith(sourceTable.tablePattern.substring(0, sourceTable.tablePattern.length - 1))
445
+ : table === sourceTable.name) !== -1;
446
+ }
447
+ return databaseFilter;
190
448
  }
191
449
  }
192
450
  //# sourceMappingURL=BinLogListener.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BinLogListener.js","sourceRoot":"","sources":["../../../src/replication/zongji/BinLogListener.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,8BAA8B,CAAC;AACvD,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAU,MAAM,IAAI,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAGpF,gFAAgF;AAChF,iIAAiI;AACjI,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAsBvC;;;GAGG;AACH,MAAM,OAAO,cAAc;IAcN;IAbX,iBAAiB,CAAyB;IAC1C,YAAY,CAAqB;IACjC,cAAc,CAAwB;IACtC,WAAW,CAA+B;IAC1C,MAAM,CAAS;IAEvB,MAAM,CAAS;IACf,eAAe,CAAiC;IAChD;;OAEG;IACH,gBAAgB,CAAS;IAEzB,YAAmB,OAA8B;QAA9B,YAAO,GAAP,OAAO,CAAuB;QAC/C,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,aAAa,CAAC;QAC9C,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;QACnD,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;QACzC,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;QAC5C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAExB,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC,CAAC;QAChE,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC5C,CAAC;IAED;;;OAGG;IACH,IAAY,gBAAgB;QAC1B,OAAO,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,yBAAyB,GAAG,IAAI,GAAG,IAAI,CAAC;IAChF,CAAC;IAEM,KAAK,CAAC,KAAK;QAChB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,8DAA8D,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;QAExG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;YAChB,qHAAqH;YACrH,8EAA8E;YAC9E,aAAa,EAAE,CAAC,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC;YAChG,aAAa,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE;YACrF,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,QAAQ;YACtC,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,MAAM;YACpC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ;SACT,CAAC,CAAC;QAE1B,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,4FAA4F;YAC5F,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC;gBAC1E,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBAChC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;oBACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;oBACnD,IAAI,CAAC,IAAI,EAAE,CAAC;oBACZ,MAAM,CAAC,KAAK,CAAC,CAAC;gBAChB,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,wCAAwC,EAAE,KAAK,CAAC,CAAC;gBACpE,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBACnC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;oBACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;oBAC1D,IAAI,CAAC,IAAI,EAAE,CAAC;oBACZ,MAAM,CAAC,KAAK,CAAC,CAAC;gBAChB,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,+CAA+C,EAAE,KAAK,CAAC,CAAC;gBAC3E,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;gBAC7B,OAAO,EAAE,CAAC;gBACV,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;YAClE,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,IAAI;QACT,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACnB,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,IAAY,SAAS;QACnB,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;IAC7B,CAAC;IAEO,oBAAoB;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,oBAAoB,EAAE,CAAC;QAE7D,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YAChC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,GAAG,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;YAChE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC/B,IAAI,CAAC,gBAAgB,IAAI,GAAG,CAAC,IAAI,CAAC;YAElC,mFAAmF;YACnF,IAAI,IAAI,CAAC,mBAAmB,EAAE,EAAE,CAAC;gBAC/B,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,4DAA4D,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,yBAAyB,+BAA+B,CACpJ,CAAC;gBACF,MAAM,CAAC,KAAK,EAAE,CAAC;gBACf,MAAM,oBAAoB,GAAG,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;oBACnD,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,uBAAuB,CAAC,CAAC;gBAChE,CAAC,CAAC,CAAC;gBAEH,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,EAAE,oBAAoB,CAAC,CAAC,CAAC;gBAEzE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC;gBACvF,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;YAC5B,iEAAiE;YACjE,iGAAiG;YACjG,qGAAqG;YACrG,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACpC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK;gBAC1B,4BAA4B;gBAC5B,4CAA4C,EAC5C,CAAC,KAAU,EAAE,OAAY,EAAE,MAAW,EAAE,EAAE;oBACxC,IAAI,KAAK,EAAE,CAAC;wBACV,MAAM,CAAC,KAAK,CAAC,CAAC;oBAChB,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAC;wBAC5E,OAAO,CAAC,OAAO,CAAC,CAAC;oBACnB,CAAC;gBACH,CAAC,CACF,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,4HAA4H;YAC5H,qEAAqE;YACrE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,OAAQ,CAAC;YAC/C,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,GAAG,EAAE;gBAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC;gBAC7E,MAAM,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC,CAAC;YAC/D,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,wDAAwD,IAAI,CAAC,cAAc,CAAC,QAAQ,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CACrH,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,iBAAiB;QACvB,OAAO,KAAK,EAAE,GAAgB,EAAE,EAAE;YAChC,QAAQ,IAAI,EAAE,CAAC;gBACb,KAAK,YAAY,CAAC,cAAc,CAAC,GAAG,CAAC;oBACnC,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,cAAc,CAAC,eAAe,CAAC;wBACvD,QAAQ,EAAE;4BACR,SAAS,EAAE,GAAG,CAAC,QAAQ;4BACvB,iBAAiB,EAAE,GAAG,CAAC,gBAAgB;yBACxC;wBACD,QAAQ,EAAE;4BACR,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,QAAQ;4BACtC,MAAM,EAAE,GAAG,CAAC,YAAY;yBACzB;qBACF,CAAC,CAAC;oBACH,MAAM,IAAI,CAAC,YAAY,CAAC,kBAAkB,CAAC,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;oBACnF,MAAM;gBACR,KAAK,YAAY,CAAC,eAAe,CAAC,GAAG,CAAC;oBACpC,IAAI,CAAC,cAAc,CAAC,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC;oBAC9C,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC;oBAC1C,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;oBACnC,MAAM;gBACR,KAAK,YAAY,CAAC,oBAAoB,CAAC,GAAG,CAAC;oBACzC,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;oBACrE,MAAM;gBACR,KAAK,YAAY,CAAC,qBAAqB,CAAC,GAAG,CAAC;oBAC1C,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,CAC9B,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAChC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EACjC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAC1B,CAAC;oBACF,MAAM;gBACR,KAAK,YAAY,CAAC,qBAAqB,CAAC,GAAG,CAAC;oBAC1C,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;oBACtE,MAAM;gBACR,KAAK,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC;oBAC/B,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,cAAc,CAAC;wBACpC,QAAQ,EAAE,IAAI,CAAC,WAAY,CAAC,GAAG;wBAC/B,QAAQ,EAAE;4BACR,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,QAAQ;4BACtC,MAAM,EAAE,GAAG,CAAC,YAAY;yBACzB;qBACF,CAAC,CAAC,UAAU,CAAC;oBACd,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;oBACtC,MAAM;YACV,CAAC;YAED,IAAI,CAAC,gBAAgB,IAAI,GAAG,CAAC,IAAI,CAAC;QACpC,CAAC,CAAC;IACJ,CAAC;IAED,mBAAmB;QACjB,OAAO,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,gBAAgB,CAAC;IACxD,CAAC;CACF"}
1
+ {"version":3,"file":"BinLogListener.js","sourceRoot":"","sources":["../../../src/replication/zongji/BinLogListener.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,11 @@
1
- import { BinLogEvent, BinLogGTIDLogEvent, BinLogRowEvent, BinLogRotationEvent, BinLogTableMapEvent, BinLogRowUpdateEvent, BinLogXidEvent } from '@powersync/mysql-zongji';
1
+ import { BinLogEvent, BinLogGTIDLogEvent, BinLogRowEvent, BinLogRotationEvent, BinLogTableMapEvent, BinLogRowUpdateEvent, BinLogXidEvent, BinLogQueryEvent, BinLogHeartbeatEvent, BinLogHeartbeatEvent_V2 } from '@powersync/mysql-zongji';
2
2
  export declare function eventIsGTIDLog(event: BinLogEvent): event is BinLogGTIDLogEvent;
3
3
  export declare function eventIsTableMap(event: BinLogEvent): event is BinLogTableMapEvent;
4
4
  export declare function eventIsXid(event: BinLogEvent): event is BinLogXidEvent;
5
+ export declare function eventIsHeartbeat(event: BinLogEvent): event is BinLogHeartbeatEvent;
6
+ export declare function eventIsHeartbeat_v2(event: BinLogEvent): event is BinLogHeartbeatEvent_V2;
5
7
  export declare function eventIsRotation(event: BinLogEvent): event is BinLogRotationEvent;
6
8
  export declare function eventIsWriteMutation(event: BinLogEvent): event is BinLogRowEvent;
7
9
  export declare function eventIsDeleteMutation(event: BinLogEvent): event is BinLogRowEvent;
8
10
  export declare function eventIsUpdateMutation(event: BinLogEvent): event is BinLogRowUpdateEvent;
11
+ export declare function eventIsQuery(event: BinLogEvent): event is BinLogQueryEvent;
@@ -7,6 +7,12 @@ export function eventIsTableMap(event) {
7
7
  export function eventIsXid(event) {
8
8
  return event.getEventName() == 'xid';
9
9
  }
10
+ export function eventIsHeartbeat(event) {
11
+ return event.getEventName() == 'heartbeat';
12
+ }
13
+ export function eventIsHeartbeat_v2(event) {
14
+ return event.getEventName() == 'heartbeat_v2';
15
+ }
10
16
  export function eventIsRotation(event) {
11
17
  return event.getEventName() == 'rotate';
12
18
  }
@@ -19,4 +25,7 @@ export function eventIsDeleteMutation(event) {
19
25
  export function eventIsUpdateMutation(event) {
20
26
  return event.getEventName() == 'updaterows';
21
27
  }
28
+ export function eventIsQuery(event) {
29
+ return event.getEventName() == 'query';
30
+ }
22
31
  //# sourceMappingURL=zongji-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"zongji-utils.js","sourceRoot":"","sources":["../../../src/replication/zongji/zongji-utils.ts"],"names":[],"mappings":"AAUA,MAAM,UAAU,cAAc,CAAC,KAAkB;IAC/C,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,SAAS,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAkB;IAChD,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,UAAU,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAkB;IAC3C,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,KAAK,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAkB;IAChD,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,QAAQ,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAkB;IACrD,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,WAAW,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAkB;IACtD,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,YAAY,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAkB;IACtD,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,YAAY,CAAC;AAC9C,CAAC"}
1
+ {"version":3,"file":"zongji-utils.js","sourceRoot":"","sources":["../../../src/replication/zongji/zongji-utils.ts"],"names":[],"mappings":"AAaA,MAAM,UAAU,cAAc,CAAC,KAAkB;IAC/C,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,SAAS,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAkB;IAChD,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,UAAU,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAkB;IAC3C,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,KAAK,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAkB;IACjD,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,WAAW,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAkB;IACpD,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,cAAc,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAkB;IAChD,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,QAAQ,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAkB;IACrD,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,WAAW,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAkB;IACtD,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,YAAY,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAkB;IACtD,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,YAAY,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAkB;IAC7C,OAAO,KAAK,CAAC,YAAY,EAAE,IAAI,OAAO,CAAC;AACzC,CAAC"}