@g9tm/syncdata 1.2.1
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/LICENSE.md +21 -0
- package/PARITY.md +71 -0
- package/README.md +71 -0
- package/THIRD-PARTY-NOTICES.md +31 -0
- package/dist/abstractions/digest.d.ts +27 -0
- package/dist/abstractions/digest.js +78 -0
- package/dist/abstractions/digest.js.map +1 -0
- package/dist/abstractions/enums.d.ts +42 -0
- package/dist/abstractions/enums.js +60 -0
- package/dist/abstractions/enums.js.map +1 -0
- package/dist/abstractions/errors.d.ts +72 -0
- package/dist/abstractions/errors.js +90 -0
- package/dist/abstractions/errors.js.map +1 -0
- package/dist/abstractions/guid.d.ts +24 -0
- package/dist/abstractions/guid.js +93 -0
- package/dist/abstractions/guid.js.map +1 -0
- package/dist/abstractions/key.d.ts +16 -0
- package/dist/abstractions/key.js +47 -0
- package/dist/abstractions/key.js.map +1 -0
- package/dist/abstractions/long.d.ts +103 -0
- package/dist/abstractions/long.js +351 -0
- package/dist/abstractions/long.js.map +1 -0
- package/dist/abstractions/parameters.d.ts +49 -0
- package/dist/abstractions/parameters.js +153 -0
- package/dist/abstractions/parameters.js.map +1 -0
- package/dist/brotli-js/decode.d.ts +8 -0
- package/dist/brotli-js/decode.js +2004 -0
- package/dist/brotli-js/decode.js.map +1 -0
- package/dist/brotli-js/index.d.ts +5 -0
- package/dist/brotli-js/index.js +19 -0
- package/dist/brotli-js/index.js.map +1 -0
- package/dist/client/engine.d.ts +110 -0
- package/dist/client/engine.js +1158 -0
- package/dist/client/engine.js.map +1 -0
- package/dist/client/model.d.ts +61 -0
- package/dist/client/model.js +154 -0
- package/dist/client/model.js.map +1 -0
- package/dist/client/progress.d.ts +101 -0
- package/dist/client/progress.js +251 -0
- package/dist/client/progress.js.map +1 -0
- package/dist/client/runs.d.ts +219 -0
- package/dist/client/runs.js +239 -0
- package/dist/client/runs.js.map +1 -0
- package/dist/client/storeTypes.d.ts +428 -0
- package/dist/client/storeTypes.js +256 -0
- package/dist/client/storeTypes.js.map +1 -0
- package/dist/client/transport.d.ts +19 -0
- package/dist/client/transport.js +2 -0
- package/dist/client/transport.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/abort.d.ts +21 -0
- package/dist/internal/abort.js +125 -0
- package/dist/internal/abort.js.map +1 -0
- package/dist/internal/base64.d.ts +8 -0
- package/dist/internal/base64.js +85 -0
- package/dist/internal/base64.js.map +1 -0
- package/dist/internal/dotnetFormat.d.ts +32 -0
- package/dist/internal/dotnetFormat.js +207 -0
- package/dist/internal/dotnetFormat.js.map +1 -0
- package/dist/internal/md5.d.ts +2 -0
- package/dist/internal/md5.js +97 -0
- package/dist/internal/md5.js.map +1 -0
- package/dist/internal/sha256.d.ts +20 -0
- package/dist/internal/sha256.js +153 -0
- package/dist/internal/sha256.js.map +1 -0
- package/dist/internal/utf8.d.ts +8 -0
- package/dist/internal/utf8.js +143 -0
- package/dist/internal/utf8.js.map +1 -0
- package/dist/node/index.d.ts +9 -0
- package/dist/node/index.js +35 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/sqliteDriver.d.ts +11 -0
- package/dist/node/sqliteDriver.js +252 -0
- package/dist/node/sqliteDriver.js.map +1 -0
- package/dist/protocol/dtos.d.ts +280 -0
- package/dist/protocol/dtos.js +33 -0
- package/dist/protocol/dtos.js.map +1 -0
- package/dist/protocol/protocol.d.ts +36 -0
- package/dist/protocol/protocol.js +63 -0
- package/dist/protocol/protocol.js.map +1 -0
- package/dist/protocol/rowBatch/columnLayout.d.ts +4 -0
- package/dist/protocol/rowBatch/columnLayout.js +309 -0
- package/dist/protocol/rowBatch/columnLayout.js.map +1 -0
- package/dist/protocol/rowBatch/format.d.ts +74 -0
- package/dist/protocol/rowBatch/format.js +163 -0
- package/dist/protocol/rowBatch/format.js.map +1 -0
- package/dist/protocol/rowBatch/reader.d.ts +119 -0
- package/dist/protocol/rowBatch/reader.js +459 -0
- package/dist/protocol/rowBatch/reader.js.map +1 -0
- package/dist/protocol/rowBatch/writer.d.ts +101 -0
- package/dist/protocol/rowBatch/writer.js +412 -0
- package/dist/protocol/rowBatch/writer.js.map +1 -0
- package/dist/protocol/wire.d.ts +32 -0
- package/dist/protocol/wire.js +329 -0
- package/dist/protocol/wire.js.map +1 -0
- package/dist/signalr/index.d.ts +2 -0
- package/dist/signalr/index.js +5 -0
- package/dist/signalr/index.js.map +1 -0
- package/dist/signalr/protocols.d.ts +17 -0
- package/dist/signalr/protocols.js +109 -0
- package/dist/signalr/protocols.js.map +1 -0
- package/dist/signalr/transport.d.ts +67 -0
- package/dist/signalr/transport.js +286 -0
- package/dist/signalr/transport.js.map +1 -0
- package/dist/sqlite/apply.d.ts +91 -0
- package/dist/sqlite/apply.js +657 -0
- package/dist/sqlite/apply.js.map +1 -0
- package/dist/sqlite/commands.d.ts +24 -0
- package/dist/sqlite/commands.js +167 -0
- package/dist/sqlite/commands.js.map +1 -0
- package/dist/sqlite/connection.d.ts +81 -0
- package/dist/sqlite/connection.js +322 -0
- package/dist/sqlite/connection.js.map +1 -0
- package/dist/sqlite/driver.d.ts +63 -0
- package/dist/sqlite/driver.js +9 -0
- package/dist/sqlite/driver.js.map +1 -0
- package/dist/sqlite/index.d.ts +6 -0
- package/dist/sqlite/index.js +7 -0
- package/dist/sqlite/index.js.map +1 -0
- package/dist/sqlite/internals.d.ts +63 -0
- package/dist/sqlite/internals.js +194 -0
- package/dist/sqlite/internals.js.map +1 -0
- package/dist/sqlite/options.d.ts +78 -0
- package/dist/sqlite/options.js +78 -0
- package/dist/sqlite/options.js.map +1 -0
- package/dist/sqlite/push.d.ts +9 -0
- package/dist/sqlite/push.js +272 -0
- package/dist/sqlite/push.js.map +1 -0
- package/dist/sqlite/query.d.ts +38 -0
- package/dist/sqlite/query.js +476 -0
- package/dist/sqlite/query.js.map +1 -0
- package/dist/sqlite/revocation.d.ts +28 -0
- package/dist/sqlite/revocation.js +337 -0
- package/dist/sqlite/revocation.js.map +1 -0
- package/dist/sqlite/sql.d.ts +60 -0
- package/dist/sqlite/sql.js +324 -0
- package/dist/sqlite/sql.js.map +1 -0
- package/dist/sqlite/store.d.ts +116 -0
- package/dist/sqlite/store.js +664 -0
- package/dist/sqlite/store.js.map +1 -0
- package/dist/sqlite/values.d.ts +29 -0
- package/dist/sqlite/values.js +288 -0
- package/dist/sqlite/values.js.map +1 -0
- package/dist/testing/index.d.ts +61 -0
- package/dist/testing/index.js +175 -0
- package/dist/testing/index.js.map +1 -0
- package/package.json +104 -0
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { G9SyncErrorCodes, G9SyncException, isSyncException } from '../abstractions/errors.js';
|
|
2
|
+
import { newGuid } from '../abstractions/guid.js';
|
|
3
|
+
import { G9SyncProtocol } from '../protocol/protocol.js';
|
|
4
|
+
import { G9RowBatchFormatError } from '../protocol/rowBatch/format.js';
|
|
5
|
+
import { columnTypeName } from '../abstractions/enums.js';
|
|
6
|
+
import { createAbortController } from '../internal/abort.js';
|
|
7
|
+
import { G9ApplyReport, G9ELocalStoreFailure, isLocalStoreFailure, } from './storeTypes.js';
|
|
8
|
+
/** Scheduling priority (`G9ESyncPriority`). A higher priority pre-empts a running background run. */
|
|
9
|
+
export const G9ESyncPriority = {
|
|
10
|
+
Background: 0,
|
|
11
|
+
Foreground: 1,
|
|
12
|
+
UserInteractive: 2,
|
|
13
|
+
};
|
|
14
|
+
const PRIORITY_NAMES = ['Background', 'Foreground', 'UserInteractive'];
|
|
15
|
+
export function priorityName(priority) {
|
|
16
|
+
var _a;
|
|
17
|
+
return (_a = PRIORITY_NAMES[priority]) !== null && _a !== void 0 ? _a : String(priority);
|
|
18
|
+
}
|
|
19
|
+
/** `G9ESyncOutcome`. */
|
|
20
|
+
export const G9ESyncOutcome = {
|
|
21
|
+
Succeeded: 0,
|
|
22
|
+
/** Data moved, but some rows were rejected or some subscriptions reported problems. */
|
|
23
|
+
CompletedWithRejections: 1,
|
|
24
|
+
Failed: 2,
|
|
25
|
+
Canceled: 3,
|
|
26
|
+
};
|
|
27
|
+
const OUTCOME_NAMES = ['Succeeded', 'CompletedWithRejections', 'Failed', 'Canceled'];
|
|
28
|
+
export function outcomeName(outcome) {
|
|
29
|
+
var _a;
|
|
30
|
+
return (_a = OUTCOME_NAMES[outcome]) !== null && _a !== void 0 ? _a : String(outcome);
|
|
31
|
+
}
|
|
32
|
+
/** An app-owned step that runs after the data applied and owns a slice of the progress bar (`G9CSyncPostStep`). */
|
|
33
|
+
export class G9SyncPostStep {
|
|
34
|
+
constructor(name, weightHint, action) {
|
|
35
|
+
if (typeof name !== 'string' || name.trim() === '')
|
|
36
|
+
throw new TypeError('A post step needs a name.');
|
|
37
|
+
if (typeof action !== 'function')
|
|
38
|
+
throw new TypeError('A post step needs an action.');
|
|
39
|
+
this.name = name;
|
|
40
|
+
this.weightHint = Math.min(Math.max(weightHint, 0), 0.9);
|
|
41
|
+
this.action = action;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export function resolveRequest(request) {
|
|
45
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
46
|
+
return {
|
|
47
|
+
subscriptions: (_a = request === null || request === void 0 ? void 0 : request.subscriptions) !== null && _a !== void 0 ? _a : null,
|
|
48
|
+
push: (_b = request === null || request === void 0 ? void 0 : request.push) !== null && _b !== void 0 ? _b : true,
|
|
49
|
+
pull: (_c = request === null || request === void 0 ? void 0 : request.pull) !== null && _c !== void 0 ? _c : true,
|
|
50
|
+
forceReconcile: (_d = request === null || request === void 0 ? void 0 : request.forceReconcile) !== null && _d !== void 0 ? _d : false,
|
|
51
|
+
priority: (_e = request === null || request === void 0 ? void 0 : request.priority) !== null && _e !== void 0 ? _e : 1,
|
|
52
|
+
postSteps: (_f = request === null || request === void 0 ? void 0 : request.postSteps) !== null && _f !== void 0 ? _f : [],
|
|
53
|
+
progress: (_g = request === null || request === void 0 ? void 0 : request.progress) !== null && _g !== void 0 ? _g : null,
|
|
54
|
+
signal: (_h = request === null || request === void 0 ? void 0 : request.signal) !== null && _h !== void 0 ? _h : null,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/** `G9CSyncRequest.CanCoalesce`. */
|
|
58
|
+
export function canCoalesce(request) {
|
|
59
|
+
return request.postSteps.length === 0 && request.progress === null && request.signal === null;
|
|
60
|
+
}
|
|
61
|
+
/** `G9CSyncRequest.Signature`. */
|
|
62
|
+
export function requestSignature(request) {
|
|
63
|
+
const subscriptions = request.subscriptions === null ? '*' : request.subscriptions.slice().sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)).join(',');
|
|
64
|
+
return `${request.push ? 'True' : 'False'}|${request.pull ? 'True' : 'False'}|${request.forceReconcile ? 'True' : 'False'}|${subscriptions}`;
|
|
65
|
+
}
|
|
66
|
+
export function describeModelProblem(problem) {
|
|
67
|
+
return `${problem.table}.${problem.column} is ${columnTypeName(problem.clientType)} on the client and ${columnTypeName(problem.serverType)} on the server`;
|
|
68
|
+
}
|
|
69
|
+
export function makeRunResult(fields) {
|
|
70
|
+
return {
|
|
71
|
+
error: null,
|
|
72
|
+
pushed: 0,
|
|
73
|
+
rejected: 0,
|
|
74
|
+
conflicts: 0,
|
|
75
|
+
downloaded: 0,
|
|
76
|
+
applied: 0,
|
|
77
|
+
durationMs: 0,
|
|
78
|
+
phaseMs: {},
|
|
79
|
+
subscriptions: [],
|
|
80
|
+
problems: [],
|
|
81
|
+
modelProblems: [],
|
|
82
|
+
changes: new G9ApplyReport(),
|
|
83
|
+
...fields,
|
|
84
|
+
isSuccess: fields.outcome === G9ESyncOutcome.Succeeded || fields.outcome === G9ESyncOutcome.CompletedWithRejections,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/** A queued or running sync (`G9CSyncRun`). Await {@link completion}; read progress with {@link onProgress} or {@link progress}. */
|
|
88
|
+
export class G9SyncRun {
|
|
89
|
+
constructor(request) {
|
|
90
|
+
this.runId = newGuid();
|
|
91
|
+
this.latestProgress = null;
|
|
92
|
+
this.isStarted = false;
|
|
93
|
+
/** @internal */
|
|
94
|
+
this.preempted = false;
|
|
95
|
+
this._listeners = [];
|
|
96
|
+
this._buffer = [];
|
|
97
|
+
this._waiters = [];
|
|
98
|
+
this._done = false;
|
|
99
|
+
this._unlink = () => undefined;
|
|
100
|
+
this.request = request;
|
|
101
|
+
this.completion = new Promise((resolve) => {
|
|
102
|
+
this._resolve = resolve;
|
|
103
|
+
});
|
|
104
|
+
this.cancellation = createAbortController();
|
|
105
|
+
const external = request.signal;
|
|
106
|
+
if (external) {
|
|
107
|
+
if (external.aborted)
|
|
108
|
+
this.cancellation.abort();
|
|
109
|
+
else {
|
|
110
|
+
const listener = () => this.cancellation.abort();
|
|
111
|
+
external.addEventListener('abort', listener);
|
|
112
|
+
this._unlink = () => external.removeEventListener('abort', listener);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/** Requests cancellation. Network phases stop at once; an apply in progress finishes atomically first. */
|
|
117
|
+
cancel() {
|
|
118
|
+
this.cancellation.abort();
|
|
119
|
+
}
|
|
120
|
+
/** Subscribes to progress samples; returns the unsubscribe function. */
|
|
121
|
+
onProgress(listener) {
|
|
122
|
+
this._listeners.push(listener);
|
|
123
|
+
return () => {
|
|
124
|
+
const index = this._listeners.indexOf(listener);
|
|
125
|
+
if (index >= 0)
|
|
126
|
+
this._listeners.splice(index, 1);
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/** The progress stream (bounded: the oldest samples are dropped when a reader falls 64 behind), ending with the run. */
|
|
130
|
+
progress() {
|
|
131
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
132
|
+
const run = this;
|
|
133
|
+
return {
|
|
134
|
+
[Symbol.asyncIterator]() {
|
|
135
|
+
return {
|
|
136
|
+
next() {
|
|
137
|
+
const value = run._buffer.shift();
|
|
138
|
+
if (value)
|
|
139
|
+
return Promise.resolve({ value, done: false });
|
|
140
|
+
if (run._done)
|
|
141
|
+
return Promise.resolve({ value: undefined, done: true });
|
|
142
|
+
return new Promise((resolve) => run._waiters.push(resolve));
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/** @internal */
|
|
149
|
+
publish(progress) {
|
|
150
|
+
var _a, _b;
|
|
151
|
+
this.latestProgress = progress;
|
|
152
|
+
const waiter = this._waiters.shift();
|
|
153
|
+
if (waiter)
|
|
154
|
+
waiter({ value: progress, done: false });
|
|
155
|
+
else {
|
|
156
|
+
this._buffer.push(progress);
|
|
157
|
+
if (this._buffer.length > 64)
|
|
158
|
+
this._buffer.shift();
|
|
159
|
+
}
|
|
160
|
+
for (const listener of this._listeners.slice()) {
|
|
161
|
+
try {
|
|
162
|
+
listener(progress);
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// A progress consumer must never break the sync.
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
try {
|
|
169
|
+
(_b = (_a = this.request).progress) === null || _b === void 0 ? void 0 : _b.call(_a, progress);
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
// A progress consumer must never break the sync.
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/** @internal */
|
|
176
|
+
complete(result) {
|
|
177
|
+
if (this._done)
|
|
178
|
+
return;
|
|
179
|
+
this._done = true;
|
|
180
|
+
for (const waiter of this._waiters.splice(0, this._waiters.length))
|
|
181
|
+
waiter({ value: undefined, done: true });
|
|
182
|
+
this._unlink();
|
|
183
|
+
this._resolve(result);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
export function resolveEngineOptions(options) {
|
|
187
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
|
|
188
|
+
return {
|
|
189
|
+
appVersion: (_a = options === null || options === void 0 ? void 0 : options.appVersion) !== null && _a !== void 0 ? _a : null,
|
|
190
|
+
pushBatchRows: (_b = options === null || options === void 0 ? void 0 : options.pushBatchRows) !== null && _b !== void 0 ? _b : 2000,
|
|
191
|
+
maxRetries: (_c = options === null || options === void 0 ? void 0 : options.maxRetries) !== null && _c !== void 0 ? _c : 5,
|
|
192
|
+
retryBaseDelayMs: (_d = options === null || options === void 0 ? void 0 : options.retryBaseDelayMs) !== null && _d !== void 0 ? _d : 1000,
|
|
193
|
+
pullOnChangesAvailable: (_e = options === null || options === void 0 ? void 0 : options.pullOnChangesAvailable) !== null && _e !== void 0 ? _e : true,
|
|
194
|
+
changesDebounceMs: (_f = options === null || options === void 0 ? void 0 : options.changesDebounceMs) !== null && _f !== void 0 ? _f : 2000,
|
|
195
|
+
progressMaxHz: (_g = options === null || options === void 0 ? void 0 : options.progressMaxHz) !== null && _g !== void 0 ? _g : 10,
|
|
196
|
+
fetchKeysPerRequest: (_h = options === null || options === void 0 ? void 0 : options.fetchKeysPerRequest) !== null && _h !== void 0 ? _h : 2000,
|
|
197
|
+
reconcileApplyRows: (_j = options === null || options === void 0 ? void 0 : options.reconcileApplyRows) !== null && _j !== void 0 ? _j : 20000,
|
|
198
|
+
reconcileSnapshotThreshold: (_k = options === null || options === void 0 ? void 0 : options.reconcileSnapshotThreshold) !== null && _k !== void 0 ? _k : 100000,
|
|
199
|
+
maxDecodedFrameBytes: (_l = options === null || options === void 0 ? void 0 : options.maxDecodedFrameBytes) !== null && _l !== void 0 ? _l : 64 * 1024 * 1024,
|
|
200
|
+
maxFrameVersion: (_m = options === null || options === void 0 ? void 0 : options.maxFrameVersion) !== null && _m !== void 0 ? _m : G9SyncProtocol.MaxFrameVersion,
|
|
201
|
+
failOnTypeMismatch: (_o = options === null || options === void 0 ? void 0 : options.failOnTypeMismatch) !== null && _o !== void 0 ? _o : false,
|
|
202
|
+
stagedPullMaxAgeMs: (_p = options === null || options === void 0 ? void 0 : options.stagedPullMaxAgeMs) !== null && _p !== void 0 ? _p : 90 * 60 * 1000,
|
|
203
|
+
stagedPullsMaxBytes: (_q = options === null || options === void 0 ? void 0 : options.stagedPullsMaxBytes) !== null && _q !== void 0 ? _q : 64 * 1024 * 1024,
|
|
204
|
+
keepDeletedFeedEntries: (_r = options === null || options === void 0 ? void 0 : options.keepDeletedFeedEntries) !== null && _r !== void 0 ? _r : 50000,
|
|
205
|
+
keepRunReports: (_s = options === null || options === void 0 ? void 0 : options.keepRunReports) !== null && _s !== void 0 ? _s : 50,
|
|
206
|
+
logger: (_t = options === null || options === void 0 ? void 0 : options.logger) !== null && _t !== void 0 ? _t : null,
|
|
207
|
+
hooks: (_u = options === null || options === void 0 ? void 0 : options.hooks) !== null && _u !== void 0 ? _u : null,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
/** `G9CSyncErrors.Normalize`: every failure becomes a G9SyncException with a stable code. */
|
|
211
|
+
export function normalizeError(error) {
|
|
212
|
+
if (isSyncException(error))
|
|
213
|
+
return error;
|
|
214
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
215
|
+
if (error instanceof Error && error.name === 'AbortError')
|
|
216
|
+
return new G9SyncException(G9SyncErrorCodes.Canceled, 'The sync was canceled.', { cause: error });
|
|
217
|
+
if (isLocalStoreFailure(error)) {
|
|
218
|
+
const code = error.localStoreFailure === G9ELocalStoreFailure.Corrupt
|
|
219
|
+
? G9SyncErrorCodes.LocalStoreCorrupt
|
|
220
|
+
: error.localStoreFailure === G9ELocalStoreFailure.DiskFull
|
|
221
|
+
? G9SyncErrorCodes.LocalStoreDiskFull
|
|
222
|
+
: error.localStoreFailure === G9ELocalStoreFailure.Busy
|
|
223
|
+
? G9SyncErrorCodes.LocalStoreBusy
|
|
224
|
+
: G9SyncErrorCodes.LocalStoreError;
|
|
225
|
+
return new G9SyncException(code, message, { cause: error });
|
|
226
|
+
}
|
|
227
|
+
if (error instanceof G9RowBatchFormatError)
|
|
228
|
+
return new G9SyncException(G9SyncErrorCodes.Unknown, message, { cause: error });
|
|
229
|
+
if (error instanceof Error && (error.name === 'TimeoutError' || /network|socket|websocket|connection/i.test(error.name))) {
|
|
230
|
+
return new G9SyncException(G9SyncErrorCodes.NetworkFailure, message, { cause: error });
|
|
231
|
+
}
|
|
232
|
+
return new G9SyncException(G9SyncErrorCodes.Unknown, message, { cause: error });
|
|
233
|
+
}
|
|
234
|
+
/** `G9CSyncErrors.IsTransient`. */
|
|
235
|
+
export function isTransientError(error) {
|
|
236
|
+
const code = normalizeError(error).code;
|
|
237
|
+
return code === G9SyncErrorCodes.NetworkFailure || code === G9SyncErrorCodes.ServerError || code === G9SyncErrorCodes.ServerBusy;
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=runs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runs.js","sourceRoot":"","sources":["../../src/client/runs.ts"],"names":[],"mappings":"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","sourcesContent":["// Twins of G9SyncData.Client/Runs/G9SyncRunTypes.cs and the option/health/error types of G9CSyncEngineOptions.cs.\nimport type { G9ESyncColumnType } from '../abstractions/enums.js';\nimport { G9SyncErrorCodes, G9SyncException, isSyncException } from '../abstractions/errors.js';\nimport { newGuid } from '../abstractions/guid.js';\nimport { G9SyncProtocol } from '../protocol/protocol.js';\nimport type { G9DtSubscriptionState } from '../protocol/dtos.js';\nimport { G9RowBatchFormatError } from '../protocol/rowBatch/format.js';\nimport { columnTypeName } from '../abstractions/enums.js';\nimport { createAbortController, type G9AbortController } from '../internal/abort.js';\nimport type { G9DtSyncProgress, G9ESyncPhase } from './progress.js';\nimport {\n G9ApplyReport,\n G9ELocalStoreFailure,\n isLocalStoreFailure,\n type G9ApplySlice,\n type G9PendingSummary,\n type G9SyncRunReport,\n type G9SyncSubscriptionRecord,\n} from './storeTypes.js';\n\n/** Scheduling priority (`G9ESyncPriority`). A higher priority pre-empts a running background run. */\nexport const G9ESyncPriority = {\n Background: 0,\n Foreground: 1,\n UserInteractive: 2,\n} as const;\nexport type G9ESyncPriority = (typeof G9ESyncPriority)[keyof typeof G9ESyncPriority];\n\nconst PRIORITY_NAMES = ['Background', 'Foreground', 'UserInteractive'];\nexport function priorityName(priority: number): string {\n return PRIORITY_NAMES[priority] ?? String(priority);\n}\n\n/** `G9ESyncOutcome`. */\nexport const G9ESyncOutcome = {\n Succeeded: 0,\n /** Data moved, but some rows were rejected or some subscriptions reported problems. */\n CompletedWithRejections: 1,\n Failed: 2,\n Canceled: 3,\n} as const;\nexport type G9ESyncOutcome = (typeof G9ESyncOutcome)[keyof typeof G9ESyncOutcome];\n\nconst OUTCOME_NAMES = ['Succeeded', 'CompletedWithRejections', 'Failed', 'Canceled'];\nexport function outcomeName(outcome: number): string {\n return OUTCOME_NAMES[outcome] ?? String(outcome);\n}\n\n/** Context handed to an app-owned post step (`G9CSyncPostStepContext`). */\nexport interface G9SyncPostStepContext {\n run: G9SyncRun;\n /** Everything this run changed so far. */\n changes: G9ApplyReport;\n /** Report 0..1 of the step; mapped into the step's slice of the bar. */\n progress: (fraction: number) => void;\n}\n\n/** An app-owned step that runs after the data applied and owns a slice of the progress bar (`G9CSyncPostStep`). */\nexport class G9SyncPostStep {\n readonly name: string;\n readonly weightHint: number;\n readonly action: (context: G9SyncPostStepContext, signal: AbortSignal) => Promise<void>;\n\n constructor(name: string, weightHint: number, action: (context: G9SyncPostStepContext, signal: AbortSignal) => Promise<void>) {\n if (typeof name !== 'string' || name.trim() === '') throw new TypeError('A post step needs a name.');\n if (typeof action !== 'function') throw new TypeError('A post step needs an action.');\n this.name = name;\n this.weightHint = Math.min(Math.max(weightHint, 0), 0.9);\n this.action = action;\n }\n}\n\n/** A sync request (`G9CSyncRequest`). */\nexport interface G9SyncRequest {\n /** Subscription keys or names to pull; omitted = every local subscription (background runs skip heavy ones). */\n subscriptions?: readonly string[] | null;\n push?: boolean;\n pull?: boolean;\n /** Reconcile the selected subscriptions even when nothing asks for it. */\n forceReconcile?: boolean;\n priority?: G9ESyncPriority;\n postSteps?: readonly G9SyncPostStep[];\n progress?: ((progress: G9DtSyncProgress) => void) | null;\n signal?: AbortSignal | null;\n}\n\n/** The request with its defaults filled in. */\nexport interface G9ResolvedSyncRequest {\n subscriptions: readonly string[] | null;\n push: boolean;\n pull: boolean;\n forceReconcile: boolean;\n priority: G9ESyncPriority;\n postSteps: readonly G9SyncPostStep[];\n progress: ((progress: G9DtSyncProgress) => void) | null;\n signal: AbortSignal | null;\n}\n\nexport function resolveRequest(request: G9SyncRequest | null | undefined): G9ResolvedSyncRequest {\n return {\n subscriptions: request?.subscriptions ?? null,\n push: request?.push ?? true,\n pull: request?.pull ?? true,\n forceReconcile: request?.forceReconcile ?? false,\n priority: request?.priority ?? 1,\n postSteps: request?.postSteps ?? [],\n progress: request?.progress ?? null,\n signal: request?.signal ?? null,\n };\n}\n\n/** `G9CSyncRequest.CanCoalesce`. */\nexport function canCoalesce(request: G9ResolvedSyncRequest): boolean {\n return request.postSteps.length === 0 && request.progress === null && request.signal === null;\n}\n\n/** `G9CSyncRequest.Signature`. */\nexport function requestSignature(request: G9ResolvedSyncRequest): string {\n const subscriptions = request.subscriptions === null ? '*' : request.subscriptions.slice().sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)).join(',');\n return `${request.push ? 'True' : 'False'}|${request.pull ? 'True' : 'False'}|${request.forceReconcile ? 'True' : 'False'}|${subscriptions}`;\n}\n\n/** One defect of the client model, as the server sees it (`G9CSyncModelProblem`). */\nexport interface G9SyncModelProblem {\n code: string;\n table: string;\n column: string;\n clientType: G9ESyncColumnType;\n serverType: G9ESyncColumnType;\n}\n\nexport function describeModelProblem(problem: G9SyncModelProblem): string {\n return `${problem.table}.${problem.column} is ${columnTypeName(problem.clientType)} on the client and ${columnTypeName(problem.serverType)} on the server`;\n}\n\n/** The result of a run (`G9CSyncRunResult`). */\nexport interface G9SyncRunResult {\n runId: string;\n outcome: G9ESyncOutcome;\n error: G9SyncException | null;\n pushed: number;\n rejected: number;\n conflicts: number;\n downloaded: number;\n applied: number;\n durationMs: number;\n /** Milliseconds spent in each phase of this run, keyed by phase name. */\n phaseMs: { [phase: string]: number };\n subscriptions: string[];\n /** Subscriptions that could not sync, with the server's reason. */\n problems: G9DtSubscriptionState[];\n /** Defects of the client model the server reported in this run's hello (ADR-0061). */\n modelProblems: G9SyncModelProblem[];\n changes: G9ApplyReport;\n isSuccess: boolean;\n}\n\nexport function makeRunResult(fields: Partial<G9SyncRunResult> & { runId: string; outcome: G9ESyncOutcome }): G9SyncRunResult {\n return {\n error: null,\n pushed: 0,\n rejected: 0,\n conflicts: 0,\n downloaded: 0,\n applied: 0,\n durationMs: 0,\n phaseMs: {},\n subscriptions: [],\n problems: [],\n modelProblems: [],\n changes: new G9ApplyReport(),\n ...fields,\n isSuccess: fields.outcome === G9ESyncOutcome.Succeeded || fields.outcome === G9ESyncOutcome.CompletedWithRejections,\n };\n}\n\n/** A queued or running sync (`G9CSyncRun`). Await {@link completion}; read progress with {@link onProgress} or {@link progress}. */\nexport class G9SyncRun {\n readonly runId: string = newGuid();\n readonly request: G9ResolvedSyncRequest;\n readonly completion: Promise<G9SyncRunResult>;\n latestProgress: G9DtSyncProgress | null = null;\n isStarted = false;\n\n /** @internal */\n readonly cancellation: G9AbortController;\n /** @internal */\n preempted = false;\n\n private _resolve!: (result: G9SyncRunResult) => void;\n private readonly _listeners: ((progress: G9DtSyncProgress) => void)[] = [];\n private readonly _buffer: G9DtSyncProgress[] = [];\n private readonly _waiters: ((value: IteratorResult<G9DtSyncProgress>) => void)[] = [];\n private _done = false;\n private _unlink: () => void = () => undefined;\n\n constructor(request: G9ResolvedSyncRequest) {\n this.request = request;\n this.completion = new Promise<G9SyncRunResult>((resolve) => {\n this._resolve = resolve;\n });\n this.cancellation = createAbortController();\n const external = request.signal;\n if (external) {\n if (external.aborted) this.cancellation.abort();\n else {\n const listener = (): void => this.cancellation.abort();\n external.addEventListener('abort', listener);\n this._unlink = () => external.removeEventListener('abort', listener);\n }\n }\n }\n\n /** Requests cancellation. Network phases stop at once; an apply in progress finishes atomically first. */\n cancel(): void {\n this.cancellation.abort();\n }\n\n /** Subscribes to progress samples; returns the unsubscribe function. */\n onProgress(listener: (progress: G9DtSyncProgress) => void): () => void {\n this._listeners.push(listener);\n return () => {\n const index = this._listeners.indexOf(listener);\n if (index >= 0) this._listeners.splice(index, 1);\n };\n }\n\n /** The progress stream (bounded: the oldest samples are dropped when a reader falls 64 behind), ending with the run. */\n progress(): AsyncIterable<G9DtSyncProgress> {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const run = this;\n return {\n [Symbol.asyncIterator](): AsyncIterator<G9DtSyncProgress> {\n return {\n next(): Promise<IteratorResult<G9DtSyncProgress>> {\n const value = run._buffer.shift();\n if (value) return Promise.resolve({ value, done: false });\n if (run._done) return Promise.resolve({ value: undefined as unknown as G9DtSyncProgress, done: true });\n return new Promise((resolve) => run._waiters.push(resolve));\n },\n };\n },\n };\n }\n\n /** @internal */\n publish(progress: G9DtSyncProgress): void {\n this.latestProgress = progress;\n const waiter = this._waiters.shift();\n if (waiter) waiter({ value: progress, done: false });\n else {\n this._buffer.push(progress);\n if (this._buffer.length > 64) this._buffer.shift();\n }\n for (const listener of this._listeners.slice()) {\n try {\n listener(progress);\n } catch {\n // A progress consumer must never break the sync.\n }\n }\n try {\n this.request.progress?.(progress);\n } catch {\n // A progress consumer must never break the sync.\n }\n }\n\n /** @internal */\n complete(result: G9SyncRunResult): void {\n if (this._done) return;\n this._done = true;\n for (const waiter of this._waiters.splice(0, this._waiters.length)) waiter({ value: undefined as unknown as G9DtSyncProgress, done: true });\n this._unlink();\n this._resolve(result);\n }\n}\n\n/** `G9CSubscriptionOptions`. */\nexport interface G9SubscriptionOptions {\n /** Overrides the server definition's ephemeral flag. */\n ephemeral?: boolean;\n ttlMs?: number;\n /** The rows already exist locally: reconcile instead of downloading a snapshot. Call adoptExistingRows first. */\n adoptExistingRows?: boolean;\n}\n\n/** Engine options (`G9CSyncEngineOptions`). Durations are milliseconds. */\nexport interface G9SyncEngineOptions {\n /** Sent at Hello; the server's connect gates may refuse old versions. */\n appVersion?: string | null;\n pushBatchRows?: number;\n /** Transient failures retried inside one run. */\n maxRetries?: number;\n retryBaseDelayMs?: number;\n /** Queue a background pull when the server pokes about changed tables. */\n pullOnChangesAvailable?: boolean;\n changesDebounceMs?: number;\n progressMaxHz?: number;\n fetchKeysPerRequest?: number;\n /** Rows a reconciliation fetches before it applies them (ADR-0066). */\n reconcileApplyRows?: number;\n /** A reconciliation that would fetch at least this many rows of one table hands them to a staged snapshot (ADR-0066). 0 = never. */\n reconcileSnapshotThreshold?: number;\n /** The largest decoded body accepted from one server frame (ADR-0051). */\n maxDecodedFrameBytes?: number;\n /** The newest G9RowBatch body layout to ask the server for (ADR-0040). */\n maxFrameVersion?: number;\n /** Fail a run when the server reports a client column whose type differs (ADR-0061). */\n failOnTypeMismatch?: boolean;\n /** A staged pull older than this is discarded instead of resumed. */\n stagedPullMaxAgeMs?: number;\n /** Most payload bytes kept in stages other than the one a run resumes (ADR-0060). */\n stagedPullsMaxBytes?: number;\n keepDeletedFeedEntries?: number;\n keepRunReports?: number;\n /** Where the engine logs (the ILogger twin); silent when omitted. */\n logger?: G9SyncLogger | null;\n /** Platform integration (foreground service, keep-awake, connectivity). */\n hooks?: G9SyncHostHooks | null;\n}\n\nexport type G9ResolvedEngineOptions = Required<Omit<G9SyncEngineOptions, 'appVersion' | 'logger' | 'hooks'>> & {\n appVersion: string | null;\n logger: G9SyncLogger | null;\n hooks: G9SyncHostHooks | null;\n};\n\nexport function resolveEngineOptions(options: G9SyncEngineOptions | null | undefined): G9ResolvedEngineOptions {\n return {\n appVersion: options?.appVersion ?? null,\n pushBatchRows: options?.pushBatchRows ?? 2000,\n maxRetries: options?.maxRetries ?? 5,\n retryBaseDelayMs: options?.retryBaseDelayMs ?? 1000,\n pullOnChangesAvailable: options?.pullOnChangesAvailable ?? true,\n changesDebounceMs: options?.changesDebounceMs ?? 2000,\n progressMaxHz: options?.progressMaxHz ?? 10,\n fetchKeysPerRequest: options?.fetchKeysPerRequest ?? 2000,\n reconcileApplyRows: options?.reconcileApplyRows ?? 20000,\n reconcileSnapshotThreshold: options?.reconcileSnapshotThreshold ?? 100000,\n maxDecodedFrameBytes: options?.maxDecodedFrameBytes ?? 64 * 1024 * 1024,\n maxFrameVersion: options?.maxFrameVersion ?? G9SyncProtocol.MaxFrameVersion,\n failOnTypeMismatch: options?.failOnTypeMismatch ?? false,\n stagedPullMaxAgeMs: options?.stagedPullMaxAgeMs ?? 90 * 60 * 1000,\n stagedPullsMaxBytes: options?.stagedPullsMaxBytes ?? 64 * 1024 * 1024,\n keepDeletedFeedEntries: options?.keepDeletedFeedEntries ?? 50000,\n keepRunReports: options?.keepRunReports ?? 50,\n logger: options?.logger ?? null,\n hooks: options?.hooks ?? null,\n };\n}\n\n/** Log levels of {@link G9SyncLogger} (Microsoft.Extensions.Logging's). */\nexport type G9SyncLogLevel = 'debug' | 'information' | 'warning' | 'error';\n\n/** Where the library logs. `eventId` is the .NET LoggerMessage event id of the same message. */\nexport interface G9SyncLogger {\n log(level: G9SyncLogLevel, eventId: number, message: string, error?: unknown): void;\n}\n\n/** Platform integration points (`IG9SyncHostHooks`). */\nexport interface G9SyncHostHooks {\n /** Called when a run starts executing; the returned scope's `dispose` runs when it ends. */\n beginRun(run: G9SyncRun, signal: AbortSignal): Promise<{ dispose(): void | Promise<void> } | null>;\n /** False skips automatic background runs. */\n readonly isNetworkAvailable: boolean;\n}\n\n/** `G9CSyncHealth`. */\nexport interface G9SyncHealth {\n clientId: string;\n isConnected: boolean;\n isRunning: boolean;\n queuedRuns: number;\n serverEpoch: string | null;\n lastHelloUtcMs: number | null;\n pending: G9PendingSummary;\n subscriptions: G9SyncSubscriptionRecord[];\n recentRuns: G9SyncRunReport[];\n}\n\n/** `G9CRowsAppliedEventArgs`. */\nexport interface G9RowsAppliedEvent {\n report: G9ApplyReport;\n source: G9ESyncPhase;\n /** Set for a staged pull applied in slices (ADR-0053). */\n slice: G9ApplySlice | null;\n}\n\n/** `G9CSyncErrors.Normalize`: every failure becomes a G9SyncException with a stable code. */\nexport function normalizeError(error: unknown): G9SyncException {\n if (isSyncException(error)) return error as G9SyncException;\n const message = error instanceof Error ? error.message : String(error);\n if (error instanceof Error && error.name === 'AbortError') return new G9SyncException(G9SyncErrorCodes.Canceled, 'The sync was canceled.', { cause: error });\n if (isLocalStoreFailure(error)) {\n const code =\n error.localStoreFailure === G9ELocalStoreFailure.Corrupt\n ? G9SyncErrorCodes.LocalStoreCorrupt\n : error.localStoreFailure === G9ELocalStoreFailure.DiskFull\n ? G9SyncErrorCodes.LocalStoreDiskFull\n : error.localStoreFailure === G9ELocalStoreFailure.Busy\n ? G9SyncErrorCodes.LocalStoreBusy\n : G9SyncErrorCodes.LocalStoreError;\n return new G9SyncException(code, message, { cause: error });\n }\n if (error instanceof G9RowBatchFormatError) return new G9SyncException(G9SyncErrorCodes.Unknown, message, { cause: error });\n if (error instanceof Error && (error.name === 'TimeoutError' || /network|socket|websocket|connection/i.test(error.name))) {\n return new G9SyncException(G9SyncErrorCodes.NetworkFailure, message, { cause: error });\n }\n return new G9SyncException(G9SyncErrorCodes.Unknown, message, { cause: error });\n}\n\n/** `G9CSyncErrors.IsTransient`. */\nexport function isTransientError(error: unknown): boolean {\n const code = normalizeError(error).code;\n return code === G9SyncErrorCodes.NetworkFailure || code === G9SyncErrorCodes.ServerError || code === G9SyncErrorCodes.ServerBusy;\n}\n"]}
|