@g9tm/syncdata 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/LICENSE.md +21 -0
  2. package/PARITY.md +71 -0
  3. package/README.md +71 -0
  4. package/THIRD-PARTY-NOTICES.md +31 -0
  5. package/dist/abstractions/digest.d.ts +27 -0
  6. package/dist/abstractions/digest.js +78 -0
  7. package/dist/abstractions/digest.js.map +1 -0
  8. package/dist/abstractions/enums.d.ts +42 -0
  9. package/dist/abstractions/enums.js +60 -0
  10. package/dist/abstractions/enums.js.map +1 -0
  11. package/dist/abstractions/errors.d.ts +72 -0
  12. package/dist/abstractions/errors.js +90 -0
  13. package/dist/abstractions/errors.js.map +1 -0
  14. package/dist/abstractions/guid.d.ts +24 -0
  15. package/dist/abstractions/guid.js +93 -0
  16. package/dist/abstractions/guid.js.map +1 -0
  17. package/dist/abstractions/key.d.ts +16 -0
  18. package/dist/abstractions/key.js +47 -0
  19. package/dist/abstractions/key.js.map +1 -0
  20. package/dist/abstractions/long.d.ts +103 -0
  21. package/dist/abstractions/long.js +351 -0
  22. package/dist/abstractions/long.js.map +1 -0
  23. package/dist/abstractions/parameters.d.ts +49 -0
  24. package/dist/abstractions/parameters.js +153 -0
  25. package/dist/abstractions/parameters.js.map +1 -0
  26. package/dist/brotli-js/decode.d.ts +8 -0
  27. package/dist/brotli-js/decode.js +2004 -0
  28. package/dist/brotli-js/decode.js.map +1 -0
  29. package/dist/brotli-js/index.d.ts +5 -0
  30. package/dist/brotli-js/index.js +19 -0
  31. package/dist/brotli-js/index.js.map +1 -0
  32. package/dist/client/engine.d.ts +110 -0
  33. package/dist/client/engine.js +1158 -0
  34. package/dist/client/engine.js.map +1 -0
  35. package/dist/client/model.d.ts +61 -0
  36. package/dist/client/model.js +154 -0
  37. package/dist/client/model.js.map +1 -0
  38. package/dist/client/progress.d.ts +101 -0
  39. package/dist/client/progress.js +251 -0
  40. package/dist/client/progress.js.map +1 -0
  41. package/dist/client/runs.d.ts +219 -0
  42. package/dist/client/runs.js +239 -0
  43. package/dist/client/runs.js.map +1 -0
  44. package/dist/client/storeTypes.d.ts +428 -0
  45. package/dist/client/storeTypes.js +256 -0
  46. package/dist/client/storeTypes.js.map +1 -0
  47. package/dist/client/transport.d.ts +19 -0
  48. package/dist/client/transport.js +2 -0
  49. package/dist/client/transport.js.map +1 -0
  50. package/dist/index.d.ts +27 -0
  51. package/dist/index.js +35 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/internal/abort.d.ts +21 -0
  54. package/dist/internal/abort.js +125 -0
  55. package/dist/internal/abort.js.map +1 -0
  56. package/dist/internal/base64.d.ts +8 -0
  57. package/dist/internal/base64.js +85 -0
  58. package/dist/internal/base64.js.map +1 -0
  59. package/dist/internal/dotnetFormat.d.ts +32 -0
  60. package/dist/internal/dotnetFormat.js +207 -0
  61. package/dist/internal/dotnetFormat.js.map +1 -0
  62. package/dist/internal/md5.d.ts +2 -0
  63. package/dist/internal/md5.js +97 -0
  64. package/dist/internal/md5.js.map +1 -0
  65. package/dist/internal/sha256.d.ts +20 -0
  66. package/dist/internal/sha256.js +153 -0
  67. package/dist/internal/sha256.js.map +1 -0
  68. package/dist/internal/utf8.d.ts +8 -0
  69. package/dist/internal/utf8.js +143 -0
  70. package/dist/internal/utf8.js.map +1 -0
  71. package/dist/node/index.d.ts +9 -0
  72. package/dist/node/index.js +35 -0
  73. package/dist/node/index.js.map +1 -0
  74. package/dist/node/sqliteDriver.d.ts +11 -0
  75. package/dist/node/sqliteDriver.js +252 -0
  76. package/dist/node/sqliteDriver.js.map +1 -0
  77. package/dist/protocol/dtos.d.ts +280 -0
  78. package/dist/protocol/dtos.js +33 -0
  79. package/dist/protocol/dtos.js.map +1 -0
  80. package/dist/protocol/protocol.d.ts +36 -0
  81. package/dist/protocol/protocol.js +63 -0
  82. package/dist/protocol/protocol.js.map +1 -0
  83. package/dist/protocol/rowBatch/columnLayout.d.ts +4 -0
  84. package/dist/protocol/rowBatch/columnLayout.js +309 -0
  85. package/dist/protocol/rowBatch/columnLayout.js.map +1 -0
  86. package/dist/protocol/rowBatch/format.d.ts +74 -0
  87. package/dist/protocol/rowBatch/format.js +163 -0
  88. package/dist/protocol/rowBatch/format.js.map +1 -0
  89. package/dist/protocol/rowBatch/reader.d.ts +119 -0
  90. package/dist/protocol/rowBatch/reader.js +459 -0
  91. package/dist/protocol/rowBatch/reader.js.map +1 -0
  92. package/dist/protocol/rowBatch/writer.d.ts +101 -0
  93. package/dist/protocol/rowBatch/writer.js +412 -0
  94. package/dist/protocol/rowBatch/writer.js.map +1 -0
  95. package/dist/protocol/wire.d.ts +32 -0
  96. package/dist/protocol/wire.js +329 -0
  97. package/dist/protocol/wire.js.map +1 -0
  98. package/dist/signalr/index.d.ts +2 -0
  99. package/dist/signalr/index.js +5 -0
  100. package/dist/signalr/index.js.map +1 -0
  101. package/dist/signalr/protocols.d.ts +17 -0
  102. package/dist/signalr/protocols.js +109 -0
  103. package/dist/signalr/protocols.js.map +1 -0
  104. package/dist/signalr/transport.d.ts +67 -0
  105. package/dist/signalr/transport.js +286 -0
  106. package/dist/signalr/transport.js.map +1 -0
  107. package/dist/sqlite/apply.d.ts +91 -0
  108. package/dist/sqlite/apply.js +657 -0
  109. package/dist/sqlite/apply.js.map +1 -0
  110. package/dist/sqlite/commands.d.ts +24 -0
  111. package/dist/sqlite/commands.js +167 -0
  112. package/dist/sqlite/commands.js.map +1 -0
  113. package/dist/sqlite/connection.d.ts +81 -0
  114. package/dist/sqlite/connection.js +322 -0
  115. package/dist/sqlite/connection.js.map +1 -0
  116. package/dist/sqlite/driver.d.ts +63 -0
  117. package/dist/sqlite/driver.js +9 -0
  118. package/dist/sqlite/driver.js.map +1 -0
  119. package/dist/sqlite/index.d.ts +6 -0
  120. package/dist/sqlite/index.js +7 -0
  121. package/dist/sqlite/index.js.map +1 -0
  122. package/dist/sqlite/internals.d.ts +63 -0
  123. package/dist/sqlite/internals.js +194 -0
  124. package/dist/sqlite/internals.js.map +1 -0
  125. package/dist/sqlite/options.d.ts +78 -0
  126. package/dist/sqlite/options.js +78 -0
  127. package/dist/sqlite/options.js.map +1 -0
  128. package/dist/sqlite/push.d.ts +9 -0
  129. package/dist/sqlite/push.js +272 -0
  130. package/dist/sqlite/push.js.map +1 -0
  131. package/dist/sqlite/query.d.ts +38 -0
  132. package/dist/sqlite/query.js +476 -0
  133. package/dist/sqlite/query.js.map +1 -0
  134. package/dist/sqlite/revocation.d.ts +28 -0
  135. package/dist/sqlite/revocation.js +337 -0
  136. package/dist/sqlite/revocation.js.map +1 -0
  137. package/dist/sqlite/sql.d.ts +60 -0
  138. package/dist/sqlite/sql.js +324 -0
  139. package/dist/sqlite/sql.js.map +1 -0
  140. package/dist/sqlite/store.d.ts +116 -0
  141. package/dist/sqlite/store.js +664 -0
  142. package/dist/sqlite/store.js.map +1 -0
  143. package/dist/sqlite/values.d.ts +29 -0
  144. package/dist/sqlite/values.js +288 -0
  145. package/dist/sqlite/values.js.map +1 -0
  146. package/dist/testing/index.d.ts +61 -0
  147. package/dist/testing/index.js +175 -0
  148. package/dist/testing/index.js.map +1 -0
  149. package/package.json +104 -0
