@mdbase-dev/connect 0.1.0-beta.31 → 0.1.0-beta.32
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/README.md +75 -19
- package/dist/advanced.d.ts +7 -0
- package/dist/advanced.js +4 -0
- package/dist/application-session.d.ts +10 -5
- package/dist/application-session.js +32 -16
- package/dist/async.js +11 -5
- package/dist/authority-proof.d.ts +3 -0
- package/dist/authority-proof.js +24 -0
- package/dist/browser/integrity.json +1 -1
- package/dist/browser/mdbase-connect.min.js +3 -3
- package/dist/browser/mdbase-connect.min.js.sha384 +1 -1
- package/dist/browser.d.ts +3 -0
- package/dist/browser.js +5 -0
- package/dist/capabilities.js +2 -1
- package/dist/collection-client.d.ts +28 -28
- package/dist/collection-client.js +42 -42
- package/dist/connect-options.d.ts +12 -4
- package/dist/connect.d.ts +12 -4
- package/dist/connect.js +105 -104
- package/dist/connection-file-transport.d.ts +2 -2
- package/dist/connection-file-transport.js +4 -4
- package/dist/connection-notifications.d.ts +10 -4
- package/dist/connection-notifications.js +41 -23
- package/dist/connection-transport.d.ts +19 -15
- package/dist/connection-transport.js +202 -202
- package/dist/connection-types.d.ts +5 -4
- package/dist/connection.d.ts +43 -43
- package/dist/connection.js +221 -77
- package/dist/crypto-entry.d.ts +4 -0
- package/dist/crypto-entry.js +4 -0
- package/dist/crypto.js +4 -4
- package/dist/external-store.d.ts +10 -0
- package/dist/external-store.js +10 -0
- package/dist/file-transfer-internals.d.ts +22 -0
- package/dist/file-transfer-internals.js +186 -0
- package/dist/files.d.ts +16 -12
- package/dist/files.js +52 -206
- package/dist/hosted-file-request.js +3 -3
- package/dist/index.d.ts +2 -5
- package/dist/index.js +1 -5
- package/dist/internal-types.d.ts +8 -1
- package/dist/local-file-transport.d.ts +2 -2
- package/dist/local-file-transport.js +13 -13
- package/dist/mdbase-connect.d.ts +6 -4
- package/dist/mdbase-connect.js +9 -8
- package/dist/notifications.d.ts +3 -2
- package/dist/operation-helpers.d.ts +3 -3
- package/dist/operation-helpers.js +12 -29
- package/dist/operation-types.d.ts +33 -8
- package/dist/outcomes.d.ts +15 -15
- package/dist/outcomes.js +13 -1
- package/dist/pending-mutation-store.d.ts +13 -0
- package/dist/pending-mutation-store.js +64 -0
- package/dist/request-budget.d.ts +27 -0
- package/dist/request-budget.js +95 -0
- package/dist/runtime-utils.d.ts +2 -0
- package/dist/runtime-utils.js +19 -0
- package/dist/session.d.ts +4 -3
- package/dist/session.js +4 -4
- package/dist/stored-token.d.ts +10 -0
- package/dist/stored-token.js +60 -0
- package/dist/token-response.d.ts +11 -0
- package/dist/token-response.js +77 -0
- package/package.json +12 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CollectionOperation, FileCapability, GrantScope, JsonObject, SyncChangesPage, SyncMutation, SyncMutationReceipt, SyncSession, SyncSnapshotPage } from "@mdbase-dev/connect-protocol";
|
|
2
|
+
import type { ConnectRequestOptions } from "./operation-types.js";
|
|
2
3
|
export type MdbaseConnectionRoute = "remote" | "direct" | "relay";
|
|
3
4
|
export type DirectAccessStatus = "disabled" | "permission_required" | "checking" | "available" | "unavailable" | "denied";
|
|
4
5
|
export interface MdbaseConnectionInfo {
|
|
@@ -25,10 +26,10 @@ export interface MdbaseAuthorizationCapabilities {
|
|
|
25
26
|
missingOperations: CollectionOperation[];
|
|
26
27
|
}
|
|
27
28
|
export interface MdbaseSyncTransport<Frontmatter extends JsonObject = JsonObject> {
|
|
28
|
-
openSession(): Promise<SyncSession>;
|
|
29
|
-
snapshot(snapshotId: string, page?: string): Promise<SyncSnapshotPage<Frontmatter>>;
|
|
30
|
-
changes(after: number, limit?: number): Promise<SyncChangesPage<Frontmatter>>;
|
|
31
|
-
mutate(mutation: SyncMutation): Promise<SyncMutationReceipt<Frontmatter>>;
|
|
29
|
+
openSession(options?: ConnectRequestOptions): Promise<SyncSession>;
|
|
30
|
+
snapshot(snapshotId: string, page?: string, options?: ConnectRequestOptions): Promise<SyncSnapshotPage<Frontmatter>>;
|
|
31
|
+
changes(after: number, limit?: number, options?: ConnectRequestOptions): Promise<SyncChangesPage<Frontmatter>>;
|
|
32
|
+
mutate(mutation: SyncMutation, options?: ConnectRequestOptions): Promise<SyncMutationReceipt<Frontmatter>>;
|
|
32
33
|
}
|
|
33
34
|
export interface MdbaseSyncConnection<Frontmatter extends JsonObject = JsonObject> {
|
|
34
35
|
collectionId: string;
|
package/dist/connection.d.ts
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CollectionChangesPage, CollectionDescription, CollectionOperation, CollectionTypeDocument, CreateViewSourceInput, DeleteViewSourceInput, DeleteViewSourceResult, ExecuteViewInput, FileCapability, GrantScope, JsonObject, ReadViewSourceInput, RecordDocument, SavedViewExecution, SavedViewList, SavedViewSourceDocument, ApplyTypePackInput, AssessTypePackInput, TypePackApplyResult, TypePackAssessment, UpdateViewSourceInput } from "@mdbase-dev/connect-protocol";
|
|
2
2
|
import { type ConnectionTransportInternals } from "./connection-transport.js";
|
|
3
3
|
import type { DirectAccessStatus, MdbaseAuthorizationCapabilities, MdbaseConnectionInfo, MdbaseConnectionRoute, MdbaseSyncConnection } from "./connection-types.js";
|
|
4
4
|
import type { GrantKeyStore } from "./crypto.js";
|
|
5
5
|
import { MdbaseFileClient } from "./files.js";
|
|
6
6
|
import { type Application } from "./internal-types.js";
|
|
7
7
|
import type { MdbaseNativeNotificationRegistration, MdbaseNativeNotificationRegistrationOptions, MdbaseNotificationRegistration, MdbaseNotificationRegistrationOptions } from "./notifications.js";
|
|
8
|
-
import type { ChangesInput, CreateInput, CreateTypeInput, DeleteInput, DeletePreflightResult, DeleteProgressOptions, DeleteResult, MdbaseDesiredTimer, MdbaseTimer, MdbaseTimerList, MdbaseTimerReconciliation,
|
|
8
|
+
import type { ChangesInput, CreateInput, CreateTypeInput, DeleteInput, DeletePreflightResult, DeleteProgressOptions, DeleteResult, MdbaseDesiredTimer, MdbaseTimer, MdbaseTimerList, MdbaseTimerReconciliation, ConnectRequestOptions, PendingMutation, QueryInput, QueryPage, QueryPagesOptions, QueryResult, ReadInput, ReadTypeInput, RenameInput, RenamePreflightResult, RenameProgressOptions, RenameResult, UpdateInput, UpdateTypeInput, MdbaseWatchSubscription, WatchInput } from "./operation-types.js";
|
|
9
9
|
import { type AuthorizationProblemCode, type CollectionChangesProblemCode, type CollectionDescriptionProblemCode, type CollectionMutationProblemCode, type CollectionQueryProblemCode, type CollectionReadProblemCode, type CollectionTypeProblemCode, type ConnectOutcome, type DirectAccessProblemCode, type NotificationProblemCode, type RegistrationProblemCode } from "./outcomes.js";
|
|
10
10
|
import type { MdbaseDeviceAuthorization } from "./authorization-types.js";
|
|
11
|
+
import { type ResolvedConnectTimeouts } from "./request-budget.js";
|
|
11
12
|
export type MdbaseAuthorizationTarget = {
|
|
12
13
|
kind: "choose";
|
|
13
14
|
} | {
|
|
14
15
|
kind: "collection";
|
|
15
16
|
collectionId: string;
|
|
16
17
|
};
|
|
17
|
-
export interface MdbaseAuthorizeOptions {
|
|
18
|
+
export interface MdbaseAuthorizeOptions extends ConnectRequestOptions {
|
|
18
19
|
operations?: CollectionOperation[];
|
|
19
20
|
/** Choose any compatible collection, or require one exact collection. */
|
|
20
21
|
target?: MdbaseAuthorizationTarget;
|
|
@@ -24,15 +25,12 @@ export interface MdbaseAuthorizeOptions {
|
|
|
24
25
|
onDeviceCode?: (authorization: MdbaseDeviceAuthorization) => void;
|
|
25
26
|
/** Replace the default popup for a downloaded application's approval page. */
|
|
26
27
|
openVerification?: (authorization: MdbaseDeviceAuthorization) => void | Promise<void>;
|
|
27
|
-
/** Stop polling and discard the unapproved, in-memory key. */
|
|
28
|
-
signal?: AbortSignal;
|
|
29
28
|
}
|
|
30
|
-
export interface MdbaseConnectionAuthorizeOptions {
|
|
29
|
+
export interface MdbaseConnectionAuthorizeOptions extends ConnectRequestOptions {
|
|
31
30
|
operations?: CollectionOperation[];
|
|
32
31
|
returnTo?: string;
|
|
33
32
|
onDeviceCode?: (authorization: MdbaseDeviceAuthorization) => void;
|
|
34
33
|
openVerification?: (authorization: MdbaseDeviceAuthorization) => void | Promise<void>;
|
|
35
|
-
signal?: AbortSignal;
|
|
36
34
|
}
|
|
37
35
|
export interface MdbaseConnectEnvironment {
|
|
38
36
|
distribution: "web" | "portable";
|
|
@@ -54,7 +52,8 @@ export interface MdbaseConnectionInternals<Frontmatter extends JsonObject> exten
|
|
|
54
52
|
readonly keyStore: GrantKeyStore;
|
|
55
53
|
readonly directAccessMode: "auto" | "disabled";
|
|
56
54
|
readonly loopbackUrl: string;
|
|
57
|
-
|
|
55
|
+
readonly timeouts: ResolvedConnectTimeouts;
|
|
56
|
+
register(options?: ConnectRequestOptions): Promise<Application>;
|
|
58
57
|
authorize(options?: MdbaseAuthorizeOptions): Promise<MdbaseAuthorizationOutcome<Frontmatter>>;
|
|
59
58
|
notificationKey(collectionId: string, transport?: "web_push" | "fcm"): string;
|
|
60
59
|
}
|
|
@@ -73,7 +72,7 @@ export declare class MdbaseConnection<Frontmatter extends JsonObject = JsonObjec
|
|
|
73
72
|
get fileCapability(): FileCapability | null;
|
|
74
73
|
get directAccess(): DirectAccessStatus;
|
|
75
74
|
get route(): MdbaseConnectionRoute;
|
|
76
|
-
register(): Promise<ConnectOutcome<Application, RegistrationProblemCode>>;
|
|
75
|
+
register(options?: ConnectRequestOptions): Promise<ConnectOutcome<Application, RegistrationProblemCode>>;
|
|
77
76
|
info(): MdbaseConnectionInfo | null;
|
|
78
77
|
authorizationCapabilities(requiredOperations?: CollectionOperation[]): MdbaseAuthorizationCapabilities;
|
|
79
78
|
hasOperations(requiredOperations: CollectionOperation[]): boolean;
|
|
@@ -84,9 +83,9 @@ export declare class MdbaseConnection<Frontmatter extends JsonObject = JsonObjec
|
|
|
84
83
|
}, AuthorizationProblemCode>>;
|
|
85
84
|
onConnectionChange(listener: (connection: MdbaseConnectionInfo | null) => void): () => void;
|
|
86
85
|
notifyStorageChanged(): void;
|
|
87
|
-
checkDirectAccess(): Promise<ConnectOutcome<DirectAccessStatus, DirectAccessProblemCode>>;
|
|
86
|
+
checkDirectAccess(options?: ConnectRequestOptions): Promise<ConnectOutcome<DirectAccessStatus, DirectAccessProblemCode>>;
|
|
88
87
|
/** Call from a user gesture to request browser permission for direct local access. */
|
|
89
|
-
requestDirectAccess(): Promise<ConnectOutcome<DirectAccessStatus, DirectAccessProblemCode>>;
|
|
88
|
+
requestDirectAccess(options?: ConnectRequestOptions): Promise<ConnectOutcome<DirectAccessStatus, DirectAccessProblemCode>>;
|
|
90
89
|
disableDirectAccess(): void;
|
|
91
90
|
/**
|
|
92
91
|
* Return one offline-replication transport regardless of whether the
|
|
@@ -102,48 +101,49 @@ export declare class MdbaseConnection<Frontmatter extends JsonObject = JsonObjec
|
|
|
102
101
|
*/
|
|
103
102
|
registerNotifications(options: MdbaseNotificationRegistrationOptions): Promise<ConnectOutcome<MdbaseNotificationRegistration, NotificationProblemCode>>;
|
|
104
103
|
registerNativeNotifications(options: MdbaseNativeNotificationRegistrationOptions): Promise<ConnectOutcome<MdbaseNativeNotificationRegistration, NotificationProblemCode>>;
|
|
105
|
-
unregisterNativeNotifications(): Promise<ConnectOutcome<void, NotificationProblemCode>>;
|
|
106
|
-
unregisterNotifications(serviceWorker?: ServiceWorkerRegistration): Promise<ConnectOutcome<void, NotificationProblemCode>>;
|
|
104
|
+
unregisterNativeNotifications(options?: ConnectRequestOptions): Promise<ConnectOutcome<void, NotificationProblemCode>>;
|
|
105
|
+
unregisterNotifications(serviceWorker?: ServiceWorkerRegistration, options?: ConnectRequestOptions): Promise<ConnectOutcome<void, NotificationProblemCode>>;
|
|
107
106
|
forget(): void;
|
|
108
|
-
describe(): Promise<ConnectOutcome<CollectionDescription, CollectionDescriptionProblemCode>>;
|
|
109
|
-
changes(input?: ChangesInput, options?:
|
|
110
|
-
read(input: ReadInput): Promise<ConnectOutcome<RecordDocument<Frontmatter>, CollectionReadProblemCode>>;
|
|
111
|
-
query(input?: QueryInput, options?:
|
|
107
|
+
describe(options?: ConnectRequestOptions): Promise<ConnectOutcome<CollectionDescription, CollectionDescriptionProblemCode>>;
|
|
108
|
+
changes(input?: ChangesInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<CollectionChangesPage, CollectionChangesProblemCode>>;
|
|
109
|
+
read(input: ReadInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<RecordDocument<Frontmatter>, CollectionReadProblemCode>>;
|
|
110
|
+
query(input?: QueryInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<QueryResult<Frontmatter>, CollectionQueryProblemCode>>;
|
|
112
111
|
queryPages(input?: QueryInput, options?: QueryPagesOptions<Frontmatter>): AsyncGenerator<ConnectOutcome<QueryPage<Frontmatter>, CollectionQueryProblemCode>>;
|
|
113
112
|
queryAll(input?: QueryInput, options?: QueryPagesOptions<Frontmatter>): Promise<ConnectOutcome<QueryResult<Frontmatter>, CollectionQueryProblemCode>>;
|
|
114
|
-
listViews(): Promise<ConnectOutcome<SavedViewList, CollectionReadProblemCode>>;
|
|
115
|
-
executeView(input: ExecuteViewInput): Promise<ConnectOutcome<SavedViewExecution<Frontmatter>, CollectionReadProblemCode>>;
|
|
116
|
-
readViewSource(input: ReadViewSourceInput): Promise<ConnectOutcome<SavedViewSourceDocument, CollectionReadProblemCode>>;
|
|
117
|
-
createViewSource(input: CreateViewSourceInput): Promise<ConnectOutcome<SavedViewSourceDocument, CollectionMutationProblemCode>>;
|
|
118
|
-
updateViewSource(input: UpdateViewSourceInput): Promise<ConnectOutcome<SavedViewSourceDocument, CollectionMutationProblemCode>>;
|
|
119
|
-
deleteViewSource(input: DeleteViewSourceInput): Promise<ConnectOutcome<DeleteViewSourceResult, CollectionMutationProblemCode>>;
|
|
120
|
-
create(input: CreateInput<Frontmatter
|
|
121
|
-
update(input: UpdateInput<Frontmatter
|
|
122
|
-
delete(input: DeleteInput, options?:
|
|
123
|
-
preflightDelete(input: DeleteInput, options?:
|
|
124
|
-
rename(input: RenameInput, options?:
|
|
125
|
-
preflightRename(input: RenameInput, options?:
|
|
113
|
+
listViews(options?: ConnectRequestOptions): Promise<ConnectOutcome<SavedViewList, CollectionReadProblemCode>>;
|
|
114
|
+
executeView(input: ExecuteViewInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<SavedViewExecution<Frontmatter>, CollectionReadProblemCode>>;
|
|
115
|
+
readViewSource(input: ReadViewSourceInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<SavedViewSourceDocument, CollectionReadProblemCode>>;
|
|
116
|
+
createViewSource(input: CreateViewSourceInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<SavedViewSourceDocument, CollectionMutationProblemCode>>;
|
|
117
|
+
updateViewSource(input: UpdateViewSourceInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<SavedViewSourceDocument, CollectionMutationProblemCode>>;
|
|
118
|
+
deleteViewSource(input: DeleteViewSourceInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<DeleteViewSourceResult, CollectionMutationProblemCode>>;
|
|
119
|
+
create(input: CreateInput<Frontmatter>, options?: ConnectRequestOptions): Promise<ConnectOutcome<RecordDocument<Frontmatter>, CollectionMutationProblemCode>>;
|
|
120
|
+
update(input: UpdateInput<Frontmatter>, options?: ConnectRequestOptions): Promise<ConnectOutcome<RecordDocument<Frontmatter>, CollectionMutationProblemCode>>;
|
|
121
|
+
delete(input: DeleteInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<DeleteResult, CollectionMutationProblemCode>>;
|
|
122
|
+
preflightDelete(input: DeleteInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<DeletePreflightResult, CollectionMutationProblemCode>>;
|
|
123
|
+
rename(input: RenameInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<RenameResult, CollectionMutationProblemCode>>;
|
|
124
|
+
preflightRename(input: RenameInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<RenamePreflightResult, CollectionMutationProblemCode>>;
|
|
126
125
|
renameWithProgress(input: RenameInput, options?: RenameProgressOptions): Promise<ConnectOutcome<RenameResult, CollectionMutationProblemCode>>;
|
|
127
126
|
deleteWithProgress(input: DeleteInput, options?: DeleteProgressOptions): Promise<ConnectOutcome<DeleteResult, CollectionMutationProblemCode>>;
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
127
|
+
pendingMutations<Result = unknown>(): readonly PendingMutation<Result>[];
|
|
128
|
+
pendingMutation<Result = unknown>(requestId: string): PendingMutation<Result> | null;
|
|
129
|
+
private recoverPendingMutation;
|
|
130
|
+
validate(input?: JsonObject, options?: ConnectRequestOptions): Promise<ConnectOutcome<JsonObject, CollectionReadProblemCode>>;
|
|
131
|
+
readType(input: ReadTypeInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<CollectionTypeDocument, CollectionTypeProblemCode>>;
|
|
132
|
+
createType(input: CreateTypeInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<CollectionTypeDocument, CollectionTypeProblemCode>>;
|
|
133
|
+
updateType(input: UpdateTypeInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<CollectionTypeDocument, CollectionTypeProblemCode>>;
|
|
134
|
+
assessTypePack(input: AssessTypePackInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<TypePackAssessment, CollectionTypeProblemCode>>;
|
|
135
|
+
applyTypePack(input: ApplyTypePackInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<TypePackApplyResult, CollectionTypeProblemCode>>;
|
|
136
|
+
listTimers(namespace: string, options?: ConnectRequestOptions): Promise<ConnectOutcome<MdbaseTimerList, CollectionReadProblemCode>>;
|
|
137
137
|
putTimer(input: {
|
|
138
138
|
namespace: string;
|
|
139
139
|
criterion_id: string;
|
|
140
140
|
timer: MdbaseDesiredTimer;
|
|
141
|
-
}): Promise<ConnectOutcome<MdbaseTimer, CollectionMutationProblemCode>>;
|
|
141
|
+
}, options?: ConnectRequestOptions): Promise<ConnectOutcome<MdbaseTimer, CollectionMutationProblemCode>>;
|
|
142
142
|
cancelTimer(input: {
|
|
143
143
|
namespace: string;
|
|
144
144
|
id: string;
|
|
145
145
|
generation?: number;
|
|
146
|
-
}): Promise<ConnectOutcome<{
|
|
146
|
+
}, options?: ConnectRequestOptions): Promise<ConnectOutcome<{
|
|
147
147
|
namespace: string;
|
|
148
148
|
id: string;
|
|
149
149
|
cancelled: boolean;
|
|
@@ -152,8 +152,8 @@ export declare class MdbaseConnection<Frontmatter extends JsonObject = JsonObjec
|
|
|
152
152
|
namespace: string;
|
|
153
153
|
criterion_id: string;
|
|
154
154
|
timers: MdbaseDesiredTimer[];
|
|
155
|
-
}): Promise<ConnectOutcome<MdbaseTimerReconciliation, CollectionMutationProblemCode>>;
|
|
156
|
-
watch(options?:
|
|
157
|
-
operation<Result>(operation: CollectionOperation, input: unknown, options?:
|
|
155
|
+
}, options?: ConnectRequestOptions): Promise<ConnectOutcome<MdbaseTimerReconciliation, CollectionMutationProblemCode>>;
|
|
156
|
+
watch(input?: WatchInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<MdbaseWatchSubscription, CollectionChangesProblemCode>>;
|
|
157
|
+
operation<Result>(operation: CollectionOperation, input: unknown, options?: ConnectRequestOptions): Promise<ConnectOutcome<Result>>;
|
|
158
158
|
private emitConnection;
|
|
159
159
|
}
|
package/dist/connection.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { MdbaseCollectionClient } from "./collection-client.js";
|
|
2
2
|
import { ConnectionNotifications } from "./connection-notifications.js";
|
|
3
3
|
import { ConnectionTransport } from "./connection-transport.js";
|
|
4
|
-
import { MdbaseConnectError } from "./errors.js";
|
|
4
|
+
import { MdbaseConnectError, connectProblem, operationProblem } from "./errors.js";
|
|
5
5
|
import { MdbaseFileClient } from "./files.js";
|
|
6
6
|
import { DEFAULT_OPERATIONS } from "./internal-types.js";
|
|
7
7
|
import { assertDeletePreview, assertRenamePreview, deleteEstimate, isCancellation, renameEstimate, throwIfCancelled, uniqueOperations } from "./operation-helpers.js";
|
|
8
|
-
import { AUTHORIZATION_PROBLEM_CODES, COLLECTION_MUTATION_PROBLEM_CODES, DIRECT_ACCESS_PROBLEM_CODES, NOTIFICATION_PROBLEM_CODES, REGISTRATION_PROBLEM_CODES, captureConnectOutcome, connectFailure, connectSuccess } from "./outcomes.js";
|
|
8
|
+
import { AUTHORIZATION_PROBLEM_CODES, COLLECTION_CHANGES_PROBLEM_CODES, COLLECTION_MUTATION_PROBLEM_CODES, DIRECT_ACCESS_PROBLEM_CODES, NOTIFICATION_PROBLEM_CODES, REGISTRATION_PROBLEM_CODES, captureConnectOutcome, connectFailure, connectSuccess } from "./outcomes.js";
|
|
9
|
+
import { withRequestBudget } from "./request-budget.js";
|
|
9
10
|
export class MdbaseConnection {
|
|
10
11
|
internals;
|
|
11
12
|
collectionId;
|
|
@@ -25,6 +26,7 @@ export class MdbaseConnection {
|
|
|
25
26
|
loopbackUrl: internals.loopbackUrl,
|
|
26
27
|
collectionId,
|
|
27
28
|
internals,
|
|
29
|
+
timeouts: internals.timeouts,
|
|
28
30
|
onChange: () => this.emitConnection()
|
|
29
31
|
});
|
|
30
32
|
this.files = new MdbaseFileClient(() => this.fileCapability, (method, path, input, signal) => this.transport.files.control(method, path, input, signal), {
|
|
@@ -32,16 +34,17 @@ export class MdbaseConnection {
|
|
|
32
34
|
downloadChunk: (session, chunkIndex, signal) => this.transport.files.downloadChunk(session, chunkIndex, signal)
|
|
33
35
|
}, {
|
|
34
36
|
downloadPart: (session, partIndex, expectedLength, signal) => this.transport.files.downloadHostedPart(session, partIndex, expectedLength, signal)
|
|
35
|
-
});
|
|
37
|
+
}, internals.timeouts);
|
|
36
38
|
this.collectionClient = new MdbaseCollectionClient({
|
|
37
39
|
operation: (operation, input, requestOptions) => this.transport.performOperation(operation, input, requestOptions)
|
|
38
40
|
});
|
|
39
41
|
this.notifications = new ConnectionNotifications({
|
|
40
42
|
serverUrl: internals.serverUrl,
|
|
41
43
|
storage: internals.storage,
|
|
42
|
-
authorizedToken: () => this.transport.authorizedToken(),
|
|
43
|
-
register: () => this.internals.register(),
|
|
44
|
-
notificationKey: (transport) => internals.notificationKey(collectionId, transport)
|
|
44
|
+
authorizedToken: (signal) => this.transport.authorizedToken({ signal, timeoutMs: null }),
|
|
45
|
+
register: (signal) => this.internals.register({ signal, timeoutMs: null }),
|
|
46
|
+
notificationKey: (transport) => internals.notificationKey(collectionId, transport),
|
|
47
|
+
requestTimeoutMs: internals.timeouts.requestMs
|
|
45
48
|
});
|
|
46
49
|
}
|
|
47
50
|
get displayName() {
|
|
@@ -63,8 +66,8 @@ export class MdbaseConnection {
|
|
|
63
66
|
get route() {
|
|
64
67
|
return this.transport.route;
|
|
65
68
|
}
|
|
66
|
-
register() {
|
|
67
|
-
return captureConnectOutcome(() => this.internals.register(), REGISTRATION_PROBLEM_CODES);
|
|
69
|
+
register(options) {
|
|
70
|
+
return captureConnectOutcome(() => this.internals.register(options), REGISTRATION_PROBLEM_CODES);
|
|
68
71
|
}
|
|
69
72
|
info() {
|
|
70
73
|
const token = this.transport.currentToken();
|
|
@@ -123,12 +126,12 @@ export class MdbaseConnection {
|
|
|
123
126
|
notifyStorageChanged() {
|
|
124
127
|
this.transport.notifyStorageChanged();
|
|
125
128
|
}
|
|
126
|
-
checkDirectAccess() {
|
|
127
|
-
return captureConnectOutcome(() => this.transport.checkDirectAccess(), DIRECT_ACCESS_PROBLEM_CODES);
|
|
129
|
+
checkDirectAccess(options) {
|
|
130
|
+
return captureConnectOutcome(() => this.transport.checkDirectAccess(options), DIRECT_ACCESS_PROBLEM_CODES);
|
|
128
131
|
}
|
|
129
132
|
/** Call from a user gesture to request browser permission for direct local access. */
|
|
130
|
-
requestDirectAccess() {
|
|
131
|
-
return captureConnectOutcome(() => this.transport.requestDirectAccess(), DIRECT_ACCESS_PROBLEM_CODES);
|
|
133
|
+
requestDirectAccess(options) {
|
|
134
|
+
return captureConnectOutcome(() => this.transport.requestDirectAccess(options), DIRECT_ACCESS_PROBLEM_CODES);
|
|
132
135
|
}
|
|
133
136
|
disableDirectAccess() {
|
|
134
137
|
this.transport.disableDirectAccess();
|
|
@@ -151,21 +154,21 @@ export class MdbaseConnection {
|
|
|
151
154
|
collectionId,
|
|
152
155
|
replicaId,
|
|
153
156
|
transport: {
|
|
154
|
-
openSession: () => this.transport.performOperation("sync", { action: "open_session" }),
|
|
155
|
-
snapshot: (snapshotId, page) => this.transport.performOperation("sync", {
|
|
157
|
+
openSession: (options) => this.transport.performOperation("sync", { action: "open_session" }, syncRequestOptions(options, this.internals.timeouts.syncMs)),
|
|
158
|
+
snapshot: (snapshotId, page, options) => this.transport.performOperation("sync", {
|
|
156
159
|
action: "snapshot",
|
|
157
160
|
snapshot_id: snapshotId,
|
|
158
161
|
...(page ? { page } : {})
|
|
159
|
-
}),
|
|
160
|
-
changes: (after, limit = 200) => this.transport.performOperation("sync", {
|
|
162
|
+
}, syncRequestOptions(options, this.internals.timeouts.syncMs)),
|
|
163
|
+
changes: (after, limit = 200, options) => this.transport.performOperation("sync", {
|
|
161
164
|
action: "changes",
|
|
162
165
|
after,
|
|
163
166
|
limit
|
|
164
|
-
}),
|
|
165
|
-
mutate: (mutation) => this.transport.performOperation("sync", {
|
|
167
|
+
}, syncRequestOptions(options, this.internals.timeouts.syncMs)),
|
|
168
|
+
mutate: (mutation, options) => this.transport.performOperation("sync", {
|
|
166
169
|
action: "mutate",
|
|
167
170
|
mutation
|
|
168
|
-
})
|
|
171
|
+
}, syncRequestOptions(options, this.internals.timeouts.syncMs))
|
|
169
172
|
}
|
|
170
173
|
};
|
|
171
174
|
}
|
|
@@ -174,15 +177,15 @@ export class MdbaseConnection {
|
|
|
174
177
|
collectionId,
|
|
175
178
|
replicaId,
|
|
176
179
|
transport: {
|
|
177
|
-
openSession: () => this.transport.performAuthoritySyncRequest(collectionId, replicaId, "POST", "sessions"),
|
|
178
|
-
snapshot: (snapshotId, page) => {
|
|
180
|
+
openSession: (options) => this.transport.performAuthoritySyncRequest(collectionId, replicaId, "POST", "sessions", undefined, options),
|
|
181
|
+
snapshot: (snapshotId, page, options) => {
|
|
179
182
|
const query = new URLSearchParams({ snapshot_id: snapshotId });
|
|
180
183
|
if (page)
|
|
181
184
|
query.set("page", page);
|
|
182
|
-
return this.transport.performAuthoritySyncRequest(collectionId, replicaId, "GET", `snapshot?${query}
|
|
185
|
+
return this.transport.performAuthoritySyncRequest(collectionId, replicaId, "GET", `snapshot?${query}`, undefined, options);
|
|
183
186
|
},
|
|
184
|
-
changes: (after, limit = 200) => this.transport.performAuthoritySyncRequest(collectionId, replicaId, "GET", `changes?${new URLSearchParams({ after: String(after), limit: String(limit) })}
|
|
185
|
-
mutate: (mutation) => this.transport.performAuthoritySyncRequest(collectionId, replicaId, "POST", "mutations", mutation)
|
|
187
|
+
changes: (after, limit = 200, options) => this.transport.performAuthoritySyncRequest(collectionId, replicaId, "GET", `changes?${new URLSearchParams({ after: String(after), limit: String(limit) })}`, undefined, options),
|
|
188
|
+
mutate: (mutation, options) => this.transport.performAuthoritySyncRequest(collectionId, replicaId, "POST", "mutations", mutation, options)
|
|
186
189
|
}
|
|
187
190
|
};
|
|
188
191
|
}
|
|
@@ -198,25 +201,25 @@ export class MdbaseConnection {
|
|
|
198
201
|
registerNativeNotifications(options) {
|
|
199
202
|
return captureConnectOutcome(() => this.notifications.registerNativeNotifications(options), NOTIFICATION_PROBLEM_CODES);
|
|
200
203
|
}
|
|
201
|
-
unregisterNativeNotifications() {
|
|
202
|
-
return captureConnectOutcome(() => this.notifications.unregisterNativeNotifications(), NOTIFICATION_PROBLEM_CODES);
|
|
204
|
+
unregisterNativeNotifications(options) {
|
|
205
|
+
return captureConnectOutcome(() => this.notifications.unregisterNativeNotifications(options), NOTIFICATION_PROBLEM_CODES);
|
|
203
206
|
}
|
|
204
|
-
unregisterNotifications(serviceWorker) {
|
|
205
|
-
return captureConnectOutcome(() => this.notifications.unregisterNotifications(serviceWorker), NOTIFICATION_PROBLEM_CODES);
|
|
207
|
+
unregisterNotifications(serviceWorker, options) {
|
|
208
|
+
return captureConnectOutcome(() => this.notifications.unregisterNotifications(serviceWorker, options), NOTIFICATION_PROBLEM_CODES);
|
|
206
209
|
}
|
|
207
210
|
forget() {
|
|
208
211
|
const token = this.transport.currentToken();
|
|
209
|
-
this.internals.removeToken(this.collectionId, token?.keyHandle, "not_authorized");
|
|
212
|
+
this.internals.removeToken(this.collectionId, token?.keyHandle, "not_authorized", true);
|
|
210
213
|
this.transport.notifyStorageChanged();
|
|
211
214
|
}
|
|
212
|
-
describe() {
|
|
213
|
-
return this.collectionClient.describe();
|
|
215
|
+
describe(options) {
|
|
216
|
+
return this.collectionClient.describe(options);
|
|
214
217
|
}
|
|
215
218
|
changes(input = {}, options) {
|
|
216
219
|
return this.collectionClient.changes(input, options);
|
|
217
220
|
}
|
|
218
|
-
read(input) {
|
|
219
|
-
return this.collectionClient.read(input);
|
|
221
|
+
read(input, options) {
|
|
222
|
+
return this.collectionClient.read(input, options);
|
|
220
223
|
}
|
|
221
224
|
query(input = {}, options) {
|
|
222
225
|
return this.collectionClient.query(input, options);
|
|
@@ -227,29 +230,29 @@ export class MdbaseConnection {
|
|
|
227
230
|
queryAll(input = {}, options = {}) {
|
|
228
231
|
return this.collectionClient.queryAll(input, options);
|
|
229
232
|
}
|
|
230
|
-
listViews() {
|
|
231
|
-
return this.collectionClient.listViews();
|
|
233
|
+
listViews(options) {
|
|
234
|
+
return this.collectionClient.listViews(options);
|
|
232
235
|
}
|
|
233
|
-
executeView(input) {
|
|
234
|
-
return this.collectionClient.executeView(input);
|
|
236
|
+
executeView(input, options) {
|
|
237
|
+
return this.collectionClient.executeView(input, options);
|
|
235
238
|
}
|
|
236
|
-
readViewSource(input) {
|
|
237
|
-
return this.collectionClient.readViewSource(input);
|
|
239
|
+
readViewSource(input, options) {
|
|
240
|
+
return this.collectionClient.readViewSource(input, options);
|
|
238
241
|
}
|
|
239
|
-
createViewSource(input) {
|
|
240
|
-
return this.collectionClient.createViewSource(input);
|
|
242
|
+
createViewSource(input, options) {
|
|
243
|
+
return this.collectionClient.createViewSource(input, options);
|
|
241
244
|
}
|
|
242
|
-
updateViewSource(input) {
|
|
243
|
-
return this.collectionClient.updateViewSource(input);
|
|
245
|
+
updateViewSource(input, options) {
|
|
246
|
+
return this.collectionClient.updateViewSource(input, options);
|
|
244
247
|
}
|
|
245
|
-
deleteViewSource(input) {
|
|
246
|
-
return this.collectionClient.deleteViewSource(input);
|
|
248
|
+
deleteViewSource(input, options) {
|
|
249
|
+
return this.collectionClient.deleteViewSource(input, options);
|
|
247
250
|
}
|
|
248
|
-
create(input) {
|
|
249
|
-
return this.collectionClient.create(input);
|
|
251
|
+
create(input, options) {
|
|
252
|
+
return this.collectionClient.create(input, options);
|
|
250
253
|
}
|
|
251
|
-
update(input) {
|
|
252
|
-
return this.collectionClient.update(input);
|
|
254
|
+
update(input, options) {
|
|
255
|
+
return this.collectionClient.update(input, options);
|
|
253
256
|
}
|
|
254
257
|
delete(input, options) {
|
|
255
258
|
return this.collectionClient.delete(input, options);
|
|
@@ -265,7 +268,7 @@ export class MdbaseConnection {
|
|
|
265
268
|
}
|
|
266
269
|
async renameWithProgress(input, options = {}) {
|
|
267
270
|
const started = Date.now();
|
|
268
|
-
const resumed =
|
|
271
|
+
const resumed = false;
|
|
269
272
|
let estimate;
|
|
270
273
|
const emit = (state, cancellable, completedUnits = 0) => {
|
|
271
274
|
options.onProgress?.({
|
|
@@ -317,7 +320,7 @@ export class MdbaseConnection {
|
|
|
317
320
|
}
|
|
318
321
|
async deleteWithProgress(input, options = {}) {
|
|
319
322
|
const started = Date.now();
|
|
320
|
-
const resumed =
|
|
323
|
+
const resumed = false;
|
|
321
324
|
let estimate;
|
|
322
325
|
const emit = (state, cancellable, completedUnits = 0) => {
|
|
323
326
|
options.onProgress?.({
|
|
@@ -367,44 +370,71 @@ export class MdbaseConnection {
|
|
|
367
370
|
throw error;
|
|
368
371
|
}
|
|
369
372
|
}
|
|
370
|
-
|
|
371
|
-
return this.transport.
|
|
373
|
+
pendingMutations() {
|
|
374
|
+
return this.transport.pendingMutations().map((summary) => ({
|
|
375
|
+
...summary,
|
|
376
|
+
recover: (options) => captureConnectOutcome(() => this.recoverPendingMutation(summary.requestId, options), COLLECTION_MUTATION_PROBLEM_CODES)
|
|
377
|
+
}));
|
|
372
378
|
}
|
|
373
|
-
|
|
374
|
-
|
|
379
|
+
pendingMutation(requestId) {
|
|
380
|
+
const summary = this.transport.pendingMutation(requestId);
|
|
381
|
+
if (!summary)
|
|
382
|
+
return null;
|
|
383
|
+
return {
|
|
384
|
+
...summary,
|
|
385
|
+
recover: (options) => captureConnectOutcome(() => this.recoverPendingMutation(requestId, options), COLLECTION_MUTATION_PROBLEM_CODES)
|
|
386
|
+
};
|
|
375
387
|
}
|
|
376
|
-
|
|
377
|
-
|
|
388
|
+
async recoverPendingMutation(requestId, options) {
|
|
389
|
+
const result = await this.transport.recoverPendingMutation(requestId, options);
|
|
390
|
+
if (result && typeof result === "object" && "valid" in result) {
|
|
391
|
+
const envelope = result;
|
|
392
|
+
if (!envelope.valid)
|
|
393
|
+
throw new MdbaseConnectError(operationProblem(envelope));
|
|
394
|
+
return envelope.result;
|
|
395
|
+
}
|
|
396
|
+
return result;
|
|
397
|
+
}
|
|
398
|
+
validate(input = {}, options) {
|
|
399
|
+
return this.collectionClient.validate(input, options);
|
|
378
400
|
}
|
|
379
|
-
readType(input) {
|
|
380
|
-
return this.collectionClient.readType(input);
|
|
401
|
+
readType(input, options) {
|
|
402
|
+
return this.collectionClient.readType(input, options);
|
|
381
403
|
}
|
|
382
|
-
createType(input) {
|
|
383
|
-
return this.collectionClient.createType(input);
|
|
404
|
+
createType(input, options) {
|
|
405
|
+
return this.collectionClient.createType(input, options);
|
|
384
406
|
}
|
|
385
|
-
updateType(input) {
|
|
386
|
-
return this.collectionClient.updateType(input);
|
|
407
|
+
updateType(input, options) {
|
|
408
|
+
return this.collectionClient.updateType(input, options);
|
|
387
409
|
}
|
|
388
|
-
assessTypePack(input) {
|
|
389
|
-
return this.collectionClient.assessTypePack(input);
|
|
410
|
+
assessTypePack(input, options) {
|
|
411
|
+
return this.collectionClient.assessTypePack(input, options);
|
|
390
412
|
}
|
|
391
|
-
applyTypePack(input) {
|
|
392
|
-
return this.collectionClient.applyTypePack(input);
|
|
413
|
+
applyTypePack(input, options) {
|
|
414
|
+
return this.collectionClient.applyTypePack(input, options);
|
|
393
415
|
}
|
|
394
|
-
listTimers(namespace) {
|
|
395
|
-
return this.collectionClient.listTimers(namespace);
|
|
416
|
+
listTimers(namespace, options) {
|
|
417
|
+
return this.collectionClient.listTimers(namespace, options);
|
|
396
418
|
}
|
|
397
|
-
putTimer(input) {
|
|
398
|
-
return this.collectionClient.putTimer(input);
|
|
419
|
+
putTimer(input, options) {
|
|
420
|
+
return this.collectionClient.putTimer(input, options);
|
|
399
421
|
}
|
|
400
|
-
cancelTimer(input) {
|
|
401
|
-
return this.collectionClient.cancelTimer(input);
|
|
422
|
+
cancelTimer(input, options) {
|
|
423
|
+
return this.collectionClient.cancelTimer(input, options);
|
|
402
424
|
}
|
|
403
|
-
reconcileTimers(input) {
|
|
404
|
-
return this.collectionClient.reconcileTimers(input);
|
|
425
|
+
reconcileTimers(input, options) {
|
|
426
|
+
return this.collectionClient.reconcileTimers(input, options);
|
|
405
427
|
}
|
|
406
|
-
watch(options = {}) {
|
|
407
|
-
return this.
|
|
428
|
+
watch(input = {}, options = {}) {
|
|
429
|
+
return captureConnectOutcome(() => withRequestBudget(options, this.internals.timeouts.watchStartMs, async (budget) => {
|
|
430
|
+
const initial = await this.collectionClient.changes(input.cursor === undefined ? {} : { after: input.cursor, limit: 200 }, { signal: budget.signal, timeoutMs: null });
|
|
431
|
+
if (!initial.ok)
|
|
432
|
+
throw new MdbaseConnectError(initial.problem);
|
|
433
|
+
if (initial.value.reset) {
|
|
434
|
+
throw new MdbaseConnectError(connectProblem("change_cursor_reset", "The collection change cursor expired. Refresh collection state before subscribing again."));
|
|
435
|
+
}
|
|
436
|
+
return new CollectionWatchSubscription(this.collectionClient, initial.value.cursor, input, input.cursor === undefined ? [] : initial.value.events, this.internals.timeouts.watchStartMs);
|
|
437
|
+
}), COLLECTION_CHANGES_PROBLEM_CODES);
|
|
408
438
|
}
|
|
409
439
|
operation(operation, input, options) {
|
|
410
440
|
return this.collectionClient.operation(operation, input, options);
|
|
@@ -415,3 +445,117 @@ export class MdbaseConnection {
|
|
|
415
445
|
listener(connection);
|
|
416
446
|
}
|
|
417
447
|
}
|
|
448
|
+
class CollectionWatchSubscription {
|
|
449
|
+
client;
|
|
450
|
+
input;
|
|
451
|
+
watchStartTimeoutMs;
|
|
452
|
+
changes = new Set();
|
|
453
|
+
statuses = new Set();
|
|
454
|
+
problems = new Set();
|
|
455
|
+
controller = new AbortController();
|
|
456
|
+
removeLifetimeAbort;
|
|
457
|
+
currentStatus;
|
|
458
|
+
currentProblem = null;
|
|
459
|
+
pendingChanges;
|
|
460
|
+
constructor(client, cursor, input, pendingChanges, watchStartTimeoutMs) {
|
|
461
|
+
this.client = client;
|
|
462
|
+
this.input = input;
|
|
463
|
+
this.watchStartTimeoutMs = watchStartTimeoutMs;
|
|
464
|
+
this.pendingChanges = [...pendingChanges];
|
|
465
|
+
this.currentStatus = { state: "connected", cursor, recovered: false };
|
|
466
|
+
const lifetimeSignal = input.lifetimeSignal;
|
|
467
|
+
if (lifetimeSignal?.aborted)
|
|
468
|
+
this.close();
|
|
469
|
+
else if (lifetimeSignal) {
|
|
470
|
+
const close = () => this.close();
|
|
471
|
+
lifetimeSignal.addEventListener("abort", close, { once: true });
|
|
472
|
+
this.removeLifetimeAbort = () => lifetimeSignal.removeEventListener("abort", close);
|
|
473
|
+
}
|
|
474
|
+
if (!this.controller.signal.aborted)
|
|
475
|
+
void this.run(cursor);
|
|
476
|
+
}
|
|
477
|
+
get status() {
|
|
478
|
+
return this.currentStatus;
|
|
479
|
+
}
|
|
480
|
+
get problem() {
|
|
481
|
+
return this.currentProblem;
|
|
482
|
+
}
|
|
483
|
+
subscribe(listener, onStatus, onProblem) {
|
|
484
|
+
this.changes.add(listener);
|
|
485
|
+
if (onStatus) {
|
|
486
|
+
this.statuses.add(onStatus);
|
|
487
|
+
onStatus(this.currentStatus);
|
|
488
|
+
}
|
|
489
|
+
if (onProblem) {
|
|
490
|
+
this.problems.add(onProblem);
|
|
491
|
+
if (this.currentProblem)
|
|
492
|
+
onProblem(this.currentProblem);
|
|
493
|
+
}
|
|
494
|
+
for (const change of this.pendingChanges)
|
|
495
|
+
listener(change);
|
|
496
|
+
this.pendingChanges = [];
|
|
497
|
+
return () => {
|
|
498
|
+
this.changes.delete(listener);
|
|
499
|
+
if (onStatus)
|
|
500
|
+
this.statuses.delete(onStatus);
|
|
501
|
+
if (onProblem)
|
|
502
|
+
this.problems.delete(onProblem);
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
close() {
|
|
506
|
+
if (this.controller.signal.aborted)
|
|
507
|
+
return;
|
|
508
|
+
this.controller.abort();
|
|
509
|
+
this.removeLifetimeAbort?.();
|
|
510
|
+
this.removeLifetimeAbort = undefined;
|
|
511
|
+
const cursor = "cursor" in this.currentStatus ? this.currentStatus.cursor : undefined;
|
|
512
|
+
this.publishStatus({ state: "closed", ...(cursor === undefined ? {} : { cursor }) });
|
|
513
|
+
}
|
|
514
|
+
async run(cursor) {
|
|
515
|
+
let firstStatus = true;
|
|
516
|
+
const iterator = this.client.watch({
|
|
517
|
+
cursor,
|
|
518
|
+
pollIntervalMs: this.input.pollIntervalMs,
|
|
519
|
+
retry: this.input.retry,
|
|
520
|
+
signal: this.controller.signal,
|
|
521
|
+
timeoutMs: this.watchStartTimeoutMs,
|
|
522
|
+
onStatus: (status) => {
|
|
523
|
+
if (firstStatus && status.state === "connecting") {
|
|
524
|
+
firstStatus = false;
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
firstStatus = false;
|
|
528
|
+
this.publishStatus(status);
|
|
529
|
+
}
|
|
530
|
+
});
|
|
531
|
+
try {
|
|
532
|
+
for await (const outcome of iterator) {
|
|
533
|
+
if (this.controller.signal.aborted)
|
|
534
|
+
return;
|
|
535
|
+
if (!outcome.ok) {
|
|
536
|
+
this.currentProblem = outcome.problem;
|
|
537
|
+
for (const listener of this.problems)
|
|
538
|
+
listener(outcome.problem);
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
for (const listener of this.changes)
|
|
542
|
+
listener(outcome.value);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
finally {
|
|
546
|
+
if (!this.controller.signal.aborted)
|
|
547
|
+
this.close();
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
publishStatus(status) {
|
|
551
|
+
this.currentStatus = status;
|
|
552
|
+
for (const listener of this.statuses)
|
|
553
|
+
listener(status);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
function syncRequestOptions(options, defaultTimeoutMs) {
|
|
557
|
+
return {
|
|
558
|
+
...options,
|
|
559
|
+
timeoutMs: options?.timeoutMs === undefined ? defaultTimeoutMs : options.timeoutMs
|
|
560
|
+
};
|
|
561
|
+
}
|