@powersync/service-core 1.16.3 → 1.18.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.
- package/CHANGELOG.md +33 -0
- package/dist/api/diagnostics.js +17 -8
- package/dist/api/diagnostics.js.map +1 -1
- package/dist/modules/loader.d.ts +14 -0
- package/dist/modules/loader.js +34 -0
- package/dist/modules/loader.js.map +1 -0
- package/dist/modules/modules-index.d.ts +1 -0
- package/dist/modules/modules-index.js +1 -0
- package/dist/modules/modules-index.js.map +1 -1
- package/dist/routes/configure-fastify.d.ts +26 -0
- package/dist/routes/endpoints/admin.d.ts +42 -0
- package/dist/routes/endpoints/admin.js +2 -2
- package/dist/routes/endpoints/admin.js.map +1 -1
- package/dist/routes/endpoints/socket-route.js +7 -0
- package/dist/routes/endpoints/socket-route.js.map +1 -1
- package/dist/routes/endpoints/sync-stream.d.ts +10 -0
- package/dist/routes/endpoints/sync-stream.js +10 -1
- package/dist/routes/endpoints/sync-stream.js.map +1 -1
- package/dist/storage/BucketStorageBatch.d.ts +1 -0
- package/dist/storage/BucketStorageBatch.js.map +1 -1
- package/dist/storage/PersistedSyncRulesContent.d.ts +1 -0
- package/dist/storage/ReportStorage.d.ts +5 -0
- package/dist/storage/SyncRulesBucketStorage.d.ts +1 -1
- package/dist/sync/sync.d.ts +2 -2
- package/dist/sync/sync.js +2 -2
- package/dist/sync/sync.js.map +1 -1
- package/dist/util/param-logging.d.ts +23 -0
- package/dist/util/param-logging.js +40 -0
- package/dist/util/param-logging.js.map +1 -0
- package/dist/util/protocol-types.d.ts +6 -2
- package/dist/util/protocol-types.js +4 -0
- package/dist/util/protocol-types.js.map +1 -1
- package/package.json +6 -6
- package/src/api/diagnostics.ts +20 -11
- package/src/modules/loader.ts +47 -0
- package/src/modules/modules-index.ts +1 -0
- package/src/routes/endpoints/admin.ts +2 -2
- package/src/routes/endpoints/socket-route.ts +9 -0
- package/src/routes/endpoints/sync-stream.ts +13 -1
- package/src/storage/BucketStorageBatch.ts +2 -0
- package/src/storage/PersistedSyncRulesContent.ts +1 -0
- package/src/storage/ReportStorage.ts +7 -0
- package/src/storage/SyncRulesBucketStorage.ts +1 -1
- package/src/sync/sync.ts +4 -10
- package/src/util/param-logging.ts +60 -0
- package/src/util/protocol-types.ts +7 -2
- package/test/src/module-loader.test.ts +102 -0
- package/test/src/routes/stream.test.ts +94 -1
- package/tsconfig.tsbuildinfo +1 -1
package/dist/sync/sync.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/sync/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/sync/sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for {@link limitParamsForLogging}.
|
|
3
|
+
*/
|
|
4
|
+
export type ParamLoggingFormatOptions = {
|
|
5
|
+
maxKeyCount: number;
|
|
6
|
+
maxStringLength: number;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Default options for {@link limitParamsForLogging}.
|
|
10
|
+
*/
|
|
11
|
+
export declare const DEFAULT_PARAM_LOGGING_FORMAT_OPTIONS: ParamLoggingFormatOptions;
|
|
12
|
+
/**
|
|
13
|
+
* Formats potentially arbitrary parameters for logging.
|
|
14
|
+
* This limits the number of keys and strings to a maximum length.
|
|
15
|
+
* A warning key-value is added if the number of keys exceeds the maximum.
|
|
16
|
+
* String values exceeding the maximum length are truncated.
|
|
17
|
+
* Non-String values are stringified, the maximum length is then applied.
|
|
18
|
+
* @param params - The parameters to format.
|
|
19
|
+
* @param options - The options to use.
|
|
20
|
+
* @default DEFAULT_PARAM_LOGGING_FORMAT_OPTIONS
|
|
21
|
+
* @returns The formatted parameters.
|
|
22
|
+
*/
|
|
23
|
+
export declare function limitParamsForLogging(params: Record<string, any>, options?: Partial<ParamLoggingFormatOptions>): any;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default options for {@link limitParamsForLogging}.
|
|
3
|
+
*/
|
|
4
|
+
export const DEFAULT_PARAM_LOGGING_FORMAT_OPTIONS = {
|
|
5
|
+
maxKeyCount: 20,
|
|
6
|
+
maxStringLength: 100
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Formats potentially arbitrary parameters for logging.
|
|
10
|
+
* This limits the number of keys and strings to a maximum length.
|
|
11
|
+
* A warning key-value is added if the number of keys exceeds the maximum.
|
|
12
|
+
* String values exceeding the maximum length are truncated.
|
|
13
|
+
* Non-String values are stringified, the maximum length is then applied.
|
|
14
|
+
* @param params - The parameters to format.
|
|
15
|
+
* @param options - The options to use.
|
|
16
|
+
* @default DEFAULT_PARAM_LOGGING_FORMAT_OPTIONS
|
|
17
|
+
* @returns The formatted parameters.
|
|
18
|
+
*/
|
|
19
|
+
export function limitParamsForLogging(params, options = DEFAULT_PARAM_LOGGING_FORMAT_OPTIONS) {
|
|
20
|
+
const { maxStringLength = DEFAULT_PARAM_LOGGING_FORMAT_OPTIONS.maxStringLength, maxKeyCount = DEFAULT_PARAM_LOGGING_FORMAT_OPTIONS.maxKeyCount } = options;
|
|
21
|
+
function trimString(value) {
|
|
22
|
+
if (value.length > maxStringLength) {
|
|
23
|
+
return value.slice(0, maxStringLength - 3) + '...';
|
|
24
|
+
}
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
return Object.fromEntries(Object.entries(params).map(([key, value], index) => {
|
|
28
|
+
if (index == maxKeyCount) {
|
|
29
|
+
return ['⚠️', 'Additional parameters omitted'];
|
|
30
|
+
}
|
|
31
|
+
if (index > maxKeyCount) {
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
if (typeof value == 'string') {
|
|
35
|
+
return [key, trimString(value)];
|
|
36
|
+
}
|
|
37
|
+
return [key, trimString(JSON.stringify(value))];
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=param-logging.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"param-logging.js","sourceRoot":"","sources":["../../src/util/param-logging.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,MAAM,CAAC,MAAM,oCAAoC,GAA8B;IAC7E,WAAW,EAAE,EAAE;IACf,eAAe,EAAE,GAAG;CACrB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,UAAU,qBAAqB,CACnC,MAA2B,EAC3B,UAA8C,oCAAoC;IAElF,MAAM,EACJ,eAAe,GAAG,oCAAoC,CAAC,eAAe,EACtE,WAAW,GAAG,oCAAoC,CAAC,WAAW,EAC/D,GAAG,OAAO,CAAC;IAEZ,SAAS,UAAU,CAAC,KAAa;QAC/B,IAAI,KAAK,CAAC,MAAM,GAAG,eAAe,EAAE,CAAC;YACnC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;QACrD,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE;QACjD,IAAI,KAAK,IAAI,WAAW,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,EAAE,+BAA+B,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,KAAK,GAAG,WAAW,EAAE,CAAC;YACxB,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,IAAI,OAAO,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as t from 'ts-codec';
|
|
2
|
-
import { BucketPriority, SqliteJsonRow } from '@powersync/service-sync-rules';
|
|
3
1
|
import { JsonContainer } from '@powersync/service-jsonbig';
|
|
2
|
+
import { BucketPriority, SqliteJsonRow } from '@powersync/service-sync-rules';
|
|
3
|
+
import * as t from 'ts-codec';
|
|
4
4
|
export declare const BucketRequest: t.ObjectCodec<{
|
|
5
5
|
name: t.IdentityCodec<t.CodecType.String>;
|
|
6
6
|
/**
|
|
@@ -89,6 +89,10 @@ export declare const StreamingSyncRequest: t.ObjectCodec<{
|
|
|
89
89
|
* Client parameters to be passed to the sync rules.
|
|
90
90
|
*/
|
|
91
91
|
parameters: t.OptionalCodec<t.Codec<Record<string, any>, Record<string, any>, string, t.CodecProps>>;
|
|
92
|
+
/**
|
|
93
|
+
* Application metadata to be used in logging.
|
|
94
|
+
*/
|
|
95
|
+
app_metadata: t.OptionalCodec<t.Codec<Record<string, string>, Record<string, string>, string, t.CodecProps>>;
|
|
92
96
|
/**
|
|
93
97
|
* Unique client id.
|
|
94
98
|
*/
|
|
@@ -62,6 +62,10 @@ export const StreamingSyncRequest = t.object({
|
|
|
62
62
|
* Client parameters to be passed to the sync rules.
|
|
63
63
|
*/
|
|
64
64
|
parameters: t.record(t.any).optional(),
|
|
65
|
+
/**
|
|
66
|
+
* Application metadata to be used in logging.
|
|
67
|
+
*/
|
|
68
|
+
app_metadata: t.record(t.string).optional(),
|
|
65
69
|
/**
|
|
66
70
|
* Unique client id.
|
|
67
71
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol-types.js","sourceRoot":"","sources":["../../src/util/protocol-types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"protocol-types.js","sourceRoot":"","sources":["../../src/util/protocol-types.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAE9B,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,IAAI,EAAE,CAAC,CAAC,MAAM;IAEd;;OAEG;IACH,KAAK,EAAE,CAAC,CAAC,MAAM;CAChB,CAAC,CAAC;AAIH;;GAEG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,CAAC;IAClD;;OAEG;IACH,MAAM,EAAE,CAAC,CAAC,MAAM;IAChB;;OAEG;IACH,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC;IAC5C;;;;;OAKG;IACH,iBAAiB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC;CAC7C,CAAC,CAAC;AAIH;;GAEG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD;;;;OAIG;IACH,gBAAgB,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE;IAEtC;;OAEG;IACH,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,2BAA2B,CAAC;CACpD,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C;;OAEG;IACH,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,QAAQ,EAAE;IAE1C;;OAEG;IACH,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE;IAElC;;OAEG;IACH,gBAAgB,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE;IAEtC;;OAEG;IACH,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE;IAE9B;;OAEG;IACH,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IAEtC;;OAEG;IACH,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE;IAE3C;;OAEG;IACH,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE;IAE9B;;OAEG;IACH,OAAO,EAAE,yBAAyB,CAAC,QAAQ,EAAE;CAC9C,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
8
|
-
"version": "1.
|
|
8
|
+
"version": "1.18.0",
|
|
9
9
|
"main": "dist/index.js",
|
|
10
10
|
"license": "FSL-1.1-ALv2",
|
|
11
11
|
"type": "module",
|
|
@@ -33,11 +33,11 @@
|
|
|
33
33
|
"uuid": "^11.1.0",
|
|
34
34
|
"winston": "^3.13.0",
|
|
35
35
|
"yaml": "^2.3.2",
|
|
36
|
-
"@powersync/lib-services-framework": "0.7.
|
|
37
|
-
"@powersync/service-
|
|
38
|
-
"@powersync/service-
|
|
39
|
-
"@powersync/service-
|
|
40
|
-
"@powersync/service-
|
|
36
|
+
"@powersync/lib-services-framework": "0.7.12",
|
|
37
|
+
"@powersync/service-rsocket-router": "0.2.9",
|
|
38
|
+
"@powersync/service-sync-rules": "0.29.8",
|
|
39
|
+
"@powersync/service-types": "0.13.3",
|
|
40
|
+
"@powersync/service-jsonbig": "0.17.12"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/async": "^3.2.24",
|
package/src/api/diagnostics.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { logger } from '@powersync/lib-services-framework';
|
|
2
2
|
import { DEFAULT_TAG, SourceTableInterface, SqlSyncRules } from '@powersync/service-sync-rules';
|
|
3
|
-
import { SyncRulesStatus, TableInfo } from '@powersync/service-types';
|
|
3
|
+
import { ReplicationError, SyncRulesStatus, TableInfo } from '@powersync/service-types';
|
|
4
4
|
|
|
5
5
|
import * as storage from '../storage/storage-index.js';
|
|
6
6
|
import { RouteAPI } from './RouteAPI.js';
|
|
@@ -39,6 +39,7 @@ export async function getSyncRulesStatus(
|
|
|
39
39
|
const include_content = options.include_content ?? false;
|
|
40
40
|
const live_status = options.live_status ?? false;
|
|
41
41
|
const check_connection = options.check_connection ?? false;
|
|
42
|
+
const now = new Date().toISOString();
|
|
42
43
|
|
|
43
44
|
let rules: SqlSyncRules;
|
|
44
45
|
let persisted: storage.PersistedSyncRules;
|
|
@@ -49,7 +50,7 @@ export async function getSyncRulesStatus(
|
|
|
49
50
|
return {
|
|
50
51
|
content: include_content ? sync_rules.sync_rules_content : undefined,
|
|
51
52
|
connections: [],
|
|
52
|
-
errors: [{ level: 'fatal', message: e.message }]
|
|
53
|
+
errors: [{ level: 'fatal', message: e.message, ts: now }]
|
|
53
54
|
};
|
|
54
55
|
}
|
|
55
56
|
|
|
@@ -99,7 +100,7 @@ export async function getSyncRulesStatus(
|
|
|
99
100
|
data_queries: false,
|
|
100
101
|
parameter_queries: false,
|
|
101
102
|
replication_id: [],
|
|
102
|
-
errors: [{ level: 'fatal', message: 'connection failed' }]
|
|
103
|
+
errors: [{ level: 'fatal', message: 'connection failed', ts: now }]
|
|
103
104
|
};
|
|
104
105
|
} else {
|
|
105
106
|
const source: SourceTableInterface = {
|
|
@@ -115,7 +116,7 @@ export async function getSyncRulesStatus(
|
|
|
115
116
|
data_queries: syncData,
|
|
116
117
|
parameter_queries: syncParameters,
|
|
117
118
|
replication_id: [],
|
|
118
|
-
errors: [{ level: 'fatal', message: 'connection failed' }]
|
|
119
|
+
errors: [{ level: 'fatal', message: 'connection failed', ts: now }]
|
|
119
120
|
};
|
|
120
121
|
}
|
|
121
122
|
});
|
|
@@ -123,13 +124,18 @@ export async function getSyncRulesStatus(
|
|
|
123
124
|
|
|
124
125
|
const errors = tables_flat.flatMap((info) => info.errors);
|
|
125
126
|
if (sync_rules.last_fatal_error) {
|
|
126
|
-
errors.push({
|
|
127
|
+
errors.push({
|
|
128
|
+
level: 'fatal',
|
|
129
|
+
message: sync_rules.last_fatal_error,
|
|
130
|
+
ts: sync_rules.last_fatal_error_ts?.toISOString()
|
|
131
|
+
});
|
|
127
132
|
}
|
|
128
133
|
errors.push(
|
|
129
134
|
...rules.errors.map((e) => {
|
|
130
135
|
return {
|
|
131
136
|
level: e.type,
|
|
132
|
-
message: e.message
|
|
137
|
+
message: e.message,
|
|
138
|
+
ts: now
|
|
133
139
|
};
|
|
134
140
|
})
|
|
135
141
|
);
|
|
@@ -140,7 +146,8 @@ export async function getSyncRulesStatus(
|
|
|
140
146
|
if (sync_rules.last_checkpoint_ts == null && sync_rules.last_keepalive_ts == null) {
|
|
141
147
|
errors.push({
|
|
142
148
|
level: 'warning',
|
|
143
|
-
message: 'No checkpoint found, cannot calculate replication lag'
|
|
149
|
+
message: 'No checkpoint found, cannot calculate replication lag',
|
|
150
|
+
ts: now
|
|
144
151
|
});
|
|
145
152
|
} else {
|
|
146
153
|
const lastTime = Math.max(
|
|
@@ -155,12 +162,14 @@ export async function getSyncRulesStatus(
|
|
|
155
162
|
if (lagSeconds > 15 * 60) {
|
|
156
163
|
errors.push({
|
|
157
164
|
level: 'fatal',
|
|
158
|
-
message: `No replicated commit in more than ${lagSeconds}s
|
|
165
|
+
message: `No replicated commit in more than ${lagSeconds}s`,
|
|
166
|
+
ts: now
|
|
159
167
|
});
|
|
160
168
|
} else if (lagSeconds > 5 * 60) {
|
|
161
169
|
errors.push({
|
|
162
170
|
level: 'warning',
|
|
163
|
-
message: `No replicated commit in more than ${lagSeconds}s
|
|
171
|
+
message: `No replicated commit in more than ${lagSeconds}s`,
|
|
172
|
+
ts: now
|
|
164
173
|
});
|
|
165
174
|
}
|
|
166
175
|
}
|
|
@@ -186,9 +195,9 @@ export async function getSyncRulesStatus(
|
|
|
186
195
|
};
|
|
187
196
|
}
|
|
188
197
|
|
|
189
|
-
function deduplicate(errors:
|
|
198
|
+
function deduplicate(errors: ReplicationError[]): ReplicationError[] {
|
|
190
199
|
let seen = new Set<string>();
|
|
191
|
-
let result:
|
|
200
|
+
let result: ReplicationError[] = [];
|
|
192
201
|
for (let error of errors) {
|
|
193
202
|
const key = JSON.stringify(error);
|
|
194
203
|
if (seen.has(key)) {
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ResolvedPowerSyncConfig } from '../util/util-index.js';
|
|
2
|
+
import { AbstractModule } from './AbstractModule.js';
|
|
3
|
+
|
|
4
|
+
interface DynamicModuleMap {
|
|
5
|
+
[key: string]: () => Promise<AbstractModule>;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface ModuleLoaders {
|
|
9
|
+
storage: DynamicModuleMap;
|
|
10
|
+
connection: DynamicModuleMap;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Utility function to dynamically load and instantiate modules.
|
|
14
|
+
*/
|
|
15
|
+
export async function loadModules(config: ResolvedPowerSyncConfig, loaders: ModuleLoaders) {
|
|
16
|
+
const requiredConnections = [...new Set(config.connections?.map((connection) => connection.type) || [])];
|
|
17
|
+
const missingConnectionModules: string[] = [];
|
|
18
|
+
const modulePromises: Promise<AbstractModule>[] = [];
|
|
19
|
+
|
|
20
|
+
// 1. Map connection types to their module loading promises making note of any
|
|
21
|
+
// missing connection types.
|
|
22
|
+
requiredConnections.forEach((connectionType) => {
|
|
23
|
+
const modulePromise = loaders.connection[connectionType];
|
|
24
|
+
if (modulePromise !== undefined) {
|
|
25
|
+
modulePromises.push(modulePromise());
|
|
26
|
+
} else {
|
|
27
|
+
missingConnectionModules.push(connectionType);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// Fail if any connection types are not found.
|
|
32
|
+
if (missingConnectionModules.length > 0) {
|
|
33
|
+
throw new Error(`Invalid connection types: "${[...missingConnectionModules].join(', ')}"`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (loaders.storage[config.storage.type] !== undefined) {
|
|
37
|
+
modulePromises.push(loaders.storage[config.storage.type]());
|
|
38
|
+
} else {
|
|
39
|
+
throw new Error(`Invalid storage type: "${config.storage.type}"`);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 2. Dynamically import and instantiate module classes and resolve all promises
|
|
43
|
+
// raising errors if any modules could not be imported.
|
|
44
|
+
const moduleInstances = await Promise.all(modulePromises);
|
|
45
|
+
|
|
46
|
+
return moduleInstances;
|
|
47
|
+
}
|
|
@@ -189,7 +189,7 @@ export const validate = routeDefinition({
|
|
|
189
189
|
const connectionStatus = await apiHandler.getConnectionStatus();
|
|
190
190
|
if (!connectionStatus) {
|
|
191
191
|
return internal_routes.ValidateResponse.encode({
|
|
192
|
-
errors: [{ level: 'fatal', message: 'No connection configured' }],
|
|
192
|
+
errors: [{ level: 'fatal', message: 'No connection configured', ts: new Date().toISOString() }],
|
|
193
193
|
connections: []
|
|
194
194
|
});
|
|
195
195
|
}
|
|
@@ -206,7 +206,7 @@ export const validate = routeDefinition({
|
|
|
206
206
|
))!;
|
|
207
207
|
|
|
208
208
|
if (connectionStatus == null) {
|
|
209
|
-
status.errors.push({ level: 'fatal', message: 'No connection configured' });
|
|
209
|
+
status.errors.push({ level: 'fatal', message: 'No connection configured', ts: new Date().toISOString() });
|
|
210
210
|
}
|
|
211
211
|
|
|
212
212
|
return internal_routes.ValidateResponse.encode(status);
|
|
@@ -6,6 +6,7 @@ import { SocketRouteGenerator } from '../router-socket.js';
|
|
|
6
6
|
import { SyncRoutes } from './sync-stream.js';
|
|
7
7
|
|
|
8
8
|
import { APIMetric, event_types } from '@powersync/service-types';
|
|
9
|
+
import { limitParamsForLogging } from '../../util/param-logging.js';
|
|
9
10
|
|
|
10
11
|
export const syncStreamReactive: SocketRouteGenerator = (router) =>
|
|
11
12
|
router.reactiveStream<util.StreamingSyncRequest, any>(SyncRoutes.STREAM, {
|
|
@@ -97,6 +98,13 @@ export const syncStreamReactive: SocketRouteGenerator = (router) =>
|
|
|
97
98
|
// Must be set before we start the stream
|
|
98
99
|
tracker.setCompressed(connection.tracker.encoding);
|
|
99
100
|
}
|
|
101
|
+
|
|
102
|
+
const formattedAppMetadata = params.app_metadata ? limitParamsForLogging(params.app_metadata) : undefined;
|
|
103
|
+
logger.info('Sync stream started', {
|
|
104
|
+
app_metadata: formattedAppMetadata,
|
|
105
|
+
client_params: params.parameters ? limitParamsForLogging(params.parameters) : undefined
|
|
106
|
+
});
|
|
107
|
+
|
|
100
108
|
try {
|
|
101
109
|
for await (const data of sync.streamResponse({
|
|
102
110
|
syncContext: syncContext,
|
|
@@ -179,6 +187,7 @@ export const syncStreamReactive: SocketRouteGenerator = (router) =>
|
|
|
179
187
|
}
|
|
180
188
|
logger.info(`Sync stream complete`, {
|
|
181
189
|
...tracker.getLogMeta(),
|
|
190
|
+
app_metadata: formattedAppMetadata,
|
|
182
191
|
stream_ms: Date.now() - streamStart,
|
|
183
192
|
close_reason: closeReason ?? 'unknown'
|
|
184
193
|
});
|
|
@@ -5,10 +5,11 @@ import { Readable } from 'stream';
|
|
|
5
5
|
import * as sync from '../../sync/sync-index.js';
|
|
6
6
|
import * as util from '../../util/util-index.js';
|
|
7
7
|
|
|
8
|
+
import { APIMetric, event_types } from '@powersync/service-types';
|
|
8
9
|
import { authUser } from '../auth.js';
|
|
9
10
|
import { routeDefinition } from '../router.js';
|
|
10
|
-
import { APIMetric, event_types } from '@powersync/service-types';
|
|
11
11
|
|
|
12
|
+
import { limitParamsForLogging } from '../../util/param-logging.js';
|
|
12
13
|
import { maybeCompressResponseStream } from '../compression.js';
|
|
13
14
|
|
|
14
15
|
export enum SyncRoutes {
|
|
@@ -75,6 +76,16 @@ export const syncStreamed = routeDefinition({
|
|
|
75
76
|
|
|
76
77
|
const controller = new AbortController();
|
|
77
78
|
const tracker = new sync.RequestTracker(metricsEngine);
|
|
79
|
+
|
|
80
|
+
const formattedAppMetadata = payload.params.app_metadata
|
|
81
|
+
? limitParamsForLogging(payload.params.app_metadata)
|
|
82
|
+
: undefined;
|
|
83
|
+
|
|
84
|
+
logger.info('Sync stream started', {
|
|
85
|
+
app_metadata: formattedAppMetadata,
|
|
86
|
+
client_params: payload.params.parameters ? limitParamsForLogging(payload.params.parameters) : undefined
|
|
87
|
+
});
|
|
88
|
+
|
|
78
89
|
try {
|
|
79
90
|
metricsEngine.getUpDownCounter(APIMetric.CONCURRENT_CONNECTIONS).add(1);
|
|
80
91
|
service_context.eventsEngine.emit(event_types.EventsEngineEventType.SDK_CONNECT_EVENT, sdkData);
|
|
@@ -149,6 +160,7 @@ export const syncStreamed = routeDefinition({
|
|
|
149
160
|
});
|
|
150
161
|
logger.info(`Sync stream complete`, {
|
|
151
162
|
...tracker.getLogMeta(),
|
|
163
|
+
app_metadata: formattedAppMetadata,
|
|
152
164
|
stream_ms: Date.now() - streamStart,
|
|
153
165
|
close_reason: closeReason ?? 'unknown'
|
|
154
166
|
});
|
|
@@ -83,6 +83,8 @@ export interface BucketStorageBatch extends ObserverClient<BucketBatchStorageLis
|
|
|
83
83
|
*/
|
|
84
84
|
resumeFromLsn: string | null;
|
|
85
85
|
|
|
86
|
+
noCheckpointBeforeLsn: string;
|
|
87
|
+
|
|
86
88
|
markSnapshotDone(tables: SourceTable[], no_checkpoint_before_lsn: string): Promise<SourceTable[]>;
|
|
87
89
|
|
|
88
90
|
updateTableProgress(table: SourceTable, progress: Partial<TableSnapshotStatus>): Promise<SourceTable>;
|
|
@@ -17,6 +17,7 @@ export interface PersistedSyncRulesContent {
|
|
|
17
17
|
readonly last_checkpoint_lsn: string | null;
|
|
18
18
|
|
|
19
19
|
readonly last_fatal_error?: string | null;
|
|
20
|
+
readonly last_fatal_error_ts?: Date | null;
|
|
20
21
|
readonly last_keepalive_ts?: Date | null;
|
|
21
22
|
readonly last_checkpoint_ts?: Date | null;
|
|
22
23
|
|
|
@@ -31,6 +31,13 @@ export interface ReportStorage extends AsyncDisposable {
|
|
|
31
31
|
getClientConnectionReports(
|
|
32
32
|
data: event_types.ClientConnectionReportRequest
|
|
33
33
|
): Promise<event_types.ClientConnectionReportResponse>;
|
|
34
|
+
/**
|
|
35
|
+
* Get a paginated list of client connection events
|
|
36
|
+
* This will return a paginated list of connections for a client/ user ID or all if neither is provided, within a date range if provided
|
|
37
|
+
*/
|
|
38
|
+
getGeneralClientConnectionAnalytics(
|
|
39
|
+
data: event_types.ClientConnectionAnalyticsRequest
|
|
40
|
+
): Promise<event_types.PaginatedResponse<event_types.ClientConnection>>;
|
|
34
41
|
/**
|
|
35
42
|
* Delete old connection data based on a specific date.
|
|
36
43
|
* This is used to clean up old connection data that is no longer needed.
|
|
@@ -56,7 +56,7 @@ export interface SyncRulesBucketStorage
|
|
|
56
56
|
* This could be a recoverable error (e.g. temporary network failure),
|
|
57
57
|
* or a permanent error (e.g. missing toast data).
|
|
58
58
|
*
|
|
59
|
-
* Errors are cleared on
|
|
59
|
+
* Errors are cleared on flush.
|
|
60
60
|
*/
|
|
61
61
|
reportError(e: any): Promise<void>;
|
|
62
62
|
|
package/src/sync/sync.ts
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import { JSONBig, JsonContainer } from '@powersync/service-jsonbig';
|
|
2
|
-
import {
|
|
3
|
-
BucketDescription,
|
|
4
|
-
BucketPriority,
|
|
5
|
-
RequestJwtPayload,
|
|
6
|
-
RequestParameters,
|
|
7
|
-
SqlSyncRules
|
|
8
|
-
} from '@powersync/service-sync-rules';
|
|
2
|
+
import { BucketDescription, BucketPriority, RequestJwtPayload } from '@powersync/service-sync-rules';
|
|
9
3
|
|
|
10
4
|
import { AbortError } from 'ix/aborterror.js';
|
|
11
5
|
|
|
@@ -14,11 +8,11 @@ import * as storage from '../storage/storage-index.js';
|
|
|
14
8
|
import * as util from '../util/util-index.js';
|
|
15
9
|
|
|
16
10
|
import { Logger, logger as defaultLogger } from '@powersync/lib-services-framework';
|
|
17
|
-
import { BucketChecksumState, CheckpointLine, VersionedSyncRules } from './BucketChecksumState.js';
|
|
18
11
|
import { mergeAsyncIterables } from '../streams/streams-index.js';
|
|
19
|
-
import {
|
|
20
|
-
import { SyncContext } from './SyncContext.js';
|
|
12
|
+
import { BucketChecksumState, CheckpointLine, VersionedSyncRules } from './BucketChecksumState.js';
|
|
21
13
|
import { OperationsSentStats, RequestTracker, statsForBatch } from './RequestTracker.js';
|
|
14
|
+
import { SyncContext } from './SyncContext.js';
|
|
15
|
+
import { TokenStreamOptions, acquireSemaphoreAbortable, settledPromise, tokenStream } from './util.js';
|
|
22
16
|
|
|
23
17
|
export interface SyncStreamParameters {
|
|
24
18
|
syncContext: SyncContext;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for {@link limitParamsForLogging}.
|
|
3
|
+
*/
|
|
4
|
+
export type ParamLoggingFormatOptions = {
|
|
5
|
+
maxKeyCount: number;
|
|
6
|
+
maxStringLength: number;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Default options for {@link limitParamsForLogging}.
|
|
11
|
+
*/
|
|
12
|
+
export const DEFAULT_PARAM_LOGGING_FORMAT_OPTIONS: ParamLoggingFormatOptions = {
|
|
13
|
+
maxKeyCount: 20,
|
|
14
|
+
maxStringLength: 100
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Formats potentially arbitrary parameters for logging.
|
|
19
|
+
* This limits the number of keys and strings to a maximum length.
|
|
20
|
+
* A warning key-value is added if the number of keys exceeds the maximum.
|
|
21
|
+
* String values exceeding the maximum length are truncated.
|
|
22
|
+
* Non-String values are stringified, the maximum length is then applied.
|
|
23
|
+
* @param params - The parameters to format.
|
|
24
|
+
* @param options - The options to use.
|
|
25
|
+
* @default DEFAULT_PARAM_LOGGING_FORMAT_OPTIONS
|
|
26
|
+
* @returns The formatted parameters.
|
|
27
|
+
*/
|
|
28
|
+
export function limitParamsForLogging(
|
|
29
|
+
params: Record<string, any>,
|
|
30
|
+
options: Partial<ParamLoggingFormatOptions> = DEFAULT_PARAM_LOGGING_FORMAT_OPTIONS
|
|
31
|
+
) {
|
|
32
|
+
const {
|
|
33
|
+
maxStringLength = DEFAULT_PARAM_LOGGING_FORMAT_OPTIONS.maxStringLength,
|
|
34
|
+
maxKeyCount = DEFAULT_PARAM_LOGGING_FORMAT_OPTIONS.maxKeyCount
|
|
35
|
+
} = options;
|
|
36
|
+
|
|
37
|
+
function trimString(value: string): string {
|
|
38
|
+
if (value.length > maxStringLength) {
|
|
39
|
+
return value.slice(0, maxStringLength - 3) + '...';
|
|
40
|
+
}
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return Object.fromEntries(
|
|
45
|
+
Object.entries(params).map(([key, value], index) => {
|
|
46
|
+
if (index == maxKeyCount) {
|
|
47
|
+
return ['⚠️', 'Additional parameters omitted'];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (index > maxKeyCount) {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (typeof value == 'string') {
|
|
55
|
+
return [key, trimString(value)];
|
|
56
|
+
}
|
|
57
|
+
return [key, trimString(JSON.stringify(value))];
|
|
58
|
+
})
|
|
59
|
+
);
|
|
60
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as t from 'ts-codec';
|
|
2
|
-
import { BucketPriority, SqliteJsonRow } from '@powersync/service-sync-rules';
|
|
3
1
|
import { JsonContainer } from '@powersync/service-jsonbig';
|
|
2
|
+
import { BucketPriority, SqliteJsonRow } from '@powersync/service-sync-rules';
|
|
3
|
+
import * as t from 'ts-codec';
|
|
4
4
|
|
|
5
5
|
export const BucketRequest = t.object({
|
|
6
6
|
name: t.string,
|
|
@@ -81,6 +81,11 @@ export const StreamingSyncRequest = t.object({
|
|
|
81
81
|
*/
|
|
82
82
|
parameters: t.record(t.any).optional(),
|
|
83
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Application metadata to be used in logging.
|
|
86
|
+
*/
|
|
87
|
+
app_metadata: t.record(t.string).optional(),
|
|
88
|
+
|
|
84
89
|
/**
|
|
85
90
|
* Unique client id.
|
|
86
91
|
*/
|