@syncular/client 0.30.6 → 0.30.7
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/dist/client.js +2 -1
- package/dist/database.d.ts +3 -0
- package/dist/database.js +26 -7
- package/dist/diagnostics.d.ts +1 -1
- package/dist/errors.d.ts +3 -1
- package/dist/errors.js +57 -15
- package/dist/worker-entry.js +3 -2
- package/package.json +3 -3
- package/src/client.ts +2 -1
- package/src/database.ts +24 -8
- package/src/diagnostics.ts +1 -0
- package/src/errors.ts +74 -20
- package/src/worker-entry.ts +7 -2
package/dist/client.js
CHANGED
|
@@ -2327,7 +2327,8 @@ export class SyncClient {
|
|
|
2327
2327
|
};
|
|
2328
2328
|
this.#emitDiagnostics();
|
|
2329
2329
|
return summary;
|
|
2330
|
-
}, (
|
|
2330
|
+
}, (caught) => {
|
|
2331
|
+
const error = classifySqliteFailure(caught).error;
|
|
2331
2332
|
const completedAtMs = this.#now();
|
|
2332
2333
|
const code = error.code;
|
|
2333
2334
|
this.#progress.update({
|
package/dist/database.d.ts
CHANGED
package/dist/database.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { classifySqliteFailure } from './errors.js';
|
|
1
2
|
/** Attach-schema aliases are code-chosen, never user input — enforce it. */
|
|
2
3
|
export function assertImageAlias(alias) {
|
|
3
4
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(alias)) {
|
|
@@ -10,6 +11,10 @@ export function assertImageAlias(alias) {
|
|
|
10
11
|
*/
|
|
11
12
|
export function runTransaction(depthHolder, run, fn) {
|
|
12
13
|
const depth = depthHolder.depth;
|
|
14
|
+
if (depth === 0)
|
|
15
|
+
delete depthHolder.aborted;
|
|
16
|
+
else if (depthHolder.aborted)
|
|
17
|
+
throw depthHolder.aborted.error;
|
|
13
18
|
const savepoint = `syncular_sp_${depth}`;
|
|
14
19
|
if (depth === 0)
|
|
15
20
|
run('BEGIN');
|
|
@@ -18,6 +23,9 @@ export function runTransaction(depthHolder, run, fn) {
|
|
|
18
23
|
depthHolder.depth = depth + 1;
|
|
19
24
|
try {
|
|
20
25
|
const result = fn();
|
|
26
|
+
const aborted = depthHolder.aborted;
|
|
27
|
+
if (aborted)
|
|
28
|
+
throw aborted.error;
|
|
21
29
|
depthHolder.depth = depth;
|
|
22
30
|
if (depth === 0)
|
|
23
31
|
run('COMMIT');
|
|
@@ -25,15 +33,26 @@ export function runTransaction(depthHolder, run, fn) {
|
|
|
25
33
|
run(`RELEASE ${savepoint}`);
|
|
26
34
|
return result;
|
|
27
35
|
}
|
|
28
|
-
catch (
|
|
36
|
+
catch (caught) {
|
|
37
|
+
const aborted = depthHolder.aborted;
|
|
38
|
+
const error = aborted?.error ?? caught;
|
|
29
39
|
depthHolder.depth = depth;
|
|
30
|
-
|
|
31
|
-
|
|
40
|
+
try {
|
|
41
|
+
if (depth === 0)
|
|
42
|
+
run('ROLLBACK');
|
|
43
|
+
else {
|
|
44
|
+
run(`ROLLBACK TO ${savepoint}`);
|
|
45
|
+
run(`RELEASE ${savepoint}`);
|
|
46
|
+
}
|
|
32
47
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
48
|
+
catch (rollbackError) {
|
|
49
|
+
// SQLite can end the whole transaction after SQLITE_FULL or SQLITE_IOERR.
|
|
50
|
+
// Poison remaining nested scopes until the outer owner unwinds.
|
|
51
|
+
depthHolder.aborted = { error };
|
|
52
|
+
if (error instanceof Error && !('rollbackError' in error)) {
|
|
53
|
+
Object.defineProperty(error, 'rollbackError', { value: rollbackError });
|
|
54
|
+
}
|
|
36
55
|
}
|
|
37
|
-
throw error;
|
|
56
|
+
throw classifySqliteFailure(error).error;
|
|
38
57
|
}
|
|
39
58
|
}
|
package/dist/diagnostics.d.ts
CHANGED
|
@@ -113,7 +113,7 @@ export interface DiagnosticQueryFailure {
|
|
|
113
113
|
readonly id: string;
|
|
114
114
|
/** Distinct generated table names the query depends on, ascending. */
|
|
115
115
|
readonly tables: readonly string[];
|
|
116
|
-
readonly code: 'client.storage_corrupt' | 'client.storage_io' | 'client.query_failed';
|
|
116
|
+
readonly code: 'client.storage_corrupt' | 'client.storage_full' | 'client.storage_io' | 'client.query_failed';
|
|
117
117
|
/** SQLite extended result code, when the driver exposed one. */
|
|
118
118
|
readonly sqliteCode?: number;
|
|
119
119
|
/** First failure since this id's last successful read. */
|
package/dist/errors.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ export declare const STORAGE_BUSY_CODE = "client.storage_busy";
|
|
|
5
5
|
export declare const STORAGE_UNAVAILABLE_CODE = "client.storage_unavailable";
|
|
6
6
|
/** A local read hit SQLITE_CORRUPT or SQLITE_NOTADB (SPEC §7.5). */
|
|
7
7
|
export declare const STORAGE_CORRUPT_CODE = "client.storage_corrupt";
|
|
8
|
+
/** Local SQLite storage has no space for the write. */
|
|
9
|
+
export declare const STORAGE_FULL_CODE = "client.storage_full";
|
|
8
10
|
/** A local read hit SQLITE_IOERR (SPEC §7.5). */
|
|
9
11
|
export declare const STORAGE_IO_CODE = "client.storage_io";
|
|
10
12
|
/** SPEC §8.8: a round under `realtimePolicy: 'required'` found no socket. */
|
|
@@ -61,6 +63,6 @@ export declare class RealtimeUnavailableError extends ClientSyncError {
|
|
|
61
63
|
*/
|
|
62
64
|
export declare function classifySqliteFailure(error: unknown): {
|
|
63
65
|
readonly sqliteCode: number | undefined;
|
|
64
|
-
readonly code: typeof STORAGE_CORRUPT_CODE | typeof STORAGE_IO_CODE | undefined;
|
|
66
|
+
readonly code: typeof STORAGE_CORRUPT_CODE | typeof STORAGE_FULL_CODE | typeof STORAGE_IO_CODE | undefined;
|
|
65
67
|
readonly error: unknown;
|
|
66
68
|
};
|
package/dist/errors.js
CHANGED
|
@@ -4,6 +4,8 @@ export const STORAGE_BUSY_CODE = 'client.storage_busy';
|
|
|
4
4
|
export const STORAGE_UNAVAILABLE_CODE = 'client.storage_unavailable';
|
|
5
5
|
/** A local read hit SQLITE_CORRUPT or SQLITE_NOTADB (SPEC §7.5). */
|
|
6
6
|
export const STORAGE_CORRUPT_CODE = 'client.storage_corrupt';
|
|
7
|
+
/** Local SQLite storage has no space for the write. */
|
|
8
|
+
export const STORAGE_FULL_CODE = 'client.storage_full';
|
|
7
9
|
/** A local read hit SQLITE_IOERR (SPEC §7.5). */
|
|
8
10
|
export const STORAGE_IO_CODE = 'client.storage_io';
|
|
9
11
|
/** SPEC §8.8: a round under `realtimePolicy: 'required'` found no socket. */
|
|
@@ -73,6 +75,31 @@ export class RealtimeUnavailableError extends ClientSyncError {
|
|
|
73
75
|
* original value.
|
|
74
76
|
*/
|
|
75
77
|
export function classifySqliteFailure(error) {
|
|
78
|
+
if (error instanceof ClientSyncError) {
|
|
79
|
+
const sqliteCode = error.details?.sqliteCode;
|
|
80
|
+
let retained = error;
|
|
81
|
+
if ('rollbackError' in error &&
|
|
82
|
+
error.details?.rollbackFailure === undefined) {
|
|
83
|
+
const rollback = error.rollbackError;
|
|
84
|
+
retained = new ClientSyncError(error.code, error.message, error.retryable, {
|
|
85
|
+
...error.details,
|
|
86
|
+
rollbackFailure: {
|
|
87
|
+
message: rollback instanceof Error ? rollback.message : String(rollback),
|
|
88
|
+
sqliteCode: classifySqliteFailure(rollback).sqliteCode,
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
Object.defineProperty(retained, 'cause', { value: error });
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
sqliteCode: typeof sqliteCode === 'number' ? sqliteCode : undefined,
|
|
95
|
+
code: error.code === STORAGE_FULL_CODE ||
|
|
96
|
+
error.code === STORAGE_IO_CODE ||
|
|
97
|
+
error.code === STORAGE_CORRUPT_CODE
|
|
98
|
+
? error.code
|
|
99
|
+
: undefined,
|
|
100
|
+
error: retained,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
76
103
|
const sqliteCode = error instanceof Error
|
|
77
104
|
? error.name === 'SQLiteError' &&
|
|
78
105
|
'errno' in error &&
|
|
@@ -87,19 +114,34 @@ export function classifySqliteFailure(error) {
|
|
|
87
114
|
: undefined
|
|
88
115
|
: undefined;
|
|
89
116
|
const primary = sqliteCode === undefined ? undefined : sqliteCode & 0xff;
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if (
|
|
98
|
-
return {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
117
|
+
const code = primary === 13
|
|
118
|
+
? STORAGE_FULL_CODE
|
|
119
|
+
: primary === 10
|
|
120
|
+
? STORAGE_IO_CODE
|
|
121
|
+
: primary === 11 || primary === 26
|
|
122
|
+
? STORAGE_CORRUPT_CODE
|
|
123
|
+
: undefined;
|
|
124
|
+
if (code === undefined)
|
|
125
|
+
return { sqliteCode, code, error };
|
|
126
|
+
const rollback = error instanceof Error && 'rollbackError' in error
|
|
127
|
+
? error.rollbackError
|
|
128
|
+
: undefined;
|
|
129
|
+
const failure = new ClientSyncError(code, primary === 13
|
|
130
|
+
? 'local SQLite storage is full'
|
|
131
|
+
: primary === 10
|
|
132
|
+
? 'local SQLite storage I/O failed'
|
|
133
|
+
: 'local SQLite storage is corrupt', false, {
|
|
134
|
+
sqliteCode,
|
|
135
|
+
sqliteMessage: error instanceof Error ? error.message : String(error),
|
|
136
|
+
...(rollback !== undefined
|
|
137
|
+
? {
|
|
138
|
+
rollbackFailure: {
|
|
139
|
+
message: rollback instanceof Error ? rollback.message : String(rollback),
|
|
140
|
+
sqliteCode: classifySqliteFailure(rollback).sqliteCode,
|
|
141
|
+
},
|
|
142
|
+
}
|
|
143
|
+
: {}),
|
|
144
|
+
});
|
|
145
|
+
Object.defineProperty(failure, 'cause', { value: error });
|
|
146
|
+
return { sqliteCode, code, error: failure };
|
|
105
147
|
}
|
package/dist/worker-entry.js
CHANGED
|
@@ -16,11 +16,12 @@
|
|
|
16
16
|
import { SyncClient } from './client.js';
|
|
17
17
|
import { withClientDiagnosticsHost, } from './diagnostics.js';
|
|
18
18
|
import { encryptionConfigFromKeyring } from './encryption.js';
|
|
19
|
-
import { ClientSyncError, STORAGE_BUSY_CODE } from './errors.js';
|
|
19
|
+
import { classifySqliteFailure, ClientSyncError, STORAGE_BUSY_CODE, } from './errors.js';
|
|
20
20
|
import { httpBlobTransport, httpSegmentDownloader, httpSyncTransport, webSocketRealtimeConnector, } from './http.js';
|
|
21
21
|
import { openPersistentWasmDatabase } from './wasm-database.js';
|
|
22
22
|
import { WORKER_FAILED_CODE, } from './worker-protocol.js';
|
|
23
|
-
function toErrorShape(
|
|
23
|
+
function toErrorShape(caught) {
|
|
24
|
+
const error = classifySqliteFailure(caught).error;
|
|
24
25
|
if (error instanceof ClientSyncError) {
|
|
25
26
|
return {
|
|
26
27
|
code: error.code,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@syncular/client",
|
|
3
|
-
"version": "0.30.
|
|
3
|
+
"version": "0.30.7",
|
|
4
4
|
"description": "Syncular TypeScript client core — offline-first sync over SQLite (WASM/OPFS, Bun, Node)",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Benjamin Kniffler",
|
|
@@ -89,10 +89,10 @@
|
|
|
89
89
|
},
|
|
90
90
|
"dependencies": {
|
|
91
91
|
"@sqlite.org/sqlite-wasm": "^3.53.0-build1",
|
|
92
|
-
"@syncular/core": "0.30.
|
|
92
|
+
"@syncular/core": "0.30.7"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
|
-
"@syncular/server": "0.30.
|
|
95
|
+
"@syncular/server": "0.30.7",
|
|
96
96
|
"playwright": "1.63.0"
|
|
97
97
|
}
|
|
98
98
|
}
|
package/src/client.ts
CHANGED
|
@@ -3391,7 +3391,8 @@ export class SyncClient {
|
|
|
3391
3391
|
this.#emitDiagnostics();
|
|
3392
3392
|
return summary;
|
|
3393
3393
|
},
|
|
3394
|
-
(
|
|
3394
|
+
(caught: unknown) => {
|
|
3395
|
+
const error = classifySqliteFailure(caught).error;
|
|
3395
3396
|
const completedAtMs = this.#now();
|
|
3396
3397
|
const code = (error as { code?: unknown }).code;
|
|
3397
3398
|
this.#progress.update({
|
package/src/database.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { classifySqliteFailure } from './errors';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Storage abstraction: the client core runs on any SQLite that
|
|
3
5
|
* implements this minimal synchronous surface. Tests use bun:sqlite
|
|
@@ -75,29 +77,43 @@ export function assertImageAlias(alias: string): void {
|
|
|
75
77
|
* `run` executes a parameterless statement.
|
|
76
78
|
*/
|
|
77
79
|
export function runTransaction<T>(
|
|
78
|
-
depthHolder: { depth: number },
|
|
80
|
+
depthHolder: { depth: number; aborted?: { error: unknown } },
|
|
79
81
|
run: (sql: string) => void,
|
|
80
82
|
fn: () => T,
|
|
81
83
|
): T {
|
|
82
84
|
const depth = depthHolder.depth;
|
|
85
|
+
if (depth === 0) delete depthHolder.aborted;
|
|
86
|
+
else if (depthHolder.aborted) throw depthHolder.aborted.error;
|
|
83
87
|
const savepoint = `syncular_sp_${depth}`;
|
|
84
88
|
if (depth === 0) run('BEGIN');
|
|
85
89
|
else run(`SAVEPOINT ${savepoint}`);
|
|
86
90
|
depthHolder.depth = depth + 1;
|
|
87
91
|
try {
|
|
88
92
|
const result = fn();
|
|
93
|
+
const aborted = depthHolder.aborted as { error: unknown } | undefined;
|
|
94
|
+
if (aborted) throw aborted.error;
|
|
89
95
|
depthHolder.depth = depth;
|
|
90
96
|
if (depth === 0) run('COMMIT');
|
|
91
97
|
else run(`RELEASE ${savepoint}`);
|
|
92
98
|
return result;
|
|
93
|
-
} catch (
|
|
99
|
+
} catch (caught) {
|
|
100
|
+
const aborted = depthHolder.aborted as { error: unknown } | undefined;
|
|
101
|
+
const error = aborted?.error ?? caught;
|
|
94
102
|
depthHolder.depth = depth;
|
|
95
|
-
|
|
96
|
-
run('ROLLBACK');
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
103
|
+
try {
|
|
104
|
+
if (depth === 0) run('ROLLBACK');
|
|
105
|
+
else {
|
|
106
|
+
run(`ROLLBACK TO ${savepoint}`);
|
|
107
|
+
run(`RELEASE ${savepoint}`);
|
|
108
|
+
}
|
|
109
|
+
} catch (rollbackError) {
|
|
110
|
+
// SQLite can end the whole transaction after SQLITE_FULL or SQLITE_IOERR.
|
|
111
|
+
// Poison remaining nested scopes until the outer owner unwinds.
|
|
112
|
+
depthHolder.aborted = { error };
|
|
113
|
+
if (error instanceof Error && !('rollbackError' in error)) {
|
|
114
|
+
Object.defineProperty(error, 'rollbackError', { value: rollbackError });
|
|
115
|
+
}
|
|
100
116
|
}
|
|
101
|
-
throw error;
|
|
117
|
+
throw classifySqliteFailure(error).error;
|
|
102
118
|
}
|
|
103
119
|
}
|
package/src/diagnostics.ts
CHANGED
|
@@ -151,6 +151,7 @@ export interface DiagnosticQueryFailure {
|
|
|
151
151
|
readonly tables: readonly string[];
|
|
152
152
|
readonly code:
|
|
153
153
|
| 'client.storage_corrupt'
|
|
154
|
+
| 'client.storage_full'
|
|
154
155
|
| 'client.storage_io'
|
|
155
156
|
| 'client.query_failed';
|
|
156
157
|
/** SQLite extended result code, when the driver exposed one. */
|
package/src/errors.ts
CHANGED
|
@@ -9,6 +9,9 @@ export const STORAGE_UNAVAILABLE_CODE = 'client.storage_unavailable';
|
|
|
9
9
|
/** A local read hit SQLITE_CORRUPT or SQLITE_NOTADB (SPEC §7.5). */
|
|
10
10
|
export const STORAGE_CORRUPT_CODE = 'client.storage_corrupt';
|
|
11
11
|
|
|
12
|
+
/** Local SQLite storage has no space for the write. */
|
|
13
|
+
export const STORAGE_FULL_CODE = 'client.storage_full';
|
|
14
|
+
|
|
12
15
|
/** A local read hit SQLITE_IOERR (SPEC §7.5). */
|
|
13
16
|
export const STORAGE_IO_CODE = 'client.storage_io';
|
|
14
17
|
|
|
@@ -107,10 +110,45 @@ export function classifySqliteFailure(error: unknown): {
|
|
|
107
110
|
readonly sqliteCode: number | undefined;
|
|
108
111
|
readonly code:
|
|
109
112
|
| typeof STORAGE_CORRUPT_CODE
|
|
113
|
+
| typeof STORAGE_FULL_CODE
|
|
110
114
|
| typeof STORAGE_IO_CODE
|
|
111
115
|
| undefined;
|
|
112
116
|
readonly error: unknown;
|
|
113
117
|
} {
|
|
118
|
+
if (error instanceof ClientSyncError) {
|
|
119
|
+
const sqliteCode = error.details?.sqliteCode;
|
|
120
|
+
let retained = error;
|
|
121
|
+
if (
|
|
122
|
+
'rollbackError' in error &&
|
|
123
|
+
error.details?.rollbackFailure === undefined
|
|
124
|
+
) {
|
|
125
|
+
const rollback = error.rollbackError;
|
|
126
|
+
retained = new ClientSyncError(
|
|
127
|
+
error.code,
|
|
128
|
+
error.message,
|
|
129
|
+
error.retryable,
|
|
130
|
+
{
|
|
131
|
+
...error.details,
|
|
132
|
+
rollbackFailure: {
|
|
133
|
+
message:
|
|
134
|
+
rollback instanceof Error ? rollback.message : String(rollback),
|
|
135
|
+
sqliteCode: classifySqliteFailure(rollback).sqliteCode,
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
);
|
|
139
|
+
Object.defineProperty(retained, 'cause', { value: error });
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
sqliteCode: typeof sqliteCode === 'number' ? sqliteCode : undefined,
|
|
143
|
+
code:
|
|
144
|
+
error.code === STORAGE_FULL_CODE ||
|
|
145
|
+
error.code === STORAGE_IO_CODE ||
|
|
146
|
+
error.code === STORAGE_CORRUPT_CODE
|
|
147
|
+
? error.code
|
|
148
|
+
: undefined,
|
|
149
|
+
error: retained,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
114
152
|
const sqliteCode =
|
|
115
153
|
error instanceof Error
|
|
116
154
|
? error.name === 'SQLiteError' &&
|
|
@@ -126,25 +164,41 @@ export function classifySqliteFailure(error: unknown): {
|
|
|
126
164
|
: undefined
|
|
127
165
|
: undefined;
|
|
128
166
|
const primary = sqliteCode === undefined ? undefined : sqliteCode & 0xff;
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
167
|
+
const code =
|
|
168
|
+
primary === 13
|
|
169
|
+
? STORAGE_FULL_CODE
|
|
170
|
+
: primary === 10
|
|
171
|
+
? STORAGE_IO_CODE
|
|
172
|
+
: primary === 11 || primary === 26
|
|
173
|
+
? STORAGE_CORRUPT_CODE
|
|
174
|
+
: undefined;
|
|
175
|
+
if (code === undefined) return { sqliteCode, code, error };
|
|
176
|
+
const rollback =
|
|
177
|
+
error instanceof Error && 'rollbackError' in error
|
|
178
|
+
? error.rollbackError
|
|
179
|
+
: undefined;
|
|
180
|
+
const failure = new ClientSyncError(
|
|
181
|
+
code,
|
|
182
|
+
primary === 13
|
|
183
|
+
? 'local SQLite storage is full'
|
|
184
|
+
: primary === 10
|
|
185
|
+
? 'local SQLite storage I/O failed'
|
|
186
|
+
: 'local SQLite storage is corrupt',
|
|
187
|
+
false,
|
|
188
|
+
{
|
|
141
189
|
sqliteCode,
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
190
|
+
sqliteMessage: error instanceof Error ? error.message : String(error),
|
|
191
|
+
...(rollback !== undefined
|
|
192
|
+
? {
|
|
193
|
+
rollbackFailure: {
|
|
194
|
+
message:
|
|
195
|
+
rollback instanceof Error ? rollback.message : String(rollback),
|
|
196
|
+
sqliteCode: classifySqliteFailure(rollback).sqliteCode,
|
|
197
|
+
},
|
|
198
|
+
}
|
|
199
|
+
: {}),
|
|
200
|
+
},
|
|
201
|
+
);
|
|
202
|
+
Object.defineProperty(failure, 'cause', { value: error });
|
|
203
|
+
return { sqliteCode, code, error: failure };
|
|
150
204
|
}
|
package/src/worker-entry.ts
CHANGED
|
@@ -20,7 +20,11 @@ import {
|
|
|
20
20
|
withClientDiagnosticsHost,
|
|
21
21
|
} from './diagnostics';
|
|
22
22
|
import { encryptionConfigFromKeyring } from './encryption';
|
|
23
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
classifySqliteFailure,
|
|
25
|
+
ClientSyncError,
|
|
26
|
+
STORAGE_BUSY_CODE,
|
|
27
|
+
} from './errors';
|
|
24
28
|
import {
|
|
25
29
|
httpBlobTransport,
|
|
26
30
|
httpSegmentDownloader,
|
|
@@ -77,7 +81,8 @@ interface WorkerScope {
|
|
|
77
81
|
): void;
|
|
78
82
|
}
|
|
79
83
|
|
|
80
|
-
function toErrorShape(
|
|
84
|
+
function toErrorShape(caught: unknown): WorkerErrorShape {
|
|
85
|
+
const error = classifySqliteFailure(caught).error;
|
|
81
86
|
if (error instanceof ClientSyncError) {
|
|
82
87
|
return {
|
|
83
88
|
code: error.code,
|