@powersync/service-module-mysql 0.0.0-dev-20250117095455 → 0.0.0-dev-20250214100224

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 (35) hide show
  1. package/CHANGELOG.md +52 -8
  2. package/dist/api/MySQLRouteAPIAdapter.d.ts +2 -1
  3. package/dist/api/MySQLRouteAPIAdapter.js +8 -0
  4. package/dist/api/MySQLRouteAPIAdapter.js.map +1 -1
  5. package/dist/common/ReplicatedGTID.js +5 -4
  6. package/dist/common/ReplicatedGTID.js.map +1 -1
  7. package/dist/module/MySQLModule.d.ts +3 -2
  8. package/dist/module/MySQLModule.js +8 -2
  9. package/dist/module/MySQLModule.js.map +1 -1
  10. package/dist/replication/BinLogReplicationJob.js +3 -2
  11. package/dist/replication/BinLogReplicationJob.js.map +1 -1
  12. package/dist/replication/BinLogReplicator.d.ts +1 -0
  13. package/dist/replication/BinLogReplicator.js +5 -0
  14. package/dist/replication/BinLogReplicator.js.map +1 -1
  15. package/dist/replication/BinLogStream.js +12 -6
  16. package/dist/replication/BinLogStream.js.map +1 -1
  17. package/dist/replication/MySQLConnectionManager.js +12 -2
  18. package/dist/replication/MySQLConnectionManager.js.map +1 -1
  19. package/dist/replication/MySQLConnectionManagerFactory.d.ts +1 -1
  20. package/dist/replication/MySQLConnectionManagerFactory.js +2 -0
  21. package/dist/replication/MySQLConnectionManagerFactory.js.map +1 -1
  22. package/dist/replication/MySQLErrorRateLimiter.js +5 -7
  23. package/dist/replication/MySQLErrorRateLimiter.js.map +1 -1
  24. package/dist/types/types.js +6 -6
  25. package/dist/types/types.js.map +1 -1
  26. package/package.json +9 -9
  27. package/src/api/MySQLRouteAPIAdapter.ts +10 -1
  28. package/src/module/MySQLModule.ts +18 -4
  29. package/src/replication/BinLogReplicationJob.ts +1 -1
  30. package/src/replication/BinLogReplicator.ts +5 -0
  31. package/src/replication/BinLogStream.ts +4 -4
  32. package/src/replication/MySQLConnectionManagerFactory.ts +1 -1
  33. package/src/types/types.ts +9 -7
  34. package/test/src/BinlogStreamUtils.ts +1 -1
  35. package/tsconfig.tsbuildinfo +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@powersync/service-module-mysql",
3
3
  "repository": "https://github.com/powersync-ja/powersync-service",
4
4
  "types": "dist/index.d.ts",
5
- "version": "0.0.0-dev-20250117095455",
5
+ "version": "0.0.0-dev-20250214100224",
6
6
  "license": "FSL-1.1-Apache-2.0",
7
7
  "main": "dist/index.js",
8
8
  "type": "module",
@@ -29,19 +29,19 @@
29
29
  "ts-codec": "^1.3.0",
30
30
  "uri-js": "^4.4.1",
31
31
  "uuid": "^9.0.1",
32
- "@powersync/lib-services-framework": "0.0.0-dev-20250117095455",
33
- "@powersync/service-core": "0.0.0-dev-20250117095455",
34
- "@powersync/service-sync-rules": "0.23.1",
35
- "@powersync/service-types": "0.0.0-dev-20250117095455",
36
- "@powersync/service-jsonbig": "0.17.10"
32
+ "@powersync/lib-services-framework": "0.5.1",
33
+ "@powersync/service-core": "0.0.0-dev-20250214100224",
34
+ "@powersync/service-sync-rules": "0.23.4",
35
+ "@powersync/service-jsonbig": "0.17.10",
36
+ "@powersync/service-types": "0.8.0"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/semver": "^7.5.4",
40
40
  "@types/async": "^3.2.24",
41
41
  "@types/uuid": "^9.0.4",
42
- "@powersync/service-core-tests": "0.0.0-dev-20250117095455",
43
- "@powersync/service-module-mongodb-storage": "0.0.0-dev-20250117095455",
44
- "@powersync/service-module-postgres-storage": "0.0.0-dev-20250117095455"
42
+ "@powersync/service-core-tests": "0.0.0-dev-20250214100224",
43
+ "@powersync/service-module-mongodb-storage": "0.0.0-dev-20250214100224",
44
+ "@powersync/service-module-postgres-storage": "0.0.0-dev-20250214100224"
45
45
  },
