@relayfile/sdk 0.10.1 → 0.10.3
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/client.d.ts +13 -1
- package/dist/client.js +64 -0
- package/dist/connection.d.ts +36 -0
- package/dist/connection.js +5 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +2 -0
- package/dist/self-host-connect.d.ts +38 -0
- package/dist/self-host-connect.js +141 -0
- package/dist/types.d.ts +7 -1
- package/package.json +6 -6
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AdminIngressStatusResponse, type AdminSyncStatusResponse, type BulkWriteInput, type BulkWriteResponse, type BackendStatusResponse, type AckResponse, type CommitForkInput, type CommitForkResponse, type CreateForkInput, type DeleteFileInput, type DeadLetterItem, type DeadLetterFeedResponse, type DeleteWebhookOptions, type DiscardForkInput, type EventFeedResponse, type ExportJsonResponse, type ExportOptions, type FileQueryResponse, type FileReadResponse, type FilesystemEvent, type GetEventsOptions, type GetAdminIngressStatusOptions, type GetAdminSyncStatusOptions, type GetOperationsOptions, type GetSyncDeadLettersOptions, type GetSyncIngressStatusOptions, type GetSyncStatusOptions, type GetWebhookDeadLettersOptions, type ListWebhooksOptions, type ListTreeOptions, type OperationFeedResponse, type OperationStatusResponse, type QueuedResponse, type ResourceAtEventResult, type ReadFileInput, type QueryFilesOptions, type RegisterWebhookInput, type RegisterWebhookResponse, type RelayFileReadCacheOptions, type Subscription, type SyncIngressStatusResponse, type SyncStatusResponse, type TreeResponse, type WriteFileInput, type WriteQueuedResponse, type IngestWebhookInput, type WritebackItem, type WebhookDeliveryDeadLetterFeedResponse, type WebhookSubscription, type AckWritebackInput, type AckWritebackResponse, type SweepWritebackDraftsInput, type SweepWritebackDraftsResponse, type ChangeEvent, type ChangeLogQueryResult, type ChangeStreamConnection, type ChangeStreamConnectionOptions, type SubscribeOptions } from "./types.js";
|
|
1
|
+
import { type AdminIngressStatusResponse, type AdminSyncStatusResponse, type BulkWriteInput, type BulkWriteResponse, type BackendStatusResponse, type AckResponse, type CommitForkInput, type CommitForkResponse, type CreateForkInput, type DeleteFileInput, type DeadLetterItem, type DeadLetterFeedResponse, type DeleteWebhookOptions, type DiscardForkInput, type EventFeedResponse, type ExportJsonResponse, type ExportOptions, type FileQueryResponse, type FileReadResponse, type FilesystemEvent, type GetEventsOptions, type GetAdminIngressStatusOptions, type GetAdminSyncStatusOptions, type GetOperationsOptions, type GetSyncDeadLettersOptions, type GetSyncIngressStatusOptions, type GetSyncStatusOptions, type GetWebhookDeadLettersOptions, type ListWebhooksOptions, type ListTreeOptions, type OperationFeedResponse, type OperationStatusResponse, type QueuedResponse, type ResourceAtEventResult, type ReadFileInput, type QueryFilesOptions, type RegisterWebhookInput, type RegisterWebhookResponse, type RelayFileReadCacheOptions, type Subscription, type SyncIngressStatusResponse, type SyncProviderStatus, type SyncStatusResponse, type TreeResponse, type WriteFileInput, type WriteQueuedResponse, type IngestWebhookInput, type WritebackItem, type WebhookDeliveryDeadLetterFeedResponse, type WebhookSubscription, type AckWritebackInput, type AckWritebackResponse, type SweepWritebackDraftsInput, type SweepWritebackDraftsResponse, type ChangeEvent, type ChangeLogQueryResult, type ChangeStreamConnection, type ChangeStreamConnectionOptions, type SubscribeOptions, type WaitForDataOptions } from "./types.js";
|
|
2
2
|
import type { ForkHandle } from "@relayfile/core";
|
|
3
3
|
/**
|
|
4
4
|
* Bearer token or token factory used for Relayfile API requests.
|
|
@@ -124,6 +124,18 @@ export declare class RelayFileClient {
|
|
|
124
124
|
getAdminIngressStatus(optionsOrCorrelationId?: GetAdminIngressStatusOptions | string, signal?: AbortSignal): Promise<AdminIngressStatusResponse>;
|
|
125
125
|
getAdminSyncStatus(optionsOrCorrelationId?: GetAdminSyncStatusOptions | string, signal?: AbortSignal): Promise<AdminSyncStatusResponse>;
|
|
126
126
|
getSyncStatus(workspaceId: string, options?: GetSyncStatusOptions): Promise<SyncStatusResponse>;
|
|
127
|
+
/**
|
|
128
|
+
* Wait until a provider is safe to read from the data plane.
|
|
129
|
+
*
|
|
130
|
+
* Cloud-managed syncs report first-sync completion through `ready: true` or
|
|
131
|
+
* `status: "ready"`. OSS self-host `/sync/status` uses `healthy` for provider
|
|
132
|
+
* health, including empty freshly filtered provider rows, so this method only
|
|
133
|
+
* treats OSS `healthy` as data-ready after processed-ingest progress appears
|
|
134
|
+
* on the status row (`cursor` or `watermarkTs`). For custom OSS ingest flows,
|
|
135
|
+
* gate on your own ingest completion when you need stronger domain-specific
|
|
136
|
+
* proof than provider progress.
|
|
137
|
+
*/
|
|
138
|
+
waitForData(workspaceId: string, provider: string, options?: WaitForDataOptions): Promise<SyncProviderStatus>;
|
|
127
139
|
getSyncIngressStatus(workspaceId: string, options?: GetSyncIngressStatusOptions): Promise<SyncIngressStatusResponse>;
|
|
128
140
|
getSyncDeadLetters(workspaceId: string, options?: GetSyncDeadLettersOptions): Promise<DeadLetterFeedResponse>;
|
|
129
141
|
getSyncDeadLetter(workspaceId: string, envelopeId: string, correlationId?: string, signal?: AbortSignal): Promise<DeadLetterItem>;
|
package/dist/client.js
CHANGED
|
@@ -186,6 +186,32 @@ function normalizeErrorDetails(data, explicitDetails) {
|
|
|
186
186
|
}
|
|
187
187
|
return Object.keys(details).length > 0 ? details : undefined;
|
|
188
188
|
}
|
|
189
|
+
function normalizeProviderId(value) {
|
|
190
|
+
const normalized = value.trim().toLowerCase();
|
|
191
|
+
if (!normalized) {
|
|
192
|
+
throw new Error("provider is required.");
|
|
193
|
+
}
|
|
194
|
+
return normalized;
|
|
195
|
+
}
|
|
196
|
+
function normalizeProviderIdOrNull(value) {
|
|
197
|
+
const normalized = value.trim().toLowerCase();
|
|
198
|
+
return normalized || null;
|
|
199
|
+
}
|
|
200
|
+
function normalizePositiveInteger(value, field) {
|
|
201
|
+
const normalized = Math.floor(value);
|
|
202
|
+
if (!Number.isFinite(normalized) || normalized <= 0) {
|
|
203
|
+
throw new Error(`${field} must be a positive integer.`);
|
|
204
|
+
}
|
|
205
|
+
return normalized;
|
|
206
|
+
}
|
|
207
|
+
function providerDataReady(status) {
|
|
208
|
+
return (status.ready === true ||
|
|
209
|
+
status.status === "ready" ||
|
|
210
|
+
(status.status === "healthy" && providerHasProgress(status)));
|
|
211
|
+
}
|
|
212
|
+
function providerHasProgress(status) {
|
|
213
|
+
return Boolean(status.cursor || status.watermarkTs);
|
|
214
|
+
}
|
|
189
215
|
class RelayFileWebSocketConnection {
|
|
190
216
|
socket;
|
|
191
217
|
handlers = {
|
|
@@ -1585,6 +1611,44 @@ export class RelayFileClient {
|
|
|
1585
1611
|
signal: options.signal
|
|
1586
1612
|
});
|
|
1587
1613
|
}
|
|
1614
|
+
/**
|
|
1615
|
+
* Wait until a provider is safe to read from the data plane.
|
|
1616
|
+
*
|
|
1617
|
+
* Cloud-managed syncs report first-sync completion through `ready: true` or
|
|
1618
|
+
* `status: "ready"`. OSS self-host `/sync/status` uses `healthy` for provider
|
|
1619
|
+
* health, including empty freshly filtered provider rows, so this method only
|
|
1620
|
+
* treats OSS `healthy` as data-ready after processed-ingest progress appears
|
|
1621
|
+
* on the status row (`cursor` or `watermarkTs`). For custom OSS ingest flows,
|
|
1622
|
+
* gate on your own ingest completion when you need stronger domain-specific
|
|
1623
|
+
* proof than provider progress.
|
|
1624
|
+
*/
|
|
1625
|
+
async waitForData(workspaceId, provider, options = {}) {
|
|
1626
|
+
const providerKey = normalizeProviderId(provider);
|
|
1627
|
+
const pollIntervalMs = normalizePositiveInteger(options.pollIntervalMs ?? 1_000, "pollIntervalMs");
|
|
1628
|
+
const timeoutMs = normalizePositiveInteger(options.timeoutMs ?? 5 * 60_000, "timeoutMs");
|
|
1629
|
+
const startedAt = Date.now();
|
|
1630
|
+
for (;;) {
|
|
1631
|
+
if (options.signal?.aborted) {
|
|
1632
|
+
throw createAbortError();
|
|
1633
|
+
}
|
|
1634
|
+
const elapsedMs = Date.now() - startedAt;
|
|
1635
|
+
if (elapsedMs >= timeoutMs) {
|
|
1636
|
+
throw new Error(`Timed out waiting for ${providerKey} data after ${elapsedMs}ms.`);
|
|
1637
|
+
}
|
|
1638
|
+
const status = await this.getSyncStatus(workspaceId, {
|
|
1639
|
+
provider: providerKey,
|
|
1640
|
+
correlationId: options.correlationId,
|
|
1641
|
+
signal: options.signal
|
|
1642
|
+
});
|
|
1643
|
+
const providerStatus = status.providers.find((entry) => normalizeProviderIdOrNull(entry.provider) === providerKey);
|
|
1644
|
+
options.onPoll?.(elapsedMs, providerStatus);
|
|
1645
|
+
if (providerStatus && providerDataReady(providerStatus)) {
|
|
1646
|
+
return providerStatus;
|
|
1647
|
+
}
|
|
1648
|
+
const remainingMs = Math.max(0, timeoutMs - (Date.now() - startedAt));
|
|
1649
|
+
await this.sleep(Math.min(pollIntervalMs, remainingMs), options.signal);
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1588
1652
|
async getSyncIngressStatus(workspaceId, options = {}) {
|
|
1589
1653
|
const query = buildQuery({
|
|
1590
1654
|
provider: options.provider
|
package/dist/connection.d.ts
CHANGED
|
@@ -41,3 +41,39 @@ export interface ConnectionProvider {
|
|
|
41
41
|
getConnection?(connectionId: string): Promise<Record<string, unknown>>;
|
|
42
42
|
listConnections?(): Promise<Array<Record<string, unknown>>>;
|
|
43
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Maps a relayfile provider slug (e.g. "github", "linear") to the provider
|
|
46
|
+
* config key it is registered under in your credential backend (e.g. the Nango
|
|
47
|
+
* `providerConfigKey`). The relayfile slug is NOT guaranteed to equal the
|
|
48
|
+
* upstream config key, so self-host callers supply this mapping explicitly.
|
|
49
|
+
*/
|
|
50
|
+
export type ProviderConfigKeyMap = Record<string, string>;
|
|
51
|
+
export interface CreateConnectSessionInput {
|
|
52
|
+
relayfileProvider: string;
|
|
53
|
+
providerConfigKey: string;
|
|
54
|
+
endUserId: string;
|
|
55
|
+
connectionId?: string;
|
|
56
|
+
metadata?: Record<string, unknown>;
|
|
57
|
+
}
|
|
58
|
+
export interface ConnectSession {
|
|
59
|
+
connectLink: string | null;
|
|
60
|
+
sessionToken: string | null;
|
|
61
|
+
expiresAt: string | null;
|
|
62
|
+
connectionId: string;
|
|
63
|
+
}
|
|
64
|
+
export interface GetConnectConnectionStatusInput {
|
|
65
|
+
relayfileProvider: string;
|
|
66
|
+
providerConfigKey: string;
|
|
67
|
+
connectionId: string;
|
|
68
|
+
}
|
|
69
|
+
export interface ConnectConnectionStatus {
|
|
70
|
+
connectionId: string;
|
|
71
|
+
state: string;
|
|
72
|
+
ready?: boolean;
|
|
73
|
+
raw?: unknown;
|
|
74
|
+
}
|
|
75
|
+
export interface ConnectCapableProvider extends ConnectionProvider {
|
|
76
|
+
createConnectSession(input: CreateConnectSessionInput): Promise<ConnectSession>;
|
|
77
|
+
getConnectionStatus(input: GetConnectConnectionStatusInput): Promise<ConnectConnectionStatus>;
|
|
78
|
+
}
|
|
79
|
+
export declare function supportsConnect(provider: ConnectionProvider): provider is ConnectCapableProvider;
|
package/dist/connection.js
CHANGED
|
@@ -3,4 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* These types are the contract every provider package must implement.
|
|
5
5
|
*/
|
|
6
|
-
export {
|
|
6
|
+
export function supportsConnect(provider) {
|
|
7
|
+
const candidate = provider;
|
|
8
|
+
return (typeof candidate.createConnectSession === "function" &&
|
|
9
|
+
typeof candidate.getConnectionStatus === "function");
|
|
10
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -9,8 +9,11 @@ export { onWrite, pathMatches, type OnWriteClient, type OnWriteHandler, type OnW
|
|
|
9
9
|
export { InvalidStateError, PayloadTooLargeError, QueueFullError, RelayFileApiError, RevisionConflictError } from "./errors.js";
|
|
10
10
|
export { IntegrationProvider, computeCanonicalPath } from "./provider.js";
|
|
11
11
|
export type { WebhookInput, ListProviderFilesOptions, WatchProviderEventsOptions } from "./provider.js";
|
|
12
|
-
export type { ConnectionProvider, NormalizedWebhook, ProxyHeaders, ProxyMethod, ProxyQuery, ProxyRequest, ProxyResponse, } from "./connection.js";
|
|
13
|
-
export
|
|
12
|
+
export type { ConnectCapableProvider, ConnectConnectionStatus, ConnectSession, ConnectionProvider, CreateConnectSessionInput, GetConnectConnectionStatusInput, NormalizedWebhook, ProviderConfigKeyMap, ProxyHeaders, ProxyMethod, ProxyQuery, ProxyRequest, ProxyResponse, } from "./connection.js";
|
|
13
|
+
export { supportsConnect } from "./connection.js";
|
|
14
|
+
export { SelfHostConnect } from "./self-host-connect.js";
|
|
15
|
+
export type { SelfHostConnectOptions, SelfHostConnectResult, StartSelfHostConnectOptions, WaitForSelfHostConnectionOptions } from "./self-host-connect.js";
|
|
16
|
+
export type { AckResponse, AckWritebackInput, AckWritebackDraftDisposition, AckWritebackResponse, AdminIngressAlert, AdminIngressAlertProfile, AdminIngressEffectiveAlertProfile, AdminIngressAlertSeverity, AdminIngressAlertThresholds, AdminIngressAlertTotals, AdminIngressAlertType, AdminIngressStatusResponse, AdminSyncAlert, AdminSyncAlertSeverity, AdminSyncAlertThresholds, AdminSyncAlertTotals, AdminSyncAlertType, AdminSyncStatusResponse, BackendStatusResponse, BulkWriteFile, BulkWriteInput, BulkWriteResponse, ChangeLogQueryResult, ChangeEvent, ChangeEventActor, ChangeEventResource, ChangeEventSummary, ChangeStreamConnection, ChangeStreamConnectionOptions, CommitForkInput, CommitForkResponse, ConflictErrorResponse, CreateForkInput, ContentIdentity, DeleteFileInput, DeleteWebhookOptions, DeadLetterFeedResponse, DeadLetterItem, DigestBullet, DigestContext, DigestHandler, DigestSection, DigestWindow, DiscardForkInput, ErrorResponse, EventSummary, EventFeedResponse, ExportFormat, ExportJsonResponse, ExportOptions, FileQueryItem, FileQueryResponse, FileReadResponse, FileSemantics, FileWriteRequest, FilesystemEvent, FilesystemEventType, EventOrigin, Expansion, ExpansionLevel, GetEventsOptions, GetAdminSyncStatusOptions, GetAdminIngressStatusOptions, GetOperationsOptions, GetSyncDeadLettersOptions, GetSyncIngressStatusOptions, GetSyncStatusOptions, WaitForDataOptions, GetWebhookDeadLettersOptions, IngestWebhookInput, LayoutManifest, LayoutManifestAlias, LayoutManifestResource, ListWebhooksOptions, ListTreeOptions, OperationFeedResponse, OperationStatus, OperationStatusResponse, QueuedResponse, QueryFilesOptions, ReadFileInput, RegisterWebhookInput, RegisterWebhookResponse, ReplayOptions, ResourceAtEventResult, SummaryExpansion, FullExpansion, DiffExpansion, ThreadExpansion, RelayFileJwtClaims, SubscribeOptions, Subscription, SyncIngressStatusResponse, SyncProviderStatus, SyncProviderStatusState, SyncRefreshRequest, SyncStatusResponse, SweepWritebackDraftsInput, SweepWritebackDraftsResponse, TreeEntry, TreeResponse, WebhookDeliveryDeadLetterFeedResponse, WebhookDeliveryDeadLetterItem, WebhookSubscription, WebhookSubscriptionHealth, WritebackActionType, WritebackDeadLetterError, WritebackDeadLetterErrorCode, WritebackListState, WritebackState, WritebackItem, WritebackItemDetail, WritebackSchemaRef, WriteFileInput, WriteQueuedResponse } from "./types.js";
|
|
14
17
|
export type { ForkHandle, ForkOptions } from "@relayfile/core";
|
|
15
18
|
export type { WriteEvent, WriteEventActor, WriteEventOperation, WriteEventSource } from "@relayfile/core";
|
|
16
19
|
export { WritebackConsumer } from "./writeback-consumer.js";
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,8 @@ export { onWrite, pathMatches } from "./onWrite.js";
|
|
|
7
7
|
export { InvalidStateError, PayloadTooLargeError, QueueFullError, RelayFileApiError, RevisionConflictError } from "./errors.js";
|
|
8
8
|
// Integration providers
|
|
9
9
|
export { IntegrationProvider, computeCanonicalPath } from "./provider.js";
|
|
10
|
+
export { supportsConnect } from "./connection.js";
|
|
11
|
+
export { SelfHostConnect } from "./self-host-connect.js";
|
|
10
12
|
export { WritebackConsumer } from "./writeback-consumer.js";
|
|
11
13
|
export * from "./integration-adapter.js";
|
|
12
14
|
// Agent workspace provisioning helpers (`seedWorkspace`, `seedAclRules`,
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ConnectConnectionStatus, ConnectionProvider, ProviderConfigKeyMap } from "./connection.js";
|
|
2
|
+
export interface SelfHostConnectOptions {
|
|
3
|
+
provider: ConnectionProvider;
|
|
4
|
+
providerConfigKeys: ProviderConfigKeyMap;
|
|
5
|
+
defaultPollIntervalMs?: number;
|
|
6
|
+
defaultTimeoutMs?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface StartSelfHostConnectOptions {
|
|
9
|
+
endUserId: string;
|
|
10
|
+
connectionId?: string;
|
|
11
|
+
metadata?: Record<string, unknown>;
|
|
12
|
+
}
|
|
13
|
+
export interface SelfHostConnectResult {
|
|
14
|
+
relayfileProvider: string;
|
|
15
|
+
providerConfigKey: string;
|
|
16
|
+
connectLink: string | null;
|
|
17
|
+
sessionToken: string | null;
|
|
18
|
+
expiresAt: string | null;
|
|
19
|
+
connectionId: string;
|
|
20
|
+
}
|
|
21
|
+
export interface WaitForSelfHostConnectionOptions {
|
|
22
|
+
connectionId: string;
|
|
23
|
+
pollIntervalMs?: number;
|
|
24
|
+
timeoutMs?: number;
|
|
25
|
+
signal?: AbortSignal;
|
|
26
|
+
onPoll?: (elapsedMs: number, status?: ConnectConnectionStatus) => void;
|
|
27
|
+
}
|
|
28
|
+
export declare class SelfHostConnect {
|
|
29
|
+
private readonly provider;
|
|
30
|
+
private readonly providerConfigKeys;
|
|
31
|
+
private readonly defaultPollIntervalMs;
|
|
32
|
+
private readonly defaultTimeoutMs;
|
|
33
|
+
constructor(options: SelfHostConnectOptions);
|
|
34
|
+
startConnect(relayfileProvider: string, options: StartSelfHostConnectOptions): Promise<SelfHostConnectResult>;
|
|
35
|
+
waitForConnection(relayfileProvider: string, options: WaitForSelfHostConnectionOptions): Promise<ConnectConnectionStatus>;
|
|
36
|
+
private resolveProviderConfigKey;
|
|
37
|
+
private requireConnectProvider;
|
|
38
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { supportsConnect } from "./connection.js";
|
|
2
|
+
const DEFAULT_WAIT_INTERVAL_MS = 2_000;
|
|
3
|
+
const DEFAULT_WAIT_TIMEOUT_MS = 5 * 60_000;
|
|
4
|
+
const AUTH_READY_STATE = "oauth_connected";
|
|
5
|
+
export class SelfHostConnect {
|
|
6
|
+
provider;
|
|
7
|
+
providerConfigKeys;
|
|
8
|
+
defaultPollIntervalMs;
|
|
9
|
+
defaultTimeoutMs;
|
|
10
|
+
constructor(options) {
|
|
11
|
+
this.provider = options.provider;
|
|
12
|
+
this.providerConfigKeys = { ...options.providerConfigKeys };
|
|
13
|
+
this.defaultPollIntervalMs = normalizePositiveInteger(options.defaultPollIntervalMs, DEFAULT_WAIT_INTERVAL_MS);
|
|
14
|
+
this.defaultTimeoutMs = normalizePositiveInteger(options.defaultTimeoutMs, DEFAULT_WAIT_TIMEOUT_MS);
|
|
15
|
+
}
|
|
16
|
+
async startConnect(relayfileProvider, options) {
|
|
17
|
+
const normalizedProvider = normalizeRelayfileProvider(relayfileProvider);
|
|
18
|
+
const providerConfigKey = this.resolveProviderConfigKey(normalizedProvider);
|
|
19
|
+
const connectProvider = this.requireConnectProvider();
|
|
20
|
+
const endUserId = options.endUserId?.trim();
|
|
21
|
+
if (!endUserId) {
|
|
22
|
+
throw new Error("endUserId is required to start a self-host connect session");
|
|
23
|
+
}
|
|
24
|
+
const input = {
|
|
25
|
+
relayfileProvider: normalizedProvider,
|
|
26
|
+
providerConfigKey,
|
|
27
|
+
endUserId
|
|
28
|
+
};
|
|
29
|
+
const connectionId = options.connectionId?.trim();
|
|
30
|
+
if (connectionId) {
|
|
31
|
+
input.connectionId = connectionId;
|
|
32
|
+
}
|
|
33
|
+
if (options.metadata) {
|
|
34
|
+
input.metadata = { ...options.metadata };
|
|
35
|
+
}
|
|
36
|
+
const session = await connectProvider.createConnectSession(input);
|
|
37
|
+
return {
|
|
38
|
+
relayfileProvider: normalizedProvider,
|
|
39
|
+
providerConfigKey,
|
|
40
|
+
connectLink: session.connectLink,
|
|
41
|
+
sessionToken: session.sessionToken,
|
|
42
|
+
expiresAt: session.expiresAt,
|
|
43
|
+
connectionId: session.connectionId
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
async waitForConnection(relayfileProvider, options) {
|
|
47
|
+
const normalizedProvider = normalizeRelayfileProvider(relayfileProvider);
|
|
48
|
+
const providerConfigKey = this.resolveProviderConfigKey(normalizedProvider);
|
|
49
|
+
const connectProvider = this.requireConnectProvider();
|
|
50
|
+
const connectionId = options.connectionId?.trim();
|
|
51
|
+
if (!connectionId) {
|
|
52
|
+
throw new Error("connectionId is required to wait for a self-host connection");
|
|
53
|
+
}
|
|
54
|
+
const pollIntervalMs = normalizeNonNegativeInteger(options.pollIntervalMs, this.defaultPollIntervalMs);
|
|
55
|
+
const timeoutMs = normalizePositiveInteger(options.timeoutMs, this.defaultTimeoutMs);
|
|
56
|
+
const startedAt = Date.now();
|
|
57
|
+
for (;;) {
|
|
58
|
+
throwIfAborted(options.signal);
|
|
59
|
+
const elapsedMs = Date.now() - startedAt;
|
|
60
|
+
if (elapsedMs >= timeoutMs) {
|
|
61
|
+
throw new Error(`Timed out waiting for ${normalizedProvider} connection "${connectionId}" after ${elapsedMs}ms.`);
|
|
62
|
+
}
|
|
63
|
+
const status = await connectProvider.getConnectionStatus({
|
|
64
|
+
relayfileProvider: normalizedProvider,
|
|
65
|
+
providerConfigKey,
|
|
66
|
+
connectionId
|
|
67
|
+
});
|
|
68
|
+
options.onPoll?.(Date.now() - startedAt, status);
|
|
69
|
+
if (isAuthReady(status)) {
|
|
70
|
+
return status;
|
|
71
|
+
}
|
|
72
|
+
const sleepMs = Math.min(pollIntervalMs, Math.max(0, timeoutMs - (Date.now() - startedAt)));
|
|
73
|
+
await sleep(sleepMs, options.signal);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
resolveProviderConfigKey(relayfileProvider) {
|
|
77
|
+
const providerConfigKey = this.providerConfigKeys[relayfileProvider]?.trim();
|
|
78
|
+
if (!providerConfigKey) {
|
|
79
|
+
throw new Error(`No providerConfigKey mapping configured for relayfile provider "${relayfileProvider}".`);
|
|
80
|
+
}
|
|
81
|
+
return providerConfigKey;
|
|
82
|
+
}
|
|
83
|
+
requireConnectProvider() {
|
|
84
|
+
if (!supportsConnect(this.provider)) {
|
|
85
|
+
throw new Error(`Provider "${this.provider.name}" does not support self-host Connect.`);
|
|
86
|
+
}
|
|
87
|
+
return this.provider;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function isAuthReady(status) {
|
|
91
|
+
return status.state === AUTH_READY_STATE || status.ready === true;
|
|
92
|
+
}
|
|
93
|
+
function normalizeRelayfileProvider(provider) {
|
|
94
|
+
const normalized = provider?.trim();
|
|
95
|
+
if (!normalized) {
|
|
96
|
+
throw new Error("relayfileProvider is required");
|
|
97
|
+
}
|
|
98
|
+
return normalized;
|
|
99
|
+
}
|
|
100
|
+
function normalizePositiveInteger(value, fallback) {
|
|
101
|
+
if (value === undefined) {
|
|
102
|
+
return fallback;
|
|
103
|
+
}
|
|
104
|
+
return Math.max(1, Math.floor(value));
|
|
105
|
+
}
|
|
106
|
+
function normalizeNonNegativeInteger(value, fallback) {
|
|
107
|
+
if (value === undefined) {
|
|
108
|
+
return fallback;
|
|
109
|
+
}
|
|
110
|
+
return Math.max(0, Math.floor(value));
|
|
111
|
+
}
|
|
112
|
+
function throwIfAborted(signal) {
|
|
113
|
+
if (signal?.aborted) {
|
|
114
|
+
throw createAbortError();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function sleep(ms, signal) {
|
|
118
|
+
if (ms <= 0) {
|
|
119
|
+
return Promise.resolve();
|
|
120
|
+
}
|
|
121
|
+
if (signal?.aborted) {
|
|
122
|
+
return Promise.reject(createAbortError());
|
|
123
|
+
}
|
|
124
|
+
return new Promise((resolve, reject) => {
|
|
125
|
+
const onAbort = () => {
|
|
126
|
+
clearTimeout(timeout);
|
|
127
|
+
signal?.removeEventListener("abort", onAbort);
|
|
128
|
+
reject(createAbortError());
|
|
129
|
+
};
|
|
130
|
+
const timeout = setTimeout(() => {
|
|
131
|
+
signal?.removeEventListener("abort", onAbort);
|
|
132
|
+
resolve();
|
|
133
|
+
}, ms);
|
|
134
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
function createAbortError() {
|
|
138
|
+
const error = new Error("Aborted while waiting for self-host connection.");
|
|
139
|
+
error.name = "AbortError";
|
|
140
|
+
return error;
|
|
141
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -357,10 +357,11 @@ export interface SyncRefreshRequest {
|
|
|
357
357
|
provider: string;
|
|
358
358
|
reason?: string;
|
|
359
359
|
}
|
|
360
|
-
export type SyncProviderStatusState = "healthy" | "lagging" | "error" | "paused";
|
|
360
|
+
export type SyncProviderStatusState = "connected" | "oauth_connected" | "sync_queued" | "syncing" | "ready" | "healthy" | "lagging" | "error" | "paused";
|
|
361
361
|
export interface SyncProviderStatus {
|
|
362
362
|
provider: string;
|
|
363
363
|
status: SyncProviderStatusState;
|
|
364
|
+
ready?: boolean;
|
|
364
365
|
cursor?: string | null;
|
|
365
366
|
watermarkTs?: string | null;
|
|
366
367
|
lagSeconds?: number;
|
|
@@ -534,6 +535,11 @@ export interface GetSyncStatusOptions {
|
|
|
534
535
|
correlationId?: string;
|
|
535
536
|
signal?: AbortSignal;
|
|
536
537
|
}
|
|
538
|
+
export interface WaitForDataOptions extends GetSyncStatusOptions {
|
|
539
|
+
pollIntervalMs?: number;
|
|
540
|
+
timeoutMs?: number;
|
|
541
|
+
onPoll?: (elapsedMs: number, status?: SyncProviderStatus) => void;
|
|
542
|
+
}
|
|
537
543
|
export interface GetSyncIngressStatusOptions {
|
|
538
544
|
provider?: string;
|
|
539
545
|
correlationId?: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@relayfile/sdk",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.3",
|
|
4
4
|
"description": "TypeScript SDK for relayfile — real-time filesystem for humans and agents",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -59,15 +59,15 @@
|
|
|
59
59
|
"prepublishOnly": "npm run build"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@relayfile/core": "0.10.
|
|
62
|
+
"@relayfile/core": "0.10.3",
|
|
63
63
|
"ignore": "^7.0.5",
|
|
64
64
|
"tar": "^7.5.10"
|
|
65
65
|
},
|
|
66
66
|
"optionalDependencies": {
|
|
67
|
-
"@relayfile/mount-darwin-arm64": "0.10.
|
|
68
|
-
"@relayfile/mount-darwin-x64": "0.10.
|
|
69
|
-
"@relayfile/mount-linux-arm64": "0.10.
|
|
70
|
-
"@relayfile/mount-linux-x64": "0.10.
|
|
67
|
+
"@relayfile/mount-darwin-arm64": "0.10.3",
|
|
68
|
+
"@relayfile/mount-darwin-x64": "0.10.3",
|
|
69
|
+
"@relayfile/mount-linux-arm64": "0.10.3",
|
|
70
|
+
"@relayfile/mount-linux-x64": "0.10.3"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
73
|
"typescript": "^5.7.3",
|