@trainstar/synchro-react-native 0.3.2 → 0.4.0-rc.2
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/README.md +112 -7
- package/SynchroReactNative.podspec +18 -1
- package/android/build.gradle +5 -1
- package/android/src/androidTest/kotlin/com/trainstar/synchro/rn/SynchroModuleTransactionTest.kt +593 -0
- package/android/src/androidTest/kotlin/com/trainstar/synchro/rn/TransactionSessionTest.kt +314 -0
- package/android/src/main/kotlin/com/trainstar/synchro/rn/SynchroModule.kt +328 -112
- package/ios/SynchroModule.mm +27 -4
- package/ios/SynchroModule.swift +251 -89
- package/ios-test-host/main.m +48 -0
- package/ios-tests/SynchroModuleTransactionTests.swift +709 -0
- package/ios-tests/TransactionSessionTests.swift +66 -0
- package/lib/module/NativeSynchro.js.map +1 -1
- package/lib/module/SynchroClient.js +141 -2
- package/lib/module/SynchroClient.js.map +1 -1
- package/lib/module/errors.js +15 -1
- package/lib/module/errors.js.map +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/inspection.js +99 -8
- package/lib/module/inspection.js.map +1 -1
- package/lib/module/types.js +18 -0
- package/lib/module/types.js.map +1 -1
- package/lib/typescript/example/e2e/schema-check.test.d.ts +2 -0
- package/lib/typescript/example/e2e/schema-check.test.d.ts.map +1 -0
- package/lib/typescript/example/src/conformance/runner.d.ts +17 -2
- package/lib/typescript/example/src/conformance/runner.d.ts.map +1 -1
- package/lib/typescript/src/NativeSynchro.d.ts +7 -1
- package/lib/typescript/src/NativeSynchro.d.ts.map +1 -1
- package/lib/typescript/src/SynchroClient.d.ts +29 -1
- package/lib/typescript/src/SynchroClient.d.ts.map +1 -1
- package/lib/typescript/src/errors.d.ts +7 -1
- package/lib/typescript/src/errors.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +3 -3
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/inspection.d.ts +23 -5
- package/lib/typescript/src/inspection.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +62 -1
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +21 -6
- package/src/NativeSynchro.ts +6 -1
- package/src/SynchroClient.ts +160 -1
- package/src/errors.ts +30 -0
- package/src/index.ts +7 -0
- package/src/inspection.ts +138 -9
- package/src/types.ts +70 -1
- package/tooling-patches/apply.cjs +163 -0
- package/tooling-patches/cli-clean-20.2.0.patch +21 -0
- package/tooling-patches/cli-config-android-20.2.0.patch +13 -0
- package/tooling-patches/react-native-builder-bob-0.40.18.patch +74 -0
- package/tooling-patches/stream-json-1.9.1.patch +40 -0
|
@@ -82,7 +82,7 @@ export type JSONValue = null | boolean | number | string | JSONValue[] | {
|
|
|
82
82
|
export type MutationOperation = 'insert' | 'upsert' | 'update' | 'delete';
|
|
83
83
|
export type LocalMutationStatus = 'pending' | 'sealed' | 'superseded_before_send' | 'cancelled_before_send' | 'blocked_by_predecessor' | 'server_rejected' | 'exceeds_push_limit';
|
|
84
84
|
export type MutationStatus = 'applied' | 'conflict' | 'rejected_terminal';
|
|
85
|
-
export type MutationRejectionCode = 'version_conflict' | 'row_already_exists' | 'row_deleted' | 'row_not_found' | 'schema_incompatible' | 'policy_rejected' | 'validation_failed' | 'table_not_synced';
|
|
85
|
+
export type MutationRejectionCode = 'version_conflict' | 'row_already_exists' | 'row_deleted' | 'row_not_found' | 'schema_incompatible' | 'policy_rejected' | 'validation_failed' | 'table_not_synced' | 'atomic_batch_rejected';
|
|
86
86
|
export interface SchemaRef {
|
|
87
87
|
version: number;
|
|
88
88
|
hash: string;
|
|
@@ -92,6 +92,7 @@ export interface AuthoredMutationField {
|
|
|
92
92
|
logicalType: string;
|
|
93
93
|
value: JSONValue;
|
|
94
94
|
}
|
|
95
|
+
/** A retained mutation with its complete ledger binding and authored values. */
|
|
95
96
|
export interface PendingMutationInspection {
|
|
96
97
|
mutationID: string;
|
|
97
98
|
localOrder: number;
|
|
@@ -112,6 +113,27 @@ export interface PendingMutationInspection {
|
|
|
112
113
|
sealedOrdinal: number | null;
|
|
113
114
|
authoredFields: AuthoredMutationField[];
|
|
114
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* A retained mutation that a queue from before the mutation ledger imported.
|
|
118
|
+
* It has only the fields that the old queue stored.
|
|
119
|
+
*/
|
|
120
|
+
export interface LegacyMutationInspection {
|
|
121
|
+
representation: 'legacy';
|
|
122
|
+
mutationID: string;
|
|
123
|
+
localOrder: number;
|
|
124
|
+
tableName: string;
|
|
125
|
+
recordID: string;
|
|
126
|
+
operation: MutationOperation;
|
|
127
|
+
baseVersion: string | null;
|
|
128
|
+
clientVersion: string;
|
|
129
|
+
status: LocalMutationStatus;
|
|
130
|
+
sourceKind: string;
|
|
131
|
+
}
|
|
132
|
+
/** One retained mutation in its stored representation. */
|
|
133
|
+
export type RetainedMutationInspection = (PendingMutationInspection & {
|
|
134
|
+
representation: 'current';
|
|
135
|
+
}) | LegacyMutationInspection;
|
|
136
|
+
/** A retained rejection with its exact mutation and rejection JSON. */
|
|
115
137
|
export interface RejectedMutationInspection {
|
|
116
138
|
mutationID: string;
|
|
117
139
|
tableName: string;
|
|
@@ -126,6 +148,27 @@ export interface RejectedMutationInspection {
|
|
|
126
148
|
createdAt: string;
|
|
127
149
|
updatedAt: string;
|
|
128
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* A retained rejection that a database from before the mutation ledger stored.
|
|
153
|
+
* It has only the fields that the old rejection table stored.
|
|
154
|
+
*/
|
|
155
|
+
export interface LegacyRejectionInspection {
|
|
156
|
+
representation: 'legacy';
|
|
157
|
+
mutationID: string;
|
|
158
|
+
tableName: string;
|
|
159
|
+
recordID: string;
|
|
160
|
+
status: MutationStatus;
|
|
161
|
+
code: MutationRejectionCode;
|
|
162
|
+
message: string | null;
|
|
163
|
+
serverRowJSON: string | null;
|
|
164
|
+
serverVersion: string | null;
|
|
165
|
+
createdAt: string;
|
|
166
|
+
updatedAt: string;
|
|
167
|
+
}
|
|
168
|
+
/** One retained rejection in its stored representation. */
|
|
169
|
+
export type RetainedRejectionInspection = (RejectedMutationInspection & {
|
|
170
|
+
representation: 'current';
|
|
171
|
+
}) | LegacyRejectionInspection;
|
|
129
172
|
export interface ScopeStateInspection {
|
|
130
173
|
scopeID: string;
|
|
131
174
|
cursor: string | null;
|
|
@@ -168,17 +211,35 @@ export interface ClientStateInspection {
|
|
|
168
211
|
rebuildReceiptCount: number;
|
|
169
212
|
provenanceMaintenanceWorkCursor: string;
|
|
170
213
|
}
|
|
214
|
+
export type MigrationCheckpoint = 'migration_prepared' | 'migration_committed';
|
|
215
|
+
export interface MigrationJournalInspection {
|
|
216
|
+
source: SchemaRef;
|
|
217
|
+
target: SchemaRef;
|
|
218
|
+
action: string;
|
|
219
|
+
phase: string;
|
|
220
|
+
stored: Record<string, string>;
|
|
221
|
+
}
|
|
222
|
+
export interface PhysicalSchemaColumnInspection {
|
|
223
|
+
table_name: string;
|
|
224
|
+
name: string;
|
|
225
|
+
type: string;
|
|
226
|
+
not_null: boolean;
|
|
227
|
+
primary_key_position: number;
|
|
228
|
+
}
|
|
171
229
|
export type TransportOperationClass = 'connect' | 'pull' | 'push' | 'checkpoint' | 'schemas' | 'rebuild' | 'other';
|
|
172
230
|
export interface TransportObservation {
|
|
173
231
|
sequence: number;
|
|
174
232
|
operationClass: TransportOperationClass;
|
|
175
233
|
statusCode: number;
|
|
234
|
+
errorCode?: string;
|
|
235
|
+
retryable?: boolean;
|
|
176
236
|
durationNanoseconds: number;
|
|
177
237
|
cursorFingerprints?: string[];
|
|
178
238
|
cursorFingerprintsComplete?: boolean;
|
|
179
239
|
requestFacts?: Record<string, JSONValue>;
|
|
180
240
|
rebuildResponseFacts?: Record<string, JSONValue>;
|
|
181
241
|
pullResponseFacts?: Record<string, JSONValue>;
|
|
242
|
+
connectResponseFacts?: Record<string, JSONValue>;
|
|
182
243
|
}
|
|
183
244
|
export interface TransportObservationSnapshot {
|
|
184
245
|
observations: TransportObservation[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trainstar/synchro-react-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0-rc.2",
|
|
4
4
|
"description": "React Native bridge for Synchro sync SDK",
|
|
5
5
|
"source": "./src/index.ts",
|
|
6
6
|
"main": "./lib/module/index.js",
|
|
@@ -16,6 +16,11 @@
|
|
|
16
16
|
"types": "./lib/typescript/src/inspection.d.ts",
|
|
17
17
|
"default": "./lib/module/inspection.js"
|
|
18
18
|
},
|
|
19
|
+
"./tooling-patches/apply": "./tooling-patches/apply.cjs",
|
|
20
|
+
"./tooling-patches/cli-config-android-20.2.0.patch": "./tooling-patches/cli-config-android-20.2.0.patch",
|
|
21
|
+
"./tooling-patches/cli-clean-20.2.0.patch": "./tooling-patches/cli-clean-20.2.0.patch",
|
|
22
|
+
"./tooling-patches/react-native-builder-bob-0.40.18.patch": "./tooling-patches/react-native-builder-bob-0.40.18.patch",
|
|
23
|
+
"./tooling-patches/stream-json-1.9.1.patch": "./tooling-patches/stream-json-1.9.1.patch",
|
|
19
24
|
"./package.json": "./package.json"
|
|
20
25
|
},
|
|
21
26
|
"files": [
|
|
@@ -23,6 +28,9 @@
|
|
|
23
28
|
"lib",
|
|
24
29
|
"android",
|
|
25
30
|
"ios",
|
|
31
|
+
"ios-test-host",
|
|
32
|
+
"ios-tests",
|
|
33
|
+
"tooling-patches",
|
|
26
34
|
"*.podspec",
|
|
27
35
|
"!ios/build",
|
|
28
36
|
"!android/build",
|
|
@@ -42,7 +50,7 @@
|
|
|
42
50
|
"pack:dry-run": "npm pack --dry-run",
|
|
43
51
|
"test:unit": "jest --runInBand --watchman=false",
|
|
44
52
|
"typecheck": "tsc",
|
|
45
|
-
"lint": "eslint src/ __tests__/ example/e2e/",
|
|
53
|
+
"lint": "eslint src/ __tests__/ example/e2e/ example/src/",
|
|
46
54
|
"test": "jest"
|
|
47
55
|
},
|
|
48
56
|
"keywords": [
|
|
@@ -68,7 +76,7 @@
|
|
|
68
76
|
"node": ">=20.19.4"
|
|
69
77
|
},
|
|
70
78
|
"devDependencies": {
|
|
71
|
-
"@react-native/babel-preset": "0.83.
|
|
79
|
+
"@react-native/babel-preset": "0.83.10",
|
|
72
80
|
"@testing-library/react-native": "^12.4.0",
|
|
73
81
|
"@types/jest": "^29.5.14",
|
|
74
82
|
"@types/react": "^19.2.4",
|
|
@@ -78,19 +86,26 @@
|
|
|
78
86
|
"eslint": "^9.0.0",
|
|
79
87
|
"jest": "^29.7.0",
|
|
80
88
|
"react": "19.2.4",
|
|
81
|
-
"react-native": "0.83.
|
|
89
|
+
"react-native": "0.83.10",
|
|
82
90
|
"react-native-builder-bob": "^0.40.18",
|
|
83
91
|
"react-test-renderer": "^19.2.4",
|
|
84
92
|
"ts-jest": "^29.1.0",
|
|
85
93
|
"typescript": "^5.9.2"
|
|
86
94
|
},
|
|
87
95
|
"peerDependencies": {
|
|
88
|
-
"react": ">=19.
|
|
89
|
-
"react-native": ">=0.
|
|
96
|
+
"react": ">=19.1.1 <20.0.0",
|
|
97
|
+
"react-native": ">=0.82.1 <0.84.0"
|
|
90
98
|
},
|
|
91
99
|
"workspaces": [
|
|
92
100
|
"example"
|
|
93
101
|
],
|
|
102
|
+
"resolutions": {
|
|
103
|
+
"@react-native-community/cli-config-android@npm:20.2.0": "patch:@react-native-community/cli-config-android@npm%3A20.2.0#./tooling-patches/cli-config-android-20.2.0.patch",
|
|
104
|
+
"@react-native-community/cli-clean@npm:20.2.0": "patch:@react-native-community/cli-clean@npm%3A20.2.0#./tooling-patches/cli-clean-20.2.0.patch",
|
|
105
|
+
"react-native-builder-bob@npm:^0.40.18": "patch:react-native-builder-bob@npm%3A0.40.18#./tooling-patches/react-native-builder-bob-0.40.18.patch",
|
|
106
|
+
"stream-json@npm:^1.7.4": "patch:stream-json@npm%3A1.9.1#./tooling-patches/stream-json-1.9.1.patch",
|
|
107
|
+
"stream-json@npm:^1.7.5": "patch:stream-json@npm%3A1.9.1#./tooling-patches/stream-json-1.9.1.patch"
|
|
108
|
+
},
|
|
94
109
|
"packageManager": "yarn@4.11.0",
|
|
95
110
|
"react-native-builder-bob": {
|
|
96
111
|
"source": "src",
|
package/src/NativeSynchro.ts
CHANGED
|
@@ -94,6 +94,7 @@ export interface Spec extends TurboModule {
|
|
|
94
94
|
|
|
95
95
|
// Transactions
|
|
96
96
|
beginWriteTransaction(): Promise<string>;
|
|
97
|
+
beginAtomicWriteTransaction(): Promise<string>;
|
|
97
98
|
beginReadTransaction(): Promise<string>;
|
|
98
99
|
txQuery(
|
|
99
100
|
txID: string,
|
|
@@ -151,8 +152,12 @@ export interface Spec extends TurboModule {
|
|
|
151
152
|
getSyncStatus(): Promise<string>;
|
|
152
153
|
inspectPendingMutations(): Promise<string>;
|
|
153
154
|
inspectRetainedMutations(): Promise<string>;
|
|
155
|
+
inspectRetainedMutationRecords(): Promise<string>;
|
|
154
156
|
inspectRejectedMutations(): Promise<string>;
|
|
155
|
-
|
|
157
|
+
inspectRejectedMutationRecords(): Promise<string>;
|
|
158
|
+
inspectClientStateSnapshot(
|
|
159
|
+
rowStatements: ReadonlyArray<NativeSQLStatement>
|
|
160
|
+
): Promise<{ inspection: string; applicationRows: ReadonlyArray<NativeRow> }>;
|
|
156
161
|
inspectDurableState(tableName: string, recordID: string): Promise<string>;
|
|
157
162
|
inspectTransportObservations(): Promise<string>;
|
|
158
163
|
armTransportPause(operationClass: string): Promise<void>;
|
package/src/SynchroClient.ts
CHANGED
|
@@ -28,6 +28,8 @@ import type {
|
|
|
28
28
|
MutationRejectionCode,
|
|
29
29
|
PendingMutationInspection,
|
|
30
30
|
RejectedMutationInspection,
|
|
31
|
+
RetainedMutationInspection,
|
|
32
|
+
RetainedRejectionInspection,
|
|
31
33
|
ClientStateInspection,
|
|
32
34
|
ScopeStateInspection,
|
|
33
35
|
ScopeRowInspection,
|
|
@@ -117,6 +119,7 @@ const MUTATION_REJECTION_CODES: readonly MutationRejectionCode[] = [
|
|
|
117
119
|
'policy_rejected',
|
|
118
120
|
'validation_failed',
|
|
119
121
|
'table_not_synced',
|
|
122
|
+
'atomic_batch_rejected',
|
|
120
123
|
];
|
|
121
124
|
|
|
122
125
|
const MUTATION_OPERATIONS = ['insert', 'upsert', 'update', 'delete'] as const;
|
|
@@ -438,6 +441,40 @@ function parsePendingMutationInspection(
|
|
|
438
441
|
};
|
|
439
442
|
}
|
|
440
443
|
|
|
444
|
+
export function parseRetainedMutationInspection(
|
|
445
|
+
value: unknown,
|
|
446
|
+
index: number
|
|
447
|
+
): RetainedMutationInspection {
|
|
448
|
+
const name = `pending mutation at index ${index}`;
|
|
449
|
+
if (!isRecord(value)) {
|
|
450
|
+
throw new InvalidResponseError(`Native bridge returned an invalid ${name}`);
|
|
451
|
+
}
|
|
452
|
+
if (value.representation === 'current') {
|
|
453
|
+
return { representation: 'current', ...parsePendingMutationInspection(value, index) };
|
|
454
|
+
}
|
|
455
|
+
if (value.representation !== 'legacy') {
|
|
456
|
+
throw new InvalidResponseError(`Native bridge returned an invalid ${name} representation`);
|
|
457
|
+
}
|
|
458
|
+
if (!MUTATION_OPERATIONS.includes(value.operation as never)) {
|
|
459
|
+
throw new InvalidResponseError(`Native bridge returned an invalid ${name} operation`);
|
|
460
|
+
}
|
|
461
|
+
if (!LOCAL_MUTATION_STATUSES.includes(value.status as never)) {
|
|
462
|
+
throw new InvalidResponseError(`Native bridge returned an invalid ${name} status`);
|
|
463
|
+
}
|
|
464
|
+
return {
|
|
465
|
+
representation: 'legacy',
|
|
466
|
+
mutationID: requiredString(value.mutationID, `${name} ID`),
|
|
467
|
+
localOrder: requiredSafeInteger(value.localOrder, `${name} local order`),
|
|
468
|
+
tableName: requiredString(value.tableName, `${name} table name`),
|
|
469
|
+
recordID: requiredString(value.recordID, `${name} record ID`),
|
|
470
|
+
operation: value.operation as PendingMutationInspection['operation'],
|
|
471
|
+
baseVersion: nullableString(value.baseVersion, `${name} base version`),
|
|
472
|
+
clientVersion: requiredString(value.clientVersion, `${name} client version`),
|
|
473
|
+
status: value.status as PendingMutationInspection['status'],
|
|
474
|
+
sourceKind: requiredString(value.sourceKind, `${name} source kind`),
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
|
|
441
478
|
function parseRejectedMutationInspection(
|
|
442
479
|
value: unknown,
|
|
443
480
|
index: number
|
|
@@ -466,6 +503,39 @@ function parseRejectedMutationInspection(
|
|
|
466
503
|
};
|
|
467
504
|
}
|
|
468
505
|
|
|
506
|
+
export function parseRetainedRejectionInspection(
|
|
507
|
+
value: unknown,
|
|
508
|
+
index: number
|
|
509
|
+
): RetainedRejectionInspection {
|
|
510
|
+
const name = `rejected mutation at index ${index}`;
|
|
511
|
+
if (!isRecord(value)) {
|
|
512
|
+
throw new InvalidResponseError(`Native bridge returned an invalid ${name}`);
|
|
513
|
+
}
|
|
514
|
+
if (value.representation === 'current') {
|
|
515
|
+
return { representation: 'current', ...parseRejectedMutationInspection(value, index) };
|
|
516
|
+
}
|
|
517
|
+
if (value.representation !== 'legacy') {
|
|
518
|
+
throw new InvalidResponseError(`Native bridge returned an invalid ${name} representation`);
|
|
519
|
+
}
|
|
520
|
+
const code = parseRejectionCode(value.code);
|
|
521
|
+
if (code === null) {
|
|
522
|
+
throw new InvalidResponseError(`Native bridge returned a missing ${name} code`);
|
|
523
|
+
}
|
|
524
|
+
return {
|
|
525
|
+
representation: 'legacy',
|
|
526
|
+
mutationID: requiredString(value.mutationID, `${name} ID`),
|
|
527
|
+
tableName: requiredString(value.tableName, `${name} table name`),
|
|
528
|
+
recordID: requiredString(value.recordID, `${name} record ID`),
|
|
529
|
+
status: parseMutationStatus(value.status),
|
|
530
|
+
code,
|
|
531
|
+
message: nullableString(value.message, `${name} message`),
|
|
532
|
+
serverRowJSON: nullableString(value.serverRowJSON, `${name} server row JSON`),
|
|
533
|
+
serverVersion: nullableString(value.serverVersion, `${name} server version`),
|
|
534
|
+
createdAt: requiredString(value.createdAt, `${name} creation time`),
|
|
535
|
+
updatedAt: requiredString(value.updatedAt, `${name} update time`),
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
|
|
469
539
|
function parseScopeStateInspection(value: unknown, index: number): ScopeStateInspection {
|
|
470
540
|
const name = `scope state at index ${index}`;
|
|
471
541
|
if (!isRecord(value)) {
|
|
@@ -621,6 +691,14 @@ function parseTransportObservation(value: unknown, index: number): TransportObse
|
|
|
621
691
|
if (!isRecord(value) || !TRANSPORT_OPERATION_CLASSES.includes(value.operation_class as TransportOperationClass)) {
|
|
622
692
|
throw new InvalidResponseError(`Native bridge returned an invalid ${name}`);
|
|
623
693
|
}
|
|
694
|
+
const errorCode = value.error_code;
|
|
695
|
+
if (errorCode !== undefined && typeof errorCode !== 'string') {
|
|
696
|
+
throw new InvalidResponseError(`Native bridge returned invalid ${name} error code`);
|
|
697
|
+
}
|
|
698
|
+
const retryable = value.retryable;
|
|
699
|
+
if (retryable !== undefined && typeof retryable !== 'boolean') {
|
|
700
|
+
throw new InvalidResponseError(`Native bridge returned invalid ${name} retryability`);
|
|
701
|
+
}
|
|
624
702
|
const cursorFingerprints = value.cursor_fingerprints;
|
|
625
703
|
if (cursorFingerprints !== undefined && (!Array.isArray(cursorFingerprints) || !cursorFingerprints.every((item) => typeof item === 'string'))) {
|
|
626
704
|
throw new InvalidResponseError(`Native bridge returned invalid ${name} cursor fingerprints`);
|
|
@@ -629,16 +707,40 @@ function parseTransportObservation(value: unknown, index: number): TransportObse
|
|
|
629
707
|
if (cursorFingerprintsComplete !== undefined && typeof cursorFingerprintsComplete !== 'boolean') {
|
|
630
708
|
throw new InvalidResponseError(`Native bridge returned invalid ${name} cursor completeness`);
|
|
631
709
|
}
|
|
710
|
+
const connectFacts = optionalTransportFacts(value.connect_response_facts, `${name} connect response facts`);
|
|
711
|
+
if (connectFacts !== undefined) {
|
|
712
|
+
const affected = connectFacts.affected_scope_fingerprints;
|
|
713
|
+
const updates = connectFacts.scope_cursor_updates;
|
|
714
|
+
const hashPattern = /^[0-9a-f]{64}$/;
|
|
715
|
+
if (
|
|
716
|
+
value.operation_class !== 'connect' || value.status_code !== 200 ||
|
|
717
|
+
Object.keys(connectFacts).length !== 7 ||
|
|
718
|
+
!['none', 'replace', 'rebuild_local', 'unsupported'].includes(connectFacts.action as string) ||
|
|
719
|
+
typeof connectFacts.schema_version !== 'number' || !Number.isSafeInteger(connectFacts.schema_version) || connectFacts.schema_version <= 0 ||
|
|
720
|
+
typeof connectFacts.schema_hash !== 'string' || !hashPattern.test(connectFacts.schema_hash) ||
|
|
721
|
+
!Array.isArray(affected) || affected.length > 16 ||
|
|
722
|
+
!affected.every((item, position) => typeof item === 'string' && hashPattern.test(item) && (position === 0 || (affected[position - 1] as string) < item)) ||
|
|
723
|
+
typeof connectFacts.affected_scopes_complete !== 'boolean' ||
|
|
724
|
+
!isRecord(updates) || Object.keys(updates).length > 16 ||
|
|
725
|
+
!Object.entries(updates).every(([scope, cursor]) => hashPattern.test(scope) && (cursor === null || typeof cursor === 'string' && hashPattern.test(cursor))) ||
|
|
726
|
+
typeof connectFacts.scope_cursor_updates_complete !== 'boolean'
|
|
727
|
+
) {
|
|
728
|
+
throw new InvalidResponseError(`Native bridge returned invalid ${name} connect response facts`);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
632
731
|
return {
|
|
633
732
|
sequence: requiredSafeInteger(value.sequence, `${name} sequence`),
|
|
634
733
|
operationClass: value.operation_class as TransportOperationClass,
|
|
635
734
|
statusCode: requiredSafeInteger(value.status_code, `${name} status code`),
|
|
735
|
+
...(errorCode === undefined ? {} : { errorCode }),
|
|
736
|
+
...(retryable === undefined ? {} : { retryable }),
|
|
636
737
|
durationNanoseconds: requiredSafeInteger(value.duration_nanoseconds, `${name} duration`),
|
|
637
738
|
...(cursorFingerprints === undefined ? {} : { cursorFingerprints: [...cursorFingerprints] as string[] }),
|
|
638
739
|
...(cursorFingerprintsComplete === undefined ? {} : { cursorFingerprintsComplete }),
|
|
639
740
|
...(value.request_facts == null ? {} : { requestFacts: optionalTransportRequestFacts(value.request_facts, `${name} request facts`)! }),
|
|
640
741
|
...(value.rebuild_response_facts == null ? {} : { rebuildResponseFacts: optionalTransportFacts(value.rebuild_response_facts, `${name} rebuild response facts`)! }),
|
|
641
742
|
...(value.pull_response_facts == null ? {} : { pullResponseFacts: optionalTransportFacts(value.pull_response_facts, `${name} pull response facts`)! }),
|
|
743
|
+
...(connectFacts === undefined ? {} : { connectResponseFacts: connectFacts }),
|
|
642
744
|
};
|
|
643
745
|
}
|
|
644
746
|
|
|
@@ -802,10 +904,28 @@ export class SynchroClient {
|
|
|
802
904
|
|
|
803
905
|
async writeTransaction<T>(
|
|
804
906
|
callback: (tx: Transaction) => Promise<T>
|
|
907
|
+
): Promise<T> {
|
|
908
|
+
return this.runWriteTransaction(() => this.native.beginWriteTransaction(), callback);
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
/**
|
|
912
|
+
* Runs a write transaction whose synced mutations the server applies all
|
|
913
|
+
* together or not at all. The native SDK owns the group. An invalid group
|
|
914
|
+
* rolls back and rejects with `AtomicGroupInvalidError`.
|
|
915
|
+
*/
|
|
916
|
+
async atomicWriteTransaction<T>(
|
|
917
|
+
callback: (tx: Transaction) => Promise<T>
|
|
918
|
+
): Promise<T> {
|
|
919
|
+
return this.runWriteTransaction(() => this.native.beginAtomicWriteTransaction(), callback);
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
private async runWriteTransaction<T>(
|
|
923
|
+
begin: () => Promise<string>,
|
|
924
|
+
callback: (tx: Transaction) => Promise<T>
|
|
805
925
|
): Promise<T> {
|
|
806
926
|
let txID: string;
|
|
807
927
|
try {
|
|
808
|
-
txID = await
|
|
928
|
+
txID = await begin();
|
|
809
929
|
} catch (error) {
|
|
810
930
|
throw mapNativeError(error);
|
|
811
931
|
}
|
|
@@ -1025,6 +1145,11 @@ export class SynchroClient {
|
|
|
1025
1145
|
}
|
|
1026
1146
|
}
|
|
1027
1147
|
|
|
1148
|
+
/**
|
|
1149
|
+
* Returns the unresolved queue records.
|
|
1150
|
+
* @deprecated Use {@link SynchroClient.inspectRetainedMutationRecords}. This method keeps its
|
|
1151
|
+
* published behavior. It rejects when the native queue holds a legacy import.
|
|
1152
|
+
*/
|
|
1028
1153
|
async inspectPendingMutations(): Promise<PendingMutationInspection[]> {
|
|
1029
1154
|
try {
|
|
1030
1155
|
return parseNativeArray(
|
|
@@ -1036,6 +1161,11 @@ export class SynchroClient {
|
|
|
1036
1161
|
}
|
|
1037
1162
|
}
|
|
1038
1163
|
|
|
1164
|
+
/**
|
|
1165
|
+
* Returns every retained queue record, including local terminal states.
|
|
1166
|
+
* @deprecated Use {@link SynchroClient.inspectRetainedMutationRecords}. This method keeps its
|
|
1167
|
+
* published behavior. It rejects when the native queue holds a legacy import.
|
|
1168
|
+
*/
|
|
1039
1169
|
async inspectRetainedMutations(): Promise<PendingMutationInspection[]> {
|
|
1040
1170
|
try {
|
|
1041
1171
|
return parseNativeArray(
|
|
@@ -1047,6 +1177,23 @@ export class SynchroClient {
|
|
|
1047
1177
|
}
|
|
1048
1178
|
}
|
|
1049
1179
|
|
|
1180
|
+
/** Returns every retained queue record in its stored representation. */
|
|
1181
|
+
async inspectRetainedMutationRecords(): Promise<RetainedMutationInspection[]> {
|
|
1182
|
+
try {
|
|
1183
|
+
return parseNativeArray(
|
|
1184
|
+
await this.native.inspectRetainedMutationRecords(),
|
|
1185
|
+
'retained mutation inspection'
|
|
1186
|
+
).map(parseRetainedMutationInspection);
|
|
1187
|
+
} catch (error) {
|
|
1188
|
+
throw mapNativeError(error);
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
/**
|
|
1193
|
+
* Returns the retained terminal outcomes.
|
|
1194
|
+
* @deprecated Use {@link SynchroClient.inspectRejectedMutationRecords}. This method keeps its
|
|
1195
|
+
* published behavior. It rejects when a legacy rejection is present.
|
|
1196
|
+
*/
|
|
1050
1197
|
async inspectRejectedMutations(): Promise<RejectedMutationInspection[]> {
|
|
1051
1198
|
try {
|
|
1052
1199
|
return parseNativeArray(
|
|
@@ -1058,6 +1205,18 @@ export class SynchroClient {
|
|
|
1058
1205
|
}
|
|
1059
1206
|
}
|
|
1060
1207
|
|
|
1208
|
+
/** Returns the retained terminal outcomes in their stored representation. */
|
|
1209
|
+
async inspectRejectedMutationRecords(): Promise<RetainedRejectionInspection[]> {
|
|
1210
|
+
try {
|
|
1211
|
+
return parseNativeArray(
|
|
1212
|
+
await this.native.inspectRejectedMutationRecords(),
|
|
1213
|
+
'rejected mutation inspection'
|
|
1214
|
+
).map(parseRetainedRejectionInspection);
|
|
1215
|
+
} catch (error) {
|
|
1216
|
+
throw mapNativeError(error);
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1061
1220
|
async clearRejectedMutations(): Promise<void> {
|
|
1062
1221
|
try {
|
|
1063
1222
|
await this.native.clearRejectedMutations();
|
package/src/errors.ts
CHANGED
|
@@ -33,6 +33,7 @@ export const NATIVE_ERROR_CODES = [
|
|
|
33
33
|
'TRANSACTION_TIMEOUT',
|
|
34
34
|
'INVALID_CONFIG',
|
|
35
35
|
'CLIENT_ALREADY_ACTIVE',
|
|
36
|
+
'atomic_group_invalid',
|
|
36
37
|
'UNKNOWN',
|
|
37
38
|
] as const;
|
|
38
39
|
|
|
@@ -233,6 +234,25 @@ export class TransactionTimeoutError extends SynchroError {
|
|
|
233
234
|
}
|
|
234
235
|
}
|
|
235
236
|
|
|
237
|
+
export const ATOMIC_GROUP_INVALID_REASONS = [
|
|
238
|
+
'deleteFollowedByWrite',
|
|
239
|
+
'tooManyMutations',
|
|
240
|
+
'mutationTooLarge',
|
|
241
|
+
'requestTooLarge',
|
|
242
|
+
] as const;
|
|
243
|
+
|
|
244
|
+
export type AtomicGroupInvalidReason = (typeof ATOMIC_GROUP_INVALID_REASONS)[number];
|
|
245
|
+
|
|
246
|
+
export class AtomicGroupInvalidError extends SynchroError {
|
|
247
|
+
readonly reason: AtomicGroupInvalidReason;
|
|
248
|
+
|
|
249
|
+
constructor(reason: AtomicGroupInvalidReason) {
|
|
250
|
+
super('atomic_group_invalid', `Atomic write group is invalid: ${reason}`);
|
|
251
|
+
this.name = 'AtomicGroupInvalidError';
|
|
252
|
+
this.reason = reason;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
236
256
|
interface NativeErrorLike {
|
|
237
257
|
code?: string;
|
|
238
258
|
message?: string;
|
|
@@ -439,6 +459,16 @@ export function mapNativeError(error: unknown): SynchroError {
|
|
|
439
459
|
return new TransactionTimeoutError();
|
|
440
460
|
case 'INVALID_CONFIG':
|
|
441
461
|
return new SynchroError('INVALID_CONFIG', message);
|
|
462
|
+
case 'atomic_group_invalid':
|
|
463
|
+
try {
|
|
464
|
+
return new AtomicGroupInvalidError(
|
|
465
|
+
requiredEnum(userInfo.reason, ATOMIC_GROUP_INVALID_REASONS, 'atomic group invalid reason')
|
|
466
|
+
);
|
|
467
|
+
} catch (parseError) {
|
|
468
|
+
return parseError instanceof SynchroError
|
|
469
|
+
? parseError
|
|
470
|
+
: new InvalidResponseError('Native bridge returned invalid atomic group details');
|
|
471
|
+
}
|
|
442
472
|
default:
|
|
443
473
|
return new SynchroError('UNKNOWN', message);
|
|
444
474
|
}
|
package/src/index.ts
CHANGED
|
@@ -30,7 +30,11 @@ export type {
|
|
|
30
30
|
SchemaRef,
|
|
31
31
|
AuthoredMutationField,
|
|
32
32
|
PendingMutationInspection,
|
|
33
|
+
LegacyMutationInspection,
|
|
34
|
+
RetainedMutationInspection,
|
|
33
35
|
RejectedMutationInspection,
|
|
36
|
+
LegacyRejectionInspection,
|
|
37
|
+
RetainedRejectionInspection,
|
|
34
38
|
SchemaAction,
|
|
35
39
|
SyncSchemaEvent,
|
|
36
40
|
SyncMutationEvent,
|
|
@@ -71,6 +75,8 @@ export {
|
|
|
71
75
|
AlreadyStartedError,
|
|
72
76
|
NotStartedError,
|
|
73
77
|
TransactionTimeoutError,
|
|
78
|
+
AtomicGroupInvalidError,
|
|
79
|
+
ATOMIC_GROUP_INVALID_REASONS,
|
|
74
80
|
NATIVE_ERROR_CODES,
|
|
75
81
|
mapNativeError,
|
|
76
82
|
} from './errors';
|
|
@@ -78,5 +84,6 @@ export {
|
|
|
78
84
|
export type {
|
|
79
85
|
NativeErrorCode,
|
|
80
86
|
SchemaUnsupportedReason,
|
|
87
|
+
AtomicGroupInvalidReason,
|
|
81
88
|
PushRejectedMutation,
|
|
82
89
|
} from './errors';
|