46
46
  "scripts": {
47
47
  "build": "tsc -b",
@@ -1,4 +1,4 @@
1
- import { api, ParseSyncRulesOptions, storage } from '@powersync/service-core';
1
+ import { api, ParseSyncRulesOptions, ReplicationHeadCallback, storage } from '@powersync/service-core';
2
2
 
3
3
  import * as sync_rules from '@powersync/service-sync-rules';
4
4
  import * as service_types from '@powersync/service-types';
@@ -275,6 +275,15 @@ export class MySQLRouteAPIAdapter implements api.RouteAPI {
275
275
  return result.comparable;
276
276
  }
277
277
 
278
+ async createReplicationHead<T>(callback: ReplicationHeadCallback<T>): Promise<T> {
279
+ const head = await this.getReplicationHead();
280
+ const r = await callback(head);
281
+
282
+ // TODO: make sure another message is replicated
283
+
284
+ return r;
285
+ }
286
+
278
287
  async getConnectionSchema(): Promise<service_types.DatabaseSchema[]> {
279
288
  const [results] = await this.retriedQuery({
280
289
  query: `
@@ -1,4 +1,11 @@
1
- import { api, ConfigurationFileSyncRulesProvider, replication, system, TearDownOptions } from '@powersync/service-core';
1
+ import {
2
+ api,
3
+ ConfigurationFileSyncRulesProvider,
4
+ ConnectionTestResult,
5
+ replication,
6
+ system,
7
+ TearDownOptions
8
+ } from '@powersync/service-core';
2
9
 
3
10
  import { MySQLRouteAPIAdapter } from '../api/MySQLRouteAPIAdapter.js';
4
11
  import { BinLogReplicator } from '../replication/BinLogReplicator.js';
@@ -54,10 +61,14 @@ export class MySQLModule extends replication.ReplicationModule<types.MySQLConnec
54
61
  // No specific teardown required for MySQL
55
62
  }
56
63
 
57
- async testConnection(config: MySQLConnectionConfig): Promise<void> {
64
+ async testConnection(config: MySQLConnectionConfig) {
58
65
  this.decodeConfig(config);
59
- const normalisedConfig = this.resolveConfig(this.decodedConfig!);
60
- const connectionManager = new MySQLConnectionManager(normalisedConfig, {});
66
+ const normalizedConfig = this.resolveConfig(this.decodedConfig!);
67
+ return await MySQLModule.testConnection(normalizedConfig);
68
+ }
69
+
70
+ static async testConnection(normalizedConfig: types.ResolvedConnectionConfig): Promise<ConnectionTestResult> {
71
+ const connectionManager = new MySQLConnectionManager(normalizedConfig, {});
61
72
  const connection = await connectionManager.getConnection();
62
73
  try {
63
74
  const errors = await checkSourceConfiguration(connection);
@@ -67,5 +78,8 @@ export class MySQLModule extends replication.ReplicationModule<types.MySQLConnec
67
78
  } finally {
68
79
  await connectionManager.end();
69
80
  }
81
+ return {
82
+ connectionDescription: normalizedConfig.hostname
83
+ };
70
84
  }
71
85
  }
@@ -70,7 +70,7 @@ export class BinLogReplicationJob extends replication.AbstractReplicationJob {
70
70
  if (this.abortController.signal.aborted) {
71
71
  return;
72
72
  }
73
- this.logger.error(`Replication error`, e);
73
+ this.logger.error(`Sync rules ${this.id} Replication error`, e);
74
74
  if (e.cause != null) {
75
75
  this.logger.error(`cause`, e.cause);
76
76
  }
@@ -1,6 +1,7 @@
1
1
  import { replication, storage } from '@powersync/service-core';
2
2
  import { BinLogReplicationJob } from './BinLogReplicationJob.js';
3
3
  import { MySQLConnectionManagerFactory } from './MySQLConnectionManagerFactory.js';
4
+ import { MySQLModule } from '../module/MySQLModule.js';
4
5
 
5
6
  export interface BinLogReplicatorOptions extends replication.AbstractReplicatorOptions {
6
7
  connectionFactory: MySQLConnectionManagerFactory;
@@ -32,4 +33,8 @@ export class BinLogReplicator extends replication.AbstractReplicator<BinLogRepli
32
33
  await super.stop();
33
34
  await this.connectionFactory.shutdown();
34
35
  }
36
+
37
+ async testConnection() {
38
+ return await MySQLModule.testConnection(this.connectionFactory.connectionConfig);
39
+ }
35
40
  }
@@ -1,4 +1,4 @@
1
- import { logger } from '@powersync/lib-services-framework';
1
+ import { logger, ReplicationAbortedError, ReplicationAssertionError } from '@powersync/lib-services-framework';
2
2
  import * as sync_rules from '@powersync/service-sync-rules';
3
3
  import async from 'async';
4
4
 
@@ -318,11 +318,11 @@ AND table_type = 'BASE TABLE';`,
318
318
 
319
319
  for await (let row of stream) {
320
320
  if (this.stopped) {
321
- throw new Error('Abort signal received - initial replication interrupted.');
321
+ throw new ReplicationAbortedError('Abort signal received - initial replication interrupted.');
322
322
  }
323
323
 
324
324
  if (columns == null) {
325
- throw new Error(`No 'fields' event emitted`);
325
+ throw new ReplicationAssertionError(`No 'fields' event emitted`);
326
326
  }
327
327
 
328
328
  const record = common.toSQLiteRow(row, columns!);
@@ -383,7 +383,7 @@ AND table_type = 'BASE TABLE';`,
383
383
  if (table == null) {
384
384
  // We should always receive a replication message before the relation is used.
385
385
  // If we can't find it, it's a bug.
386
- throw new Error(`Missing relation cache for ${tableId}`);
386
+ throw new ReplicationAssertionError(`Missing relation cache for ${tableId}`);
387
387
  }
388
388
  return table;
389
389
  }
@@ -5,7 +5,7 @@ import { ResolvedConnectionConfig } from '../types/types.js';
5
5
 
6
6
  export class MySQLConnectionManagerFactory {
7
7
  private readonly connectionManagers: MySQLConnectionManager[];
8
- private readonly connectionConfig: ResolvedConnectionConfig;
8
+ public readonly connectionConfig: ResolvedConnectionConfig;
9
9
 
10
10
  constructor(connectionConfig: ResolvedConnectionConfig) {
11
11
  this.connectionConfig = connectionConfig;
@@ -1,6 +1,5 @@
1
- import { makeHostnameLookupFunction } from '@powersync/lib-services-framework';
1
+ import { ErrorCode, makeHostnameLookupFunction, ServiceError } from '@powersync/lib-services-framework';
2
2
  import * as service_types from '@powersync/service-types';
3
- import { reject } from 'async';
4
3
  import { LookupFunction } from 'node:net';
5
4
  import * as t from 'ts-codec';
6
5
  import * as urijs from 'uri-js';
@@ -65,7 +64,10 @@ export function normalizeConnectionConfig(options: MySQLConnectionConfig): Norma
65
64
  if (options.uri) {
66
65
  uri = urijs.parse(options.uri);
67
66
  if (uri.scheme != 'mysql') {
68
- throw new Error(`Invalid URI - protocol must be mysql, got ${uri.scheme}`);
67
+ throw new ServiceError(
68
+ ErrorCode.PSYNC_S1109,
69
+ `Invalid URI - protocol must be mysql, got ${JSON.stringify(uri.scheme)}`
70
+ );
69
71
  }
70
72
  } else {
71
73
  uri = urijs.parse('mysql:///');
@@ -82,19 +84,19 @@ export function normalizeConnectionConfig(options: MySQLConnectionConfig): Norma
82
84
  const password = options.password ?? uri_password ?? '';
83
85
 
84
86
  if (hostname == '') {
85
- throw new Error(`hostname required`);
87
+ throw new ServiceError(ErrorCode.PSYNC_S1106, `MySQL connection: hostname required`);
86
88
  }
87
89
 
88
90
  if (username == '') {
89
- throw new Error(`username required`);
91
+ throw new ServiceError(ErrorCode.PSYNC_S1107, `MySQL connection: username required`);
90
92
  }
91
93
 
92
94
  if (password == '') {
93
- throw new Error(`password required`);
95
+ throw new ServiceError(ErrorCode.PSYNC_S1108, `MySQL connection: password required`);
94
96
  }
95
97
 
96
98
  if (database == '') {
97
- throw new Error(`database required`);
99
+ throw new ServiceError(ErrorCode.PSYNC_S1105, `MySQL connection: database required`);
98
100
  }
99
101
 
100
102
  const lookup = makeHostnameLookupFunction(hostname, { reject_ip_ranges: options.reject_ip_ranges ?? [] });
@@ -61,7 +61,7 @@ export class BinlogStreamTestContext {
61
61
  }
62
62
 
63
63
  async updateSyncRules(content: string): Promise<SyncRulesBucketStorage> {
64
- const syncRules = await this.factory.updateSyncRules({ content: content });
64
+ const syncRules = await this.factory.updateSyncRules({ content: content, validate: true });
65
65
  this.storage = this.factory.getInstance(syncRules);
66
66
  return this.storage!;
67
67
  }