@g9tm/syncdata 1.5.13 → 1.5.14
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/PARITY.md +2 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/signalr/transport.d.ts +6 -0
- package/dist/signalr/transport.js +20 -2
- package/dist/signalr/transport.js.map +1 -1
- package/dist/sqlite/push.js +45 -5
- package/dist/sqlite/push.js.map +1 -1
- package/package.json +1 -1
package/PARITY.md
CHANGED
|
@@ -45,9 +45,10 @@ it). This file maps every .NET piece to its twin and lists every deliberate diff
|
|
|
45
45
|
| `ExportPendingChangesAsync(path)` | `exportPendingChanges(writeLine)` | the caller writes the lines where it wants |
|
|
46
46
|
| `CheckIntegrityAsync` | `checkIntegrity()` | |
|
|
47
47
|
| `KeepLostConflicts` (LES-0072) | `keepLostConflicts` | same SQL, same rejection row (code, lost columns, server values as JSON); `G9ApplyReport.conflictsKept`; `test/keepLostConflicts.test.ts` |
|
|
48
|
+
| Lost = pushed columns only; timestamps as instants (LES-0086) | `pushedMask`, `sameValue(…, type)` / `instant` | `PushedMask` / `SameValue(type, …)` / `Instant`: the dirty mask restricted to the batch's columns; DateTime/DateTimeOffset text in either form equal within one microsecond (TS: no BigInt - milliseconds plus 100 ns units); `HeldValueTests` / `test/heldValues.test.ts` |
|
|
48
49
|
| `SaveHelloAsync(hello, localMidpointUtc, ct)` (LES-0075) | `saveHello(hello, signal, localMidpointMs)` | the engine measures the Hello round trip in both clients and stores `serverTime - midpoint` |
|
|
49
50
|
| `G9CSqliteException` (`IG9SyncLocalStoreFailure`) | `G9SqliteStoreError` (`localStoreFailure`) | classified from the driver's code |
|
|
50
|
-
| `G9CSignalRSyncTransport`, options | `G9SignalRSyncTransport` (`@g9tm/syncdata/signalr`) | over `G9Client` of `@g9tm/signalr-supernetcore-client`; Lynx: `createLynxSyncTransport`. Limits (ADR-0074): `CallTimeout` / `PlanTimeout` / `PushTimeout` / `StreamIdleTimeout` = `callTimeoutMs` / `planTimeoutMs` / `pushTimeoutMs` / `streamIdleTimeoutMs`, same defaults, same retryable `G9S-NET-FAILURE`, same connection drop (`SignalRTimeoutTests` / `test/transportTimeouts.test.ts`) |
|
|
51
|
+
| `G9CSignalRSyncTransport`, options | `G9SignalRSyncTransport` (`@g9tm/syncdata/signalr`) | over `G9Client` of `@g9tm/signalr-supernetcore-client`; Lynx: `createLynxSyncTransport`. Limits (ADR-0074): `CallTimeout` / `PlanTimeout` / `PushTimeout` / `StreamIdleTimeout` = `callTimeoutMs` / `planTimeoutMs` / `pushTimeoutMs` / `streamIdleTimeoutMs`, same defaults, same retryable `G9S-NET-FAILURE`, same connection drop (`SignalRTimeoutTests` / `test/transportTimeouts.test.ts`). After an automatic reconnect both resend the last accepted Hello so the new connection rejoins its poke groups (LES-0087: `OnReconnectedAsync` / `_rejoin`; `SignalRTransportTests.After_the_connection_reconnects_by_itself_…` / `test/transportRejoin.test.ts`) |
|
|
51
52
|
| `G9CInMemorySyncTransport`, `G9CTransportFaults` | `G9FaultInjectingTransport`, `G9TransportFaults` (`@g9tm/syncdata/testing`) | wraps a real transport (no in-process server engine in JavaScript) |
|
|
52
53
|
|
|
53
54
|
## Deliberate differences
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** The package version; equal to the .NET packages' (G9SyncDataVersion) — one release, both sides. */
|
|
2
|
-
export declare const VERSION = "1.5.
|
|
2
|
+
export declare const VERSION = "1.5.14";
|
|
3
3
|
export { G9EConflictPolicy, G9EMoveOutPolicy, G9ESyncColumnType, G9ESyncDirection, columnTypeName, isColumnType } from './abstractions/enums.js';
|
|
4
4
|
export { G9SyncErrorCodes, G9SyncException, isRetryableCode, isSyncException, type G9SyncExceptionOptions } from './abstractions/errors.js';
|
|
5
5
|
export { G9Long, parseJson, stringifyJson } from './abstractions/long.js';
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// doubles `@g9tm/syncdata/testing`, the pure-JavaScript Brotli decoder `@g9tm/syncdata/brotli-js`; Lynx wiring is the
|
|
4
4
|
// separate package `@g9tm/syncdata-lynx`. Every public type keeps its .NET name without the G9C prefix (PARITY.md).
|
|
5
5
|
/** The package version; equal to the .NET packages' (G9SyncDataVersion) — one release, both sides. */
|
|
6
|
-
export const VERSION = '1.5.
|
|
6
|
+
export const VERSION = '1.5.14';
|
|
7
7
|
// abstractions
|
|
8
8
|
export { G9EConflictPolicy, G9EMoveOutPolicy, G9ESyncColumnType, G9ESyncDirection, columnTypeName, isColumnType } from './abstractions/enums.js';
|
|
9
9
|
export { G9SyncErrorCodes, G9SyncException, isRetryableCode, isSyncException } from './abstractions/errors.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wHAAwH;AACxH,uHAAuH;AACvH,sHAAsH;AACtH,oHAAoH;AAEpH,sGAAsG;AACtG,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAC;AAEhC,eAAe;AACf,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACjJ,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAA+B,MAAM,0BAA0B,CAAC;AAC5I,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACvG,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAElF,WAAW;AACX,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAC5G,OAAO,EACL,UAAU,EACV,UAAU,EACV,oBAAoB,EACpB,UAAU,EACV,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,kBAAkB,GAEnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACrI,OAAO,EAAE,gBAAgB,EAA4E,MAAM,+BAA+B,CAAC;AAC3I,OAAO,EACL,gBAAgB,EAChB,2BAA2B,EAC3B,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,2BAA2B,GAI5B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAqB,MAAM,4BAA4B,CAAC;AAE3H,SAAS;AACT,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,wBAAwB,EAAmD,MAAM,mBAAmB,CAAC;AAC9K,cAAc,wBAAwB,CAAC;AAEvC,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,SAAS,EAAyB,MAAM,sBAAsB,CAAC;AAC7G,OAAO,EACL,cAAc,EACd,eAAe,EACf,cAAc,EACd,SAAS,EACT,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,YAAY,EACZ,oBAAoB,GAYrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAEnE,2CAA2C;AAC3C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC","sourcesContent":["// @g9tm/syncdata — the TypeScript twin of the G9SyncData .NET client (abstractions, protocol, engine). The SQLite store\r\n// is `@g9tm/syncdata/sqlite`, the SignalR transport `@g9tm/syncdata/signalr`, Node helpers `@g9tm/syncdata/node`, test\r\n// doubles `@g9tm/syncdata/testing`, the pure-JavaScript Brotli decoder `@g9tm/syncdata/brotli-js`; Lynx wiring is the\r\n// separate package `@g9tm/syncdata-lynx`. Every public type keeps its .NET name without the G9C prefix (PARITY.md).\r\n\r\n/** The package version; equal to the .NET packages' (G9SyncDataVersion) — one release, both sides. */\r\nexport const VERSION = '1.5.
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wHAAwH;AACxH,uHAAuH;AACvH,sHAAsH;AACtH,oHAAoH;AAEpH,sGAAsG;AACtG,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAC;AAEhC,eAAe;AACf,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACjJ,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAA+B,MAAM,0BAA0B,CAAC;AAC5I,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACvG,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAElF,WAAW;AACX,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAC5G,OAAO,EACL,UAAU,EACV,UAAU,EACV,oBAAoB,EACpB,UAAU,EACV,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,kBAAkB,GAEnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACrI,OAAO,EAAE,gBAAgB,EAA4E,MAAM,+BAA+B,CAAC;AAC3I,OAAO,EACL,gBAAgB,EAChB,2BAA2B,EAC3B,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,2BAA2B,GAI5B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAqB,MAAM,4BAA4B,CAAC;AAE3H,SAAS;AACT,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,wBAAwB,EAAmD,MAAM,mBAAmB,CAAC;AAC9K,cAAc,wBAAwB,CAAC;AAEvC,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,SAAS,EAAyB,MAAM,sBAAsB,CAAC;AAC7G,OAAO,EACL,cAAc,EACd,eAAe,EACf,cAAc,EACd,SAAS,EACT,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,YAAY,EACZ,oBAAoB,GAYrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAEnE,2CAA2C;AAC3C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC","sourcesContent":["// @g9tm/syncdata — the TypeScript twin of the G9SyncData .NET client (abstractions, protocol, engine). The SQLite store\r\n// is `@g9tm/syncdata/sqlite`, the SignalR transport `@g9tm/syncdata/signalr`, Node helpers `@g9tm/syncdata/node`, test\r\n// doubles `@g9tm/syncdata/testing`, the pure-JavaScript Brotli decoder `@g9tm/syncdata/brotli-js`; Lynx wiring is the\r\n// separate package `@g9tm/syncdata-lynx`. Every public type keeps its .NET name without the G9C prefix (PARITY.md).\r\n\r\n/** The package version; equal to the .NET packages' (G9SyncDataVersion) — one release, both sides. */\r\nexport const VERSION = '1.5.14';\r\n\r\n// abstractions\r\nexport { G9EConflictPolicy, G9EMoveOutPolicy, G9ESyncColumnType, G9ESyncDirection, columnTypeName, isColumnType } from './abstractions/enums.js';\r\nexport { G9SyncErrorCodes, G9SyncException, isRetryableCode, isSyncException, type G9SyncExceptionOptions } from './abstractions/errors.js';\r\nexport { G9Long, parseJson, stringifyJson } from './abstractions/long.js';\r\nexport { EMPTY_GUID, guidToN, newGuid, normalizeGuid, tryNormalizeGuid } from './abstractions/guid.js';\r\nexport { G9SyncKey } from './abstractions/key.js';\r\nexport { G9SyncDigest } from './abstractions/digest.js';\r\nexport { G9SyncParameters, escapeDataString } from './abstractions/parameters.js';\r\n\r\n// protocol\r\nexport * from './protocol/dtos.js';\r\nexport { G9SyncHubErrors, G9SyncProtocol, negotiateFrameVersion, tableGroup } from './protocol/protocol.js';\r\nexport {\r\n bytesField,\r\n dateTimeMs,\r\n fromMessagePackNames,\r\n G9WireGuid,\r\n GUID_EXTENSION_TYPE,\r\n readChangesAvailable,\r\n readContinuation,\r\n readHelloResult,\r\n readPullPlan,\r\n readPushResult,\r\n readReconcileSummary,\r\n readSyncChunk,\r\n toMessagePackNames,\r\n type G9WireFormat,\r\n} from './protocol/wire.js';\r\nexport { G9ECompression, G9EPushRowOp, G9ERowBatchOp, G9RowBatchFormat, G9RowBatchFormatError } from './protocol/rowBatch/format.js';\r\nexport { G9RowBatchWriter, type G9DateTimeOffsetValue, type G9DateTimeValue, type G9FrameCompressor } from './protocol/rowBatch/writer.js';\r\nexport {\r\n G9RowBatchReader,\r\n getDefaultFrameDecompressor,\r\n openRowBatch,\r\n openRowBatchSync,\r\n readFrameHeader,\r\n setDefaultFrameDecompressor,\r\n type G9FrameDecompressor,\r\n type G9FrameHeader,\r\n type G9OpenRowBatchOptions,\r\n} from './protocol/rowBatch/reader.js';\r\nexport { decimalToDouble, formatDecimal, formatDouble, parseDecimal, type DecimalParts } from './internal/dotnetFormat.js';\r\n\r\n// client\r\nexport { G9SyncClientModel, G9SyncClientModelBuilder, G9SyncClientTable, G9SyncClientTableBuilder, type G9SyncClientColumn, type G9SyncClientIndex } from './client/model.js';\r\nexport * from './client/storeTypes.js';\r\nexport type { G9SyncTransport } from './client/transport.js';\r\nexport { G9ESyncPhase, G9SyncProgressTracker, phaseName, type G9DtSyncProgress } from './client/progress.js';\r\nexport {\r\n G9ESyncOutcome,\r\n G9ESyncPriority,\r\n G9SyncPostStep,\r\n G9SyncRun,\r\n describeModelProblem,\r\n isTransientError,\r\n normalizeError,\r\n outcomeName,\r\n priorityName,\r\n resolveEngineOptions,\r\n type G9RowsAppliedEvent,\r\n type G9SubscriptionOptions,\r\n type G9SyncEngineOptions,\r\n type G9SyncHealth,\r\n type G9SyncHostHooks,\r\n type G9SyncLogger,\r\n type G9SyncLogLevel,\r\n type G9SyncModelProblem,\r\n type G9SyncPostStepContext,\r\n type G9SyncRequest,\r\n type G9SyncRunResult,\r\n} from './client/runs.js';\r\nexport { G9SyncEngine, stageGeneration } from './client/engine.js';\r\n\r\n// helpers the Lynx package and tests share\r\nexport { base64ToBytes, bytesToBase64 } from './internal/base64.js';\r\nexport { utf8Decode, utf8Encode } from './internal/utf8.js';\r\nexport { md5 } from './internal/md5.js';\r\nexport { sha256, toHex } from './internal/sha256.js';\r\nexport { cancellationError, createAbortController, delay, linkSignals, onAbort, yieldToEventLoop } from './internal/abort.js';\r\n"]}
|
|
@@ -57,6 +57,7 @@ export declare class G9SignalRSyncTransport implements G9SyncTransport {
|
|
|
57
57
|
private readonly _options;
|
|
58
58
|
private readonly _handlers;
|
|
59
59
|
private _connecting;
|
|
60
|
+
private _lastHello;
|
|
60
61
|
constructor(options: G9SignalRSyncTransportOptions);
|
|
61
62
|
get isConnected(): boolean;
|
|
62
63
|
onChangesAvailable(handler: (changes: G9DtChangesAvailable) => void): () => void;
|
|
@@ -64,6 +65,11 @@ export declare class G9SignalRSyncTransport implements G9SyncTransport {
|
|
|
64
65
|
connect(signal?: AbortSignal): Promise<void>;
|
|
65
66
|
private _connectCore;
|
|
66
67
|
hello(request: G9DtHelloRequest, signal?: AbortSignal): Promise<G9DtHelloResult>;
|
|
68
|
+
/**
|
|
69
|
+
* After an automatic reconnect the last accepted Hello is sent again, so the new connection joins the table groups pokes go to
|
|
70
|
+
* (S-2, LES-0087). Fire and forget, bounded by the call timeout; the answer is not used and a failure only delays a hint.
|
|
71
|
+
*/
|
|
72
|
+
private _rejoin;
|
|
67
73
|
push(request: G9DtPushRequest, chunks: AsyncIterable<G9DtSyncChunk>, signal?: AbortSignal): Promise<G9DtPushResult>;
|
|
68
74
|
planPull(request: G9DtPullRequest, signal?: AbortSignal): Promise<G9DtPullPlan>;
|
|
69
75
|
pull(token: string, continuation: G9DtPullContinuation | null, signal?: AbortSignal): AsyncIterable<G9DtSyncChunk>;
|
|
@@ -22,6 +22,7 @@ export class G9SignalRSyncTransport {
|
|
|
22
22
|
var _a, _b, _c, _d;
|
|
23
23
|
this._handlers = [];
|
|
24
24
|
this._connecting = null;
|
|
25
|
+
this._lastHello = null;
|
|
25
26
|
if (!options || typeof options.url !== 'string' || options.url.trim() === '')
|
|
26
27
|
throw new TypeError('A hub URL is required.');
|
|
27
28
|
this._options = options;
|
|
@@ -40,6 +41,10 @@ export class G9SignalRSyncTransport {
|
|
|
40
41
|
clientOptions.accessTokenFactory = options.accessTokenFactory;
|
|
41
42
|
this.client = options.createClient ? options.createClient(clientOptions) : new G9Client(clientOptions);
|
|
42
43
|
this.client.on(G9SyncProtocol.Listeners.OnChangesAvailable, (payload) => this._onChanges(payload));
|
|
44
|
+
// Twin of .NET OnReconnectedAsync (S-2, LES-0087): a connection that reconnected by itself is a new connection id in no table group.
|
|
45
|
+
const connection = this.client.connection;
|
|
46
|
+
if (typeof connection.onreconnected === 'function')
|
|
47
|
+
connection.onreconnected(() => this._rejoin());
|
|
43
48
|
}
|
|
44
49
|
get isConnected() {
|
|
45
50
|
return this.client.connection.state === HubConnectionState.Connected;
|
|
@@ -97,8 +102,21 @@ export class G9SignalRSyncTransport {
|
|
|
97
102
|
throw new G9SyncException(G9SyncErrorCodes.NetworkFailure, `The sync connection is ${String(this.client.connection.state)}.`, { retryable: true });
|
|
98
103
|
}
|
|
99
104
|
}
|
|
100
|
-
hello(request, signal) {
|
|
101
|
-
|
|
105
|
+
async hello(request, signal) {
|
|
106
|
+
const result = await this._invoke(G9SyncProtocol.Methods.Hello, [this._wire(request)], readHelloResult, this._callTimeoutMs(), signal);
|
|
107
|
+
if (!result.error)
|
|
108
|
+
this._lastHello = request;
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* After an automatic reconnect the last accepted Hello is sent again, so the new connection joins the table groups pokes go to
|
|
113
|
+
* (S-2, LES-0087). Fire and forget, bounded by the call timeout; the answer is not used and a failure only delays a hint.
|
|
114
|
+
*/
|
|
115
|
+
_rejoin() {
|
|
116
|
+
const hello = this._lastHello;
|
|
117
|
+
if (!hello)
|
|
118
|
+
return;
|
|
119
|
+
this._invoke(G9SyncProtocol.Methods.Hello, [this._wire(hello)], readHelloResult, this._callTimeoutMs()).catch(() => undefined);
|
|
102
120
|
}
|
|
103
121
|
push(request, chunks, signal) {
|
|
104
122
|
var _a;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/signalr/transport.ts"],"names":[],"mappings":"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","sourcesContent":["// Twin of G9SyncData.Client.SignalR/G9CSignalRSyncTransport.cs: the sync transport over the G9SignalRSuperNetCore client\r\n// (its jittered reconnect policy and connection states), every failure surfacing as a G9SyncException with the server's\r\n// stable code. Lynx hosts build the client with the native WebSocket of @g9tm/signalr-supernetcore-lynx\r\n// (`createLynxSyncTransport` in @g9tm/syncdata-lynx does).\r\nimport { G9Client, type G9ClientOptions } from '@g9tm/signalr-supernetcore-client';\r\nimport { HubConnectionState, Subject, type IHubProtocol, type IStreamResult, type ISubscription } from '@microsoft/signalr';\r\nimport { G9SyncErrorCodes, G9SyncException, isSyncException } from '../abstractions/errors.js';\r\nimport { createAbortController, onAbort } from '../internal/abort.js';\r\nimport type { G9SyncTransport } from '../client/transport.js';\r\nimport type {\r\n G9DtChangesAvailable,\r\n G9DtFetchRowsRequest,\r\n G9DtHelloRequest,\r\n G9DtHelloResult,\r\n G9DtPullContinuation,\r\n G9DtPullPlan,\r\n G9DtPullRequest,\r\n G9DtPushRequest,\r\n G9DtPushResult,\r\n G9DtReconcileRequest,\r\n G9DtSyncChunk,\r\n} from '../protocol/dtos.js';\r\nimport { G9SyncHubErrors, G9SyncProtocol } from '../protocol/protocol.js';\r\nimport {\r\n fromMessagePackNames,\r\n readChangesAvailable,\r\n readHelloResult,\r\n readPullPlan,\r\n readPushResult,\r\n readSyncChunk,\r\n toMessagePackNames,\r\n type G9WireFormat,\r\n} from '../protocol/wire.js';\r\nimport { createSyncMessagePackProtocol, G9SyncJsonHubProtocol } from './protocols.js';\r\n\r\n/** The SignalR hub protocol a client speaks (`G9ESyncHubProtocol`). The server accepts both. */\r\nexport const G9ESyncHubProtocol = {\r\n /** Text frames; payloads base64-encoded (+33%). Readable in traces. */\r\n Json: 0,\r\n /** Binary frames: payloads as raw bytes. The default. */\r\n MessagePack: 1,\r\n} as const;\r\nexport type G9ESyncHubProtocol = (typeof G9ESyncHubProtocol)[keyof typeof G9ESyncHubProtocol];\r\n\r\n/** Options of {@link G9SignalRSyncTransport} (`G9CSignalRSyncTransportOptions`). Durations are milliseconds. */\r\nexport interface G9SignalRSyncTransportOptions {\r\n /** Absolute hub URL, e.g. `https://sync.example.com/g9sync`. */\r\n url: string;\r\n /** Hub protocol; MessagePack by default. */\r\n protocol?: G9ESyncHubProtocol;\r\n /** Supplies the bearer token for every (re)connect. */\r\n accessTokenFactory?: () => string | Promise<string>;\r\n /** SignalR stateful reconnect (ADR-0069); off by default, the server must allow it too. */\r\n statefulReconnect?: boolean;\r\n /** How long one connect may take before it counts as a network failure. */\r\n connectTimeoutMs?: number;\r\n serverTimeoutMs?: number;\r\n keepAliveIntervalMs?: number;\r\n /**\r\n * How long a Hello waits for its answer before it is a retryable G9S-NET-FAILURE (ADR-0074). Default 60000; 0 = no limit.\r\n * A live connection does not guarantee an answer: pings keep it up while the call's message was lost on the way.\r\n */\r\n callTimeoutMs?: number;\r\n /**\r\n * How long a PlanPull waits for its plan. Default 300000 (5 minutes); 0 = no limit (ADR-0074, amended in 1.5.1): a site's first\r\n * plan builds key sets and plans a snapshot file - 16 s for a 450,000-row farm on a desktop, several times that on a busy server.\r\n */\r\n planTimeoutMs?: number;\r\n /** How long a push may take from its first chunk to its result; a safety net, not a pace. Default 600000; 0 = no limit. */\r\n pushTimeoutMs?: number;\r\n /**\r\n * How long a server stream (Pull, Reconcile, FetchRows) may go without a chunk before it is a retryable G9S-NET-FAILURE; the\r\n * engine resumes from its last continuation. Default 120000 (a snapshot file may still be building); 0 = no limit (ADR-0074).\r\n */\r\n streamIdleTimeoutMs?: number;\r\n /**\r\n * Everything else the G9 client takes (transport, headers, WebSocket constructor, skipNegotiation, reconnect policy, log\r\n * level…) — the twin of ConfigureHttpConnection/ConfigureBuilder. `url`, `protocol` and the timeouts above win.\r\n */\r\n client?: Partial<G9ClientOptions>;\r\n /** Builds the client (tests, hosts with their own wiring); `new G9Client(options)` by default. */\r\n createClient?: (options: G9ClientOptions) => G9Client;\r\n}\r\n\r\n/** The SignalR implementation of {@link G9SyncTransport}. */\r\nexport class G9SignalRSyncTransport implements G9SyncTransport {\r\n readonly client: G9Client;\r\n readonly format: G9WireFormat;\r\n private readonly _options: G9SignalRSyncTransportOptions;\r\n private readonly _handlers: ((changes: G9DtChangesAvailable) => void)[] = [];\r\n private _connecting: Promise<void> | null = null;\r\n\r\n constructor(options: G9SignalRSyncTransportOptions) {\r\n if (!options || typeof options.url !== 'string' || options.url.trim() === '') throw new TypeError('A hub URL is required.');\r\n this._options = options;\r\n const json = options.protocol === G9ESyncHubProtocol.Json;\r\n this.format = json ? 'json' : 'messagepack';\r\n const protocol: IHubProtocol = json ? new G9SyncJsonHubProtocol() : createSyncMessagePackProtocol();\r\n const clientOptions: G9ClientOptions = {\r\n ...(options.client ?? {}),\r\n url: options.url,\r\n protocol,\r\n statefulReconnect: options.statefulReconnect ?? false,\r\n serverTimeoutMs: options.serverTimeoutMs ?? 30000,\r\n keepAliveIntervalMs: options.keepAliveIntervalMs ?? 10000,\r\n };\r\n if (options.accessTokenFactory) clientOptions.accessTokenFactory = options.accessTokenFactory;\r\n this.client = options.createClient ? options.createClient(clientOptions) : new G9Client(clientOptions);\r\n this.client.on(G9SyncProtocol.Listeners.OnChangesAvailable, (payload: unknown) => this._onChanges(payload));\r\n }\r\n\r\n get isConnected(): boolean {\r\n return this.client.connection.state === HubConnectionState.Connected;\r\n }\r\n\r\n onChangesAvailable(handler: (changes: G9DtChangesAvailable) => void): () => void {\r\n this._handlers.push(handler);\r\n return () => {\r\n const index = this._handlers.indexOf(handler);\r\n if (index >= 0) this._handlers.splice(index, 1);\r\n };\r\n }\r\n\r\n /** Connects (joins a connect in progress); a connect that takes longer than connectTimeoutMs is a network failure. */\r\n connect(signal?: AbortSignal): Promise<void> {\r\n if (this.isConnected) return Promise.resolve();\r\n if (!this._connecting) {\r\n const connecting = this._connectCore().finally(() => {\r\n if (this._connecting === connecting) this._connecting = null;\r\n });\r\n this._connecting = connecting;\r\n }\r\n const connecting = this._connecting;\r\n if (!signal) return connecting;\r\n return new Promise<void>((resolve, reject) => {\r\n const unsubscribe = onAbort(signal, () => reject(new G9SyncException(G9SyncErrorCodes.Canceled, 'The connect was canceled.')));\r\n connecting.then(\r\n () => {\r\n unsubscribe();\r\n resolve();\r\n },\r\n (error) => {\r\n unsubscribe();\r\n reject(error);\r\n },\r\n );\r\n });\r\n }\r\n\r\n private async _connectCore(): Promise<void> {\r\n const timeout = createAbortController();\r\n const timer = setTimeout(() => timeout.abort(), this._options.connectTimeoutMs ?? 20000);\r\n try {\r\n await this.client.start(timeout.signal);\r\n } catch (error) {\r\n const mapped = mapError(error, false) ?? new G9SyncException(G9SyncErrorCodes.NetworkFailure, messageOf(error), { retryable: true, cause: error });\r\n throw mapped.code === G9SyncErrorCodes.Canceled\r\n ? new G9SyncException(G9SyncErrorCodes.NetworkFailure, `The sync connection to ${this._options.url} did not open in time.`, { retryable: true, cause: error })\r\n : mapped;\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n if (!this.isConnected) {\r\n throw new G9SyncException(G9SyncErrorCodes.NetworkFailure, `The sync connection is ${String(this.client.connection.state)}.`, { retryable: true });\r\n }\r\n }\r\n\r\n hello(request: G9DtHelloRequest, signal?: AbortSignal): Promise<G9DtHelloResult> {\r\n return this._invoke(G9SyncProtocol.Methods.Hello, [this._wire(request)], readHelloResult, this._callTimeoutMs(), signal);\r\n }\r\n\r\n push(request: G9DtPushRequest, chunks: AsyncIterable<G9DtSyncChunk>, signal?: AbortSignal): Promise<G9DtPushResult> {\r\n const subject = new Subject<unknown>();\r\n const result = this._invoke(G9SyncProtocol.Methods.Push, [this._wire(request), subject], readPushResult, this._options.pushTimeoutMs ?? 600000, signal);\r\n void (async () => {\r\n try {\r\n for await (const chunk of chunks) subject.next(this._wire(chunk));\r\n subject.complete();\r\n } catch (error) {\r\n subject.error(error);\r\n }\r\n })();\r\n return result;\r\n }\r\n\r\n planPull(request: G9DtPullRequest, signal?: AbortSignal): Promise<G9DtPullPlan> {\r\n return this._invoke(G9SyncProtocol.Methods.PlanPull, [this._wire(request)], readPullPlan, this._options.planTimeoutMs ?? 300000, signal);\r\n }\r\n\r\n pull(token: string, continuation: G9DtPullContinuation | null, signal?: AbortSignal): AsyncIterable<G9DtSyncChunk> {\r\n return this._stream(G9SyncProtocol.Methods.Pull, [token, continuation === null ? null : this._wire(continuation)], signal);\r\n }\r\n\r\n reconcile(request: G9DtReconcileRequest, signal?: AbortSignal): AsyncIterable<G9DtSyncChunk> {\r\n return this._stream(G9SyncProtocol.Methods.Reconcile, [this._wire(request)], signal);\r\n }\r\n\r\n fetchRows(request: G9DtFetchRowsRequest, signal?: AbortSignal): AsyncIterable<G9DtSyncChunk> {\r\n return this._stream(G9SyncProtocol.Methods.FetchRows, [this._wire(request)], signal);\r\n }\r\n\r\n async dispose(): Promise<void> {\r\n this._handlers.length = 0;\r\n await this.client.stop();\r\n }\r\n\r\n // ================================================================ plumbing\r\n\r\n private _wire(value: unknown): unknown {\r\n return this.format === 'messagepack' ? toMessagePackNames(value) : value;\r\n }\r\n\r\n private _read(value: unknown): unknown {\r\n return this.format === 'messagepack' ? fromMessagePackNames(value) : value;\r\n }\r\n\r\n private _callTimeoutMs(): number {\r\n return this._options.callTimeoutMs ?? 60000;\r\n }\r\n\r\n private async _invoke<T>(method: string, args: unknown[], read: (value: unknown) => T, timeoutMs: number, signal?: AbortSignal): Promise<T> {\r\n if (signal && signal.aborted) throw new G9SyncException(G9SyncErrorCodes.Canceled, 'The call was canceled.');\r\n let unsubscribe: () => void = () => undefined;\r\n let timer: ReturnType<typeof setTimeout> | null = null;\r\n let timedOut = false;\r\n try {\r\n const call = this.client.connection.invoke(method, ...args);\r\n const raw =\r\n signal || timeoutMs > 0\r\n ? await new Promise<unknown>((resolve, reject) => {\r\n if (signal) unsubscribe = onAbort(signal, () => reject(new G9SyncException(G9SyncErrorCodes.Canceled, 'The call was canceled.')));\r\n if (timeoutMs > 0) {\r\n timer = setTimeout(() => {\r\n timedOut = true;\r\n reject(\r\n new G9SyncException(G9SyncErrorCodes.NetworkFailure, `The sync server did not answer ${method} within ${Math.round(timeoutMs / 1000)} s.`, {\r\n retryable: true,\r\n }),\r\n );\r\n }, timeoutMs);\r\n }\r\n call.then(resolve, reject);\r\n })\r\n : await call;\r\n return read(this._read(raw));\r\n } catch (error) {\r\n // ADR-0074: the answer did not come in time. The connection is not trusted any more (the server runs one invocation per\r\n // connection at a time, and whatever lost this answer may lose the next): drop it, so the retry runs on a fresh one.\r\n if (timedOut) await this._dropConnection();\r\n throw mapError(error, signal ? signal.aborted : false) ?? error;\r\n } finally {\r\n if (timer !== null) clearTimeout(timer);\r\n unsubscribe();\r\n }\r\n }\r\n\r\n /** Ends the connection after a call or stream ran out of time (ADR-0074); the next call connects afresh. Never throws. */\r\n private async _dropConnection(): Promise<void> {\r\n try {\r\n await this.client.connection.stop();\r\n } catch {\r\n // Stopping a connection that is already gone may throw; the next call connects afresh either way.\r\n }\r\n }\r\n\r\n private _stream(method: string, args: unknown[], signal?: AbortSignal): AsyncIterable<G9DtSyncChunk> {\r\n // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n const self = this;\r\n return {\r\n [Symbol.asyncIterator](): AsyncIterator<G9DtSyncChunk> {\r\n const queue: G9DtSyncChunk[] = [];\r\n let done = false;\r\n let failure: unknown = null;\r\n let wake: (() => void) | null = null;\r\n let subscription: ISubscription<unknown> | null = null;\r\n const notify = (): void => {\r\n const w = wake;\r\n wake = null;\r\n if (w) w();\r\n };\r\n let unsubscribeAbort: () => void = () => undefined;\r\n // ADR-0074: the idle limit runs only while the iterator waits for the next chunk, never while the caller processes one.\r\n const idleMs = self._options.streamIdleTimeoutMs ?? 120000;\r\n let idleTimer: ReturnType<typeof setTimeout> | null = null;\r\n let idleExpired = false;\r\n const stopIdle = (): void => {\r\n if (idleTimer !== null) clearTimeout(idleTimer);\r\n idleTimer = null;\r\n };\r\n const armIdle = (): void => {\r\n stopIdle();\r\n if (idleMs <= 0 || done) return;\r\n idleTimer = setTimeout(() => {\r\n idleTimer = null;\r\n if (done) return;\r\n idleExpired = true;\r\n failure = new G9SyncException(G9SyncErrorCodes.NetworkFailure, `The sync server sent nothing on ${method} for ${Math.round(idleMs / 1000)} s.`, {\r\n retryable: true,\r\n });\r\n done = true;\r\n subscription?.dispose();\r\n notify();\r\n }, idleMs);\r\n };\r\n const start = (): void => {\r\n if (subscription || done) return;\r\n let stream: IStreamResult<unknown>;\r\n try {\r\n stream = self.client.connection.stream(method, ...args);\r\n } catch (error) {\r\n failure = error;\r\n done = true;\r\n return;\r\n }\r\n subscription = stream.subscribe({\r\n next: (item) => {\r\n queue.push(readSyncChunk(self._read(item)));\r\n notify();\r\n },\r\n error: (error) => {\r\n failure = error;\r\n done = true;\r\n notify();\r\n },\r\n complete: () => {\r\n done = true;\r\n notify();\r\n },\r\n });\r\n unsubscribeAbort = onAbort(signal, () => {\r\n failure = new G9SyncException(G9SyncErrorCodes.Canceled, 'The stream was canceled.');\r\n done = true;\r\n subscription?.dispose();\r\n notify();\r\n });\r\n };\r\n const finish = (): void => {\r\n stopIdle();\r\n unsubscribeAbort();\r\n if (subscription && !done) subscription.dispose();\r\n done = true;\r\n };\r\n return {\r\n async next(): Promise<IteratorResult<G9DtSyncChunk>> {\r\n start();\r\n for (;;) {\r\n const item = queue.shift();\r\n if (item) {\r\n stopIdle();\r\n return { value: item, done: false };\r\n }\r\n if (done) {\r\n stopIdle();\r\n unsubscribeAbort();\r\n if (idleExpired) await self._dropConnection();\r\n if (failure !== null) throw mapError(failure, signal ? signal.aborted : false) ?? failure;\r\n return { value: undefined as unknown as G9DtSyncChunk, done: true };\r\n }\r\n if (idleTimer === null) armIdle();\r\n await new Promise<void>((resolve) => {\r\n wake = resolve;\r\n });\r\n }\r\n },\r\n async return(): Promise<IteratorResult<G9DtSyncChunk>> {\r\n finish();\r\n return { value: undefined as unknown as G9DtSyncChunk, done: true };\r\n },\r\n };\r\n },\r\n };\r\n }\r\n\r\n private _onChanges(payload: unknown): void {\r\n const changes = readChangesAvailable(this._read(payload));\r\n for (const handler of this._handlers.slice()) {\r\n try {\r\n handler(changes);\r\n } catch {\r\n // A ChangesAvailable handler threw (logged by the .NET transport); it must not break the connection.\r\n }\r\n }\r\n }\r\n}\r\n\r\nfunction messageOf(error: unknown): string {\r\n return error instanceof Error ? error.message : String(error);\r\n}\r\n\r\n/**\r\n * The sync exception for a transport failure (`Map`): the server's `[G9S|code|retryable]` marker wins; any other hub\r\n * error is a retryable server error; 401/403 is Unauthorized; the rest is a retryable network failure. Null leaves the\r\n * error as it is (an already mapped one).\r\n */\r\nexport function mapError(error: unknown, canceled: boolean): G9SyncException | null {\r\n if (isSyncException(error)) return null;\r\n if (canceled) return new G9SyncException(G9SyncErrorCodes.Canceled, 'The call was canceled.', { cause: error });\r\n const message = messageOf(error);\r\n const marked = G9SyncHubErrors.tryParse(message);\r\n if (marked) return marked;\r\n const status = (error as { statusCode?: unknown }).statusCode;\r\n if (status === 401 || status === 403) return new G9SyncException(G9SyncErrorCodes.Unauthorized, 'The sync server refused the credentials.', { cause: error });\r\n if (error instanceof Error && error.name === 'AbortError') return new G9SyncException(G9SyncErrorCodes.Canceled, message, { cause: error });\r\n // A completion error from the hub: SignalR words it \"An unexpected error occurred invoking '…' on the server.\"\r\n if (/on the server|HubException/i.test(message)) return new G9SyncException(G9SyncErrorCodes.ServerError, message, { retryable: true, cause: error });\r\n return new G9SyncException(G9SyncErrorCodes.NetworkFailure, message, { retryable: true, cause: error });\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/signalr/transport.ts"],"names":[],"mappings":"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","sourcesContent":["// Twin of G9SyncData.Client.SignalR/G9CSignalRSyncTransport.cs: the sync transport over the G9SignalRSuperNetCore client\r\n// (its jittered reconnect policy and connection states), every failure surfacing as a G9SyncException with the server's\r\n// stable code. Lynx hosts build the client with the native WebSocket of @g9tm/signalr-supernetcore-lynx\r\n// (`createLynxSyncTransport` in @g9tm/syncdata-lynx does).\r\nimport { G9Client, type G9ClientOptions } from '@g9tm/signalr-supernetcore-client';\r\nimport { HubConnectionState, Subject, type IHubProtocol, type IStreamResult, type ISubscription } from '@microsoft/signalr';\r\nimport { G9SyncErrorCodes, G9SyncException, isSyncException } from '../abstractions/errors.js';\r\nimport { createAbortController, onAbort } from '../internal/abort.js';\r\nimport type { G9SyncTransport } from '../client/transport.js';\r\nimport type {\r\n G9DtChangesAvailable,\r\n G9DtFetchRowsRequest,\r\n G9DtHelloRequest,\r\n G9DtHelloResult,\r\n G9DtPullContinuation,\r\n G9DtPullPlan,\r\n G9DtPullRequest,\r\n G9DtPushRequest,\r\n G9DtPushResult,\r\n G9DtReconcileRequest,\r\n G9DtSyncChunk,\r\n} from '../protocol/dtos.js';\r\nimport { G9SyncHubErrors, G9SyncProtocol } from '../protocol/protocol.js';\r\nimport {\r\n fromMessagePackNames,\r\n readChangesAvailable,\r\n readHelloResult,\r\n readPullPlan,\r\n readPushResult,\r\n readSyncChunk,\r\n toMessagePackNames,\r\n type G9WireFormat,\r\n} from '../protocol/wire.js';\r\nimport { createSyncMessagePackProtocol, G9SyncJsonHubProtocol } from './protocols.js';\r\n\r\n/** The SignalR hub protocol a client speaks (`G9ESyncHubProtocol`). The server accepts both. */\r\nexport const G9ESyncHubProtocol = {\r\n /** Text frames; payloads base64-encoded (+33%). Readable in traces. */\r\n Json: 0,\r\n /** Binary frames: payloads as raw bytes. The default. */\r\n MessagePack: 1,\r\n} as const;\r\nexport type G9ESyncHubProtocol = (typeof G9ESyncHubProtocol)[keyof typeof G9ESyncHubProtocol];\r\n\r\n/** Options of {@link G9SignalRSyncTransport} (`G9CSignalRSyncTransportOptions`). Durations are milliseconds. */\r\nexport interface G9SignalRSyncTransportOptions {\r\n /** Absolute hub URL, e.g. `https://sync.example.com/g9sync`. */\r\n url: string;\r\n /** Hub protocol; MessagePack by default. */\r\n protocol?: G9ESyncHubProtocol;\r\n /** Supplies the bearer token for every (re)connect. */\r\n accessTokenFactory?: () => string | Promise<string>;\r\n /** SignalR stateful reconnect (ADR-0069); off by default, the server must allow it too. */\r\n statefulReconnect?: boolean;\r\n /** How long one connect may take before it counts as a network failure. */\r\n connectTimeoutMs?: number;\r\n serverTimeoutMs?: number;\r\n keepAliveIntervalMs?: number;\r\n /**\r\n * How long a Hello waits for its answer before it is a retryable G9S-NET-FAILURE (ADR-0074). Default 60000; 0 = no limit.\r\n * A live connection does not guarantee an answer: pings keep it up while the call's message was lost on the way.\r\n */\r\n callTimeoutMs?: number;\r\n /**\r\n * How long a PlanPull waits for its plan. Default 300000 (5 minutes); 0 = no limit (ADR-0074, amended in 1.5.1): a site's first\r\n * plan builds key sets and plans a snapshot file - 16 s for a 450,000-row farm on a desktop, several times that on a busy server.\r\n */\r\n planTimeoutMs?: number;\r\n /** How long a push may take from its first chunk to its result; a safety net, not a pace. Default 600000; 0 = no limit. */\r\n pushTimeoutMs?: number;\r\n /**\r\n * How long a server stream (Pull, Reconcile, FetchRows) may go without a chunk before it is a retryable G9S-NET-FAILURE; the\r\n * engine resumes from its last continuation. Default 120000 (a snapshot file may still be building); 0 = no limit (ADR-0074).\r\n */\r\n streamIdleTimeoutMs?: number;\r\n /**\r\n * Everything else the G9 client takes (transport, headers, WebSocket constructor, skipNegotiation, reconnect policy, log\r\n * level…) — the twin of ConfigureHttpConnection/ConfigureBuilder. `url`, `protocol` and the timeouts above win.\r\n */\r\n client?: Partial<G9ClientOptions>;\r\n /** Builds the client (tests, hosts with their own wiring); `new G9Client(options)` by default. */\r\n createClient?: (options: G9ClientOptions) => G9Client;\r\n}\r\n\r\n/** The SignalR implementation of {@link G9SyncTransport}. */\r\nexport class G9SignalRSyncTransport implements G9SyncTransport {\r\n readonly client: G9Client;\r\n readonly format: G9WireFormat;\r\n private readonly _options: G9SignalRSyncTransportOptions;\r\n private readonly _handlers: ((changes: G9DtChangesAvailable) => void)[] = [];\r\n private _connecting: Promise<void> | null = null;\r\n private _lastHello: G9DtHelloRequest | null = null;\r\n\r\n constructor(options: G9SignalRSyncTransportOptions) {\r\n if (!options || typeof options.url !== 'string' || options.url.trim() === '') throw new TypeError('A hub URL is required.');\r\n this._options = options;\r\n const json = options.protocol === G9ESyncHubProtocol.Json;\r\n this.format = json ? 'json' : 'messagepack';\r\n const protocol: IHubProtocol = json ? new G9SyncJsonHubProtocol() : createSyncMessagePackProtocol();\r\n const clientOptions: G9ClientOptions = {\r\n ...(options.client ?? {}),\r\n url: options.url,\r\n protocol,\r\n statefulReconnect: options.statefulReconnect ?? false,\r\n serverTimeoutMs: options.serverTimeoutMs ?? 30000,\r\n keepAliveIntervalMs: options.keepAliveIntervalMs ?? 10000,\r\n };\r\n if (options.accessTokenFactory) clientOptions.accessTokenFactory = options.accessTokenFactory;\r\n this.client = options.createClient ? options.createClient(clientOptions) : new G9Client(clientOptions);\r\n this.client.on(G9SyncProtocol.Listeners.OnChangesAvailable, (payload: unknown) => this._onChanges(payload));\r\n // Twin of .NET OnReconnectedAsync (S-2, LES-0087): a connection that reconnected by itself is a new connection id in no table group.\r\n const connection = this.client.connection as { onreconnected?: (callback: (connectionId?: string) => void) => void };\r\n if (typeof connection.onreconnected === 'function') connection.onreconnected(() => this._rejoin());\r\n }\r\n\r\n get isConnected(): boolean {\r\n return this.client.connection.state === HubConnectionState.Connected;\r\n }\r\n\r\n onChangesAvailable(handler: (changes: G9DtChangesAvailable) => void): () => void {\r\n this._handlers.push(handler);\r\n return () => {\r\n const index = this._handlers.indexOf(handler);\r\n if (index >= 0) this._handlers.splice(index, 1);\r\n };\r\n }\r\n\r\n /** Connects (joins a connect in progress); a connect that takes longer than connectTimeoutMs is a network failure. */\r\n connect(signal?: AbortSignal): Promise<void> {\r\n if (this.isConnected) return Promise.resolve();\r\n if (!this._connecting) {\r\n const connecting = this._connectCore().finally(() => {\r\n if (this._connecting === connecting) this._connecting = null;\r\n });\r\n this._connecting = connecting;\r\n }\r\n const connecting = this._connecting;\r\n if (!signal) return connecting;\r\n return new Promise<void>((resolve, reject) => {\r\n const unsubscribe = onAbort(signal, () => reject(new G9SyncException(G9SyncErrorCodes.Canceled, 'The connect was canceled.')));\r\n connecting.then(\r\n () => {\r\n unsubscribe();\r\n resolve();\r\n },\r\n (error) => {\r\n unsubscribe();\r\n reject(error);\r\n },\r\n );\r\n });\r\n }\r\n\r\n private async _connectCore(): Promise<void> {\r\n const timeout = createAbortController();\r\n const timer = setTimeout(() => timeout.abort(), this._options.connectTimeoutMs ?? 20000);\r\n try {\r\n await this.client.start(timeout.signal);\r\n } catch (error) {\r\n const mapped = mapError(error, false) ?? new G9SyncException(G9SyncErrorCodes.NetworkFailure, messageOf(error), { retryable: true, cause: error });\r\n throw mapped.code === G9SyncErrorCodes.Canceled\r\n ? new G9SyncException(G9SyncErrorCodes.NetworkFailure, `The sync connection to ${this._options.url} did not open in time.`, { retryable: true, cause: error })\r\n : mapped;\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n if (!this.isConnected) {\r\n throw new G9SyncException(G9SyncErrorCodes.NetworkFailure, `The sync connection is ${String(this.client.connection.state)}.`, { retryable: true });\r\n }\r\n }\r\n\r\n async hello(request: G9DtHelloRequest, signal?: AbortSignal): Promise<G9DtHelloResult> {\r\n const result = await this._invoke(G9SyncProtocol.Methods.Hello, [this._wire(request)], readHelloResult, this._callTimeoutMs(), signal);\r\n if (!result.error) this._lastHello = request;\r\n return result;\r\n }\r\n\r\n /**\r\n * After an automatic reconnect the last accepted Hello is sent again, so the new connection joins the table groups pokes go to\r\n * (S-2, LES-0087). Fire and forget, bounded by the call timeout; the answer is not used and a failure only delays a hint.\r\n */\r\n private _rejoin(): void {\r\n const hello = this._lastHello;\r\n if (!hello) return;\r\n this._invoke(G9SyncProtocol.Methods.Hello, [this._wire(hello)], readHelloResult, this._callTimeoutMs()).catch(() => undefined);\r\n }\r\n\r\n push(request: G9DtPushRequest, chunks: AsyncIterable<G9DtSyncChunk>, signal?: AbortSignal): Promise<G9DtPushResult> {\r\n const subject = new Subject<unknown>();\r\n const result = this._invoke(G9SyncProtocol.Methods.Push, [this._wire(request), subject], readPushResult, this._options.pushTimeoutMs ?? 600000, signal);\r\n void (async () => {\r\n try {\r\n for await (const chunk of chunks) subject.next(this._wire(chunk));\r\n subject.complete();\r\n } catch (error) {\r\n subject.error(error);\r\n }\r\n })();\r\n return result;\r\n }\r\n\r\n planPull(request: G9DtPullRequest, signal?: AbortSignal): Promise<G9DtPullPlan> {\r\n return this._invoke(G9SyncProtocol.Methods.PlanPull, [this._wire(request)], readPullPlan, this._options.planTimeoutMs ?? 300000, signal);\r\n }\r\n\r\n pull(token: string, continuation: G9DtPullContinuation | null, signal?: AbortSignal): AsyncIterable<G9DtSyncChunk> {\r\n return this._stream(G9SyncProtocol.Methods.Pull, [token, continuation === null ? null : this._wire(continuation)], signal);\r\n }\r\n\r\n reconcile(request: G9DtReconcileRequest, signal?: AbortSignal): AsyncIterable<G9DtSyncChunk> {\r\n return this._stream(G9SyncProtocol.Methods.Reconcile, [this._wire(request)], signal);\r\n }\r\n\r\n fetchRows(request: G9DtFetchRowsRequest, signal?: AbortSignal): AsyncIterable<G9DtSyncChunk> {\r\n return this._stream(G9SyncProtocol.Methods.FetchRows, [this._wire(request)], signal);\r\n }\r\n\r\n async dispose(): Promise<void> {\r\n this._handlers.length = 0;\r\n await this.client.stop();\r\n }\r\n\r\n // ================================================================ plumbing\r\n\r\n private _wire(value: unknown): unknown {\r\n return this.format === 'messagepack' ? toMessagePackNames(value) : value;\r\n }\r\n\r\n private _read(value: unknown): unknown {\r\n return this.format === 'messagepack' ? fromMessagePackNames(value) : value;\r\n }\r\n\r\n private _callTimeoutMs(): number {\r\n return this._options.callTimeoutMs ?? 60000;\r\n }\r\n\r\n private async _invoke<T>(method: string, args: unknown[], read: (value: unknown) => T, timeoutMs: number, signal?: AbortSignal): Promise<T> {\r\n if (signal && signal.aborted) throw new G9SyncException(G9SyncErrorCodes.Canceled, 'The call was canceled.');\r\n let unsubscribe: () => void = () => undefined;\r\n let timer: ReturnType<typeof setTimeout> | null = null;\r\n let timedOut = false;\r\n try {\r\n const call = this.client.connection.invoke(method, ...args);\r\n const raw =\r\n signal || timeoutMs > 0\r\n ? await new Promise<unknown>((resolve, reject) => {\r\n if (signal) unsubscribe = onAbort(signal, () => reject(new G9SyncException(G9SyncErrorCodes.Canceled, 'The call was canceled.')));\r\n if (timeoutMs > 0) {\r\n timer = setTimeout(() => {\r\n timedOut = true;\r\n reject(\r\n new G9SyncException(G9SyncErrorCodes.NetworkFailure, `The sync server did not answer ${method} within ${Math.round(timeoutMs / 1000)} s.`, {\r\n retryable: true,\r\n }),\r\n );\r\n }, timeoutMs);\r\n }\r\n call.then(resolve, reject);\r\n })\r\n : await call;\r\n return read(this._read(raw));\r\n } catch (error) {\r\n // ADR-0074: the answer did not come in time. The connection is not trusted any more (the server runs one invocation per\r\n // connection at a time, and whatever lost this answer may lose the next): drop it, so the retry runs on a fresh one.\r\n if (timedOut) await this._dropConnection();\r\n throw mapError(error, signal ? signal.aborted : false) ?? error;\r\n } finally {\r\n if (timer !== null) clearTimeout(timer);\r\n unsubscribe();\r\n }\r\n }\r\n\r\n /** Ends the connection after a call or stream ran out of time (ADR-0074); the next call connects afresh. Never throws. */\r\n private async _dropConnection(): Promise<void> {\r\n try {\r\n await this.client.connection.stop();\r\n } catch {\r\n // Stopping a connection that is already gone may throw; the next call connects afresh either way.\r\n }\r\n }\r\n\r\n private _stream(method: string, args: unknown[], signal?: AbortSignal): AsyncIterable<G9DtSyncChunk> {\r\n // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n const self = this;\r\n return {\r\n [Symbol.asyncIterator](): AsyncIterator<G9DtSyncChunk> {\r\n const queue: G9DtSyncChunk[] = [];\r\n let done = false;\r\n let failure: unknown = null;\r\n let wake: (() => void) | null = null;\r\n let subscription: ISubscription<unknown> | null = null;\r\n const notify = (): void => {\r\n const w = wake;\r\n wake = null;\r\n if (w) w();\r\n };\r\n let unsubscribeAbort: () => void = () => undefined;\r\n // ADR-0074: the idle limit runs only while the iterator waits for the next chunk, never while the caller processes one.\r\n const idleMs = self._options.streamIdleTimeoutMs ?? 120000;\r\n let idleTimer: ReturnType<typeof setTimeout> | null = null;\r\n let idleExpired = false;\r\n const stopIdle = (): void => {\r\n if (idleTimer !== null) clearTimeout(idleTimer);\r\n idleTimer = null;\r\n };\r\n const armIdle = (): void => {\r\n stopIdle();\r\n if (idleMs <= 0 || done) return;\r\n idleTimer = setTimeout(() => {\r\n idleTimer = null;\r\n if (done) return;\r\n idleExpired = true;\r\n failure = new G9SyncException(G9SyncErrorCodes.NetworkFailure, `The sync server sent nothing on ${method} for ${Math.round(idleMs / 1000)} s.`, {\r\n retryable: true,\r\n });\r\n done = true;\r\n subscription?.dispose();\r\n notify();\r\n }, idleMs);\r\n };\r\n const start = (): void => {\r\n if (subscription || done) return;\r\n let stream: IStreamResult<unknown>;\r\n try {\r\n stream = self.client.connection.stream(method, ...args);\r\n } catch (error) {\r\n failure = error;\r\n done = true;\r\n return;\r\n }\r\n subscription = stream.subscribe({\r\n next: (item) => {\r\n queue.push(readSyncChunk(self._read(item)));\r\n notify();\r\n },\r\n error: (error) => {\r\n failure = error;\r\n done = true;\r\n notify();\r\n },\r\n complete: () => {\r\n done = true;\r\n notify();\r\n },\r\n });\r\n unsubscribeAbort = onAbort(signal, () => {\r\n failure = new G9SyncException(G9SyncErrorCodes.Canceled, 'The stream was canceled.');\r\n done = true;\r\n subscription?.dispose();\r\n notify();\r\n });\r\n };\r\n const finish = (): void => {\r\n stopIdle();\r\n unsubscribeAbort();\r\n if (subscription && !done) subscription.dispose();\r\n done = true;\r\n };\r\n return {\r\n async next(): Promise<IteratorResult<G9DtSyncChunk>> {\r\n start();\r\n for (;;) {\r\n const item = queue.shift();\r\n if (item) {\r\n stopIdle();\r\n return { value: item, done: false };\r\n }\r\n if (done) {\r\n stopIdle();\r\n unsubscribeAbort();\r\n if (idleExpired) await self._dropConnection();\r\n if (failure !== null) throw mapError(failure, signal ? signal.aborted : false) ?? failure;\r\n return { value: undefined as unknown as G9DtSyncChunk, done: true };\r\n }\r\n if (idleTimer === null) armIdle();\r\n await new Promise<void>((resolve) => {\r\n wake = resolve;\r\n });\r\n }\r\n },\r\n async return(): Promise<IteratorResult<G9DtSyncChunk>> {\r\n finish();\r\n return { value: undefined as unknown as G9DtSyncChunk, done: true };\r\n },\r\n };\r\n },\r\n };\r\n }\r\n\r\n private _onChanges(payload: unknown): void {\r\n const changes = readChangesAvailable(this._read(payload));\r\n for (const handler of this._handlers.slice()) {\r\n try {\r\n handler(changes);\r\n } catch {\r\n // A ChangesAvailable handler threw (logged by the .NET transport); it must not break the connection.\r\n }\r\n }\r\n }\r\n}\r\n\r\nfunction messageOf(error: unknown): string {\r\n return error instanceof Error ? error.message : String(error);\r\n}\r\n\r\n/**\r\n * The sync exception for a transport failure (`Map`): the server's `[G9S|code|retryable]` marker wins; any other hub\r\n * error is a retryable server error; 401/403 is Unauthorized; the rest is a retryable network failure. Null leaves the\r\n * error as it is (an already mapped one).\r\n */\r\nexport function mapError(error: unknown, canceled: boolean): G9SyncException | null {\r\n if (isSyncException(error)) return null;\r\n if (canceled) return new G9SyncException(G9SyncErrorCodes.Canceled, 'The call was canceled.', { cause: error });\r\n const message = messageOf(error);\r\n const marked = G9SyncHubErrors.tryParse(message);\r\n if (marked) return marked;\r\n const status = (error as { statusCode?: unknown }).statusCode;\r\n if (status === 401 || status === 403) return new G9SyncException(G9SyncErrorCodes.Unauthorized, 'The sync server refused the credentials.', { cause: error });\r\n if (error instanceof Error && error.name === 'AbortError') return new G9SyncException(G9SyncErrorCodes.Canceled, message, { cause: error });\r\n // A completion error from the hub: SignalR words it \"An unexpected error occurred invoking '…' on the server.\"\r\n if (/on the server|HubException/i.test(message)) return new G9SyncException(G9SyncErrorCodes.ServerError, message, { retryable: true, cause: error });\r\n return new G9SyncException(G9SyncErrorCodes.NetworkFailure, message, { retryable: true, cause: error });\r\n}\r\n"]}
|
package/dist/sqlite/push.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Twin of G9SyncData.Client.Sqlite/G9CSqliteSyncStore.Push.cs: dirty rows in local change order become push frames; the
|
|
2
2
|
// result clears exactly the rows that were sent (rows edited meanwhile stay dirty), flags rejections and applies canonical
|
|
3
3
|
// server rows.
|
|
4
|
-
import { G9ESyncDirection } from '../abstractions/enums.js';
|
|
4
|
+
import { G9ESyncColumnType, G9ESyncDirection } from '../abstractions/enums.js';
|
|
5
5
|
import { G9SyncErrorCodes } from '../abstractions/errors.js';
|
|
6
6
|
import { G9Long } from '../abstractions/long.js';
|
|
7
7
|
import { utf8Encode } from '../internal/utf8.js';
|
|
@@ -300,8 +300,12 @@ async function readLostConflicts(store, batch, result) {
|
|
|
300
300
|
const serverDeleted = conflict.code === G9SyncErrorCodes.ConflictDeleted;
|
|
301
301
|
if (dirty === 2 && serverDeleted)
|
|
302
302
|
continue; // both sides deleted it: nothing was lost
|
|
303
|
-
|
|
303
|
+
// Only what this push CARRIED can have been lost (LES-0086): a column the device changed but never sends - read-only on the
|
|
304
|
+
// server, or not negotiated - was not part of the conflict, and the canonical row simply replaces it.
|
|
304
305
|
const names = pushOrder.get(conflict.tableId);
|
|
306
|
+
let lostMask = names ? mask.and(pushedMask(table, names)) : mask;
|
|
307
|
+
if (dirty === 1 && lostMask.isZero())
|
|
308
|
+
continue;
|
|
305
309
|
if (dirty === 1 && conflict.partiallyApplied && !conflict.serverChangedMask.isNegative() && conflict.code === G9SyncErrorCodes.ConflictColumns && names) {
|
|
306
310
|
// The server's bits are in push column order; the device's are model columns.
|
|
307
311
|
lostMask = G9Long.ZERO;
|
|
@@ -319,13 +323,49 @@ async function readLostConflicts(store, batch, result) {
|
|
|
319
323
|
}
|
|
320
324
|
return lost;
|
|
321
325
|
}
|
|
326
|
+
/** The device's column bits of the columns a push sent for this table (push column order → model order). Twin of .NET PushedMask. */
|
|
327
|
+
function pushedMask(table, pushed) {
|
|
328
|
+
let mask = G9Long.ZERO;
|
|
329
|
+
for (const name of pushed) {
|
|
330
|
+
const local = table.model.indexOf(name);
|
|
331
|
+
if (local >= 0 && local < 63)
|
|
332
|
+
mask = mask.or(G9Long.ONE.shiftLeft(local));
|
|
333
|
+
}
|
|
334
|
+
return mask;
|
|
335
|
+
}
|
|
322
336
|
/** Two SQLite values are the same value (a blob by its bytes); a different type counts as different. Twin of .NET SameValue. */
|
|
323
|
-
function sameValue(a, b) {
|
|
337
|
+
function sameValue(a, b, type) {
|
|
324
338
|
if (a instanceof Uint8Array && b instanceof Uint8Array)
|
|
325
339
|
return a.length === b.length && a.every((x, i) => x === b[i]);
|
|
326
340
|
if (typeof a === 'bigint' || typeof b === 'bigint')
|
|
327
341
|
return typeof a === typeof b && a === b;
|
|
328
|
-
|
|
342
|
+
if (a === b || (a == null && b == null))
|
|
343
|
+
return true;
|
|
344
|
+
// A timestamp is the same INSTANT to the microsecond (LES-0086): the device keeps 100 ns, the server microseconds.
|
|
345
|
+
if ((type === G9ESyncColumnType.DateTime || type === G9ESyncColumnType.DateTimeOffset) && typeof a === 'string' && typeof b === 'string') {
|
|
346
|
+
const first = instant(a);
|
|
347
|
+
const second = instant(b);
|
|
348
|
+
if (first && second)
|
|
349
|
+
return Math.abs((first[0] - second[0]) * 10000 + (first[1] - second[1])) < 10;
|
|
350
|
+
}
|
|
351
|
+
return false;
|
|
352
|
+
}
|
|
353
|
+
const instantPattern = /^(\d{4})-(\d{2})-(\d{2})[T ](\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,7}))?(Z|[+-]\d{2}:?\d{2})?$/;
|
|
354
|
+
/** A timestamp text as [Unix milliseconds, 100 ns units within that millisecond]; no BigInt (Lynx). Twin of .NET Instant. */
|
|
355
|
+
function instant(text) {
|
|
356
|
+
var _a;
|
|
357
|
+
const m = instantPattern.exec(text.trim());
|
|
358
|
+
if (!m)
|
|
359
|
+
return null;
|
|
360
|
+
const fraction = (((_a = m[7]) !== null && _a !== void 0 ? _a : '') + '0000000').slice(0, 7);
|
|
361
|
+
let ms = Date.UTC(Number(m[1]), Number(m[2]) - 1, Number(m[3]), Number(m[4]), Number(m[5]), Number(m[6]), Number(fraction.slice(0, 3)));
|
|
362
|
+
const zone = m[8];
|
|
363
|
+
if (zone && zone !== 'Z') {
|
|
364
|
+
const sign = zone[0] === '-' ? -1 : 1;
|
|
365
|
+
const digits = zone.slice(1).replace(':', '');
|
|
366
|
+
ms -= sign * (Number(digits.slice(0, 2)) * 60 + Number(digits.slice(2, 4))) * 60000;
|
|
367
|
+
}
|
|
368
|
+
return [ms, Number(fraction.slice(3))];
|
|
329
369
|
}
|
|
330
370
|
/** Twin of .NET KeepLostConflicts: the device's lost values back over the canonical rows, parked as rejections (LES-0072). */
|
|
331
371
|
async function keepLostConflicts(store, context, lost) {
|
|
@@ -354,7 +394,7 @@ async function keepLostConflicts(store, context, lost) {
|
|
|
354
394
|
else {
|
|
355
395
|
const lostColumns = table.model.columns.map((c, i) => ({ name: c.name, i })).filter((c) => item.lostMask.testBit(c.i) && c.name in item.values);
|
|
356
396
|
// LES-0085: a column the server already holds with the device's own value lost nothing; when none differs, the row is in sync.
|
|
357
|
-
const differing = lostColumns.filter((c) => !sameValue(item.values[c.name], now[c.name]));
|
|
397
|
+
const differing = lostColumns.filter((c) => { var _a; return !sameValue(item.values[c.name], now[c.name], (_a = table.model.columns[c.i]) === null || _a === void 0 ? void 0 : _a.type); });
|
|
358
398
|
if (lostColumns.length > 0 && differing.length === 0) {
|
|
359
399
|
context.report.conflictsSameValue++;
|
|
360
400
|
continue;
|
package/dist/sqlite/push.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/sqlite/push.ts"],"names":[],"mappings":"AAAA,wHAAwH;AACxH,2HAA2H;AAC3H,eAAe;AACf,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAoB,MAAM,yBAAyB,CAAC;AAE1E,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE7D,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,OAAO,EAAwC,MAAM,gBAAgB,CAAC;AACpK,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAiB1F,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB,+GAA+G;AAC/G,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAqB,EAAE,MAAsC,EAAE,OAAe,EAAE,QAAgB;IACnI,KAAK,CAAC,iBAAiB,EAAE,CAAC;IAC1B,MAAM,UAAU,GAAG,IAAI,GAAG,EAAyF,CAAC;IACpH,KAAK,MAAM,UAAU,IAAI,MAAM,EAAE,CAAC;QAChC,IAAI,UAAU,CAAC,SAAS,KAAK,gBAAgB,CAAC,YAAY;YAAE,SAAS;QACrE,MAAM,KAAK,GAAG,gBAAgB,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;QACvD,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;QACnC,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,eAAe;YAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAC1E,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,eAAe;YAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAC1E,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO;aAC/B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aACtF,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QACpF,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,OAAO,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,CAC9B,KAAK,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,WAAW,EAAE,KAAK,IAAI,EAAE;;QACjD,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC;QAClE,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;QAC/D,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;QAC9D,MAAM,QAAQ,GAAG,UAAU,KAAK,IAAI,IAAI,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAE/F,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3C,iHAAiH;QACjH,kHAAkH;QAClH,mHAAmH;QACnH,MAAM,GAAG,GACP,4IAA4I;YAC5I,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;YACd,GAAG;YACH,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,yBAAyB,CAAC;YACvD,gCAAgC,CAAC;QACnC,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;QACnG,MAAM,OAAO,GACX,UAAU,CAAC,IAAI,KAAK,CAAC;YACnB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,MAAM,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QACtJ,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC/B,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACnB,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACnB,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACrB,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAClB,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACpB,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACnB,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SACpB,CAAC,CAAC,CAAC;QAEJ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/C,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;gBAC3B,mFAAmF;gBACnF,MAAM,UAAU,CAAC,IAAI,CAAC,4EAA4E,CAAC,CAAC;YACtG,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,qHAAqH;QACrH,kEAAkE;QAClE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAuB,CAAC;QAChD,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,IAAI,mBAAmB,GAAG,CAAC,CAAC;QAC5B,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,MAAM,QAAQ,GAAkD,EAAE,CAAC;QACnE,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACtC,IAAI,CAAC,KAAK;gBAAE,SAAS;YACrB,IAAI,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACpC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,MAAM,GACV,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;oBACxB,CAAC,CAAC,iBAAiB,KAAK,CAAC,KAAK,CAAC,MAAM,UAAU,KAAK,CAAC,KAAK,CAAC,SAAS,OAAO;oBAC3E,CAAC,CAAC,UAAU,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,KAAK,CAAC,MAAM,UAAU,KAAK,CAAC,KAAK,CAAC,SAAS,OAAO,CAAC;gBAClK,MAAM,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAC;gBACtC,MAAM,CAAC,YAAY,CACjB,aAAa,CAAC,IAAI,EAClB,KAAK,CAAC,UAAU,CAAC,OAAO,EACxB,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EACzB,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CACjC,CAAC;gBACF,OAAO,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;gBAChH,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YACjC,CAAC;YAED,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,QAAQ,CAAC;YACnD,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;YAC5C,IAAI,GAAG,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;gBACpB,MAAM,WAAW,GAAG,YAAY,GAAG,QAAQ,CAAC;gBAC5C,IAAI,QAAQ,GAAG,CAAC,IAAI,UAAU,GAAG,WAAW,GAAG,QAAQ,EAAE,CAAC;oBACxD,SAAS,GAAG,IAAI,CAAC;oBACjB,MAAM;gBACR,CAAC;gBACD,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;gBAC/F,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBACxB,OAAO,CAAC,IAAI,EAAE,CAAC;gBACf,QAAQ,EAAE,CAAC;gBACX,mBAAmB,GAAG,GAAG,CAAC,GAAG,CAAC;gBAC9B,UAAU,IAAI,WAAW,CAAC;gBAC1B,SAAS;YACX,CAAC;YAED,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC/F,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACxB,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;gBAC/F,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBACxB,OAAO,CAAC,IAAI,EAAE,CAAC;gBACf,QAAQ,EAAE,CAAC;gBACX,mBAAmB,GAAG,GAAG,CAAC,GAAG,CAAC;gBAC9B,UAAU,IAAI,YAAY,GAAG,QAAQ,CAAC;gBACtC,SAAS;YACX,CAAC;YAED,IAAI,QAAQ,GAAG,YAAY,GAAG,QAAQ,CAAC;YACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE;gBAAE,QAAQ,IAAI,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAe,EAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAgB,CAAC,IAAI,CAAC,CAAC;YACpJ,IAAI,QAAQ,GAAG,QAAQ,EAAE,CAAC;gBACxB,wGAAwG;gBACxG,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAC/D,SAAS;YACX,CAAC;YACD,IAAI,QAAQ,GAAG,CAAC,IAAI,UAAU,GAAG,QAAQ,GAAG,QAAQ,EAAE,CAAC;gBACrD,SAAS,GAAG,IAAI,CAAC;gBACjB,MAAM;YACR,CAAC;YAED,IAAI,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC;YAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAChD,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAgB,CAAC,KAAK,CAAC;oBAAE,QAAQ,GAAG,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;YAClH,CAAC;YACD,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;YAC5F,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE;gBAAE,eAAe,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAe,EAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAgB,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YAClK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,QAAQ,EAAE,CAAC;YACX,mBAAmB,GAAG,GAAG,CAAC,GAAG,CAAC;YAC9B,UAAU,IAAI,QAAQ,CAAC;QACzB,CAAC;QAED,KAAK,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,QAAQ,EAAE,CAAC;YAC3C,MAAM,UAAU,CAAC,IAAI,CAAC,6DAA6D,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;YAC5G,MAAM,UAAU,CAAC,IAAI,CACnB,0HAA0H;gBACxH,gEAAgE,EAClE;gBACE,EAAE,EAAE,GAAG;gBACP,GAAG,EAAE,GAAG;gBACR,KAAK,EAAE,gBAAgB,CAAC,cAAc;gBACtC,QAAQ,EAAE,uBAAuB,KAAK,sCAAsC,QAAQ,kBAAkB;gBACtG,GAAG,EAAE,KAAK,EAAE;aACb,CACF,CAAC;QACJ,CAAC;QAED,IAAI,QAAQ,KAAK,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC;YACvC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,eAAe,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QAC/I,CAAC;QAED,MAAM,MAAM,GAAiB,EAAE,CAAC;QAChC,MAAM,UAAU,GAAuB,EAAE,CAAC;QAC1C,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC3B,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC;gBAAE,OAAO;YAC/B,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YAC5B,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;YACnF,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACxG,CAAC,CAAC,CAAC;QAEH,IAAI,OAAe,CAAC;QACpB,IAAI,WAAmB,CAAC;QACxB,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;YAC3B,OAAO,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;YAChC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;QACpC,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,MAAM,CAAC,MAAA,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC,mCAAI,GAAG,CAAC,CAAC;YACnE,WAAW,GAAG,mBAAmB,CAAC;YAClC,MAAM,OAAO,CAAC,UAAU,EAAE,eAAe,EAAE,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC;YAChE,MAAM,OAAO,CAAC,UAAU,EAAE,mBAAmB,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;YAChE,MAAM,OAAO,CAAC,UAAU,EAAE,kBAAkB,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;QACrE,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,MAAM,UAAU,CAAC,IAAI,CAAC,6DAA6D,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QAC7H,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC;IACzI,CAAC,CAAC,CACH,CAAC;AACJ,CAAC;AAED,2GAA2G;AAC3G,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,KAAqB,EAAE,UAAkB,EAAE,IAA8B;IAChH,KAAK,CAAC,iBAAiB,EAAE,CAAC;IAC1B,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAC1C,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,CAAC,SAAS,KAAK,gBAAgB,CAAC,UAAU,EAAE,CAAC;QACpF,MAAM,IAAI,KAAK,CAAC,IAAI,UAAU,sFAAsF,CAAC,CAAC;IACxH,CAAC;IACD,OAAO,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,CAC9B,KAAK,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,WAAW,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,UAAU,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC,CAAC,gCAAgC;QACtG,MAAM,UAAU,CAAC,IAAI,CAAC,wFAAwF,CAAC,CAAC;QAChH,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,MAAM,UAAU,CAAC,IAAI,CAAC,gFAAgF,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAC7H,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,MAAM,UAAU,CAAC,IAAI,CAAC,uGAAuG,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;YAC9J,CAAC;QACH,CAAC;QACD,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,UAAU,CAAC,MAAM,CAAC,gCAAgC,CAAC,CAAC,CAAC;QACtF,MAAM,UAAU,CAAC,IAAI,CAAC,eAAe,KAAK,CAAC,MAAM,eAAe,KAAK,CAAC,SAAS,yCAAyC,CAAC,CAAC;QAC1H,MAAM,UAAU,CAAC,IAAI,CAAC,gGAAgG,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAC3I,MAAM,UAAU,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;QACrE,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC,CACH,CAAC;AACJ,CAAC;AAED,8BAA8B;AAC9B,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAqB,EAAE,KAAkB,EAAE,MAAsB,EAAE,MAAoB;IAC3H,KAAK,CAAC,iBAAiB,EAAE,CAAC;IAC1B,OAAO,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,CAC9B,KAAK,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,WAAW,EAAE,KAAK,IAAI,EAAE;;QACjD,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QAClC,oHAAoH;QACpH,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,UAAU,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;QAC5E,mHAAmH;QACnH,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAC3D,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,kBAAkB,EAAE,KAAK,CAAC,WAAW,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACtH,OAAO,CAAC,MAAM,CAAC,iBAAiB,GAAG,SAAS,CAAC;QAE7C,MAAM,SAAS,GACb,sCAAsC;YACtC,2DAA2D;YAC3D,qEAAqE;YACrE,6EAA6E;YAC7E,4CAA4C;YAC5C,uDAAuD,CAAC;QAC1D,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACrD,IAAI,CAAC,KAAK;gBAAE,SAAS;YACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC9C,MAAM,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAY,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,WAAW,EAAE,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAW,EAAE,CAAC,CAAC;gBACnL,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YAC5B,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GACb,mFAAmF;YACnF,0HAA0H;YAC1H,iFAAiF,CAAC;QACpF,MAAM,GAAG,GAAG,KAAK,EAAE,CAAC;QACpB,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACtD,IAAI,CAAC,KAAK;gBAAE,SAAS;YACrB,MAAM,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE;gBAC7B,EAAE,EAAE,KAAK,CAAC,GAAG;gBACb,GAAG,EAAE,SAAS,CAAC,GAAG;gBAClB,EAAE,EAAE,KAAK,CAAC,WAAW;gBACrB,KAAK,EAAE,SAAS,CAAC,IAAI;gBACrB,QAAQ,EAAE,MAAA,SAAS,CAAC,OAAO,mCAAI,IAAI;gBACnC,MAAM,EAAE,MAAA,SAAS,CAAC,QAAQ,mCAAI,IAAI;gBAClC,WAAW,EAAE,MAAA,SAAS,CAAC,UAAU,mCAAI,IAAI;gBACzC,OAAO,EAAE,MAAA,SAAS,CAAC,MAAM,mCAAI,IAAI;gBACjC,QAAQ,EAAE,MAAA,SAAS,CAAC,OAAO,mCAAI,IAAI;gBACnC,IAAI,EAAE,GAAG;aACV,CAAC,CAAC;YACH,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC;QAED,OAAO,CAAC,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC;QACnD,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACtB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,eAAe;YAAE,MAAM,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAC1F,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACtB,MAAM,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAE9C,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC;QACxB,MAAM,UAAU,CAAC,IAAI,CAAC,4EAA4E,CAAC,CAAC;QACpG,OAAO,OAAO,CAAC,MAAM,CAAC;IACxB,CAAC,CAAC,CACH,CAAC;AACJ,CAAC;AAcD;;;GAGG;AACH,KAAK,UAAU,iBAAiB,CAAC,KAAqB,EAAE,KAAkB,EAAE,MAAsB;IAChG,MAAM,IAAI,GAAmB,EAAE,CAAC;IAChC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACnF,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;IAClC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC3E,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACrD,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,GAAG,GAAG,CAAC,MAAM,UAAU,CAAC,KAAK,CAAC,gGAAgG,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAChL,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,KAAK,KAAK,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,WAAW;YAAE,SAAS;QAClE,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,KAAK,gBAAgB,CAAC,eAAe,CAAC;QACzE,IAAI,KAAK,KAAK,CAAC,IAAI,aAAa;YAAE,SAAS,CAAC,0CAA0C;QAEtF,IAAI,QAAQ,GAAG,IAAI,CAAC;QACpB,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC9C,IAAI,KAAK,KAAK,CAAC,IAAI,QAAQ,CAAC,gBAAgB,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,UAAU,EAAE,IAAI,QAAQ,CAAC,IAAI,KAAK,gBAAgB,CAAC,eAAe,IAAI,KAAK,EAAE,CAAC;YACxJ,8EAA8E;YAC9E,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC;YACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;gBAChD,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC;oBAAE,SAAS;gBACrD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAW,CAAC,CAAC;gBACtD,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;oBAAE,QAAQ,GAAG,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;YAC7F,CAAC;YACD,IAAI,QAAQ,CAAC,MAAM,EAAE;gBAAE,SAAS;QAClC,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/L,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,gIAAgI;AAChI,SAAS,SAAS,CAAC,CAAU,EAAE,CAAU;IACvC,IAAI,CAAC,YAAY,UAAU,IAAI,CAAC,YAAY,UAAU;QAAE,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtH,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5F,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED,8HAA8H;AAC9H,KAAK,UAAU,iBAAiB,CAAC,KAAqB,EAAE,OAA+C,EAAE,IAAoB;;IAC3H,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACtC,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACzB,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,UAAU,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/D,IAAI,WAAW,GAAkB,IAAI,CAAC;QACtC,IAAI,YAAY,GAAkB,IAAI,CAAC;QACvC,IAAI,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC7B,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;YACrB,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC;gBAAE,MAAM,UAAU,CAAC,IAAI,CAAC,eAAe,KAAK,CAAC,MAAM,UAAU,KAAK,CAAC,SAAS,OAAO,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QACnI,CAAC;aAAM,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzC,qEAAqE;YACrE,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACrC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YAC/B,MAAM,MAAM,GAAmC,EAAE,CAAC;YAClD,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAe,CAAC,CAAC,CAAC;YACnF,MAAM,UAAU,CAAC,IAAI,CAAC,eAAe,KAAK,CAAC,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACjJ,CAAC;aAAM,CAAC;YACN,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC;YAChJ,+HAA+H;YAC/H,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC1F,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACrD,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;gBACpC,SAAS;YACX,CAAC;YACD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;gBAAE,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YAC9G,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC7C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAChC,MAAM,MAAM,GAAkC,EAAE,CAAC;gBACjD,KAAK,MAAM,MAAM,IAAI,OAAO;oBAAE,MAAM,CAAC,MAAM,CAAC,GAAG,MAAA,GAAG,CAAC,MAAM,CAAC,mCAAI,IAAI,CAAC;gBACnE,YAAY,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;gBACvC,MAAM,MAAM,GAAmC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC;gBAC3D,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAe,CAAC,CAAC,CAAC;gBACvF,MAAM,UAAU,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,MAAM,QAAQ,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,SAAS,OAAO,EAAE,MAAM,CAAC,CAAC;YACxJ,CAAC;QACH,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;QACvD,MAAM,UAAU,CAAC,IAAI,CACnB,mGAAmG;YACjG,yFAAyF;YACzF,0HAA0H;YAC1H,8GAA8G;YAC9G,gDAAgD,EAClD,EAAE,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,EAAE,CACtI,CAAC;QACF,MAAM,UAAU,CAAC,IAAI,CACnB,0HAA0H;YACxH,wEAAwE,EAC1E;YACE,EAAE,EAAE,KAAK,CAAC,GAAG;YACb,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,KAAK,EAAE,IAAI,CAAC,IAAI;YAChB,QAAQ,EACN,IAAI,CAAC,KAAK,KAAK,CAAC;gBACd,CAAC,CAAC,2GAA2G;gBAC7G,CAAC,CAAC,sBAAsB,WAAW,aAAX,WAAW,cAAX,WAAW,GAAI,UAAU,iFAAiF;YACtI,OAAO,EAAE,WAAW;YACpB,QAAQ,EAAE,YAAY;YACtB,IAAI,EAAE,KAAK,EAAE;SACd,CACF,CAAC;QACF,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC;YAAE,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1G,CAAC;AACH,CAAC","sourcesContent":["// Twin of G9SyncData.Client.Sqlite/G9CSqliteSyncStore.Push.cs: dirty rows in local change order become push frames; the\r\n// result clears exactly the rows that were sent (rows edited meanwhile stay dirty), flags rejections and applies canonical\r\n// server rows.\r\nimport { G9ESyncDirection } from '../abstractions/enums.js';\r\nimport { G9SyncErrorCodes } from '../abstractions/errors.js';\r\nimport { G9Long } from '../abstractions/long.js';\r\nimport { utf8Encode } from '../internal/utf8.js';\r\nimport { G9ApplyReport, type G9PushBatch } from '../client/storeTypes.js';\r\nimport type { G9DtNegotiatedTable, G9DtPushResult, G9DtTableColumns } from '../protocol/dtos.js';\r\nimport { G9EPushRowOp, G9ERowBatchOp } from '../protocol/rowBatch/format.js';\r\nimport { G9RowBatchWriter } from '../protocol/rowBatch/writer.js';\r\nimport { applyFrame, beginApply, endApply } from './apply.js';\r\nimport { completeCommands, readPendingCommands } from './commands.js';\r\nimport { asLong, asNumber, asString } from './connection.js';\r\nimport type { G9SqlValue } from './driver.js';\r\nimport { findByServerName, getLocal, keyValue, meta, nowMs, readLocalValues, serializeValues, setMeta, type LocalTable, type StoreInternals } from './internals.js';\r\nimport { quote } from './sql.js';\r\nimport { estimateEncodedBytes, pushSelectExpression, writeLocalValue } from './values.js';\r\n\r\ninterface PushColumn {\r\n name: string;\r\n type: number;\r\n local: number;\r\n}\r\n\r\ninterface PushSection {\r\n table: LocalTable;\r\n negotiated: G9DtNegotiatedTable;\r\n columns: PushColumn[];\r\n writer: G9RowBatchWriter;\r\n select: string;\r\n rows: number;\r\n}\r\n\r\nconst ROW_OVERHEAD = 48;\r\n\r\n/** `BuildPushBatchAsync`: the next batch of pending changes, oldest first, within the row and byte budgets. */\r\nexport async function buildPushBatch(store: StoreInternals, tables: readonly G9DtNegotiatedTable[], maxRows: number, maxBytes: number): Promise<G9PushBatch | null> {\r\n store.ensureInitialized();\r\n const uploadable = new Map<number, { table: LocalTable; negotiated: G9DtNegotiatedTable; columns: PushColumn[] }>();\r\n for (const negotiated of tables) {\r\n if (negotiated.direction === G9ESyncDirection.DownloadOnly) continue;\r\n const local = findByServerName(store, negotiated.name);\r\n if (!local) continue;\r\n const readOnly = new Set<string>();\r\n for (const c of negotiated.readOnlyColumns) readOnly.add(c.toLowerCase());\r\n for (const c of negotiated.computedColumns) readOnly.add(c.toLowerCase());\r\n const columns = negotiated.columns\r\n .filter((c) => !readOnly.has(c.name.toLowerCase()) && local.model.indexOf(c.name) >= 0)\r\n .map((c) => ({ name: c.name, type: c.type, local: local.model.indexOf(c.name) }));\r\n uploadable.set(local.tid, { table: local, negotiated, columns });\r\n }\r\n\r\n return store.writeLock.run(() =>\r\n store.writer().transaction('immediate', async () => {\r\n const connection = store.writer();\r\n const inflightBatch = await meta(connection, 'inflight_batch_id');\r\n const inflightMax = await meta(connection, 'inflight_max_seq');\r\n const offsetText = await meta(connection, 'server_offset_ms');\r\n const offsetMs = offsetText !== null && /^[+-]?\\d+$/.test(offsetText) ? Number(offsetText) : 0;\r\n\r\n const tids = Array.from(uploadable.keys());\r\n // `+tid`: the unary plus keeps the tid list from driving the plan. Without it SQLite searches the primary key by\r\n // tid — every row of every uploadable table (486k on a farm device, 16 s on the bridge) — and sorts them, instead\r\n // of walking the partial g9_rows_dirty index, which holds only the pending rows and is already in local_seq order.\r\n const sql =\r\n 'SELECT tid, pk, dirty, dirty_mask, server_ver, local_seq, coalesce(hlc_ms, 0) FROM g9_rows WHERE dirty <> 0 AND rejected = 0 AND +tid IN (' +\r\n tids.join(',') +\r\n ')' +\r\n (inflightMax === null ? '' : ' AND local_seq <= $imax') +\r\n ' ORDER BY local_seq LIMIT $max';\r\n const commands = await readPendingCommands(store, connection, inflightBatch, Math.max(1, maxRows));\r\n const pending =\r\n uploadable.size === 0\r\n ? []\r\n : await connection.query(sql, inflightMax === null ? { $max: Math.max(1, maxRows) } : { $max: Math.max(1, maxRows), $imax: Number(inflightMax) });\r\n const rows = pending.map((r) => ({\r\n tid: asNumber(r[0]),\r\n key: asString(r[1]),\r\n dirty: asNumber(r[2]),\r\n mask: asLong(r[3]),\r\n base: asNumber(r[4]),\r\n seq: asNumber(r[5]),\r\n hlc: asNumber(r[6]),\r\n }));\r\n\r\n if (rows.length === 0 && commands.length === 0) {\r\n if (inflightBatch !== null) {\r\n // Everything the in-flight batch carried has been resolved another way; forget it.\r\n await connection.exec(\"DELETE FROM g9_meta WHERE key IN ('inflight_batch_id', 'inflight_max_seq')\");\r\n }\r\n return null;\r\n }\r\n\r\n // Rows are encoded in local_seq order and the batch ends at the first row past the byte budget, so a batch is always\r\n // a PREFIX of the pending changes. One section (frame) per table.\r\n const sections = new Map<number, PushSection>();\r\n let included = 0;\r\n let includedMaxSequence = 0;\r\n let budgetUsed = 0;\r\n let truncated = false;\r\n const tooLarge: { tid: number; key: string; bytes: number }[] = [];\r\n for (const row of rows) {\r\n const entry = uploadable.get(row.tid);\r\n if (!entry) continue;\r\n let section = sections.get(row.tid);\r\n if (!section) {\r\n const select =\r\n entry.columns.length === 0\r\n ? `SELECT 1 FROM ${entry.table.quoted} WHERE ${entry.table.keyQuoted} = $k`\r\n : `SELECT ${entry.columns.map((c) => pushSelectExpression(quote(c.name), c.type)).join(', ')} FROM ${entry.table.quoted} WHERE ${entry.table.keyQuoted} = $k`;\r\n const writer = new G9RowBatchWriter();\r\n writer.beginSection(\r\n G9ERowBatchOp.Push,\r\n entry.negotiated.tableId,\r\n entry.table.model.keyType,\r\n entry.columns.map((c) => c.type),\r\n );\r\n section = { table: entry.table, negotiated: entry.negotiated, columns: entry.columns, writer, select, rows: 0 };\r\n sections.set(row.tid, section);\r\n }\r\n\r\n const hlc = row.hlc === 0 ? 0 : row.hlc + offsetMs;\r\n const keyBytes = utf8Encode(row.key).length;\r\n if (row.dirty === 2) {\r\n const deleteBytes = ROW_OVERHEAD + keyBytes;\r\n if (included > 0 && budgetUsed + deleteBytes > maxBytes) {\r\n truncated = true;\r\n break;\r\n }\r\n section.writer.beginPushRow(row.key, G9EPushRowOp.Delete, row.seq, row.base, G9Long.ZERO, hlc);\r\n section.writer.endRow();\r\n section.rows++;\r\n included++;\r\n includedMaxSequence = row.seq;\r\n budgetUsed += deleteBytes;\r\n continue;\r\n }\r\n\r\n const found = await connection.query(section.select, { $k: keyValue(section.table, row.key) });\r\n const values = found[0];\r\n if (!values) {\r\n section.writer.beginPushRow(row.key, G9EPushRowOp.Delete, row.seq, row.base, G9Long.ZERO, hlc);\r\n section.writer.endRow();\r\n section.rows++;\r\n included++;\r\n includedMaxSequence = row.seq;\r\n budgetUsed += ROW_OVERHEAD + keyBytes;\r\n continue;\r\n }\r\n\r\n let rowBytes = ROW_OVERHEAD + keyBytes;\r\n for (let j = 0; j < section.columns.length; j++) rowBytes += estimateEncodedBytes(values[j] as G9SqlValue, (section.columns[j] as PushColumn).type);\r\n if (rowBytes > maxBytes) {\r\n // Can never fit, whatever else the batch carries: reject it here so it does not block every later push.\r\n tooLarge.push({ tid: row.tid, key: row.key, bytes: rowBytes });\r\n continue;\r\n }\r\n if (included > 0 && budgetUsed + rowBytes > maxBytes) {\r\n truncated = true;\r\n break;\r\n }\r\n\r\n let pushMask = G9Long.ZERO;\r\n for (let j = 0; j < section.columns.length; j++) {\r\n if (row.mask.testBit((section.columns[j] as PushColumn).local)) pushMask = pushMask.or(G9Long.ONE.shiftLeft(j));\r\n }\r\n section.writer.beginPushRow(row.key, G9EPushRowOp.Upsert, row.seq, row.base, pushMask, hlc);\r\n for (let j = 0; j < section.columns.length; j++) writeLocalValue(section.writer, values[j] as G9SqlValue, (section.columns[j] as PushColumn).type, store.options);\r\n section.writer.endRow();\r\n section.rows++;\r\n included++;\r\n includedMaxSequence = row.seq;\r\n budgetUsed += rowBytes;\r\n }\r\n\r\n for (const { tid, key, bytes } of tooLarge) {\r\n await connection.exec('UPDATE g9_rows SET rejected = 1 WHERE tid = $t AND pk = $pk', { $t: tid, $pk: key });\r\n await connection.exec(\r\n 'INSERT OR REPLACE INTO g9_rejections (tid, pk, code, message, sql_state, constraint_name, column_name, details, at_utc) ' +\r\n 'VALUES ($t, $pk, $code, $message, NULL, NULL, NULL, NULL, $at)',\r\n {\r\n $t: tid,\r\n $pk: key,\r\n $code: G9SyncErrorCodes.RejectTooLarge,\r\n $message: `The row needs about ${bytes} bytes; the server accepts at most ${maxBytes} bytes per push.`,\r\n $at: nowMs(),\r\n },\r\n );\r\n }\r\n\r\n if (included === 0 && commands.length === 0) {\r\n if (tooLarge.length === 0) return null;\r\n return { batchId: 0, maxSequence: 0, frames: [], tables: [], rowCount: 0, truncated: false, rejectedLocally: tooLarge.length, commands: [] };\r\n }\r\n\r\n const frames: Uint8Array[] = [];\r\n const usedTables: G9DtTableColumns[] = [];\r\n sections.forEach((section) => {\r\n if (section.rows === 0) return;\r\n section.writer.endSection();\r\n frames.push(section.writer.toFrame({ compressor: store.options.frameCompressor }));\r\n usedTables.push({ tableId: section.negotiated.tableId, columns: section.columns.map((c) => c.name) });\r\n });\r\n\r\n let batchId: number;\r\n let maxSequence: number;\r\n if (inflightBatch !== null) {\r\n batchId = Number(inflightBatch);\r\n maxSequence = Number(inflightMax);\r\n } else {\r\n batchId = Number((await meta(connection, 'next_batch_id')) ?? '1');\r\n maxSequence = includedMaxSequence;\r\n await setMeta(connection, 'next_batch_id', String(batchId + 1));\r\n await setMeta(connection, 'inflight_batch_id', String(batchId));\r\n await setMeta(connection, 'inflight_max_seq', String(maxSequence));\r\n }\r\n for (const item of commands) {\r\n await connection.exec('UPDATE g9_commands SET batch_id = $b WHERE command_id = $id', { $b: batchId, $id: item.commandId });\r\n }\r\n return { batchId, maxSequence, frames, tables: usedTables, rowCount: included, truncated, rejectedLocally: tooLarge.length, commands };\r\n }),\r\n );\r\n}\r\n\r\n/** `ForgetUploadedRowsAsync`: removes uploaded rows of an UPLOAD-ONLY table without uploading a delete. */\r\nexport async function forgetUploadedRows(store: StoreInternals, localTable: string, keys: readonly string[] | null): Promise<number> {\r\n store.ensureInitialized();\r\n const table = getLocal(store, localTable);\r\n if (!table.negotiated || table.negotiated.direction !== G9ESyncDirection.UploadOnly) {\r\n throw new Error(`'${localTable}' is not upload-only: deleting its rows locally is a change the server must receive.`);\r\n }\r\n return store.writeLock.run(() =>\r\n store.writer().transaction('immediate', async () => {\r\n const connection = store.writer();\r\n await connection.exec('UPDATE g9_ctx SET applying = 1 WHERE id = 1'); // a library write: not captured\r\n await connection.exec('CREATE TEMP TABLE IF NOT EXISTS g9_forget (pk TEXT PRIMARY KEY); DELETE FROM g9_forget');\r\n if (keys === null) {\r\n await connection.exec('INSERT INTO g9_forget (pk) SELECT pk FROM g9_rows WHERE tid = $t AND dirty = 0', { $t: table.tid });\r\n } else {\r\n for (const key of keys) {\r\n await connection.exec('INSERT OR IGNORE INTO g9_forget (pk) SELECT pk FROM g9_rows WHERE tid = $t AND pk = $pk AND dirty = 0', { $t: table.tid, $pk: key });\r\n }\r\n }\r\n const forgotten = asNumber(await connection.scalar('SELECT count(*) FROM g9_forget'));\r\n await connection.exec(`DELETE FROM ${table.quoted} WHERE CAST(${table.keyQuoted} AS TEXT) IN (SELECT pk FROM g9_forget)`);\r\n await connection.exec('DELETE FROM g9_rows WHERE tid = $t AND pk IN (SELECT pk FROM g9_forget); DELETE FROM g9_forget', { $t: table.tid });\r\n await connection.exec('UPDATE g9_ctx SET applying = 0 WHERE id = 1');\r\n return forgotten;\r\n }),\r\n );\r\n}\r\n\r\n/** `ApplyPushResultAsync`. */\r\nexport async function applyPushResult(store: StoreInternals, batch: G9PushBatch, result: G9DtPushResult, signal?: AbortSignal): Promise<G9ApplyReport> {\r\n store.ensureInitialized();\r\n return store.writeLock.run(() =>\r\n store.writer().transaction('immediate', async () => {\r\n const connection = store.writer();\r\n // Before BeginApply: finished commands release their rows, so the canonical rows below replace the optimistic ones.\r\n const completed = await completeCommands(connection, result.commandResults);\r\n // Read BEFORE anything below touches the rows: what the device sent for each conflict it may have lost (LES-0072).\r\n const lost = await readLostConflicts(store, batch, result);\r\n const context = await beginApply(store, connection, { dirtyAfterSequence: batch.maxSequence, backfills: [], signal });\r\n context.report.commandsCompleted = completed;\r\n\r\n const acceptSql =\r\n 'UPDATE g9_rows SET server_ver = $v, ' +\r\n 'dirty = CASE WHEN local_seq <= $m THEN 0 ELSE dirty END, ' +\r\n 'dirty_mask = CASE WHEN local_seq <= $m THEN 0 ELSE dirty_mask END, ' +\r\n 'deleted = CASE WHEN local_seq <= $m AND dirty = 2 THEN 1 ELSE deleted END, ' +\r\n 'rejected = 0 WHERE tid = $t AND pk = $pk; ' +\r\n 'DELETE FROM g9_rejections WHERE tid = $t AND pk = $pk';\r\n for (const accepted of result.accepted) {\r\n const table = store.byServerId.get(accepted.tableId);\r\n if (!table) continue;\r\n for (let i = 0; i < accepted.keys.length; i++) {\r\n await context.queue(acceptSql, { $v: i < accepted.versions.length ? (accepted.versions[i] as number) : 0, $m: batch.maxSequence, $t: table.tid, $pk: accepted.keys[i] as string });\r\n context.report.accepted++;\r\n }\r\n }\r\n\r\n const rejectSql =\r\n 'UPDATE g9_rows SET rejected = 1 WHERE tid = $t AND pk = $pk AND local_seq <= $m; ' +\r\n 'INSERT OR REPLACE INTO g9_rejections (tid, pk, code, message, sql_state, constraint_name, column_name, details, at_utc) ' +\r\n 'VALUES ($t, $pk, $code, $message, $state, $constraint, $column, $details, $now)';\r\n const now = nowMs();\r\n for (const rejection of result.rejections) {\r\n const table = store.byServerId.get(rejection.tableId);\r\n if (!table) continue;\r\n await context.queue(rejectSql, {\r\n $t: table.tid,\r\n $pk: rejection.key,\r\n $m: batch.maxSequence,\r\n $code: rejection.code,\r\n $message: rejection.message ?? null,\r\n $state: rejection.sqlState ?? null,\r\n $constraint: rejection.constraint ?? null,\r\n $column: rejection.column ?? null,\r\n $details: rejection.details ?? null,\r\n $now: now,\r\n });\r\n context.report.rejected++;\r\n }\r\n\r\n context.report.conflicts = result.conflicts.length;\r\n await context.flush();\r\n for (const frame of result.canonicalFrames) await applyFrame(store, context, frame, null);\r\n await context.flush();\r\n await keepLostConflicts(store, context, lost);\r\n\r\n await endApply(context);\r\n await connection.exec(\"DELETE FROM g9_meta WHERE key IN ('inflight_batch_id', 'inflight_max_seq')\");\r\n return context.report;\r\n }),\r\n );\r\n}\r\n\r\n/** A conflict the device lost, with its row as it was sent. */\r\ninterface LostConflict {\r\n table: LocalTable;\r\n key: string;\r\n code: string;\r\n dirty: number;\r\n lostMask: G9Long;\r\n subs: G9Long;\r\n version: G9Long;\r\n values: { [column: string]: G9SqlValue };\r\n}\r\n\r\n/**\r\n * Twin of .NET ReadLostConflicts (LES-0072): the conflicts of this push in which the server kept its own values for something the\r\n * device changed - the whole change, or the overlapping columns of a column merge - each with the device's row as it was sent.\r\n */\r\nasync function readLostConflicts(store: StoreInternals, batch: G9PushBatch, result: G9DtPushResult): Promise<LostConflict[]> {\r\n const lost: LostConflict[] = [];\r\n if (!store.options.keepLostConflicts || result.conflicts.length === 0) return lost;\r\n const connection = store.writer();\r\n const pushOrder = new Map(batch.tables.map((t) => [t.tableId, t.columns]));\r\n for (const conflict of result.conflicts) {\r\n const table = store.byServerId.get(conflict.tableId);\r\n if (!table) continue;\r\n const row = (await connection.query('SELECT dirty, dirty_mask, subs, server_ver, local_seq FROM g9_rows WHERE tid = $t AND pk = $pk', { $t: table.tid, $pk: conflict.key }))[0];\r\n if (!row) continue;\r\n const dirty = asNumber(row[0]);\r\n const mask = asLong(row[1]);\r\n if (dirty === 0 || asNumber(row[4]) > batch.maxSequence) continue;\r\n const serverDeleted = conflict.code === G9SyncErrorCodes.ConflictDeleted;\r\n if (dirty === 2 && serverDeleted) continue; // both sides deleted it: nothing was lost\r\n\r\n let lostMask = mask;\r\n const names = pushOrder.get(conflict.tableId);\r\n if (dirty === 1 && conflict.partiallyApplied && !conflict.serverChangedMask.isNegative() && conflict.code === G9SyncErrorCodes.ConflictColumns && names) {\r\n // The server's bits are in push column order; the device's are model columns.\r\n lostMask = G9Long.ZERO;\r\n for (let j = 0; j < names.length && j < 63; j++) {\r\n if (!conflict.serverChangedMask.testBit(j)) continue;\r\n const local = table.model.indexOf(names[j] as string);\r\n if (local >= 0 && mask.testBit(local)) lostMask = lostMask.or(G9Long.ONE.shiftLeft(local));\r\n }\r\n if (lostMask.isZero()) continue;\r\n }\r\n\r\n lost.push({ table, key: conflict.key, code: conflict.code, dirty, lostMask, subs: asLong(row[2]), version: asLong(row[3]), values: await readLocalValues(connection, table, conflict.key) });\r\n }\r\n return lost;\r\n}\r\n\r\n/** Two SQLite values are the same value (a blob by its bytes); a different type counts as different. Twin of .NET SameValue. */\r\nfunction sameValue(a: unknown, b: unknown): boolean {\r\n if (a instanceof Uint8Array && b instanceof Uint8Array) return a.length === b.length && a.every((x, i) => x === b[i]);\r\n if (typeof a === 'bigint' || typeof b === 'bigint') return typeof a === typeof b && a === b;\r\n return a === b || (a == null && b == null);\r\n}\r\n\r\n/** Twin of .NET KeepLostConflicts: the device's lost values back over the canonical rows, parked as rejections (LES-0072). */\r\nasync function keepLostConflicts(store: StoreInternals, context: Awaited<ReturnType<typeof beginApply>>, lost: LostConflict[]): Promise<void> {\r\n const connection = context.connection;\r\n for (const item of lost) {\r\n const table = item.table;\r\n const key = keyValue(table, item.key);\r\n const now = await readLocalValues(connection, table, item.key);\r\n let columnNames: string | null = null;\r\n let serverValues: string | null = null;\r\n let lostMask = item.lostMask;\r\n if (item.dirty === 2) {\r\n if (Object.keys(now).length > 0) await connection.exec(`DELETE FROM ${table.quoted} WHERE ${table.keyQuoted} = $k`, { $k: key });\r\n } else if (Object.keys(now).length === 0) {\r\n // The server deleted it: the device's row comes back as it was sent.\r\n const all = Object.keys(item.values);\r\n if (all.length === 0) continue;\r\n const params: { [name: string]: G9SqlValue } = {};\r\n all.forEach((column, i) => (params['$v' + i] = item.values[column] as G9SqlValue));\r\n await connection.exec(`INSERT INTO ${table.quoted} (${all.map(quote).join(', ')}) VALUES (${all.map((_, i) => '$v' + i).join(', ')})`, params);\r\n } else {\r\n const lostColumns = table.model.columns.map((c, i) => ({ name: c.name, i })).filter((c) => item.lostMask.testBit(c.i) && c.name in item.values);\r\n // LES-0085: a column the server already holds with the device's own value lost nothing; when none differs, the row is in sync.\r\n const differing = lostColumns.filter((c) => !sameValue(item.values[c.name], now[c.name]));\r\n if (lostColumns.length > 0 && differing.length === 0) {\r\n context.report.conflictsSameValue++;\r\n continue;\r\n }\r\n if (differing.length > 0) lostMask = differing.reduce((m, c) => m.or(G9Long.ONE.shiftLeft(c.i)), G9Long.ZERO);\r\n const columns = differing.map((c) => c.name);\r\n if (columns.length > 0) {\r\n columnNames = columns.join(',');\r\n const server: { [column: string]: unknown } = {};\r\n for (const column of columns) server[column] = now[column] ?? null;\r\n serverValues = serializeValues(server);\r\n const params: { [name: string]: G9SqlValue } = { $k: key };\r\n columns.forEach((column, i) => (params['$v' + i] = item.values[column] as G9SqlValue));\r\n await connection.exec(`UPDATE ${table.quoted} SET ${columns.map((c, i) => quote(c) + ' = $v' + i).join(', ')} WHERE ${table.keyQuoted} = $k`, params);\r\n }\r\n }\r\n\r\n const mask = item.dirty === 2 ? G9Long.ZERO : lostMask;\r\n await connection.exec(\r\n 'INSERT INTO g9_rows (tid, pk, server_ver, local_seq, subs, dirty, dirty_mask, rejected, deleted) ' +\r\n 'VALUES ($t, $pk, $v, (SELECT seq FROM g9_clock WHERE id = 1) + 1, $subs, $d, $m, 1, 0) ' +\r\n 'ON CONFLICT(tid, pk) DO UPDATE SET dirty = excluded.dirty, dirty_mask = excluded.dirty_mask, rejected = 1, deleted = 0, ' +\r\n 'subs = CASE WHEN g9_rows.subs = 0 THEN excluded.subs ELSE g9_rows.subs END, local_seq = excluded.local_seq; ' +\r\n 'UPDATE g9_clock SET seq = seq + 1 WHERE id = 1',\r\n { $t: table.tid, $pk: item.key, $v: item.version.toSqlValue(), $subs: item.subs.toSqlValue(), $d: item.dirty, $m: mask.toSqlValue() },\r\n );\r\n await connection.exec(\r\n 'INSERT OR REPLACE INTO g9_rejections (tid, pk, code, message, sql_state, constraint_name, column_name, details, at_utc) ' +\r\n 'VALUES ($t, $pk, $code, $message, NULL, NULL, $column, $details, $now)',\r\n {\r\n $t: table.tid,\r\n $pk: item.key,\r\n $code: item.code,\r\n $message:\r\n item.dirty === 2\r\n ? \"The server changed this row after the device last saw it; the device's delete was kept here, not applied.\"\r\n : `The server changed ${columnNames ?? 'this row'} after the device last saw it; the device's values were kept here, not applied.`,\r\n $column: columnNames,\r\n $details: serverValues,\r\n $now: nowMs(),\r\n },\r\n );\r\n context.report.conflictsKept++;\r\n if (context.wantsChangedKey(table.model.localName)) context.addChanged(table.model.localName, item.key);\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/sqlite/push.ts"],"names":[],"mappings":"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","sourcesContent":["// Twin of G9SyncData.Client.Sqlite/G9CSqliteSyncStore.Push.cs: dirty rows in local change order become push frames; the\r\n// result clears exactly the rows that were sent (rows edited meanwhile stay dirty), flags rejections and applies canonical\r\n// server rows.\r\nimport { G9ESyncColumnType, G9ESyncDirection } from '../abstractions/enums.js';\r\nimport { G9SyncErrorCodes } from '../abstractions/errors.js';\r\nimport { G9Long } from '../abstractions/long.js';\r\nimport { utf8Encode } from '../internal/utf8.js';\r\nimport { G9ApplyReport, type G9PushBatch } from '../client/storeTypes.js';\r\nimport type { G9DtNegotiatedTable, G9DtPushResult, G9DtTableColumns } from '../protocol/dtos.js';\r\nimport { G9EPushRowOp, G9ERowBatchOp } from '../protocol/rowBatch/format.js';\r\nimport { G9RowBatchWriter } from '../protocol/rowBatch/writer.js';\r\nimport { applyFrame, beginApply, endApply } from './apply.js';\r\nimport { completeCommands, readPendingCommands } from './commands.js';\r\nimport { asLong, asNumber, asString } from './connection.js';\r\nimport type { G9SqlValue } from './driver.js';\r\nimport { findByServerName, getLocal, keyValue, meta, nowMs, readLocalValues, serializeValues, setMeta, type LocalTable, type StoreInternals } from './internals.js';\r\nimport { quote } from './sql.js';\r\nimport { estimateEncodedBytes, pushSelectExpression, writeLocalValue } from './values.js';\r\n\r\ninterface PushColumn {\r\n name: string;\r\n type: number;\r\n local: number;\r\n}\r\n\r\ninterface PushSection {\r\n table: LocalTable;\r\n negotiated: G9DtNegotiatedTable;\r\n columns: PushColumn[];\r\n writer: G9RowBatchWriter;\r\n select: string;\r\n rows: number;\r\n}\r\n\r\nconst ROW_OVERHEAD = 48;\r\n\r\n/** `BuildPushBatchAsync`: the next batch of pending changes, oldest first, within the row and byte budgets. */\r\nexport async function buildPushBatch(store: StoreInternals, tables: readonly G9DtNegotiatedTable[], maxRows: number, maxBytes: number): Promise<G9PushBatch | null> {\r\n store.ensureInitialized();\r\n const uploadable = new Map<number, { table: LocalTable; negotiated: G9DtNegotiatedTable; columns: PushColumn[] }>();\r\n for (const negotiated of tables) {\r\n if (negotiated.direction === G9ESyncDirection.DownloadOnly) continue;\r\n const local = findByServerName(store, negotiated.name);\r\n if (!local) continue;\r\n const readOnly = new Set<string>();\r\n for (const c of negotiated.readOnlyColumns) readOnly.add(c.toLowerCase());\r\n for (const c of negotiated.computedColumns) readOnly.add(c.toLowerCase());\r\n const columns = negotiated.columns\r\n .filter((c) => !readOnly.has(c.name.toLowerCase()) && local.model.indexOf(c.name) >= 0)\r\n .map((c) => ({ name: c.name, type: c.type, local: local.model.indexOf(c.name) }));\r\n uploadable.set(local.tid, { table: local, negotiated, columns });\r\n }\r\n\r\n return store.writeLock.run(() =>\r\n store.writer().transaction('immediate', async () => {\r\n const connection = store.writer();\r\n const inflightBatch = await meta(connection, 'inflight_batch_id');\r\n const inflightMax = await meta(connection, 'inflight_max_seq');\r\n const offsetText = await meta(connection, 'server_offset_ms');\r\n const offsetMs = offsetText !== null && /^[+-]?\\d+$/.test(offsetText) ? Number(offsetText) : 0;\r\n\r\n const tids = Array.from(uploadable.keys());\r\n // `+tid`: the unary plus keeps the tid list from driving the plan. Without it SQLite searches the primary key by\r\n // tid — every row of every uploadable table (486k on a farm device, 16 s on the bridge) — and sorts them, instead\r\n // of walking the partial g9_rows_dirty index, which holds only the pending rows and is already in local_seq order.\r\n const sql =\r\n 'SELECT tid, pk, dirty, dirty_mask, server_ver, local_seq, coalesce(hlc_ms, 0) FROM g9_rows WHERE dirty <> 0 AND rejected = 0 AND +tid IN (' +\r\n tids.join(',') +\r\n ')' +\r\n (inflightMax === null ? '' : ' AND local_seq <= $imax') +\r\n ' ORDER BY local_seq LIMIT $max';\r\n const commands = await readPendingCommands(store, connection, inflightBatch, Math.max(1, maxRows));\r\n const pending =\r\n uploadable.size === 0\r\n ? []\r\n : await connection.query(sql, inflightMax === null ? { $max: Math.max(1, maxRows) } : { $max: Math.max(1, maxRows), $imax: Number(inflightMax) });\r\n const rows = pending.map((r) => ({\r\n tid: asNumber(r[0]),\r\n key: asString(r[1]),\r\n dirty: asNumber(r[2]),\r\n mask: asLong(r[3]),\r\n base: asNumber(r[4]),\r\n seq: asNumber(r[5]),\r\n hlc: asNumber(r[6]),\r\n }));\r\n\r\n if (rows.length === 0 && commands.length === 0) {\r\n if (inflightBatch !== null) {\r\n // Everything the in-flight batch carried has been resolved another way; forget it.\r\n await connection.exec(\"DELETE FROM g9_meta WHERE key IN ('inflight_batch_id', 'inflight_max_seq')\");\r\n }\r\n return null;\r\n }\r\n\r\n // Rows are encoded in local_seq order and the batch ends at the first row past the byte budget, so a batch is always\r\n // a PREFIX of the pending changes. One section (frame) per table.\r\n const sections = new Map<number, PushSection>();\r\n let included = 0;\r\n let includedMaxSequence = 0;\r\n let budgetUsed = 0;\r\n let truncated = false;\r\n const tooLarge: { tid: number; key: string; bytes: number }[] = [];\r\n for (const row of rows) {\r\n const entry = uploadable.get(row.tid);\r\n if (!entry) continue;\r\n let section = sections.get(row.tid);\r\n if (!section) {\r\n const select =\r\n entry.columns.length === 0\r\n ? `SELECT 1 FROM ${entry.table.quoted} WHERE ${entry.table.keyQuoted} = $k`\r\n : `SELECT ${entry.columns.map((c) => pushSelectExpression(quote(c.name), c.type)).join(', ')} FROM ${entry.table.quoted} WHERE ${entry.table.keyQuoted} = $k`;\r\n const writer = new G9RowBatchWriter();\r\n writer.beginSection(\r\n G9ERowBatchOp.Push,\r\n entry.negotiated.tableId,\r\n entry.table.model.keyType,\r\n entry.columns.map((c) => c.type),\r\n );\r\n section = { table: entry.table, negotiated: entry.negotiated, columns: entry.columns, writer, select, rows: 0 };\r\n sections.set(row.tid, section);\r\n }\r\n\r\n const hlc = row.hlc === 0 ? 0 : row.hlc + offsetMs;\r\n const keyBytes = utf8Encode(row.key).length;\r\n if (row.dirty === 2) {\r\n const deleteBytes = ROW_OVERHEAD + keyBytes;\r\n if (included > 0 && budgetUsed + deleteBytes > maxBytes) {\r\n truncated = true;\r\n break;\r\n }\r\n section.writer.beginPushRow(row.key, G9EPushRowOp.Delete, row.seq, row.base, G9Long.ZERO, hlc);\r\n section.writer.endRow();\r\n section.rows++;\r\n included++;\r\n includedMaxSequence = row.seq;\r\n budgetUsed += deleteBytes;\r\n continue;\r\n }\r\n\r\n const found = await connection.query(section.select, { $k: keyValue(section.table, row.key) });\r\n const values = found[0];\r\n if (!values) {\r\n section.writer.beginPushRow(row.key, G9EPushRowOp.Delete, row.seq, row.base, G9Long.ZERO, hlc);\r\n section.writer.endRow();\r\n section.rows++;\r\n included++;\r\n includedMaxSequence = row.seq;\r\n budgetUsed += ROW_OVERHEAD + keyBytes;\r\n continue;\r\n }\r\n\r\n let rowBytes = ROW_OVERHEAD + keyBytes;\r\n for (let j = 0; j < section.columns.length; j++) rowBytes += estimateEncodedBytes(values[j] as G9SqlValue, (section.columns[j] as PushColumn).type);\r\n if (rowBytes > maxBytes) {\r\n // Can never fit, whatever else the batch carries: reject it here so it does not block every later push.\r\n tooLarge.push({ tid: row.tid, key: row.key, bytes: rowBytes });\r\n continue;\r\n }\r\n if (included > 0 && budgetUsed + rowBytes > maxBytes) {\r\n truncated = true;\r\n break;\r\n }\r\n\r\n let pushMask = G9Long.ZERO;\r\n for (let j = 0; j < section.columns.length; j++) {\r\n if (row.mask.testBit((section.columns[j] as PushColumn).local)) pushMask = pushMask.or(G9Long.ONE.shiftLeft(j));\r\n }\r\n section.writer.beginPushRow(row.key, G9EPushRowOp.Upsert, row.seq, row.base, pushMask, hlc);\r\n for (let j = 0; j < section.columns.length; j++) writeLocalValue(section.writer, values[j] as G9SqlValue, (section.columns[j] as PushColumn).type, store.options);\r\n section.writer.endRow();\r\n section.rows++;\r\n included++;\r\n includedMaxSequence = row.seq;\r\n budgetUsed += rowBytes;\r\n }\r\n\r\n for (const { tid, key, bytes } of tooLarge) {\r\n await connection.exec('UPDATE g9_rows SET rejected = 1 WHERE tid = $t AND pk = $pk', { $t: tid, $pk: key });\r\n await connection.exec(\r\n 'INSERT OR REPLACE INTO g9_rejections (tid, pk, code, message, sql_state, constraint_name, column_name, details, at_utc) ' +\r\n 'VALUES ($t, $pk, $code, $message, NULL, NULL, NULL, NULL, $at)',\r\n {\r\n $t: tid,\r\n $pk: key,\r\n $code: G9SyncErrorCodes.RejectTooLarge,\r\n $message: `The row needs about ${bytes} bytes; the server accepts at most ${maxBytes} bytes per push.`,\r\n $at: nowMs(),\r\n },\r\n );\r\n }\r\n\r\n if (included === 0 && commands.length === 0) {\r\n if (tooLarge.length === 0) return null;\r\n return { batchId: 0, maxSequence: 0, frames: [], tables: [], rowCount: 0, truncated: false, rejectedLocally: tooLarge.length, commands: [] };\r\n }\r\n\r\n const frames: Uint8Array[] = [];\r\n const usedTables: G9DtTableColumns[] = [];\r\n sections.forEach((section) => {\r\n if (section.rows === 0) return;\r\n section.writer.endSection();\r\n frames.push(section.writer.toFrame({ compressor: store.options.frameCompressor }));\r\n usedTables.push({ tableId: section.negotiated.tableId, columns: section.columns.map((c) => c.name) });\r\n });\r\n\r\n let batchId: number;\r\n let maxSequence: number;\r\n if (inflightBatch !== null) {\r\n batchId = Number(inflightBatch);\r\n maxSequence = Number(inflightMax);\r\n } else {\r\n batchId = Number((await meta(connection, 'next_batch_id')) ?? '1');\r\n maxSequence = includedMaxSequence;\r\n await setMeta(connection, 'next_batch_id', String(batchId + 1));\r\n await setMeta(connection, 'inflight_batch_id', String(batchId));\r\n await setMeta(connection, 'inflight_max_seq', String(maxSequence));\r\n }\r\n for (const item of commands) {\r\n await connection.exec('UPDATE g9_commands SET batch_id = $b WHERE command_id = $id', { $b: batchId, $id: item.commandId });\r\n }\r\n return { batchId, maxSequence, frames, tables: usedTables, rowCount: included, truncated, rejectedLocally: tooLarge.length, commands };\r\n }),\r\n );\r\n}\r\n\r\n/** `ForgetUploadedRowsAsync`: removes uploaded rows of an UPLOAD-ONLY table without uploading a delete. */\r\nexport async function forgetUploadedRows(store: StoreInternals, localTable: string, keys: readonly string[] | null): Promise<number> {\r\n store.ensureInitialized();\r\n const table = getLocal(store, localTable);\r\n if (!table.negotiated || table.negotiated.direction !== G9ESyncDirection.UploadOnly) {\r\n throw new Error(`'${localTable}' is not upload-only: deleting its rows locally is a change the server must receive.`);\r\n }\r\n return store.writeLock.run(() =>\r\n store.writer().transaction('immediate', async () => {\r\n const connection = store.writer();\r\n await connection.exec('UPDATE g9_ctx SET applying = 1 WHERE id = 1'); // a library write: not captured\r\n await connection.exec('CREATE TEMP TABLE IF NOT EXISTS g9_forget (pk TEXT PRIMARY KEY); DELETE FROM g9_forget');\r\n if (keys === null) {\r\n await connection.exec('INSERT INTO g9_forget (pk) SELECT pk FROM g9_rows WHERE tid = $t AND dirty = 0', { $t: table.tid });\r\n } else {\r\n for (const key of keys) {\r\n await connection.exec('INSERT OR IGNORE INTO g9_forget (pk) SELECT pk FROM g9_rows WHERE tid = $t AND pk = $pk AND dirty = 0', { $t: table.tid, $pk: key });\r\n }\r\n }\r\n const forgotten = asNumber(await connection.scalar('SELECT count(*) FROM g9_forget'));\r\n await connection.exec(`DELETE FROM ${table.quoted} WHERE CAST(${table.keyQuoted} AS TEXT) IN (SELECT pk FROM g9_forget)`);\r\n await connection.exec('DELETE FROM g9_rows WHERE tid = $t AND pk IN (SELECT pk FROM g9_forget); DELETE FROM g9_forget', { $t: table.tid });\r\n await connection.exec('UPDATE g9_ctx SET applying = 0 WHERE id = 1');\r\n return forgotten;\r\n }),\r\n );\r\n}\r\n\r\n/** `ApplyPushResultAsync`. */\r\nexport async function applyPushResult(store: StoreInternals, batch: G9PushBatch, result: G9DtPushResult, signal?: AbortSignal): Promise<G9ApplyReport> {\r\n store.ensureInitialized();\r\n return store.writeLock.run(() =>\r\n store.writer().transaction('immediate', async () => {\r\n const connection = store.writer();\r\n // Before BeginApply: finished commands release their rows, so the canonical rows below replace the optimistic ones.\r\n const completed = await completeCommands(connection, result.commandResults);\r\n // Read BEFORE anything below touches the rows: what the device sent for each conflict it may have lost (LES-0072).\r\n const lost = await readLostConflicts(store, batch, result);\r\n const context = await beginApply(store, connection, { dirtyAfterSequence: batch.maxSequence, backfills: [], signal });\r\n context.report.commandsCompleted = completed;\r\n\r\n const acceptSql =\r\n 'UPDATE g9_rows SET server_ver = $v, ' +\r\n 'dirty = CASE WHEN local_seq <= $m THEN 0 ELSE dirty END, ' +\r\n 'dirty_mask = CASE WHEN local_seq <= $m THEN 0 ELSE dirty_mask END, ' +\r\n 'deleted = CASE WHEN local_seq <= $m AND dirty = 2 THEN 1 ELSE deleted END, ' +\r\n 'rejected = 0 WHERE tid = $t AND pk = $pk; ' +\r\n 'DELETE FROM g9_rejections WHERE tid = $t AND pk = $pk';\r\n for (const accepted of result.accepted) {\r\n const table = store.byServerId.get(accepted.tableId);\r\n if (!table) continue;\r\n for (let i = 0; i < accepted.keys.length; i++) {\r\n await context.queue(acceptSql, { $v: i < accepted.versions.length ? (accepted.versions[i] as number) : 0, $m: batch.maxSequence, $t: table.tid, $pk: accepted.keys[i] as string });\r\n context.report.accepted++;\r\n }\r\n }\r\n\r\n const rejectSql =\r\n 'UPDATE g9_rows SET rejected = 1 WHERE tid = $t AND pk = $pk AND local_seq <= $m; ' +\r\n 'INSERT OR REPLACE INTO g9_rejections (tid, pk, code, message, sql_state, constraint_name, column_name, details, at_utc) ' +\r\n 'VALUES ($t, $pk, $code, $message, $state, $constraint, $column, $details, $now)';\r\n const now = nowMs();\r\n for (const rejection of result.rejections) {\r\n const table = store.byServerId.get(rejection.tableId);\r\n if (!table) continue;\r\n await context.queue(rejectSql, {\r\n $t: table.tid,\r\n $pk: rejection.key,\r\n $m: batch.maxSequence,\r\n $code: rejection.code,\r\n $message: rejection.message ?? null,\r\n $state: rejection.sqlState ?? null,\r\n $constraint: rejection.constraint ?? null,\r\n $column: rejection.column ?? null,\r\n $details: rejection.details ?? null,\r\n $now: now,\r\n });\r\n context.report.rejected++;\r\n }\r\n\r\n context.report.conflicts = result.conflicts.length;\r\n await context.flush();\r\n for (const frame of result.canonicalFrames) await applyFrame(store, context, frame, null);\r\n await context.flush();\r\n await keepLostConflicts(store, context, lost);\r\n\r\n await endApply(context);\r\n await connection.exec(\"DELETE FROM g9_meta WHERE key IN ('inflight_batch_id', 'inflight_max_seq')\");\r\n return context.report;\r\n }),\r\n );\r\n}\r\n\r\n/** A conflict the device lost, with its row as it was sent. */\r\ninterface LostConflict {\r\n table: LocalTable;\r\n key: string;\r\n code: string;\r\n dirty: number;\r\n lostMask: G9Long;\r\n subs: G9Long;\r\n version: G9Long;\r\n values: { [column: string]: G9SqlValue };\r\n}\r\n\r\n/**\r\n * Twin of .NET ReadLostConflicts (LES-0072): the conflicts of this push in which the server kept its own values for something the\r\n * device changed - the whole change, or the overlapping columns of a column merge - each with the device's row as it was sent.\r\n */\r\nasync function readLostConflicts(store: StoreInternals, batch: G9PushBatch, result: G9DtPushResult): Promise<LostConflict[]> {\r\n const lost: LostConflict[] = [];\r\n if (!store.options.keepLostConflicts || result.conflicts.length === 0) return lost;\r\n const connection = store.writer();\r\n const pushOrder = new Map(batch.tables.map((t) => [t.tableId, t.columns]));\r\n for (const conflict of result.conflicts) {\r\n const table = store.byServerId.get(conflict.tableId);\r\n if (!table) continue;\r\n const row = (await connection.query('SELECT dirty, dirty_mask, subs, server_ver, local_seq FROM g9_rows WHERE tid = $t AND pk = $pk', { $t: table.tid, $pk: conflict.key }))[0];\r\n if (!row) continue;\r\n const dirty = asNumber(row[0]);\r\n const mask = asLong(row[1]);\r\n if (dirty === 0 || asNumber(row[4]) > batch.maxSequence) continue;\r\n const serverDeleted = conflict.code === G9SyncErrorCodes.ConflictDeleted;\r\n if (dirty === 2 && serverDeleted) continue; // both sides deleted it: nothing was lost\r\n\r\n // Only what this push CARRIED can have been lost (LES-0086): a column the device changed but never sends - read-only on the\r\n // server, or not negotiated - was not part of the conflict, and the canonical row simply replaces it.\r\n const names = pushOrder.get(conflict.tableId);\r\n let lostMask = names ? mask.and(pushedMask(table, names)) : mask;\r\n if (dirty === 1 && lostMask.isZero()) continue;\r\n if (dirty === 1 && conflict.partiallyApplied && !conflict.serverChangedMask.isNegative() && conflict.code === G9SyncErrorCodes.ConflictColumns && names) {\r\n // The server's bits are in push column order; the device's are model columns.\r\n lostMask = G9Long.ZERO;\r\n for (let j = 0; j < names.length && j < 63; j++) {\r\n if (!conflict.serverChangedMask.testBit(j)) continue;\r\n const local = table.model.indexOf(names[j] as string);\r\n if (local >= 0 && mask.testBit(local)) lostMask = lostMask.or(G9Long.ONE.shiftLeft(local));\r\n }\r\n if (lostMask.isZero()) continue;\r\n }\r\n\r\n lost.push({ table, key: conflict.key, code: conflict.code, dirty, lostMask, subs: asLong(row[2]), version: asLong(row[3]), values: await readLocalValues(connection, table, conflict.key) });\r\n }\r\n return lost;\r\n}\r\n\r\n/** The device's column bits of the columns a push sent for this table (push column order → model order). Twin of .NET PushedMask. */\r\nfunction pushedMask(table: { model: { indexOf(name: string): number } }, pushed: readonly string[]): G9Long {\r\n let mask = G9Long.ZERO;\r\n for (const name of pushed) {\r\n const local = table.model.indexOf(name);\r\n if (local >= 0 && local < 63) mask = mask.or(G9Long.ONE.shiftLeft(local));\r\n }\r\n return mask;\r\n}\r\n\r\n/** Two SQLite values are the same value (a blob by its bytes); a different type counts as different. Twin of .NET SameValue. */\r\nfunction sameValue(a: unknown, b: unknown, type?: G9ESyncColumnType): boolean {\r\n if (a instanceof Uint8Array && b instanceof Uint8Array) return a.length === b.length && a.every((x, i) => x === b[i]);\r\n if (typeof a === 'bigint' || typeof b === 'bigint') return typeof a === typeof b && a === b;\r\n if (a === b || (a == null && b == null)) return true;\r\n // A timestamp is the same INSTANT to the microsecond (LES-0086): the device keeps 100 ns, the server microseconds.\r\n if ((type === G9ESyncColumnType.DateTime || type === G9ESyncColumnType.DateTimeOffset) && typeof a === 'string' && typeof b === 'string') {\r\n const first = instant(a);\r\n const second = instant(b);\r\n if (first && second) return Math.abs((first[0] - second[0]) * 10000 + (first[1] - second[1])) < 10;\r\n }\r\n return false;\r\n}\r\n\r\nconst instantPattern = /^(\\d{4})-(\\d{2})-(\\d{2})[T ](\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d{1,7}))?(Z|[+-]\\d{2}:?\\d{2})?$/;\r\n\r\n/** A timestamp text as [Unix milliseconds, 100 ns units within that millisecond]; no BigInt (Lynx). Twin of .NET Instant. */\r\nfunction instant(text: string): [number, number] | null {\r\n const m = instantPattern.exec(text.trim());\r\n if (!m) return null;\r\n const fraction = ((m[7] ?? '') + '0000000').slice(0, 7);\r\n let ms = Date.UTC(Number(m[1]), Number(m[2]) - 1, Number(m[3]), Number(m[4]), Number(m[5]), Number(m[6]), Number(fraction.slice(0, 3)));\r\n const zone = m[8];\r\n if (zone && zone !== 'Z') {\r\n const sign = zone[0] === '-' ? -1 : 1;\r\n const digits = zone.slice(1).replace(':', '');\r\n ms -= sign * (Number(digits.slice(0, 2)) * 60 + Number(digits.slice(2, 4))) * 60000;\r\n }\r\n return [ms, Number(fraction.slice(3))];\r\n}\r\n\r\n/** Twin of .NET KeepLostConflicts: the device's lost values back over the canonical rows, parked as rejections (LES-0072). */\r\nasync function keepLostConflicts(store: StoreInternals, context: Awaited<ReturnType<typeof beginApply>>, lost: LostConflict[]): Promise<void> {\r\n const connection = context.connection;\r\n for (const item of lost) {\r\n const table = item.table;\r\n const key = keyValue(table, item.key);\r\n const now = await readLocalValues(connection, table, item.key);\r\n let columnNames: string | null = null;\r\n let serverValues: string | null = null;\r\n let lostMask = item.lostMask;\r\n if (item.dirty === 2) {\r\n if (Object.keys(now).length > 0) await connection.exec(`DELETE FROM ${table.quoted} WHERE ${table.keyQuoted} = $k`, { $k: key });\r\n } else if (Object.keys(now).length === 0) {\r\n // The server deleted it: the device's row comes back as it was sent.\r\n const all = Object.keys(item.values);\r\n if (all.length === 0) continue;\r\n const params: { [name: string]: G9SqlValue } = {};\r\n all.forEach((column, i) => (params['$v' + i] = item.values[column] as G9SqlValue));\r\n await connection.exec(`INSERT INTO ${table.quoted} (${all.map(quote).join(', ')}) VALUES (${all.map((_, i) => '$v' + i).join(', ')})`, params);\r\n } else {\r\n const lostColumns = table.model.columns.map((c, i) => ({ name: c.name, i })).filter((c) => item.lostMask.testBit(c.i) && c.name in item.values);\r\n // LES-0085: a column the server already holds with the device's own value lost nothing; when none differs, the row is in sync.\r\n const differing = lostColumns.filter((c) => !sameValue(item.values[c.name], now[c.name], table.model.columns[c.i]?.type));\r\n if (lostColumns.length > 0 && differing.length === 0) {\r\n context.report.conflictsSameValue++;\r\n continue;\r\n }\r\n if (differing.length > 0) lostMask = differing.reduce((m, c) => m.or(G9Long.ONE.shiftLeft(c.i)), G9Long.ZERO);\r\n const columns = differing.map((c) => c.name);\r\n if (columns.length > 0) {\r\n columnNames = columns.join(',');\r\n const server: { [column: string]: unknown } = {};\r\n for (const column of columns) server[column] = now[column] ?? null;\r\n serverValues = serializeValues(server);\r\n const params: { [name: string]: G9SqlValue } = { $k: key };\r\n columns.forEach((column, i) => (params['$v' + i] = item.values[column] as G9SqlValue));\r\n await connection.exec(`UPDATE ${table.quoted} SET ${columns.map((c, i) => quote(c) + ' = $v' + i).join(', ')} WHERE ${table.keyQuoted} = $k`, params);\r\n }\r\n }\r\n\r\n const mask = item.dirty === 2 ? G9Long.ZERO : lostMask;\r\n await connection.exec(\r\n 'INSERT INTO g9_rows (tid, pk, server_ver, local_seq, subs, dirty, dirty_mask, rejected, deleted) ' +\r\n 'VALUES ($t, $pk, $v, (SELECT seq FROM g9_clock WHERE id = 1) + 1, $subs, $d, $m, 1, 0) ' +\r\n 'ON CONFLICT(tid, pk) DO UPDATE SET dirty = excluded.dirty, dirty_mask = excluded.dirty_mask, rejected = 1, deleted = 0, ' +\r\n 'subs = CASE WHEN g9_rows.subs = 0 THEN excluded.subs ELSE g9_rows.subs END, local_seq = excluded.local_seq; ' +\r\n 'UPDATE g9_clock SET seq = seq + 1 WHERE id = 1',\r\n { $t: table.tid, $pk: item.key, $v: item.version.toSqlValue(), $subs: item.subs.toSqlValue(), $d: item.dirty, $m: mask.toSqlValue() },\r\n );\r\n await connection.exec(\r\n 'INSERT OR REPLACE INTO g9_rejections (tid, pk, code, message, sql_state, constraint_name, column_name, details, at_utc) ' +\r\n 'VALUES ($t, $pk, $code, $message, NULL, NULL, $column, $details, $now)',\r\n {\r\n $t: table.tid,\r\n $pk: item.key,\r\n $code: item.code,\r\n $message:\r\n item.dirty === 2\r\n ? \"The server changed this row after the device last saw it; the device's delete was kept here, not applied.\"\r\n : `The server changed ${columnNames ?? 'this row'} after the device last saw it; the device's values were kept here, not applied.`,\r\n $column: columnNames,\r\n $details: serverValues,\r\n $now: nowMs(),\r\n },\r\n );\r\n context.report.conflictsKept++;\r\n if (context.wantsChangedKey(table.model.localName)) context.addChanged(table.model.localName, item.key);\r\n }\r\n}\r\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@g9tm/syncdata",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.14",
|
|
4
4
|
"description": "TypeScript twin of the G9SyncData .NET client for Lynx, Node and browsers: the sync engine, the G9RowBatch protocol, the SQLite client store (same schema as the .NET store) and the SignalR transport.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Iman Kari (G9TM)",
|