lakesync 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter.d.ts +185 -20
- package/dist/adapter.js +13 -3
- package/dist/analyst.js +2 -2
- package/dist/{base-poller-BpUyuG2R.d.ts → base-poller-Bj9kX9dv.d.ts} +76 -19
- package/dist/catalogue.d.ts +1 -1
- package/dist/catalogue.js +3 -3
- package/dist/chunk-DGUM43GV.js +11 -0
- package/dist/{chunk-IRJ4QRWV.js → chunk-JI4C4R5H.js} +249 -140
- package/dist/chunk-JI4C4R5H.js.map +1 -0
- package/dist/{chunk-FHVTUKXL.js → chunk-KVSWLIJR.js} +2 -2
- package/dist/{chunk-P3FT7QCW.js → chunk-LDFFCG2K.js} +377 -247
- package/dist/chunk-LDFFCG2K.js.map +1 -0
- package/dist/{chunk-GUJWMK5P.js → chunk-LPWXOYNS.js} +373 -350
- package/dist/chunk-LPWXOYNS.js.map +1 -0
- package/dist/{chunk-QMS7TGFL.js → chunk-PYRS74YP.js} +15 -4
- package/dist/{chunk-QMS7TGFL.js.map → chunk-PYRS74YP.js.map} +1 -1
- package/dist/{chunk-NCZYFZ3B.js → chunk-QNITY4F6.js} +30 -7
- package/dist/{chunk-NCZYFZ3B.js.map → chunk-QNITY4F6.js.map} +1 -1
- package/dist/{chunk-SF7Y6ZUA.js → chunk-SSICS5KI.js} +2 -2
- package/dist/{chunk-UAUQGP3B.js → chunk-TMLG32QV.js} +2 -2
- package/dist/client.d.ts +164 -13
- package/dist/client.js +310 -163
- package/dist/client.js.map +1 -1
- package/dist/compactor.d.ts +1 -1
- package/dist/compactor.js +4 -4
- package/dist/connector-jira.d.ts +2 -2
- package/dist/connector-jira.js +3 -3
- package/dist/connector-salesforce.d.ts +2 -2
- package/dist/connector-salesforce.js +3 -3
- package/dist/{coordinator-D32a5rNk.d.ts → coordinator-NXy6tA0h.d.ts} +23 -16
- package/dist/{db-types-BlN-4KbQ.d.ts → db-types-CfLMUBfW.d.ts} +1 -1
- package/dist/gateway-server.d.ts +158 -64
- package/dist/gateway-server.js +482 -4003
- package/dist/gateway-server.js.map +1 -1
- package/dist/gateway.d.ts +61 -104
- package/dist/gateway.js +12 -6
- package/dist/index.d.ts +45 -10
- package/dist/index.js +14 -2
- package/dist/parquet.d.ts +1 -1
- package/dist/parquet.js +3 -3
- package/dist/proto.d.ts +1 -1
- package/dist/proto.js +3 -3
- package/dist/react.d.ts +47 -10
- package/dist/react.js +88 -40
- package/dist/react.js.map +1 -1
- package/dist/{registry-CPTgO9jv.d.ts → registry-BcspAtZI.d.ts} +19 -4
- package/dist/{gateway-Bpvatd9n.d.ts → request-handler-pUvL7ozF.d.ts} +139 -10
- package/dist/{resolver-CbuXm3nB.d.ts → resolver-CXxmC0jR.d.ts} +1 -1
- package/dist/{src-FPJQYQNA.js → src-B6NLV3FP.js} +4 -4
- package/dist/{src-RHKJFQKR.js → src-ROW4XLO7.js} +15 -3
- package/dist/{src-CLCALYDT.js → src-ZRHKG42A.js} +4 -4
- package/dist/{types-CLlD4XOy.d.ts → types-BdGBv2ba.d.ts} +17 -2
- package/dist/{types-D-E0VrfS.d.ts → types-BrcD1oJg.d.ts} +26 -19
- package/package.json +1 -1
- package/dist/chunk-7D4SUZUM.js +0 -38
- package/dist/chunk-GUJWMK5P.js.map +0 -1
- package/dist/chunk-IRJ4QRWV.js.map +0 -1
- package/dist/chunk-P3FT7QCW.js.map +0 -1
- /package/dist/{chunk-7D4SUZUM.js.map → chunk-DGUM43GV.js.map} +0 -0
- /package/dist/{chunk-FHVTUKXL.js.map → chunk-KVSWLIJR.js.map} +0 -0
- /package/dist/{chunk-SF7Y6ZUA.js.map → chunk-SSICS5KI.js.map} +0 -0
- /package/dist/{chunk-UAUQGP3B.js.map → chunk-TMLG32QV.js.map} +0 -0
- /package/dist/{src-CLCALYDT.js.map → src-B6NLV3FP.js.map} +0 -0
- /package/dist/{src-FPJQYQNA.js.map → src-ROW4XLO7.js.map} +0 -0
- /package/dist/{src-RHKJFQKR.js.map → src-ZRHKG42A.js.map} +0 -0
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isDatabaseAdapter,
|
|
3
3
|
isMaterialisable
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-LPWXOYNS.js";
|
|
5
5
|
import {
|
|
6
6
|
buildPartitionSpec,
|
|
7
7
|
lakeSyncTableName,
|
|
8
8
|
tableSchemaToIceberg
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-TMLG32QV.js";
|
|
10
10
|
import {
|
|
11
11
|
writeDeltasToParquet
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-SSICS5KI.js";
|
|
13
13
|
import {
|
|
14
14
|
AdapterNotFoundError,
|
|
15
15
|
BackpressureError,
|
|
16
|
+
COLUMN_TYPES,
|
|
16
17
|
Err,
|
|
17
18
|
FlushError,
|
|
18
19
|
HLC,
|
|
@@ -28,19 +29,25 @@ import {
|
|
|
28
29
|
validateAction,
|
|
29
30
|
validateConnectorConfig,
|
|
30
31
|
validateSyncRules
|
|
31
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-LDFFCG2K.js";
|
|
32
33
|
|
|
33
34
|
// ../gateway/src/action-dispatcher.ts
|
|
35
|
+
var DEFAULT_MAX_CACHE_SIZE = 1e4;
|
|
36
|
+
var DEFAULT_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
34
37
|
var ActionDispatcher = class {
|
|
35
38
|
actionHandlers = /* @__PURE__ */ new Map();
|
|
36
39
|
executedActions = /* @__PURE__ */ new Set();
|
|
37
40
|
idempotencyMap = /* @__PURE__ */ new Map();
|
|
38
|
-
|
|
41
|
+
maxCacheSize;
|
|
42
|
+
cacheTtlMs;
|
|
43
|
+
constructor(handlers, cacheConfig) {
|
|
39
44
|
if (handlers) {
|
|
40
45
|
for (const [name, handler] of Object.entries(handlers)) {
|
|
41
46
|
this.actionHandlers.set(name, handler);
|
|
42
47
|
}
|
|
43
48
|
}
|
|
49
|
+
this.maxCacheSize = cacheConfig?.maxSize ?? DEFAULT_MAX_CACHE_SIZE;
|
|
50
|
+
this.cacheTtlMs = cacheConfig?.ttlMs ?? DEFAULT_CACHE_TTL_MS;
|
|
44
51
|
}
|
|
45
52
|
/**
|
|
46
53
|
* Dispatch an action push to registered handlers.
|
|
@@ -55,6 +62,7 @@ var ActionDispatcher = class {
|
|
|
55
62
|
* @returns A `Result` containing results for each action.
|
|
56
63
|
*/
|
|
57
64
|
async dispatch(msg, hlcNow, context) {
|
|
65
|
+
this.evictStaleEntries();
|
|
58
66
|
const results = [];
|
|
59
67
|
for (const action of msg.actions) {
|
|
60
68
|
const validation = validateAction(action);
|
|
@@ -62,7 +70,7 @@ var ActionDispatcher = class {
|
|
|
62
70
|
return Err(validation.error);
|
|
63
71
|
}
|
|
64
72
|
if (this.executedActions.has(action.actionId)) {
|
|
65
|
-
const cached = this.
|
|
73
|
+
const cached = this.getCachedResult(action.actionId);
|
|
66
74
|
if (cached) {
|
|
67
75
|
results.push(cached);
|
|
68
76
|
continue;
|
|
@@ -70,7 +78,7 @@ var ActionDispatcher = class {
|
|
|
70
78
|
continue;
|
|
71
79
|
}
|
|
72
80
|
if (action.idempotencyKey) {
|
|
73
|
-
const cached = this.
|
|
81
|
+
const cached = this.getCachedResult(`idem:${action.idempotencyKey}`);
|
|
74
82
|
if (cached) {
|
|
75
83
|
results.push(cached);
|
|
76
84
|
continue;
|
|
@@ -163,10 +171,43 @@ var ActionDispatcher = class {
|
|
|
163
171
|
}
|
|
164
172
|
/** Cache an action result for idempotency deduplication. */
|
|
165
173
|
cacheActionResult(action, result) {
|
|
174
|
+
const entry = { value: result, cachedAt: Date.now() };
|
|
166
175
|
this.executedActions.add(action.actionId);
|
|
167
|
-
this.idempotencyMap.set(action.actionId,
|
|
176
|
+
this.idempotencyMap.set(action.actionId, entry);
|
|
168
177
|
if (action.idempotencyKey) {
|
|
169
|
-
this.idempotencyMap.set(`idem:${action.idempotencyKey}`,
|
|
178
|
+
this.idempotencyMap.set(`idem:${action.idempotencyKey}`, entry);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/** Get a cached result if it exists and hasn't expired. */
|
|
182
|
+
getCachedResult(key) {
|
|
183
|
+
const entry = this.idempotencyMap.get(key);
|
|
184
|
+
if (!entry) return void 0;
|
|
185
|
+
if (Date.now() - entry.cachedAt > this.cacheTtlMs) {
|
|
186
|
+
this.idempotencyMap.delete(key);
|
|
187
|
+
return void 0;
|
|
188
|
+
}
|
|
189
|
+
return entry.value;
|
|
190
|
+
}
|
|
191
|
+
/** Evict expired entries and trim to max size. */
|
|
192
|
+
evictStaleEntries() {
|
|
193
|
+
const now = Date.now();
|
|
194
|
+
for (const [key, entry] of this.idempotencyMap) {
|
|
195
|
+
if (now - entry.cachedAt > this.cacheTtlMs) {
|
|
196
|
+
this.idempotencyMap.delete(key);
|
|
197
|
+
if (!key.startsWith("idem:")) {
|
|
198
|
+
this.executedActions.delete(key);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if (this.executedActions.size > this.maxCacheSize) {
|
|
203
|
+
const excess = this.executedActions.size - this.maxCacheSize;
|
|
204
|
+
let removed = 0;
|
|
205
|
+
for (const actionId of this.executedActions) {
|
|
206
|
+
if (removed >= excess) break;
|
|
207
|
+
this.executedActions.delete(actionId);
|
|
208
|
+
this.idempotencyMap.delete(actionId);
|
|
209
|
+
removed++;
|
|
210
|
+
}
|
|
170
211
|
}
|
|
171
212
|
}
|
|
172
213
|
};
|
|
@@ -284,9 +325,18 @@ var DeltaBuffer = class {
|
|
|
284
325
|
this.tableLog.delete(table);
|
|
285
326
|
return tableDeltas;
|
|
286
327
|
}
|
|
287
|
-
/**
|
|
288
|
-
|
|
289
|
-
|
|
328
|
+
/**
|
|
329
|
+
* Snapshot the current buffer state without clearing it.
|
|
330
|
+
*
|
|
331
|
+
* Useful for inspecting the buffer contents without draining.
|
|
332
|
+
* Use {@link clear} separately after a successful flush for
|
|
333
|
+
* transactional semantics.
|
|
334
|
+
*/
|
|
335
|
+
snapshot() {
|
|
336
|
+
return { entries: [...this.log], byteSize: this.estimatedBytes };
|
|
337
|
+
}
|
|
338
|
+
/** Clear all buffer state. */
|
|
339
|
+
clear() {
|
|
290
340
|
this.log = [];
|
|
291
341
|
this.index.clear();
|
|
292
342
|
this.deltaIds.clear();
|
|
@@ -294,6 +344,11 @@ var DeltaBuffer = class {
|
|
|
294
344
|
this.createdAt = Date.now();
|
|
295
345
|
this.tableBytes.clear();
|
|
296
346
|
this.tableLog.clear();
|
|
347
|
+
}
|
|
348
|
+
/** Drain the log for flush. Returns log entries and clears both structures. */
|
|
349
|
+
drain() {
|
|
350
|
+
const { entries } = this.snapshot();
|
|
351
|
+
this.clear();
|
|
297
352
|
return entries;
|
|
298
353
|
}
|
|
299
354
|
/** Number of log entries */
|
|
@@ -344,7 +399,7 @@ var MAX_PUSH_PAYLOAD_BYTES = 1048576;
|
|
|
344
399
|
var MAX_DELTAS_PER_PUSH = 1e4;
|
|
345
400
|
var MAX_PULL_LIMIT = 1e4;
|
|
346
401
|
var DEFAULT_PULL_LIMIT = 100;
|
|
347
|
-
var VALID_COLUMN_TYPES =
|
|
402
|
+
var VALID_COLUMN_TYPES = new Set(COLUMN_TYPES);
|
|
348
403
|
var DEFAULT_MAX_BUFFER_BYTES = 4 * 1024 * 1024;
|
|
349
404
|
var DEFAULT_MAX_BUFFER_AGE_MS = 3e4;
|
|
350
405
|
|
|
@@ -463,6 +518,117 @@ async function commitToCatalogue(objectKey, fileSizeInBytes, recordCount, catalo
|
|
|
463
518
|
}
|
|
464
519
|
}
|
|
465
520
|
|
|
521
|
+
// ../gateway/src/flush-coordinator.ts
|
|
522
|
+
var FlushCoordinator = class {
|
|
523
|
+
flushing = false;
|
|
524
|
+
/** Whether a flush is currently in progress. */
|
|
525
|
+
get isFlushing() {
|
|
526
|
+
return this.flushing;
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Flush all entries from the buffer to the adapter.
|
|
530
|
+
*
|
|
531
|
+
* Drains the buffer first, then writes to the adapter. On failure,
|
|
532
|
+
* entries are restored to the buffer.
|
|
533
|
+
*/
|
|
534
|
+
async flush(buffer, adapter, deps) {
|
|
535
|
+
if (this.flushing) {
|
|
536
|
+
return Err(new FlushError("Flush already in progress"));
|
|
537
|
+
}
|
|
538
|
+
if (buffer.logSize === 0) {
|
|
539
|
+
return Ok(void 0);
|
|
540
|
+
}
|
|
541
|
+
if (!adapter) {
|
|
542
|
+
return Err(new FlushError("No adapter configured"));
|
|
543
|
+
}
|
|
544
|
+
this.flushing = true;
|
|
545
|
+
const byteSize = isDatabaseAdapter(adapter) ? 0 : buffer.byteSize;
|
|
546
|
+
const entries = buffer.drain();
|
|
547
|
+
if (entries.length === 0) {
|
|
548
|
+
this.flushing = false;
|
|
549
|
+
return Ok(void 0);
|
|
550
|
+
}
|
|
551
|
+
try {
|
|
552
|
+
return await flushEntries(entries, byteSize, {
|
|
553
|
+
adapter,
|
|
554
|
+
config: deps.config,
|
|
555
|
+
restoreEntries: (e) => this.restoreEntries(buffer, e),
|
|
556
|
+
schemas: deps.schemas
|
|
557
|
+
});
|
|
558
|
+
} finally {
|
|
559
|
+
this.flushing = false;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Flush a single table's deltas from the buffer.
|
|
564
|
+
*
|
|
565
|
+
* Drains only the specified table's deltas and flushes them,
|
|
566
|
+
* leaving other tables in the buffer.
|
|
567
|
+
*/
|
|
568
|
+
async flushTable(table, buffer, adapter, deps) {
|
|
569
|
+
if (this.flushing) {
|
|
570
|
+
return Err(new FlushError("Flush already in progress"));
|
|
571
|
+
}
|
|
572
|
+
if (!adapter) {
|
|
573
|
+
return Err(new FlushError("No adapter configured"));
|
|
574
|
+
}
|
|
575
|
+
const entries = buffer.drainTable(table);
|
|
576
|
+
if (entries.length === 0) {
|
|
577
|
+
return Ok(void 0);
|
|
578
|
+
}
|
|
579
|
+
this.flushing = true;
|
|
580
|
+
try {
|
|
581
|
+
return await flushEntries(
|
|
582
|
+
entries,
|
|
583
|
+
0,
|
|
584
|
+
{
|
|
585
|
+
adapter,
|
|
586
|
+
config: deps.config,
|
|
587
|
+
restoreEntries: (e) => this.restoreEntries(buffer, e),
|
|
588
|
+
schemas: deps.schemas
|
|
589
|
+
},
|
|
590
|
+
table
|
|
591
|
+
);
|
|
592
|
+
} finally {
|
|
593
|
+
this.flushing = false;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
/** Restore drained entries back to the buffer for retry. */
|
|
597
|
+
restoreEntries(buffer, entries) {
|
|
598
|
+
for (const entry of entries) {
|
|
599
|
+
buffer.append(entry);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
};
|
|
603
|
+
|
|
604
|
+
// ../gateway/src/source-registry.ts
|
|
605
|
+
var SourceRegistry = class {
|
|
606
|
+
sources = /* @__PURE__ */ new Map();
|
|
607
|
+
constructor(initial) {
|
|
608
|
+
if (initial) {
|
|
609
|
+
for (const [name, adapter] of Object.entries(initial)) {
|
|
610
|
+
this.sources.set(name, adapter);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
/** Register a named source adapter. */
|
|
615
|
+
register(name, adapter) {
|
|
616
|
+
this.sources.set(name, adapter);
|
|
617
|
+
}
|
|
618
|
+
/** Unregister a named source adapter. */
|
|
619
|
+
unregister(name) {
|
|
620
|
+
this.sources.delete(name);
|
|
621
|
+
}
|
|
622
|
+
/** Get a source adapter by name, or undefined if not registered. */
|
|
623
|
+
get(name) {
|
|
624
|
+
return this.sources.get(name);
|
|
625
|
+
}
|
|
626
|
+
/** List all registered source adapter names. */
|
|
627
|
+
list() {
|
|
628
|
+
return [...this.sources.keys()];
|
|
629
|
+
}
|
|
630
|
+
};
|
|
631
|
+
|
|
466
632
|
// ../gateway/src/gateway.ts
|
|
467
633
|
var SyncGateway = class {
|
|
468
634
|
hlc;
|
|
@@ -470,20 +636,20 @@ var SyncGateway = class {
|
|
|
470
636
|
actions;
|
|
471
637
|
config;
|
|
472
638
|
adapter;
|
|
473
|
-
|
|
639
|
+
sources;
|
|
640
|
+
flushCoordinator;
|
|
474
641
|
constructor(config, adapter) {
|
|
475
642
|
this.config = { sourceAdapters: {}, ...config };
|
|
476
643
|
this.hlc = new HLC();
|
|
477
644
|
this.buffer = new DeltaBuffer();
|
|
478
645
|
this.adapter = this.config.adapter ?? adapter ?? null;
|
|
479
646
|
this.actions = new ActionDispatcher(config.actionHandlers);
|
|
647
|
+
this.sources = new SourceRegistry(this.config.sourceAdapters);
|
|
648
|
+
this.flushCoordinator = new FlushCoordinator();
|
|
480
649
|
}
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
this.buffer.append(entry);
|
|
485
|
-
}
|
|
486
|
-
}
|
|
650
|
+
// -----------------------------------------------------------------------
|
|
651
|
+
// Push — pipeline of validation steps then buffer append
|
|
652
|
+
// -----------------------------------------------------------------------
|
|
487
653
|
/**
|
|
488
654
|
* Handle an incoming push from a client.
|
|
489
655
|
*
|
|
@@ -494,14 +660,8 @@ var SyncGateway = class {
|
|
|
494
660
|
* or a `ClockDriftError` if the client clock is too far ahead.
|
|
495
661
|
*/
|
|
496
662
|
handlePush(msg) {
|
|
497
|
-
const
|
|
498
|
-
if (
|
|
499
|
-
return Err(
|
|
500
|
-
new BackpressureError(
|
|
501
|
-
`Buffer backpressure exceeded (${this.buffer.byteSize} >= ${backpressureLimit} bytes)`
|
|
502
|
-
)
|
|
503
|
-
);
|
|
504
|
-
}
|
|
663
|
+
const bpResult = this.checkBackpressure();
|
|
664
|
+
if (!bpResult.ok) return bpResult;
|
|
505
665
|
let accepted = 0;
|
|
506
666
|
const ingested = [];
|
|
507
667
|
for (const delta of msg.deltas) {
|
|
@@ -536,6 +696,18 @@ var SyncGateway = class {
|
|
|
536
696
|
const serverHlc = this.hlc.now();
|
|
537
697
|
return Ok({ serverHlc, accepted, deltas: ingested });
|
|
538
698
|
}
|
|
699
|
+
/** Check buffer backpressure. */
|
|
700
|
+
checkBackpressure() {
|
|
701
|
+
const backpressureLimit = this.config.maxBackpressureBytes ?? this.config.maxBufferBytes * 2;
|
|
702
|
+
if (this.buffer.byteSize >= backpressureLimit) {
|
|
703
|
+
return Err(
|
|
704
|
+
new BackpressureError(
|
|
705
|
+
`Buffer backpressure exceeded (${this.buffer.byteSize} >= ${backpressureLimit} bytes)`
|
|
706
|
+
)
|
|
707
|
+
);
|
|
708
|
+
}
|
|
709
|
+
return Ok(void 0);
|
|
710
|
+
}
|
|
539
711
|
handlePull(msg, context) {
|
|
540
712
|
if (msg.source) {
|
|
541
713
|
return this.handleAdapterPull(msg, context);
|
|
@@ -580,7 +752,7 @@ var SyncGateway = class {
|
|
|
580
752
|
}
|
|
581
753
|
/** Pull from a named source adapter. */
|
|
582
754
|
async handleAdapterPull(msg, context) {
|
|
583
|
-
const adapter = this.
|
|
755
|
+
const adapter = this.sources.get(msg.source);
|
|
584
756
|
if (!adapter) {
|
|
585
757
|
return Err(new AdapterNotFoundError(`Source adapter "${msg.source}" not found`));
|
|
586
758
|
}
|
|
@@ -598,7 +770,7 @@ var SyncGateway = class {
|
|
|
598
770
|
return Ok({ deltas: sliced, serverHlc, hasMore });
|
|
599
771
|
}
|
|
600
772
|
// -----------------------------------------------------------------------
|
|
601
|
-
// Flush — delegates to
|
|
773
|
+
// Flush — delegates to FlushCoordinator
|
|
602
774
|
// -----------------------------------------------------------------------
|
|
603
775
|
/**
|
|
604
776
|
* Flush the buffer to the configured adapter.
|
|
@@ -611,55 +783,15 @@ var SyncGateway = class {
|
|
|
611
783
|
* @returns A `Result` indicating success or a `FlushError`.
|
|
612
784
|
*/
|
|
613
785
|
async flush() {
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
}
|
|
623
|
-
this.flushing = true;
|
|
624
|
-
if (isDatabaseAdapter(this.adapter)) {
|
|
625
|
-
const entries2 = this.buffer.drain();
|
|
626
|
-
if (entries2.length === 0) {
|
|
627
|
-
this.flushing = false;
|
|
628
|
-
return Ok(void 0);
|
|
629
|
-
}
|
|
630
|
-
try {
|
|
631
|
-
return await flushEntries(entries2, 0, {
|
|
632
|
-
adapter: this.adapter,
|
|
633
|
-
config: {
|
|
634
|
-
gatewayId: this.config.gatewayId,
|
|
635
|
-
flushFormat: this.config.flushFormat,
|
|
636
|
-
tableSchema: this.config.tableSchema,
|
|
637
|
-
catalogue: this.config.catalogue
|
|
638
|
-
},
|
|
639
|
-
restoreEntries: (e) => this.restoreEntries(e),
|
|
640
|
-
schemas: this.config.schemas
|
|
641
|
-
});
|
|
642
|
-
} finally {
|
|
643
|
-
this.flushing = false;
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
const byteSize = this.buffer.byteSize;
|
|
647
|
-
const entries = this.buffer.drain();
|
|
648
|
-
try {
|
|
649
|
-
return await flushEntries(entries, byteSize, {
|
|
650
|
-
adapter: this.adapter,
|
|
651
|
-
config: {
|
|
652
|
-
gatewayId: this.config.gatewayId,
|
|
653
|
-
flushFormat: this.config.flushFormat,
|
|
654
|
-
tableSchema: this.config.tableSchema,
|
|
655
|
-
catalogue: this.config.catalogue
|
|
656
|
-
},
|
|
657
|
-
restoreEntries: (e) => this.restoreEntries(e),
|
|
658
|
-
schemas: this.config.schemas
|
|
659
|
-
});
|
|
660
|
-
} finally {
|
|
661
|
-
this.flushing = false;
|
|
662
|
-
}
|
|
786
|
+
return this.flushCoordinator.flush(this.buffer, this.adapter, {
|
|
787
|
+
config: {
|
|
788
|
+
gatewayId: this.config.gatewayId,
|
|
789
|
+
flushFormat: this.config.flushFormat,
|
|
790
|
+
tableSchema: this.config.tableSchema,
|
|
791
|
+
catalogue: this.config.catalogue
|
|
792
|
+
},
|
|
793
|
+
schemas: this.config.schemas
|
|
794
|
+
});
|
|
663
795
|
}
|
|
664
796
|
/**
|
|
665
797
|
* Flush a single table's deltas from the buffer.
|
|
@@ -668,37 +800,15 @@ var SyncGateway = class {
|
|
|
668
800
|
* leaving other tables in the buffer.
|
|
669
801
|
*/
|
|
670
802
|
async flushTable(table) {
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
}
|
|
681
|
-
this.flushing = true;
|
|
682
|
-
try {
|
|
683
|
-
return await flushEntries(
|
|
684
|
-
entries,
|
|
685
|
-
0,
|
|
686
|
-
{
|
|
687
|
-
adapter: this.adapter,
|
|
688
|
-
config: {
|
|
689
|
-
gatewayId: this.config.gatewayId,
|
|
690
|
-
flushFormat: this.config.flushFormat,
|
|
691
|
-
tableSchema: this.config.tableSchema,
|
|
692
|
-
catalogue: this.config.catalogue
|
|
693
|
-
},
|
|
694
|
-
restoreEntries: (e) => this.restoreEntries(e),
|
|
695
|
-
schemas: this.config.schemas
|
|
696
|
-
},
|
|
697
|
-
table
|
|
698
|
-
);
|
|
699
|
-
} finally {
|
|
700
|
-
this.flushing = false;
|
|
701
|
-
}
|
|
803
|
+
return this.flushCoordinator.flushTable(table, this.buffer, this.adapter, {
|
|
804
|
+
config: {
|
|
805
|
+
gatewayId: this.config.gatewayId,
|
|
806
|
+
flushFormat: this.config.flushFormat,
|
|
807
|
+
tableSchema: this.config.tableSchema,
|
|
808
|
+
catalogue: this.config.catalogue
|
|
809
|
+
},
|
|
810
|
+
schemas: this.config.schemas
|
|
811
|
+
});
|
|
702
812
|
}
|
|
703
813
|
// -----------------------------------------------------------------------
|
|
704
814
|
// Actions — delegates to ActionDispatcher
|
|
@@ -724,7 +834,7 @@ var SyncGateway = class {
|
|
|
724
834
|
return this.actions.describe();
|
|
725
835
|
}
|
|
726
836
|
// -----------------------------------------------------------------------
|
|
727
|
-
// Source adapters
|
|
837
|
+
// Source adapters — delegates to SourceRegistry
|
|
728
838
|
// -----------------------------------------------------------------------
|
|
729
839
|
/**
|
|
730
840
|
* Register a named source adapter for adapter-sourced pulls.
|
|
@@ -733,7 +843,7 @@ var SyncGateway = class {
|
|
|
733
843
|
* @param adapter - The database adapter to register.
|
|
734
844
|
*/
|
|
735
845
|
registerSource(name, adapter) {
|
|
736
|
-
this.
|
|
846
|
+
this.sources.register(name, adapter);
|
|
737
847
|
}
|
|
738
848
|
/**
|
|
739
849
|
* Unregister a named source adapter.
|
|
@@ -741,7 +851,7 @@ var SyncGateway = class {
|
|
|
741
851
|
* @param name - The source name to remove.
|
|
742
852
|
*/
|
|
743
853
|
unregisterSource(name) {
|
|
744
|
-
|
|
854
|
+
this.sources.unregister(name);
|
|
745
855
|
}
|
|
746
856
|
/**
|
|
747
857
|
* List all registered source adapter names.
|
|
@@ -749,7 +859,7 @@ var SyncGateway = class {
|
|
|
749
859
|
* @returns Array of registered source adapter names.
|
|
750
860
|
*/
|
|
751
861
|
listSources() {
|
|
752
|
-
return
|
|
862
|
+
return this.sources.list();
|
|
753
863
|
}
|
|
754
864
|
// -----------------------------------------------------------------------
|
|
755
865
|
// Buffer queries
|
|
@@ -789,13 +899,17 @@ var SyncGateway = class {
|
|
|
789
899
|
};
|
|
790
900
|
|
|
791
901
|
// ../gateway/src/validation.ts
|
|
792
|
-
function
|
|
793
|
-
let body;
|
|
902
|
+
function parseJson(raw, reviver) {
|
|
794
903
|
try {
|
|
795
|
-
|
|
904
|
+
return Ok(JSON.parse(raw, reviver));
|
|
796
905
|
} catch {
|
|
797
906
|
return Err({ status: 400, message: "Invalid JSON body" });
|
|
798
907
|
}
|
|
908
|
+
}
|
|
909
|
+
function validatePushBody(raw, headerClientId) {
|
|
910
|
+
const parsed = parseJson(raw, bigintReviver);
|
|
911
|
+
if (!parsed.ok) return parsed;
|
|
912
|
+
const body = parsed.value;
|
|
799
913
|
if (!body.clientId || !Array.isArray(body.deltas)) {
|
|
800
914
|
return Err({ status: 400, message: "Missing required fields: clientId, deltas" });
|
|
801
915
|
}
|
|
@@ -840,12 +954,9 @@ function parsePullParams(params) {
|
|
|
840
954
|
return Ok(msg);
|
|
841
955
|
}
|
|
842
956
|
function validateActionBody(raw, headerClientId) {
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
} catch {
|
|
847
|
-
return Err({ status: 400, message: "Invalid JSON body" });
|
|
848
|
-
}
|
|
957
|
+
const parsed = parseJson(raw, bigintReviver);
|
|
958
|
+
if (!parsed.ok) return parsed;
|
|
959
|
+
const body = parsed.value;
|
|
849
960
|
if (!body.clientId || !Array.isArray(body.actions)) {
|
|
850
961
|
return Err({ status: 400, message: "Missing required fields: clientId, actions" });
|
|
851
962
|
}
|
|
@@ -858,12 +969,9 @@ function validateActionBody(raw, headerClientId) {
|
|
|
858
969
|
return Ok(body);
|
|
859
970
|
}
|
|
860
971
|
function validateSchemaBody(raw) {
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
} catch {
|
|
865
|
-
return Err({ status: 400, message: "Invalid JSON body" });
|
|
866
|
-
}
|
|
972
|
+
const parsed = parseJson(raw);
|
|
973
|
+
if (!parsed.ok) return parsed;
|
|
974
|
+
const schema = parsed.value;
|
|
867
975
|
if (!schema.table || !Array.isArray(schema.columns)) {
|
|
868
976
|
return Err({ status: 400, message: "Missing required fields: table, columns" });
|
|
869
977
|
}
|
|
@@ -1000,12 +1108,11 @@ async function handleSaveSchema(raw, store, gatewayId) {
|
|
|
1000
1108
|
return { status: 200, body: { saved: true } };
|
|
1001
1109
|
}
|
|
1002
1110
|
async function handleSaveSyncRules(raw, store, gatewayId) {
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
} catch {
|
|
1007
|
-
return { status: 400, body: { error: "Invalid JSON body" } };
|
|
1111
|
+
const parsed = parseJson(raw);
|
|
1112
|
+
if (!parsed.ok) {
|
|
1113
|
+
return { status: parsed.error.status, body: { error: parsed.error.message } };
|
|
1008
1114
|
}
|
|
1115
|
+
const config = parsed.value;
|
|
1009
1116
|
const validation = validateSyncRules(config);
|
|
1010
1117
|
if (!validation.ok) {
|
|
1011
1118
|
return { status: 400, body: { error: validation.error.message } };
|
|
@@ -1014,12 +1121,11 @@ async function handleSaveSyncRules(raw, store, gatewayId) {
|
|
|
1014
1121
|
return { status: 200, body: { saved: true } };
|
|
1015
1122
|
}
|
|
1016
1123
|
async function handleRegisterConnector(raw, store) {
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
body
|
|
1020
|
-
} catch {
|
|
1021
|
-
return { status: 400, body: { error: "Invalid JSON body" } };
|
|
1124
|
+
const parsed = parseJson(raw);
|
|
1125
|
+
if (!parsed.ok) {
|
|
1126
|
+
return { status: parsed.error.status, body: { error: parsed.error.message } };
|
|
1022
1127
|
}
|
|
1128
|
+
const body = parsed.value;
|
|
1023
1129
|
const validation = validateConnectorConfig(body);
|
|
1024
1130
|
if (!validation.ok) {
|
|
1025
1131
|
return { status: 400, body: { error: validation.error.message } };
|
|
@@ -1146,7 +1252,10 @@ export {
|
|
|
1146
1252
|
hlcRange,
|
|
1147
1253
|
flushEntries,
|
|
1148
1254
|
commitToCatalogue,
|
|
1255
|
+
FlushCoordinator,
|
|
1256
|
+
SourceRegistry,
|
|
1149
1257
|
SyncGateway,
|
|
1258
|
+
parseJson,
|
|
1150
1259
|
validatePushBody,
|
|
1151
1260
|
parsePullParams,
|
|
1152
1261
|
validateActionBody,
|
|
@@ -1166,4 +1275,4 @@ export {
|
|
|
1166
1275
|
handleMetrics,
|
|
1167
1276
|
SchemaManager
|
|
1168
1277
|
};
|
|
1169
|
-
//# sourceMappingURL=chunk-
|
|
1278
|
+
//# sourceMappingURL=chunk-JI4C4R5H.js.map
|