@@ -0,0 +1,280 @@
1
+ import type { G9EConflictPolicy, G9EMoveOutPolicy, G9ESyncColumnType, G9ESyncDirection } from '../abstractions/enums.js';
2
+ import { G9SyncException } from '../abstractions/errors.js';
3
+ import type { G9Long } from '../abstractions/long.js';
4
+ /** What a subscription must do next, as decided by the server (`G9ESubscriptionAction`). */
5
+ export declare const G9ESubscriptionAction: {
6
+ readonly Ok: 0;
7
+ readonly Initial: 1;
8
+ readonly Reconcile: 2;
9
+ readonly ResyncRequired: 3;
10
+ readonly Unknown: 4;
11
+ readonly InvalidParameters: 5;
12
+ readonly Forbidden: 6;
13
+ };
14
+ export type G9ESubscriptionAction = (typeof G9ESubscriptionAction)[keyof typeof G9ESubscriptionAction];
15
+ /** Kind of a planned pull part (`G9EPullPartKind`). */
16
+ export declare const G9EPullPartKind: {
17
+ readonly Snapshot: 0;
18
+ readonly Delta: 1;
19
+ readonly Backfill: 2;
20
+ };
21
+ export type G9EPullPartKind = (typeof G9EPullPartKind)[keyof typeof G9EPullPartKind];
22
+ /** Outcome of a command executed by the server (`G9ECommandStatus`). */
23
+ export declare const G9ECommandStatus: {
24
+ readonly Ok: 0;
25
+ readonly Rejected: 1;
26
+ readonly Superseded: 2;
27
+ };
28
+ export type G9ECommandStatus = (typeof G9ECommandStatus)[keyof typeof G9ECommandStatus];
29
+ export interface G9DtSyncError {
30
+ code: string;
31
+ message: string;
32
+ retryable: boolean;
33
+ details?: string | null;
34
+ }
35
+ /** `G9DtSyncError.ToException()`. */
36
+ export declare function syncErrorToException(error: G9DtSyncError): G9SyncException;
37
+ /** `G9DtSyncError.From(exception)`. */
38
+ export declare function syncErrorFrom(exception: G9SyncException): G9DtSyncError;
39
+ export interface G9DtColumnModel {
40
+ name: string;
41
+ type: G9ESyncColumnType;
42
+ nullable: boolean;
43
+ }
44
+ /** A subscription as the client holds it: name, canonical parameters and its sync state. */
45
+ export interface G9DtSubscriptionRef {
46
+ name: string;
47
+ parameters: {
48
+ [name: string]: string;
49
+ };
50
+ /** Opaque server cursor of the last completed pull. Null before the first pull. */
51
+ cursor?: string | null;
52
+ definitionHash?: string | null;
53
+ authHash?: string | null;
54
+ }
55
+ /** Resume point after a chunk. Only chunks that carry one are safe restart points. */
56
+ export interface G9DtPullContinuation {
57
+ partIndex: number;
58
+ afterKey?: string | null;
59
+ nextSequence: number;
60
+ }
61
+ /** One unit of a data stream; `payload` is a G9RowBatch frame. */
62
+ export interface G9DtSyncChunk {
63
+ sequence: number;
64
+ payload?: Uint8Array | null;
65
+ rowCount: number;
66
+ subscriptionKey?: string | null;
67
+ isFinal: boolean;
68
+ continuation?: G9DtPullContinuation | null;
69
+ reconcileSummary?: G9DtReconcileSummary | null;
70
+ }
71
+ /** Server → client hint that tables changed. */
72
+ export interface G9DtChangesAvailable {
73
+ tables: string[];
74
+ }
75
+ export interface G9DtClientTableModel {
76
+ name: string;
77
+ keyColumn: string;
78
+ keyType: G9ESyncColumnType;
79
+ columns: G9DtColumnModel[];
80
+ }
81
+ export interface G9DtHelloRequest {
82
+ clientId: string;
83
+ appVersion?: string | null;
84
+ protocolVersion: number;
85
+ tables: G9DtClientTableModel[];
86
+ subscriptions: G9DtSubscriptionRef[];
87
+ }
88
+ export interface G9DtColumnTypeMismatch {
89
+ name: string;
90
+ clientType: G9ESyncColumnType;
91
+ serverType: G9ESyncColumnType;
92
+ }
93
+ /** The column set both sides agreed on for one table. */
94
+ export interface G9DtNegotiatedTable {
95
+ tableId: number;
96
+ name: string;
97
+ keyColumn: string;
98
+ keyType: G9ESyncColumnType;
99
+ columns: G9DtColumnModel[];
100
+ computedColumns: string[];
101
+ readOnlyColumns: string[];
102
+ missingColumns: string[];
103
+ typeMismatchColumns: G9DtColumnTypeMismatch[];
104
+ direction: G9ESyncDirection;
105
+ conflictPolicy: G9EConflictPolicy;
106
+ }
107
+ export interface G9DtParameterDefinition {
108
+ name: string;
109
+ type: G9ESyncColumnType;
110
+ required: boolean;
111
+ isList: boolean;
112
+ }
113
+ export interface G9DtSubscriptionDependency {
114
+ name: string;
115
+ required: boolean;
116
+ }
117
+ export interface G9DtSubscriptionDefinition {
118
+ name: string;
119
+ parameters: G9DtParameterDefinition[];
120
+ dependsOn: G9DtSubscriptionDependency[];
121
+ tables: string[];
122
+ ephemeral: boolean;
123
+ ttlSeconds: number;
124
+ heavy: boolean;
125
+ moveOutPolicy: G9EMoveOutPolicy;
126
+ reconcileIntervalMinutes: number;
127
+ definitionHash: string;
128
+ }
129
+ export interface G9DtSubscriptionState {
130
+ key: string;
131
+ action: G9ESubscriptionAction;
132
+ definitionHash?: string | null;
133
+ authHash?: string | null;
134
+ message?: string | null;
135
+ }
136
+ export interface G9DtHelloResult {
137
+ epoch: string;
138
+ /** Server clock at the answer, epoch milliseconds UTC (.NET `DateTime ServerTimeUtc`). */
139
+ serverTimeUtcMs: number;
140
+ protocolVersion: number;
141
+ tables: G9DtNegotiatedTable[];
142
+ unknownTables: string[];
143
+ definitions: G9DtSubscriptionDefinition[];
144
+ subscriptions: G9DtSubscriptionState[];
145
+ maxPushRows: number;
146
+ maxPushBytes: number;
147
+ error?: G9DtSyncError | null;
148
+ }
149
+ export interface G9DtTableColumns {
150
+ tableId: number;
151
+ columns: string[];
152
+ }
153
+ export interface G9DtRowRef {
154
+ tableId: number;
155
+ key: string;
156
+ }
157
+ export interface G9DtCommand {
158
+ commandId: string;
159
+ sequence: number;
160
+ name: string;
161
+ version: number;
162
+ payload: string;
163
+ createdUtcMs: number;
164
+ touched: G9DtRowRef[];
165
+ }
166
+ export interface G9DtCommandResult {
167
+ commandId: string;
168
+ status: G9ECommandStatus;
169
+ code?: string | null;
170
+ message?: string | null;
171
+ result?: string | null;
172
+ }
173
+ export interface G9DtPushRequest {
174
+ clientId: string;
175
+ batchId: number;
176
+ subscriptions: G9DtSubscriptionRef[];
177
+ tables: G9DtTableColumns[];
178
+ commands: G9DtCommand[];
179
+ heldTables: G9DtTableColumns[];
180
+ frameVersion: number;
181
+ }
182
+ export interface G9DtAcceptedRows {
183
+ tableId: number;
184
+ keys: string[];
185
+ versions: number[];
186
+ deleted: boolean[];
187
+ }
188
+ export interface G9DtRowRejection {
189
+ tableId: number;
190
+ key: string;
191
+ code: string;
192
+ message?: string | null;
193
+ sqlState?: string | null;
194
+ constraint?: string | null;
195
+ column?: string | null;
196
+ details?: string | null;
197
+ }
198
+ export interface G9DtRowConflict {
199
+ tableId: number;
200
+ key: string;
201
+ code: string;
202
+ /** Bits (push column order) the server changed after the client's base version; -1 when unknown. */
203
+ serverChangedMask: G9Long;
204
+ partiallyApplied: boolean;
205
+ }
206
+ export interface G9DtPushResult {
207
+ batchId: number;
208
+ alreadyApplied: boolean;
209
+ accepted: G9DtAcceptedRows[];
210
+ rejections: G9DtRowRejection[];
211
+ conflicts: G9DtRowConflict[];
212
+ canonicalFrames: Uint8Array[];
213
+ commandResults: G9DtCommandResult[];
214
+ error?: G9DtSyncError | null;
215
+ }
216
+ export interface G9DtBackfillRequest {
217
+ tableId: number;
218
+ columns: string[];
219
+ }
220
+ export interface G9DtPullRequest {
221
+ clientId: string;
222
+ subscriptions: G9DtSubscriptionRef[];
223
+ tables: G9DtTableColumns[];
224
+ backfills: G9DtBackfillRequest[];
225
+ frameVersion: number;
226
+ }
227
+ export interface G9DtPlannedPart {
228
+ subscriptionKey: string;
229
+ tableId: number;
230
+ kind: G9EPullPartKind;
231
+ rows: number;
232
+ estimatedBytes: number;
233
+ }
234
+ export interface G9DtSubscriptionCursor {
235
+ key: string;
236
+ cursor: string;
237
+ definitionHash: string;
238
+ authHash: string;
239
+ }
240
+ export interface G9DtPullPlan {
241
+ token: string;
242
+ parts: G9DtPlannedPart[];
243
+ totalRows: number;
244
+ estimatedBytes: number;
245
+ cursors: G9DtSubscriptionCursor[];
246
+ skipped: G9DtSubscriptionState[];
247
+ error?: G9DtSyncError | null;
248
+ }
249
+ export interface G9DtTableDigest {
250
+ tableId: number;
251
+ computedColumns: string[];
252
+ /** 256 bucket digests (XOR of row hashes). */
253
+ digests: G9Long[];
254
+ /** 256 bucket row counts. */
255
+ counts: number[];
256
+ }
257
+ export interface G9DtReconcileRequest {
258
+ clientId: string;
259
+ subscription: G9DtSubscriptionRef;
260
+ tables: G9DtTableDigest[];
261
+ frameVersion: number;
262
+ }
263
+ export interface G9DtTableBuckets {
264
+ tableId: number;
265
+ buckets: number[];
266
+ }
267
+ export interface G9DtReconcileSummary {
268
+ cursor: string;
269
+ definitionHash: string;
270
+ authHash: string;
271
+ mismatched: G9DtTableBuckets[];
272
+ }
273
+ export interface G9DtFetchRowsRequest {
274
+ clientId: string;
275
+ subscription: G9DtSubscriptionRef;
276
+ tableId: number;
277
+ keys: string[];
278
+ columns: string[];
279
+ frameVersion: number;
280
+ }
@@ -0,0 +1,33 @@
1
+ import { G9SyncException } from '../abstractions/errors.js';
2
+ /** What a subscription must do next, as decided by the server (`G9ESubscriptionAction`). */
3
+ export const G9ESubscriptionAction = {
4
+ Ok: 0,
5
+ Initial: 1,
6
+ Reconcile: 2,
7
+ ResyncRequired: 3,
8
+ Unknown: 4,
9
+ InvalidParameters: 5,
10
+ Forbidden: 6,
11
+ };
12
+ /** Kind of a planned pull part (`G9EPullPartKind`). */
13
+ export const G9EPullPartKind = {
14
+ Snapshot: 0,
15
+ Delta: 1,
16
+ Backfill: 2,
17
+ };
18
+ /** Outcome of a command executed by the server (`G9ECommandStatus`). */
19
+ export const G9ECommandStatus = {
20
+ Ok: 0,
21
+ Rejected: 1,
22
+ Superseded: 2,
23
+ };
24
+ /** `G9DtSyncError.ToException()`. */
25
+ export function syncErrorToException(error) {
26
+ var _a;
27
+ return new G9SyncException(error.code, error.message, { retryable: error.retryable, details: (_a = error.details) !== null && _a !== void 0 ? _a : null });
28
+ }
29
+ /** `G9DtSyncError.From(exception)`. */
30
+ export function syncErrorFrom(exception) {
31
+ return { code: exception.code, message: exception.message, retryable: exception.retryable, details: exception.details };
32
+ }
33
+ //# sourceMappingURL=dtos.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dtos.js","sourceRoot":"","sources":["../../src/protocol/dtos.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAG5D,4FAA4F;AAC5F,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,EAAE,EAAE,CAAC;IACL,OAAO,EAAE,CAAC;IACV,SAAS,EAAE,CAAC;IACZ,cAAc,EAAE,CAAC;IACjB,OAAO,EAAE,CAAC;IACV,iBAAiB,EAAE,CAAC;IACpB,SAAS,EAAE,CAAC;CACJ,CAAC;AAGX,uDAAuD;AACvD,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,QAAQ,EAAE,CAAC;IACX,KAAK,EAAE,CAAC;IACR,QAAQ,EAAE,CAAC;CACH,CAAC;AAGX,wEAAwE;AACxE,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,EAAE,EAAE,CAAC;IACL,QAAQ,EAAE,CAAC;IACX,UAAU,EAAE,CAAC;CACL,CAAC;AAYX,qCAAqC;AACrC,MAAM,UAAU,oBAAoB,CAAC,KAAoB;;IACvD,OAAO,IAAI,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,MAAA,KAAK,CAAC,OAAO,mCAAI,IAAI,EAAE,CAAC,CAAC;AACxH,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,aAAa,CAAC,SAA0B;IACtD,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,EAAE,CAAC;AAC1H,CAAC","sourcesContent":["// Twins of G9SyncData.Protocol/Dtos/*.cs. Property names are the camelCase of the .NET names (the JSON wire names);\n// the MessagePack codec maps them to the PascalCase keys Nerdbank.MessagePack writes. .NET `long` values are numbers\n// except where they must stay exact: reconciliation digests and conflict masks are G9Long.\nimport type { G9EConflictPolicy, G9EMoveOutPolicy, G9ESyncColumnType, G9ESyncDirection } from '../abstractions/enums.js';\nimport { G9SyncException } from '../abstractions/errors.js';\nimport type { G9Long } from '../abstractions/long.js';\n\n/** What a subscription must do next, as decided by the server (`G9ESubscriptionAction`). */\nexport const G9ESubscriptionAction = {\n Ok: 0,\n Initial: 1,\n Reconcile: 2,\n ResyncRequired: 3,\n Unknown: 4,\n InvalidParameters: 5,\n Forbidden: 6,\n} as const;\nexport type G9ESubscriptionAction = (typeof G9ESubscriptionAction)[keyof typeof G9ESubscriptionAction];\n\n/** Kind of a planned pull part (`G9EPullPartKind`). */\nexport const G9EPullPartKind = {\n Snapshot: 0,\n Delta: 1,\n Backfill: 2,\n} as const;\nexport type G9EPullPartKind = (typeof G9EPullPartKind)[keyof typeof G9EPullPartKind];\n\n/** Outcome of a command executed by the server (`G9ECommandStatus`). */\nexport const G9ECommandStatus = {\n Ok: 0,\n Rejected: 1,\n Superseded: 2,\n} as const;\nexport type G9ECommandStatus = (typeof G9ECommandStatus)[keyof typeof G9ECommandStatus];\n\n// ---------------------------------------------------------------- common\n\nexport interface G9DtSyncError {\n code: string;\n message: string;\n retryable: boolean;\n details?: string | null;\n}\n\n/** `G9DtSyncError.ToException()`. */\nexport function syncErrorToException(error: G9DtSyncError): G9SyncException {\n return new G9SyncException(error.code, error.message, { retryable: error.retryable, details: error.details ?? null });\n}\n\n/** `G9DtSyncError.From(exception)`. */\nexport function syncErrorFrom(exception: G9SyncException): G9DtSyncError {\n return { code: exception.code, message: exception.message, retryable: exception.retryable, details: exception.details };\n}\n\nexport interface G9DtColumnModel {\n name: string;\n type: G9ESyncColumnType;\n nullable: boolean;\n}\n\n/** A subscription as the client holds it: name, canonical parameters and its sync state. */\nexport interface G9DtSubscriptionRef {\n name: string;\n parameters: { [name: string]: string };\n /** Opaque server cursor of the last completed pull. Null before the first pull. */\n cursor?: string | null;\n definitionHash?: string | null;\n authHash?: string | null;\n}\n\n/** Resume point after a chunk. Only chunks that carry one are safe restart points. */\nexport interface G9DtPullContinuation {\n partIndex: number;\n afterKey?: string | null;\n nextSequence: number;\n}\n\n/** One unit of a data stream; `payload` is a G9RowBatch frame. */\nexport interface G9DtSyncChunk {\n sequence: number;\n payload?: Uint8Array | null;\n rowCount: number;\n subscriptionKey?: string | null;\n isFinal: boolean;\n continuation?: G9DtPullContinuation | null;\n reconcileSummary?: G9DtReconcileSummary | null;\n}\n\n/** Server → client hint that tables changed. */\nexport interface G9DtChangesAvailable {\n tables: string[];\n}\n\n// ---------------------------------------------------------------- hello\n\nexport interface G9DtClientTableModel {\n name: string;\n keyColumn: string;\n keyType: G9ESyncColumnType;\n columns: G9DtColumnModel[];\n}\n\nexport interface G9DtHelloRequest {\n clientId: string;\n appVersion?: string | null;\n protocolVersion: number;\n tables: G9DtClientTableModel[];\n subscriptions: G9DtSubscriptionRef[];\n}\n\nexport interface G9DtColumnTypeMismatch {\n name: string;\n clientType: G9ESyncColumnType;\n serverType: G9ESyncColumnType;\n}\n\n/** The column set both sides agreed on for one table. */\nexport interface G9DtNegotiatedTable {\n tableId: number;\n name: string;\n keyColumn: string;\n keyType: G9ESyncColumnType;\n columns: G9DtColumnModel[];\n computedColumns: string[];\n readOnlyColumns: string[];\n missingColumns: string[];\n typeMismatchColumns: G9DtColumnTypeMismatch[];\n direction: G9ESyncDirection;\n conflictPolicy: G9EConflictPolicy;\n}\n\nexport interface G9DtParameterDefinition {\n name: string;\n type: G9ESyncColumnType;\n required: boolean;\n isList: boolean;\n}\n\nexport interface G9DtSubscriptionDependency {\n name: string;\n required: boolean;\n}\n\nexport interface G9DtSubscriptionDefinition {\n name: string;\n parameters: G9DtParameterDefinition[];\n dependsOn: G9DtSubscriptionDependency[];\n tables: string[];\n ephemeral: boolean;\n ttlSeconds: number;\n heavy: boolean;\n moveOutPolicy: G9EMoveOutPolicy;\n reconcileIntervalMinutes: number;\n definitionHash: string;\n}\n\nexport interface G9DtSubscriptionState {\n key: string;\n action: G9ESubscriptionAction;\n definitionHash?: string | null;\n authHash?: string | null;\n message?: string | null;\n}\n\nexport interface G9DtHelloResult {\n epoch: string;\n /** Server clock at the answer, epoch milliseconds UTC (.NET `DateTime ServerTimeUtc`). */\n serverTimeUtcMs: number;\n protocolVersion: number;\n tables: G9DtNegotiatedTable[];\n unknownTables: string[];\n definitions: G9DtSubscriptionDefinition[];\n subscriptions: G9DtSubscriptionState[];\n maxPushRows: number;\n maxPushBytes: number;\n error?: G9DtSyncError | null;\n}\n\n// ---------------------------------------------------------------- push / pull\n\nexport interface G9DtTableColumns {\n tableId: number;\n columns: string[];\n}\n\nexport interface G9DtRowRef {\n tableId: number;\n key: string;\n}\n\nexport interface G9DtCommand {\n commandId: string;\n sequence: number;\n name: string;\n version: number;\n payload: string;\n createdUtcMs: number;\n touched: G9DtRowRef[];\n}\n\nexport interface G9DtCommandResult {\n commandId: string;\n status: G9ECommandStatus;\n code?: string | null;\n message?: string | null;\n result?: string | null;\n}\n\nexport interface G9DtPushRequest {\n clientId: string;\n batchId: number;\n subscriptions: G9DtSubscriptionRef[];\n tables: G9DtTableColumns[];\n commands: G9DtCommand[];\n heldTables: G9DtTableColumns[];\n frameVersion: number;\n}\n\nexport interface G9DtAcceptedRows {\n tableId: number;\n keys: string[];\n versions: number[];\n deleted: boolean[];\n}\n\nexport interface G9DtRowRejection {\n tableId: number;\n key: string;\n code: string;\n message?: string | null;\n sqlState?: string | null;\n constraint?: string | null;\n column?: string | null;\n details?: string | null;\n}\n\nexport interface G9DtRowConflict {\n tableId: number;\n key: string;\n code: string;\n /** Bits (push column order) the server changed after the client's base version; -1 when unknown. */\n serverChangedMask: G9Long;\n partiallyApplied: boolean;\n}\n\nexport interface G9DtPushResult {\n batchId: number;\n alreadyApplied: boolean;\n accepted: G9DtAcceptedRows[];\n rejections: G9DtRowRejection[];\n conflicts: G9DtRowConflict[];\n canonicalFrames: Uint8Array[];\n commandResults: G9DtCommandResult[];\n error?: G9DtSyncError | null;\n}\n\nexport interface G9DtBackfillRequest {\n tableId: number;\n columns: string[];\n}\n\nexport interface G9DtPullRequest {\n clientId: string;\n subscriptions: G9DtSubscriptionRef[];\n tables: G9DtTableColumns[];\n backfills: G9DtBackfillRequest[];\n frameVersion: number;\n}\n\nexport interface G9DtPlannedPart {\n subscriptionKey: string;\n tableId: number;\n kind: G9EPullPartKind;\n rows: number;\n estimatedBytes: number;\n}\n\nexport interface G9DtSubscriptionCursor {\n key: string;\n cursor: string;\n definitionHash: string;\n authHash: string;\n}\n\nexport interface G9DtPullPlan {\n token: string;\n parts: G9DtPlannedPart[];\n totalRows: number;\n estimatedBytes: number;\n cursors: G9DtSubscriptionCursor[];\n skipped: G9DtSubscriptionState[];\n error?: G9DtSyncError | null;\n}\n\nexport interface G9DtTableDigest {\n tableId: number;\n computedColumns: string[];\n /** 256 bucket digests (XOR of row hashes). */\n digests: G9Long[];\n /** 256 bucket row counts. */\n counts: number[];\n}\n\nexport interface G9DtReconcileRequest {\n clientId: string;\n subscription: G9DtSubscriptionRef;\n tables: G9DtTableDigest[];\n frameVersion: number;\n}\n\nexport interface G9DtTableBuckets {\n tableId: number;\n buckets: number[];\n}\n\nexport interface G9DtReconcileSummary {\n cursor: string;\n definitionHash: string;\n authHash: string;\n mismatched: G9DtTableBuckets[];\n}\n\nexport interface G9DtFetchRowsRequest {\n clientId: string;\n subscription: G9DtSubscriptionRef;\n tableId: number;\n keys: string[];\n columns: string[];\n frameVersion: number;\n}\n"]}
@@ -0,0 +1,36 @@
1
+ import { G9SyncException } from '../abstractions/errors.js';
2
+ /** Protocol constants shared by every transport (`G9SyncProtocol`). */
3
+ export declare const G9SyncProtocol: {
4
+ /** Wire protocol version. The server refuses a Hello from a different major version. */
5
+ readonly Version: 1;
6
+ /** The newest G9RowBatch body layout this build reads and writes (1 row-wise, 2 column-grouped; ADR-0040). */
7
+ readonly MaxFrameVersion: 2;
8
+ /** Default SignalR hub route. */
9
+ readonly DefaultHubRoute: "/g9sync";
10
+ /** Hub method names (client → server). */
11
+ readonly Methods: {
12
+ readonly Hello: "Hello";
13
+ readonly Push: "Push";
14
+ readonly PlanPull: "PlanPull";
15
+ readonly Pull: "Pull";
16
+ readonly Reconcile: "Reconcile";
17
+ readonly FetchRows: "FetchRows";
18
+ };
19
+ /** Listener method names (server → client). */
20
+ readonly Listeners: {
21
+ readonly OnChangesAvailable: "OnChangesAvailable";
22
+ };
23
+ };
24
+ /** The frame layout to answer a request with: the newest both sides know, and 1 for a sender that did not say. */
25
+ export declare function negotiateFrameVersion(requested: number): number;
26
+ /** The SignalR group of connections that negotiated a table (`G9SyncProtocol.TableGroup`). */
27
+ export declare function tableGroup(logicalTable: string): string;
28
+ /**
29
+ * Carries a G9SyncException through SignalR (`G9SyncHubErrors`): a HubException message is the only error text SignalR
30
+ * forwards, so the code travels inside it as `[G9S|{code}|{retryable 0/1}] {message}`.
31
+ */
32
+ export declare const G9SyncHubErrors: {
33
+ format(exception: G9SyncException): string;
34
+ /** Finds the marker anywhere in `text` (the client wraps it in its own words); null when there is none. */
35
+ tryParse(text: string | null | undefined): G9SyncException | null;
36
+ };
@@ -0,0 +1,63 @@
1
+ // Twins of G9SyncData.Protocol/G9SyncProtocol.cs and G9SyncHubContract.cs (G9SyncHubErrors).
2
+ import { G9SyncException } from '../abstractions/errors.js';
3
+ /** Protocol constants shared by every transport (`G9SyncProtocol`). */
4
+ export const G9SyncProtocol = {
5
+ /** Wire protocol version. The server refuses a Hello from a different major version. */
6
+ Version: 1,
7
+ /** The newest G9RowBatch body layout this build reads and writes (1 row-wise, 2 column-grouped; ADR-0040). */
8
+ MaxFrameVersion: 2,
9
+ /** Default SignalR hub route. */
10
+ DefaultHubRoute: '/g9sync',
11
+ /** Hub method names (client → server). */
12
+ Methods: {
13
+ Hello: 'Hello',
14
+ Push: 'Push',
15
+ PlanPull: 'PlanPull',
16
+ Pull: 'Pull',
17
+ Reconcile: 'Reconcile',
18
+ FetchRows: 'FetchRows',
19
+ },
20
+ /** Listener method names (server → client). */
21
+ Listeners: {
22
+ OnChangesAvailable: 'OnChangesAvailable',
23
+ },
24
+ };
25
+ /** The frame layout to answer a request with: the newest both sides know, and 1 for a sender that did not say. */
26
+ export function negotiateFrameVersion(requested) {
27
+ return Math.min(Math.max(requested, 1), G9SyncProtocol.MaxFrameVersion);
28
+ }
29
+ /** The SignalR group of connections that negotiated a table (`G9SyncProtocol.TableGroup`). */
30
+ export function tableGroup(logicalTable) {
31
+ if (typeof logicalTable !== 'string' || logicalTable.trim() === '')
32
+ throw new TypeError('A table name is required.');
33
+ return 'g9sync:' + logicalTable.toLowerCase();
34
+ }
35
+ const PREFIX = '[G9S|';
36
+ /**
37
+ * Carries a G9SyncException through SignalR (`G9SyncHubErrors`): a HubException message is the only error text SignalR
38
+ * forwards, so the code travels inside it as `[G9S|{code}|{retryable 0/1}] {message}`.
39
+ */
40
+ export const G9SyncHubErrors = {
41
+ format(exception) {
42
+ return PREFIX + exception.code + '|' + (exception.retryable ? '1' : '0') + '] ' + exception.message;
43
+ },
44
+ /** Finds the marker anywhere in `text` (the client wraps it in its own words); null when there is none. */
45
+ tryParse(text) {
46
+ if (!text)
47
+ return null;
48
+ const start = text.indexOf(PREFIX);
49
+ if (start < 0)
50
+ return null;
51
+ const end = text.indexOf(']', start);
52
+ if (end < 0)
53
+ return null;
54
+ const header = text.slice(start + PREFIX.length, end);
55
+ const bar = header.lastIndexOf('|');
56
+ if (bar <= 0)
57
+ return null;
58
+ const code = header.slice(0, bar);
59
+ const retryable = header.slice(bar + 1) === '1';
60
+ return new G9SyncException(code, text.slice(end + 1).trim(), { retryable });
61
+ },
62
+ };
63
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/protocol/protocol.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,uEAAuE;AACvE,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,wFAAwF;IACxF,OAAO,EAAE,CAAC;IACV,8GAA8G;IAC9G,eAAe,EAAE,CAAC;IAClB,iCAAiC;IACjC,eAAe,EAAE,SAAS;IAC1B,0CAA0C;IAC1C,OAAO,EAAE;QACP,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,UAAU;QACpB,IAAI,EAAE,MAAM;QACZ,SAAS,EAAE,WAAW;QACtB,SAAS,EAAE,WAAW;KACvB;IACD,+CAA+C;IAC/C,SAAS,EAAE;QACT,kBAAkB,EAAE,oBAAoB;KACzC;CACO,CAAC;AAEX,kHAAkH;AAClH,MAAM,UAAU,qBAAqB,CAAC,SAAiB;IACrD,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,cAAc,CAAC,eAAe,CAAC,CAAC;AAC1E,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,UAAU,CAAC,YAAoB;IAC7C,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,MAAM,IAAI,SAAS,CAAC,2BAA2B,CAAC,CAAC;IACrH,OAAO,SAAS,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC;AAChD,CAAC;AAED,MAAM,MAAM,GAAG,OAAO,CAAC;AAEvB;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,MAAM,CAAC,SAA0B;QAC/B,OAAO,MAAM,GAAG,SAAS,CAAC,IAAI,GAAG,GAAG,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC;IACtG,CAAC;IAED,2GAA2G;IAC3G,QAAQ,CAAC,IAA+B;QACtC,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACnC,IAAI,KAAK,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACrC,IAAI,GAAG,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QACzB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACtD,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,GAAG,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1B,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAClC,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC;QAChD,OAAO,IAAI,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IAC9E,CAAC;CACF,CAAC","sourcesContent":["// Twins of G9SyncData.Protocol/G9SyncProtocol.cs and G9SyncHubContract.cs (G9SyncHubErrors).\nimport { G9SyncException } from '../abstractions/errors.js';\n\n/** Protocol constants shared by every transport (`G9SyncProtocol`). */\nexport const G9SyncProtocol = {\n /** Wire protocol version. The server refuses a Hello from a different major version. */\n Version: 1,\n /** The newest G9RowBatch body layout this build reads and writes (1 row-wise, 2 column-grouped; ADR-0040). */\n MaxFrameVersion: 2,\n /** Default SignalR hub route. */\n DefaultHubRoute: '/g9sync',\n /** Hub method names (client → server). */\n Methods: {\n Hello: 'Hello',\n Push: 'Push',\n PlanPull: 'PlanPull',\n Pull: 'Pull',\n Reconcile: 'Reconcile',\n FetchRows: 'FetchRows',\n },\n /** Listener method names (server → client). */\n Listeners: {\n OnChangesAvailable: 'OnChangesAvailable',\n },\n} as const;\n\n/** The frame layout to answer a request with: the newest both sides know, and 1 for a sender that did not say. */\nexport function negotiateFrameVersion(requested: number): number {\n return Math.min(Math.max(requested, 1), G9SyncProtocol.MaxFrameVersion);\n}\n\n/** The SignalR group of connections that negotiated a table (`G9SyncProtocol.TableGroup`). */\nexport function tableGroup(logicalTable: string): string {\n if (typeof logicalTable !== 'string' || logicalTable.trim() === '') throw new TypeError('A table name is required.');\n return 'g9sync:' + logicalTable.toLowerCase();\n}\n\nconst PREFIX = '[G9S|';\n\n/**\n * Carries a G9SyncException through SignalR (`G9SyncHubErrors`): a HubException message is the only error text SignalR\n * forwards, so the code travels inside it as `[G9S|{code}|{retryable 0/1}] {message}`.\n */\nexport const G9SyncHubErrors = {\n format(exception: G9SyncException): string {\n return PREFIX + exception.code + '|' + (exception.retryable ? '1' : '0') + '] ' + exception.message;\n },\n\n /** Finds the marker anywhere in `text` (the client wraps it in its own words); null when there is none. */\n tryParse(text: string | null | undefined): G9SyncException | null {\n if (!text) return null;\n const start = text.indexOf(PREFIX);\n if (start < 0) return null;\n const end = text.indexOf(']', start);\n if (end < 0) return null;\n const header = text.slice(start + PREFIX.length, end);\n const bar = header.lastIndexOf('|');\n if (bar <= 0) return null;\n const code = header.slice(0, bar);\n const retryable = header.slice(bar + 1) === '1';\n return new G9SyncException(code, text.slice(end + 1).trim(), { retryable });\n },\n};\n"]}
@@ -0,0 +1,4 @@
1
+ /** Converts a version 1 (row-wise) body to the version 2 (column-grouped) layout. */
2
+ export declare function fromRows(rows: Uint8Array): Uint8Array;
3
+ /** Converts a version 2 (column-grouped) body back to the version 1 layout, which is never longer. */
4
+ export declare function toRows(columns: Uint8Array): Uint8Array;