@powerhousedao/reactor 6.0.0-dev.69 → 6.0.0-dev.77
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/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +19998 -62
- package/dist/src/sync/index.d.ts +1 -1
- package/dist/src/sync/index.d.ts.map +1 -1
- package/dist/src/sync/sync-manager.d.ts.map +1 -1
- package/dist/src/sync/types.d.ts +11 -0
- package/dist/src/sync/types.d.ts.map +1 -1
- package/package.json +17 -10
- package/dist/src/actions/index.js +0 -76
- package/dist/src/actions/index.js.map +0 -1
- package/dist/src/cache/buffer/ring-buffer.js +0 -69
- package/dist/src/cache/buffer/ring-buffer.js.map +0 -1
- package/dist/src/cache/collection-membership-cache.js +0 -33
- package/dist/src/cache/collection-membership-cache.js.map +0 -1
- package/dist/src/cache/document-meta-cache-types.js +0 -2
- package/dist/src/cache/document-meta-cache-types.js.map +0 -1
- package/dist/src/cache/document-meta-cache.js +0 -129
- package/dist/src/cache/document-meta-cache.js.map +0 -1
- package/dist/src/cache/index.js +0 -2
- package/dist/src/cache/index.js.map +0 -1
- package/dist/src/cache/kysely-operation-index.js +0 -345
- package/dist/src/cache/kysely-operation-index.js.map +0 -1
- package/dist/src/cache/kysely-write-cache.js +0 -411
- package/dist/src/cache/kysely-write-cache.js.map +0 -1
- package/dist/src/cache/lru/lru-tracker.js +0 -96
- package/dist/src/cache/lru/lru-tracker.js.map +0 -1
- package/dist/src/cache/operation-index-types.js +0 -4
- package/dist/src/cache/operation-index-types.js.map +0 -1
- package/dist/src/cache/write/interfaces.js +0 -2
- package/dist/src/cache/write/interfaces.js.map +0 -1
- package/dist/src/cache/write-cache-types.js +0 -2
- package/dist/src/cache/write-cache-types.js.map +0 -1
- package/dist/src/client/reactor-client.js +0 -497
- package/dist/src/client/reactor-client.js.map +0 -1
- package/dist/src/client/types.js +0 -14
- package/dist/src/client/types.js.map +0 -1
- package/dist/src/core/reactor-builder.js +0 -306
- package/dist/src/core/reactor-builder.js.map +0 -1
- package/dist/src/core/reactor-client-builder.js +0 -132
- package/dist/src/core/reactor-client-builder.js.map +0 -1
- package/dist/src/core/reactor.js +0 -640
- package/dist/src/core/reactor.js.map +0 -1
- package/dist/src/core/types.js +0 -2
- package/dist/src/core/types.js.map +0 -1
- package/dist/src/core/utils.js +0 -225
- package/dist/src/core/utils.js.map +0 -1
- package/dist/src/events/event-bus.js +0 -53
- package/dist/src/events/event-bus.js.map +0 -1
- package/dist/src/events/interfaces.js +0 -2
- package/dist/src/events/interfaces.js.map +0 -1
- package/dist/src/events/types.js +0 -30
- package/dist/src/events/types.js.map +0 -1
- package/dist/src/executor/document-action-handler.js +0 -356
- package/dist/src/executor/document-action-handler.js.map +0 -1
- package/dist/src/executor/interfaces.js +0 -2
- package/dist/src/executor/interfaces.js.map +0 -1
- package/dist/src/executor/signature-verifier.js +0 -70
- package/dist/src/executor/signature-verifier.js.map +0 -1
- package/dist/src/executor/simple-job-executor-manager.js +0 -345
- package/dist/src/executor/simple-job-executor-manager.js.map +0 -1
- package/dist/src/executor/simple-job-executor.js +0 -423
- package/dist/src/executor/simple-job-executor.js.map +0 -1
- package/dist/src/executor/types.js +0 -11
- package/dist/src/executor/types.js.map +0 -1
- package/dist/src/executor/util.js +0 -230
- package/dist/src/executor/util.js.map +0 -1
- package/dist/src/index.js.map +0 -1
- package/dist/src/job-tracker/in-memory-job-tracker.js +0 -114
- package/dist/src/job-tracker/in-memory-job-tracker.js.map +0 -1
- package/dist/src/job-tracker/index.js +0 -2
- package/dist/src/job-tracker/index.js.map +0 -1
- package/dist/src/job-tracker/interfaces.js +0 -2
- package/dist/src/job-tracker/interfaces.js.map +0 -1
- package/dist/src/logging/console.js +0 -2
- package/dist/src/logging/console.js.map +0 -1
- package/dist/src/logging/types.js +0 -2
- package/dist/src/logging/types.js.map +0 -1
- package/dist/src/processors/index.js +0 -2
- package/dist/src/processors/index.js.map +0 -1
- package/dist/src/processors/processor-manager.js +0 -165
- package/dist/src/processors/processor-manager.js.map +0 -1
- package/dist/src/processors/relational/types.js +0 -2
- package/dist/src/processors/relational/types.js.map +0 -1
- package/dist/src/processors/relational/utils.js +0 -2
- package/dist/src/processors/relational/utils.js.map +0 -1
- package/dist/src/processors/utils.js +0 -59
- package/dist/src/processors/utils.js.map +0 -1
- package/dist/src/queue/interfaces.js +0 -2
- package/dist/src/queue/interfaces.js.map +0 -1
- package/dist/src/queue/job-execution-handle.js +0 -71
- package/dist/src/queue/job-execution-handle.js.map +0 -1
- package/dist/src/queue/queue.js +0 -493
- package/dist/src/queue/queue.js.map +0 -1
- package/dist/src/queue/types.js +0 -19
- package/dist/src/queue/types.js.map +0 -1
- package/dist/src/read-models/base-read-model.js +0 -143
- package/dist/src/read-models/base-read-model.js.map +0 -1
- package/dist/src/read-models/coordinator.js +0 -72
- package/dist/src/read-models/coordinator.js.map +0 -1
- package/dist/src/read-models/document-view.js +0 -457
- package/dist/src/read-models/document-view.js.map +0 -1
- package/dist/src/read-models/interfaces.js +0 -2
- package/dist/src/read-models/interfaces.js.map +0 -1
- package/dist/src/read-models/types.js +0 -2
- package/dist/src/read-models/types.js.map +0 -1
- package/dist/src/registry/document-model-resolver.js +0 -81
- package/dist/src/registry/document-model-resolver.js.map +0 -1
- package/dist/src/registry/implementation.js +0 -226
- package/dist/src/registry/implementation.js.map +0 -1
- package/dist/src/registry/index.js +0 -3
- package/dist/src/registry/index.js.map +0 -1
- package/dist/src/registry/interfaces.js +0 -2
- package/dist/src/registry/interfaces.js.map +0 -1
- package/dist/src/shared/awaiter.js +0 -123
- package/dist/src/shared/awaiter.js.map +0 -1
- package/dist/src/shared/collect-all-pages.js +0 -17
- package/dist/src/shared/collect-all-pages.js.map +0 -1
- package/dist/src/shared/consistency-tracker.js +0 -123
- package/dist/src/shared/consistency-tracker.js.map +0 -1
- package/dist/src/shared/drive-url.js +0 -17
- package/dist/src/shared/drive-url.js.map +0 -1
- package/dist/src/shared/errors.js +0 -93
- package/dist/src/shared/errors.js.map +0 -1
- package/dist/src/shared/factories.js +0 -41
- package/dist/src/shared/factories.js.map +0 -1
- package/dist/src/shared/types.js +0 -38
- package/dist/src/shared/types.js.map +0 -1
- package/dist/src/shared/utils.js +0 -8
- package/dist/src/shared/utils.js.map +0 -1
- package/dist/src/signer/passthrough-signer.js +0 -17
- package/dist/src/signer/passthrough-signer.js.map +0 -1
- package/dist/src/signer/types.js +0 -2
- package/dist/src/signer/types.js.map +0 -1
- package/dist/src/storage/index.js +0 -3
- package/dist/src/storage/index.js.map +0 -1
- package/dist/src/storage/interfaces.js +0 -29
- package/dist/src/storage/interfaces.js.map +0 -1
- package/dist/src/storage/kysely/document-indexer.js +0 -421
- package/dist/src/storage/kysely/document-indexer.js.map +0 -1
- package/dist/src/storage/kysely/keyframe-store.js +0 -64
- package/dist/src/storage/kysely/keyframe-store.js.map +0 -1
- package/dist/src/storage/kysely/store.js +0 -264
- package/dist/src/storage/kysely/store.js.map +0 -1
- package/dist/src/storage/kysely/sync-cursor-storage.js +0 -97
- package/dist/src/storage/kysely/sync-cursor-storage.js.map +0 -1
- package/dist/src/storage/kysely/sync-dead-letter-storage.js +0 -110
- package/dist/src/storage/kysely/sync-dead-letter-storage.js.map +0 -1
- package/dist/src/storage/kysely/sync-remote-storage.js +0 -133
- package/dist/src/storage/kysely/sync-remote-storage.js.map +0 -1
- package/dist/src/storage/kysely/types.js +0 -2
- package/dist/src/storage/kysely/types.js.map +0 -1
- package/dist/src/storage/migrations/001_create_operation_table.js +0 -41
- package/dist/src/storage/migrations/001_create_operation_table.js.map +0 -1
- package/dist/src/storage/migrations/002_create_keyframe_table.js +0 -27
- package/dist/src/storage/migrations/002_create_keyframe_table.js.map +0 -1
- package/dist/src/storage/migrations/003_create_document_table.js +0 -10
- package/dist/src/storage/migrations/003_create_document_table.js.map +0 -1
- package/dist/src/storage/migrations/004_create_document_relationship_table.js +0 -35
- package/dist/src/storage/migrations/004_create_document_relationship_table.js.map +0 -1
- package/dist/src/storage/migrations/005_create_indexer_state_table.js +0 -10
- package/dist/src/storage/migrations/005_create_indexer_state_table.js.map +0 -1
- package/dist/src/storage/migrations/006_create_document_snapshot_table.js +0 -49
- package/dist/src/storage/migrations/006_create_document_snapshot_table.js.map +0 -1
- package/dist/src/storage/migrations/007_create_slug_mapping_table.js +0 -24
- package/dist/src/storage/migrations/007_create_slug_mapping_table.js.map +0 -1
- package/dist/src/storage/migrations/008_create_view_state_table.js +0 -10
- package/dist/src/storage/migrations/008_create_view_state_table.js.map +0 -1
- package/dist/src/storage/migrations/009_create_operation_index_tables.js +0 -50
- package/dist/src/storage/migrations/009_create_operation_index_tables.js.map +0 -1
- package/dist/src/storage/migrations/010_create_sync_tables.js +0 -43
- package/dist/src/storage/migrations/010_create_sync_tables.js.map +0 -1
- package/dist/src/storage/migrations/011_add_cursor_type_column.js +0 -29
- package/dist/src/storage/migrations/011_add_cursor_type_column.js.map +0 -1
- package/dist/src/storage/migrations/012_add_source_remote_column.js +0 -7
- package/dist/src/storage/migrations/012_add_source_remote_column.js.map +0 -1
- package/dist/src/storage/migrations/013_create_sync_dead_letters_table.js +0 -24
- package/dist/src/storage/migrations/013_create_sync_dead_letters_table.js.map +0 -1
- package/dist/src/storage/migrations/index.js +0 -3
- package/dist/src/storage/migrations/index.js.map +0 -1
- package/dist/src/storage/migrations/migrator.js +0 -84
- package/dist/src/storage/migrations/migrator.js.map +0 -1
- package/dist/src/storage/migrations/run-migrations.js +0 -58
- package/dist/src/storage/migrations/run-migrations.js.map +0 -1
- package/dist/src/storage/migrations/types.js +0 -2
- package/dist/src/storage/migrations/types.js.map +0 -1
- package/dist/src/storage/txn.js +0 -42
- package/dist/src/storage/txn.js.map +0 -1
- package/dist/src/subs/default-error-handler.js +0 -27
- package/dist/src/subs/default-error-handler.js.map +0 -1
- package/dist/src/subs/react-subscription-manager.js +0 -185
- package/dist/src/subs/react-subscription-manager.js.map +0 -1
- package/dist/src/subs/subscription-notification-read-model.js +0 -62
- package/dist/src/subs/subscription-notification-read-model.js.map +0 -1
- package/dist/src/subs/types.js +0 -2
- package/dist/src/subs/types.js.map +0 -1
- package/dist/src/sync/batch-aggregator.js +0 -94
- package/dist/src/sync/batch-aggregator.js.map +0 -1
- package/dist/src/sync/buffered-mailbox.js +0 -164
- package/dist/src/sync/buffered-mailbox.js.map +0 -1
- package/dist/src/sync/channels/gql-req-channel.js +0 -548
- package/dist/src/sync/channels/gql-req-channel.js.map +0 -1
- package/dist/src/sync/channels/gql-request-channel-factory.js +0 -105
- package/dist/src/sync/channels/gql-request-channel-factory.js.map +0 -1
- package/dist/src/sync/channels/gql-res-channel.js +0 -79
- package/dist/src/sync/channels/gql-res-channel.js.map +0 -1
- package/dist/src/sync/channels/gql-response-channel-factory.js +0 -14
- package/dist/src/sync/channels/gql-response-channel-factory.js.map +0 -1
- package/dist/src/sync/channels/index.js +0 -8
- package/dist/src/sync/channels/index.js.map +0 -1
- package/dist/src/sync/channels/interval-poll-timer.js +0 -123
- package/dist/src/sync/channels/interval-poll-timer.js.map +0 -1
- package/dist/src/sync/channels/poll-timer.js +0 -2
- package/dist/src/sync/channels/poll-timer.js.map +0 -1
- package/dist/src/sync/channels/utils.js +0 -161
- package/dist/src/sync/channels/utils.js.map +0 -1
- package/dist/src/sync/errors.js +0 -17
- package/dist/src/sync/errors.js.map +0 -1
- package/dist/src/sync/index.js +0 -11
- package/dist/src/sync/index.js.map +0 -1
- package/dist/src/sync/interfaces.js +0 -2
- package/dist/src/sync/interfaces.js.map +0 -1
- package/dist/src/sync/mailbox.js +0 -142
- package/dist/src/sync/mailbox.js.map +0 -1
- package/dist/src/sync/sync-awaiter.js +0 -124
- package/dist/src/sync/sync-awaiter.js.map +0 -1
- package/dist/src/sync/sync-builder.js +0 -52
- package/dist/src/sync/sync-builder.js.map +0 -1
- package/dist/src/sync/sync-manager.js +0 -447
- package/dist/src/sync/sync-manager.js.map +0 -1
- package/dist/src/sync/sync-operation.js +0 -70
- package/dist/src/sync/sync-operation.js.map +0 -1
- package/dist/src/sync/sync-status-tracker.js +0 -137
- package/dist/src/sync/sync-status-tracker.js.map +0 -1
- package/dist/src/sync/types.js +0 -31
- package/dist/src/sync/types.js.map +0 -1
- package/dist/src/sync/utils.js +0 -283
- package/dist/src/sync/utils.js.map +0 -1
- package/dist/src/utils/reshuffle.js +0 -91
- package/dist/src/utils/reshuffle.js.map +0 -1
|
@@ -1,548 +0,0 @@
|
|
|
1
|
-
import { BufferedMailbox } from "../buffered-mailbox.js";
|
|
2
|
-
import { ChannelError } from "../errors.js";
|
|
3
|
-
import { Mailbox } from "../mailbox.js";
|
|
4
|
-
import { SyncOperation } from "../sync-operation.js";
|
|
5
|
-
import { ChannelErrorSource } from "../types.js";
|
|
6
|
-
import { consolidateSyncOperations, sortEnvelopesByFirstOperationTimestamp, trimMailboxFromAckOrdinal, } from "../utils.js";
|
|
7
|
-
import { calculateBackoffDelay } from "./interval-poll-timer.js";
|
|
8
|
-
import { envelopesToSyncOperations, getLatestAppliedOrdinal, serializeEnvelope, } from "./utils.js";
|
|
9
|
-
/**
|
|
10
|
-
* GraphQL-based synchronization channel for network communication between reactors.
|
|
11
|
-
*/
|
|
12
|
-
export class GqlRequestChannel {
|
|
13
|
-
logger;
|
|
14
|
-
inbox;
|
|
15
|
-
outbox;
|
|
16
|
-
deadLetter;
|
|
17
|
-
config;
|
|
18
|
-
bufferedOutbox;
|
|
19
|
-
channelId;
|
|
20
|
-
remoteName;
|
|
21
|
-
cursorStorage;
|
|
22
|
-
operationIndex;
|
|
23
|
-
pollTimer;
|
|
24
|
-
isShutdown;
|
|
25
|
-
failureCount;
|
|
26
|
-
lastSuccessUtcMs;
|
|
27
|
-
lastFailureUtcMs;
|
|
28
|
-
lastPersistedInboxOrdinal = 0;
|
|
29
|
-
lastPersistedOutboxOrdinal = 0;
|
|
30
|
-
pushFailureCount = 0;
|
|
31
|
-
pushRetryTimer = null;
|
|
32
|
-
pushBlocked = false;
|
|
33
|
-
constructor(logger, channelId, remoteName, cursorStorage, config, operationIndex, pollTimer) {
|
|
34
|
-
this.logger = logger;
|
|
35
|
-
this.channelId = channelId;
|
|
36
|
-
this.remoteName = remoteName;
|
|
37
|
-
this.cursorStorage = cursorStorage;
|
|
38
|
-
this.operationIndex = operationIndex;
|
|
39
|
-
this.pollTimer = pollTimer;
|
|
40
|
-
this.config = {
|
|
41
|
-
url: config.url,
|
|
42
|
-
jwtHandler: config.jwtHandler,
|
|
43
|
-
fetchFn: config.fetchFn,
|
|
44
|
-
collectionId: config.collectionId,
|
|
45
|
-
filter: config.filter,
|
|
46
|
-
retryBaseDelayMs: config.retryBaseDelayMs,
|
|
47
|
-
retryMaxDelayMs: config.retryMaxDelayMs,
|
|
48
|
-
};
|
|
49
|
-
this.isShutdown = false;
|
|
50
|
-
this.failureCount = 0;
|
|
51
|
-
this.inbox = new Mailbox();
|
|
52
|
-
this.bufferedOutbox = new BufferedMailbox(500, 25);
|
|
53
|
-
this.outbox = this.bufferedOutbox;
|
|
54
|
-
this.deadLetter = new Mailbox();
|
|
55
|
-
// when a dead letter is added, stop polling and cancel any pending push retry
|
|
56
|
-
this.deadLetter.onAdded(() => {
|
|
57
|
-
this.pollTimer.stop();
|
|
58
|
-
if (this.pushRetryTimer) {
|
|
59
|
-
clearTimeout(this.pushRetryTimer);
|
|
60
|
-
this.pushRetryTimer = null;
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
// when sync ops are added to the outbox, push them to the remote
|
|
64
|
-
this.outbox.onAdded((syncOps) => {
|
|
65
|
-
if (this.isShutdown)
|
|
66
|
-
return;
|
|
67
|
-
if (this.pushBlocked)
|
|
68
|
-
return; // ops stay in outbox, included in next retry
|
|
69
|
-
if (this.deadLetter.items.length > 0)
|
|
70
|
-
return;
|
|
71
|
-
this.attemptPush(syncOps);
|
|
72
|
-
});
|
|
73
|
-
// Instead of listening to syncops directly for cursor updates, we listen
|
|
74
|
-
// to the mailbox. This is for efficiency: many syncops may fire on a trim,
|
|
75
|
-
// but only one onRemoved callback will be fired for the batch.
|
|
76
|
-
this.outbox.onRemoved((syncOps) => {
|
|
77
|
-
const maxOrdinal = getLatestAppliedOrdinal(syncOps);
|
|
78
|
-
if (maxOrdinal > this.lastPersistedOutboxOrdinal) {
|
|
79
|
-
this.lastPersistedOutboxOrdinal = maxOrdinal;
|
|
80
|
-
this.cursorStorage
|
|
81
|
-
.upsert({
|
|
82
|
-
remoteName: this.remoteName,
|
|
83
|
-
cursorType: "outbox",
|
|
84
|
-
cursorOrdinal: maxOrdinal,
|
|
85
|
-
lastSyncedAtUtcMs: Date.now(),
|
|
86
|
-
})
|
|
87
|
-
.catch((error) => {
|
|
88
|
-
this.logger.error("Failed to update outbox cursor for @ChannelId! This means that future application runs may resend duplicate operations. This is recoverable (with deduplication protection), but not-optimal: @Error", this.channelId, error);
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
this.inbox.onRemoved((syncOps) => {
|
|
93
|
-
const maxOrdinal = getLatestAppliedOrdinal(syncOps);
|
|
94
|
-
if (maxOrdinal > this.lastPersistedInboxOrdinal) {
|
|
95
|
-
this.lastPersistedInboxOrdinal = maxOrdinal;
|
|
96
|
-
this.cursorStorage
|
|
97
|
-
.upsert({
|
|
98
|
-
remoteName: this.remoteName,
|
|
99
|
-
cursorType: "inbox",
|
|
100
|
-
cursorOrdinal: maxOrdinal,
|
|
101
|
-
lastSyncedAtUtcMs: Date.now(),
|
|
102
|
-
})
|
|
103
|
-
.catch((error) => {
|
|
104
|
-
this.logger.error("Failed to update inbox cursor for @ChannelId! This is unlikely to cause a problem, but not-optimal: @Error", this.channelId, error);
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Shuts down the channel and prevents further operations.
|
|
111
|
-
*/
|
|
112
|
-
shutdown() {
|
|
113
|
-
this.bufferedOutbox.flush();
|
|
114
|
-
this.isShutdown = true;
|
|
115
|
-
this.pollTimer.stop();
|
|
116
|
-
if (this.pushRetryTimer) {
|
|
117
|
-
clearTimeout(this.pushRetryTimer);
|
|
118
|
-
this.pushRetryTimer = null;
|
|
119
|
-
}
|
|
120
|
-
return Promise.resolve();
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Initializes the channel by registering it on the remote server and starting polling.
|
|
124
|
-
*/
|
|
125
|
-
async init() {
|
|
126
|
-
await this.touchRemoteChannel();
|
|
127
|
-
// get cursors -- these are the last acknowledged ordinals for the inbox and outbox
|
|
128
|
-
const cursors = await this.cursorStorage.list(this.remoteName);
|
|
129
|
-
const inboxOrdinal = cursors.find((c) => c.cursorType === "inbox")?.cursorOrdinal ?? 0;
|
|
130
|
-
const outboxOrdinal = cursors.find((c) => c.cursorType === "outbox")?.cursorOrdinal ?? 0;
|
|
131
|
-
this.inbox.init(inboxOrdinal);
|
|
132
|
-
this.outbox.init(outboxOrdinal);
|
|
133
|
-
this.lastPersistedInboxOrdinal = inboxOrdinal;
|
|
134
|
-
this.lastPersistedOutboxOrdinal = outboxOrdinal;
|
|
135
|
-
this.pollTimer.setDelegate(() => this.poll());
|
|
136
|
-
this.pollTimer.start();
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Polls the remote for new sync envelopes.
|
|
140
|
-
*/
|
|
141
|
-
async poll() {
|
|
142
|
-
if (this.isShutdown) {
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
let response;
|
|
146
|
-
try {
|
|
147
|
-
response = await this.pollSyncEnvelopes(this.inbox.ackOrdinal, this.inbox.latestOrdinal);
|
|
148
|
-
}
|
|
149
|
-
catch (error) {
|
|
150
|
-
if (!this.handlePollError(error)) {
|
|
151
|
-
throw error;
|
|
152
|
-
}
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
const { envelopes, ackOrdinal, deadLetters } = response;
|
|
156
|
-
// first: trim outbox
|
|
157
|
-
if (ackOrdinal > 0) {
|
|
158
|
-
trimMailboxFromAckOrdinal(this.outbox, ackOrdinal);
|
|
159
|
-
}
|
|
160
|
-
// todo: Is this necessary? Outbox items should have been sorted when returned.
|
|
161
|
-
const sortedEnvelopes = sortEnvelopesByFirstOperationTimestamp(envelopes);
|
|
162
|
-
// convert the envelopes to sync operations
|
|
163
|
-
const allSyncOps = [];
|
|
164
|
-
for (const envelope of sortedEnvelopes) {
|
|
165
|
-
if (envelope.type.toLowerCase() === "operations" && envelope.operations) {
|
|
166
|
-
const syncOps = envelopesToSyncOperations(envelope, this.remoteName);
|
|
167
|
-
for (const syncOp of syncOps) {
|
|
168
|
-
syncOp.transported();
|
|
169
|
-
}
|
|
170
|
-
allSyncOps.push(...syncOps);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
// merge SyncOps sharing the same (documentId, scope, branch) so
|
|
174
|
-
// multiple polled envelopes for one document become a single load job
|
|
175
|
-
const consolidated = allSyncOps.length > 1
|
|
176
|
-
? consolidateSyncOperations(allSyncOps)
|
|
177
|
-
: allSyncOps;
|
|
178
|
-
if (consolidated.length > 0) {
|
|
179
|
-
this.inbox.add(...consolidated);
|
|
180
|
-
}
|
|
181
|
-
// handle dead letters from the remote
|
|
182
|
-
if (deadLetters.length > 0) {
|
|
183
|
-
this.handleRemoteDeadLetters(deadLetters);
|
|
184
|
-
}
|
|
185
|
-
this.lastSuccessUtcMs = Date.now();
|
|
186
|
-
this.failureCount = 0;
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* Handles dead letters reported by the remote server.
|
|
190
|
-
* Creates local dead letter SyncOperations so the channel quiesces.
|
|
191
|
-
*/
|
|
192
|
-
handleRemoteDeadLetters(deadLetters) {
|
|
193
|
-
for (const dl of deadLetters) {
|
|
194
|
-
this.logger.error("Remote dead letter on @ChannelId: document @DocumentId failed with: @Error", this.channelId, dl.documentId, dl.error);
|
|
195
|
-
}
|
|
196
|
-
const syncOps = [];
|
|
197
|
-
for (const dl of deadLetters) {
|
|
198
|
-
const syncOp = new SyncOperation(crypto.randomUUID(), dl.jobId, [], this.remoteName, dl.documentId, dl.scopes, dl.branch, []);
|
|
199
|
-
syncOp.failed(new ChannelError(ChannelErrorSource.Outbox, new Error(dl.error)));
|
|
200
|
-
syncOps.push(syncOp);
|
|
201
|
-
}
|
|
202
|
-
this.deadLetter.add(...syncOps);
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* Handles polling errors with exponential backoff.
|
|
206
|
-
*/
|
|
207
|
-
handlePollError(error) {
|
|
208
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
209
|
-
if (err.message.includes("Channel not found")) {
|
|
210
|
-
this.recoverFromChannelNotFound();
|
|
211
|
-
return true;
|
|
212
|
-
}
|
|
213
|
-
this.failureCount++;
|
|
214
|
-
this.lastFailureUtcMs = Date.now();
|
|
215
|
-
const channelError = new ChannelError(ChannelErrorSource.Inbox, err);
|
|
216
|
-
this.logger.error("GqlChannel poll error (@FailureCount): @Error", this.failureCount, channelError);
|
|
217
|
-
return false;
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Recovers from a "Channel not found" error by re-registering and restarting polling.
|
|
221
|
-
*/
|
|
222
|
-
recoverFromChannelNotFound() {
|
|
223
|
-
this.logger.info("GqlChannel @ChannelId not found on remote, re-registering...", this.channelId);
|
|
224
|
-
this.pollTimer.stop();
|
|
225
|
-
void this.touchRemoteChannel()
|
|
226
|
-
.then(() => {
|
|
227
|
-
this.logger.info("GqlChannel @ChannelId re-registered successfully", this.channelId);
|
|
228
|
-
this.failureCount = 0;
|
|
229
|
-
this.pollTimer.start();
|
|
230
|
-
})
|
|
231
|
-
.catch((recoveryError) => {
|
|
232
|
-
this.logger.error("GqlChannel @ChannelId failed to re-register: @Error", this.channelId, recoveryError);
|
|
233
|
-
this.failureCount++;
|
|
234
|
-
this.lastFailureUtcMs = Date.now();
|
|
235
|
-
this.pollTimer.start();
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* Queries the remote GraphQL endpoint for sync envelopes.
|
|
240
|
-
*/
|
|
241
|
-
async pollSyncEnvelopes(ackOrdinal, latestOrdinal) {
|
|
242
|
-
const query = `
|
|
243
|
-
query PollSyncEnvelopes($channelId: String!, $outboxAck: Int!, $outboxLatest: Int!) {
|
|
244
|
-
pollSyncEnvelopes(channelId: $channelId, outboxAck: $outboxAck, outboxLatest: $outboxLatest) {
|
|
245
|
-
envelopes {
|
|
246
|
-
type
|
|
247
|
-
channelMeta {
|
|
248
|
-
id
|
|
249
|
-
}
|
|
250
|
-
operations {
|
|
251
|
-
operation {
|
|
252
|
-
index
|
|
253
|
-
timestampUtcMs
|
|
254
|
-
hash
|
|
255
|
-
skip
|
|
256
|
-
error
|
|
257
|
-
id
|
|
258
|
-
action {
|
|
259
|
-
id
|
|
260
|
-
type
|
|
261
|
-
timestampUtcMs
|
|
262
|
-
input
|
|
263
|
-
scope
|
|
264
|
-
attachments {
|
|
265
|
-
data
|
|
266
|
-
mimeType
|
|
267
|
-
hash
|
|
268
|
-
extension
|
|
269
|
-
fileName
|
|
270
|
-
}
|
|
271
|
-
context {
|
|
272
|
-
signer {
|
|
273
|
-
user {
|
|
274
|
-
address
|
|
275
|
-
networkId
|
|
276
|
-
chainId
|
|
277
|
-
}
|
|
278
|
-
app {
|
|
279
|
-
name
|
|
280
|
-
key
|
|
281
|
-
}
|
|
282
|
-
signatures
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
context {
|
|
288
|
-
documentId
|
|
289
|
-
documentType
|
|
290
|
-
scope
|
|
291
|
-
branch
|
|
292
|
-
ordinal
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
cursor {
|
|
296
|
-
remoteName
|
|
297
|
-
cursorOrdinal
|
|
298
|
-
lastSyncedAtUtcMs
|
|
299
|
-
}
|
|
300
|
-
key
|
|
301
|
-
dependsOn
|
|
302
|
-
}
|
|
303
|
-
ackOrdinal
|
|
304
|
-
deadLetters {
|
|
305
|
-
documentId
|
|
306
|
-
error
|
|
307
|
-
jobId
|
|
308
|
-
branch
|
|
309
|
-
scopes
|
|
310
|
-
operationCount
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
`;
|
|
315
|
-
const variables = {
|
|
316
|
-
channelId: this.channelId,
|
|
317
|
-
outboxAck: ackOrdinal,
|
|
318
|
-
outboxLatest: latestOrdinal,
|
|
319
|
-
};
|
|
320
|
-
const response = await this.executeGraphQL(query, variables);
|
|
321
|
-
return {
|
|
322
|
-
envelopes: response.pollSyncEnvelopes.envelopes,
|
|
323
|
-
ackOrdinal: response.pollSyncEnvelopes.ackOrdinal,
|
|
324
|
-
deadLetters: response.pollSyncEnvelopes.deadLetters ?? [],
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
/**
|
|
328
|
-
* Registers or updates this channel on the remote server via GraphQL mutation.
|
|
329
|
-
*/
|
|
330
|
-
async touchRemoteChannel() {
|
|
331
|
-
let sinceTimestampUtcMs = "0";
|
|
332
|
-
try {
|
|
333
|
-
const result = await this.operationIndex.getLatestTimestampForCollection(this.config.collectionId);
|
|
334
|
-
if (result) {
|
|
335
|
-
sinceTimestampUtcMs = result;
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
catch {
|
|
339
|
-
// If query fails, use default "0" (sends all operations)
|
|
340
|
-
}
|
|
341
|
-
const mutation = `
|
|
342
|
-
mutation TouchChannel($input: TouchChannelInput!) {
|
|
343
|
-
touchChannel(input: $input)
|
|
344
|
-
}
|
|
345
|
-
`;
|
|
346
|
-
const variables = {
|
|
347
|
-
input: {
|
|
348
|
-
id: this.channelId,
|
|
349
|
-
name: this.channelId,
|
|
350
|
-
collectionId: this.config.collectionId,
|
|
351
|
-
filter: {
|
|
352
|
-
documentId: this.config.filter.documentId,
|
|
353
|
-
scope: this.config.filter.scope,
|
|
354
|
-
branch: this.config.filter.branch,
|
|
355
|
-
},
|
|
356
|
-
sinceTimestampUtcMs,
|
|
357
|
-
},
|
|
358
|
-
};
|
|
359
|
-
await this.executeGraphQL(mutation, variables);
|
|
360
|
-
}
|
|
361
|
-
/**
|
|
362
|
-
* Fire-and-forget push with retry on recoverable errors.
|
|
363
|
-
* On success, clears push blocked state. On recoverable error, blocks
|
|
364
|
-
* further pushes and schedules a retry. On unrecoverable error, moves
|
|
365
|
-
* ops to deadLetter.
|
|
366
|
-
*/
|
|
367
|
-
attemptPush(syncOps) {
|
|
368
|
-
this.pushSyncOperations(syncOps)
|
|
369
|
-
.then(() => {
|
|
370
|
-
this.pushBlocked = false;
|
|
371
|
-
this.pushFailureCount = 0;
|
|
372
|
-
})
|
|
373
|
-
.catch((error) => {
|
|
374
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
375
|
-
if (this.isRecoverablePushError(err)) {
|
|
376
|
-
this.pushFailureCount++;
|
|
377
|
-
this.pushBlocked = true;
|
|
378
|
-
this.logger.error("GqlChannel push failed (attempt @FailureCount), will retry: @Error", this.pushFailureCount, err);
|
|
379
|
-
this.schedulePushRetry();
|
|
380
|
-
}
|
|
381
|
-
else {
|
|
382
|
-
const channelError = new ChannelError(ChannelErrorSource.Outbox, err);
|
|
383
|
-
for (const syncOp of syncOps) {
|
|
384
|
-
syncOp.failed(channelError);
|
|
385
|
-
}
|
|
386
|
-
this.deadLetter.add(...syncOps);
|
|
387
|
-
this.outbox.remove(...syncOps);
|
|
388
|
-
}
|
|
389
|
-
});
|
|
390
|
-
}
|
|
391
|
-
/**
|
|
392
|
-
* Schedules a retry of all current outbox items using exponential backoff.
|
|
393
|
-
*/
|
|
394
|
-
schedulePushRetry() {
|
|
395
|
-
if (this.pushRetryTimer)
|
|
396
|
-
return;
|
|
397
|
-
const delay = calculateBackoffDelay(this.pushFailureCount, this.config.retryBaseDelayMs, this.config.retryMaxDelayMs, Math.random());
|
|
398
|
-
this.pushRetryTimer = setTimeout(() => {
|
|
399
|
-
this.pushRetryTimer = null;
|
|
400
|
-
if (this.isShutdown)
|
|
401
|
-
return;
|
|
402
|
-
const allItems = this.outbox.items;
|
|
403
|
-
if (allItems.length === 0) {
|
|
404
|
-
this.pushBlocked = false;
|
|
405
|
-
this.pushFailureCount = 0;
|
|
406
|
-
return;
|
|
407
|
-
}
|
|
408
|
-
this.attemptPush([...allItems]);
|
|
409
|
-
}, delay);
|
|
410
|
-
}
|
|
411
|
-
/**
|
|
412
|
-
* Returns true if the error is recoverable (transient network/HTTP/parse
|
|
413
|
-
* failure). Returns false for explicit GraphQL server rejections.
|
|
414
|
-
*/
|
|
415
|
-
isRecoverablePushError(error) {
|
|
416
|
-
if (error.message.startsWith("GraphQL errors:"))
|
|
417
|
-
return false;
|
|
418
|
-
if (error.message === "GraphQL response missing data field")
|
|
419
|
-
return false;
|
|
420
|
-
return true;
|
|
421
|
-
}
|
|
422
|
-
/**
|
|
423
|
-
* Pushes multiple sync operations to the remote via a single GraphQL mutation.
|
|
424
|
-
* Creates one SyncEnvelope per SyncOperation with key/dependsOn for batch ordering.
|
|
425
|
-
*/
|
|
426
|
-
async pushSyncOperations(syncOps) {
|
|
427
|
-
for (const syncOp of syncOps) {
|
|
428
|
-
syncOp.started();
|
|
429
|
-
}
|
|
430
|
-
const jobIdToKeys = new Map();
|
|
431
|
-
const envelopes = [];
|
|
432
|
-
for (let i = 0; i < syncOps.length; i++) {
|
|
433
|
-
const syncOp = syncOps[i];
|
|
434
|
-
const key = String(i);
|
|
435
|
-
if (syncOp.jobId) {
|
|
436
|
-
if (!jobIdToKeys.has(syncOp.jobId)) {
|
|
437
|
-
jobIdToKeys.set(syncOp.jobId, []);
|
|
438
|
-
}
|
|
439
|
-
jobIdToKeys.get(syncOp.jobId).push(key);
|
|
440
|
-
}
|
|
441
|
-
const dependsOn = [];
|
|
442
|
-
for (const dep of syncOp.jobDependencies) {
|
|
443
|
-
const depKeys = jobIdToKeys.get(dep);
|
|
444
|
-
if (depKeys) {
|
|
445
|
-
dependsOn.push(...depKeys);
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
this.logger.debug("[PUSH]: @Operations", syncOp.operations.map((op) => `(${op.context.documentId}, ${op.context.branch}, ${op.context.scope}, ${op.operation.index})`));
|
|
449
|
-
envelopes.push({
|
|
450
|
-
type: "operations",
|
|
451
|
-
channelMeta: { id: this.channelId },
|
|
452
|
-
operations: syncOp.operations,
|
|
453
|
-
key,
|
|
454
|
-
dependsOn,
|
|
455
|
-
});
|
|
456
|
-
}
|
|
457
|
-
const mutation = `
|
|
458
|
-
mutation PushSyncEnvelopes($envelopes: [SyncEnvelopeInput!]!) {
|
|
459
|
-
pushSyncEnvelopes(envelopes: $envelopes)
|
|
460
|
-
}
|
|
461
|
-
`;
|
|
462
|
-
const variables = {
|
|
463
|
-
envelopes: envelopes.map((e) => serializeEnvelope(e)),
|
|
464
|
-
};
|
|
465
|
-
await this.executeGraphQL(mutation, variables);
|
|
466
|
-
}
|
|
467
|
-
/**
|
|
468
|
-
* Gets the authorization header value using jwtHandler.
|
|
469
|
-
*/
|
|
470
|
-
async getAuthorizationHeader() {
|
|
471
|
-
if (!this.config.jwtHandler) {
|
|
472
|
-
return undefined;
|
|
473
|
-
}
|
|
474
|
-
try {
|
|
475
|
-
const token = await this.config.jwtHandler(this.config.url);
|
|
476
|
-
if (token) {
|
|
477
|
-
return `Bearer ${token}`;
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
catch (error) {
|
|
481
|
-
this.logger.error("JWT handler failed: @Error", error);
|
|
482
|
-
}
|
|
483
|
-
return undefined;
|
|
484
|
-
}
|
|
485
|
-
/**
|
|
486
|
-
* Executes a GraphQL query or mutation against the remote endpoint.
|
|
487
|
-
*/
|
|
488
|
-
async executeGraphQL(query, variables) {
|
|
489
|
-
const headers = {
|
|
490
|
-
"Content-Type": "application/json",
|
|
491
|
-
};
|
|
492
|
-
const authHeader = await this.getAuthorizationHeader();
|
|
493
|
-
if (authHeader) {
|
|
494
|
-
headers["Authorization"] = authHeader;
|
|
495
|
-
}
|
|
496
|
-
const operationMatch = query.match(/(?:query|mutation)\s+(\w+)/);
|
|
497
|
-
const operationName = operationMatch?.[1] ?? "unknown";
|
|
498
|
-
this.logger.verbose("GQL request @channelId @operation @url vars=@variables", this.channelId, operationName, this.config.url, JSON.stringify(variables));
|
|
499
|
-
const fetchFn = this.config.fetchFn ?? fetch;
|
|
500
|
-
let response;
|
|
501
|
-
try {
|
|
502
|
-
response = await fetchFn(this.config.url, {
|
|
503
|
-
method: "POST",
|
|
504
|
-
headers,
|
|
505
|
-
body: JSON.stringify({
|
|
506
|
-
query,
|
|
507
|
-
variables,
|
|
508
|
-
}),
|
|
509
|
-
});
|
|
510
|
-
}
|
|
511
|
-
catch (error) {
|
|
512
|
-
throw new Error(`GraphQL request failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
513
|
-
}
|
|
514
|
-
if (!response.ok) {
|
|
515
|
-
throw new Error(`GraphQL request failed: ${response.status} ${response.statusText}`);
|
|
516
|
-
}
|
|
517
|
-
let result;
|
|
518
|
-
try {
|
|
519
|
-
result = (await response.json());
|
|
520
|
-
}
|
|
521
|
-
catch (error) {
|
|
522
|
-
throw new Error(`Failed to parse GraphQL response: ${error instanceof Error ? error.message : String(error)}`);
|
|
523
|
-
}
|
|
524
|
-
this.logger.verbose("GQL response @channelId @operation status=@status data=@data errors=@errors", this.channelId, operationName, response.status, JSON.stringify(result.data), result.errors ? JSON.stringify(result.errors) : "none");
|
|
525
|
-
if (result.errors) {
|
|
526
|
-
throw new Error(`GraphQL errors: ${JSON.stringify(result.errors, null, 2)}`);
|
|
527
|
-
}
|
|
528
|
-
if (!result.data) {
|
|
529
|
-
throw new Error("GraphQL response missing data field");
|
|
530
|
-
}
|
|
531
|
-
return result.data;
|
|
532
|
-
}
|
|
533
|
-
/**
|
|
534
|
-
* Gets the current health status of the channel.
|
|
535
|
-
*/
|
|
536
|
-
getHealth() {
|
|
537
|
-
return {
|
|
538
|
-
state: this.failureCount > 0 ? "error" : "idle",
|
|
539
|
-
lastSuccessUtcMs: this.lastSuccessUtcMs,
|
|
540
|
-
lastFailureUtcMs: this.lastFailureUtcMs,
|
|
541
|
-
failureCount: this.failureCount,
|
|
542
|
-
};
|
|
543
|
-
}
|
|
544
|
-
get poller() {
|
|
545
|
-
return this.pollTimer;
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
//# sourceMappingURL=gql-req-channel.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gql-req-channel.js","sourceRoot":"","sources":["../../../../src/sync/channels/gql-req-channel.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { GqlRequestChannel } from "./gql-req-channel.js";
|
|
2
|
-
import { IntervalPollTimer } from "./interval-poll-timer.js";
|
|
3
|
-
/**
|
|
4
|
-
* Factory for creating GqlRequestChannel instances.
|
|
5
|
-
*
|
|
6
|
-
* Extracts GraphQL-specific configuration from ChannelConfig.parameters and
|
|
7
|
-
* instantiates GqlRequestChannel instances for network-based synchronization.
|
|
8
|
-
*
|
|
9
|
-
* The optional jwtHandler enables dynamic JWT token generation per-request,
|
|
10
|
-
* which is useful for short-lived tokens with audience-specific claims.
|
|
11
|
-
*/
|
|
12
|
-
export class GqlRequestChannelFactory {
|
|
13
|
-
logger;
|
|
14
|
-
jwtHandler;
|
|
15
|
-
queue;
|
|
16
|
-
constructor(logger, jwtHandler, queue) {
|
|
17
|
-
this.logger = logger;
|
|
18
|
-
this.jwtHandler = jwtHandler;
|
|
19
|
-
this.queue = queue;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Creates a new GqlRequestChannel instance with the given configuration.
|
|
23
|
-
* See GqlChannelConfig for the expected parameters.
|
|
24
|
-
*
|
|
25
|
-
* @param config - Channel configuration including type and parameters
|
|
26
|
-
* @param cursorStorage - Storage for persisting synchronization cursors
|
|
27
|
-
* @param operationIndex - Operation index for querying timestamps
|
|
28
|
-
* @returns A new GqlRequestChannel instance
|
|
29
|
-
*/
|
|
30
|
-
instance(remoteId, remoteName, config, cursorStorage, collectionId, filter, operationIndex) {
|
|
31
|
-
// Extract and validate required parameters
|
|
32
|
-
const url = config.parameters.url;
|
|
33
|
-
if (typeof url !== "string" || !url) {
|
|
34
|
-
throw new Error('GqlRequestChannelFactory requires "url" parameter in config.parameters');
|
|
35
|
-
}
|
|
36
|
-
// Extract optional parameters with validation
|
|
37
|
-
const gqlConfig = {
|
|
38
|
-
url,
|
|
39
|
-
collectionId,
|
|
40
|
-
filter,
|
|
41
|
-
jwtHandler: this.jwtHandler,
|
|
42
|
-
retryBaseDelayMs: 1000,
|
|
43
|
-
retryMaxDelayMs: 300000,
|
|
44
|
-
};
|
|
45
|
-
let pollIntervalMs = 2000;
|
|
46
|
-
if (config.parameters.pollIntervalMs !== undefined) {
|
|
47
|
-
if (typeof config.parameters.pollIntervalMs !== "number") {
|
|
48
|
-
throw new Error('"pollIntervalMs" parameter must be a number');
|
|
49
|
-
}
|
|
50
|
-
pollIntervalMs = config.parameters.pollIntervalMs;
|
|
51
|
-
}
|
|
52
|
-
let retryBaseDelayMs;
|
|
53
|
-
if (config.parameters.retryBaseDelayMs !== undefined) {
|
|
54
|
-
if (typeof config.parameters.retryBaseDelayMs !== "number") {
|
|
55
|
-
throw new Error('"retryBaseDelayMs" parameter must be a number');
|
|
56
|
-
}
|
|
57
|
-
retryBaseDelayMs = config.parameters.retryBaseDelayMs;
|
|
58
|
-
}
|
|
59
|
-
let retryMaxDelayMs;
|
|
60
|
-
if (config.parameters.retryMaxDelayMs !== undefined) {
|
|
61
|
-
if (typeof config.parameters.retryMaxDelayMs !== "number") {
|
|
62
|
-
throw new Error('"retryMaxDelayMs" parameter must be a number');
|
|
63
|
-
}
|
|
64
|
-
retryMaxDelayMs = config.parameters.retryMaxDelayMs;
|
|
65
|
-
}
|
|
66
|
-
if (config.parameters.fetchFn !== undefined) {
|
|
67
|
-
if (typeof config.parameters.fetchFn !== "function") {
|
|
68
|
-
throw new Error('"fetchFn" parameter must be a function');
|
|
69
|
-
}
|
|
70
|
-
gqlConfig.fetchFn = config.parameters.fetchFn;
|
|
71
|
-
}
|
|
72
|
-
if (retryBaseDelayMs !== undefined) {
|
|
73
|
-
gqlConfig.retryBaseDelayMs = retryBaseDelayMs;
|
|
74
|
-
}
|
|
75
|
-
if (retryMaxDelayMs !== undefined) {
|
|
76
|
-
gqlConfig.retryMaxDelayMs = retryMaxDelayMs;
|
|
77
|
-
}
|
|
78
|
-
let maxQueueDepth;
|
|
79
|
-
if (config.parameters.maxQueueDepth !== undefined) {
|
|
80
|
-
if (typeof config.parameters.maxQueueDepth !== "number") {
|
|
81
|
-
throw new Error('"maxQueueDepth" parameter must be a number');
|
|
82
|
-
}
|
|
83
|
-
maxQueueDepth = config.parameters.maxQueueDepth;
|
|
84
|
-
}
|
|
85
|
-
let backpressureCheckIntervalMs;
|
|
86
|
-
if (config.parameters.backpressureCheckIntervalMs !== undefined) {
|
|
87
|
-
if (typeof config.parameters.backpressureCheckIntervalMs !== "number") {
|
|
88
|
-
throw new Error('"backpressureCheckIntervalMs" parameter must be a number');
|
|
89
|
-
}
|
|
90
|
-
backpressureCheckIntervalMs =
|
|
91
|
-
config.parameters.backpressureCheckIntervalMs;
|
|
92
|
-
}
|
|
93
|
-
const pollTimer = new IntervalPollTimer(this.queue, {
|
|
94
|
-
intervalMs: pollIntervalMs,
|
|
95
|
-
...(retryBaseDelayMs !== undefined && { retryBaseDelayMs }),
|
|
96
|
-
...(retryMaxDelayMs !== undefined && { retryMaxDelayMs }),
|
|
97
|
-
...(maxQueueDepth !== undefined && { maxQueueDepth }),
|
|
98
|
-
...(backpressureCheckIntervalMs !== undefined && {
|
|
99
|
-
backpressureCheckIntervalMs,
|
|
100
|
-
}),
|
|
101
|
-
});
|
|
102
|
-
return new GqlRequestChannel(this.logger, remoteId, remoteName, cursorStorage, gqlConfig, operationIndex, pollTimer);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
//# sourceMappingURL=gql-request-channel-factory.js.map
|