@mdbase-dev/connect 0.1.0-beta.21 → 0.1.0-beta.22
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 +108 -38
- package/dist/authorization-url.d.ts +2 -1
- package/dist/authorization-url.js +5 -7
- 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/collection-client.d.ts +34 -31
- package/dist/collection-client.js +107 -61
- package/dist/connect.d.ts +4 -3
- package/dist/connect.js +53 -38
- package/dist/connection-file-transport.d.ts +31 -0
- package/dist/connection-file-transport.js +42 -0
- package/dist/connection-notifications.js +21 -21
- package/dist/connection-transport.d.ts +2 -0
- package/dist/connection-transport.js +95 -37
- package/dist/connection-types.d.ts +2 -1
- package/dist/connection.d.ts +49 -45
- package/dist/connection.js +73 -33
- package/dist/crypto.d.ts +5 -6
- package/dist/crypto.js +13 -13
- package/dist/errors.d.ts +38 -24
- package/dist/errors.js +130 -71
- package/dist/file-crypto.d.ts +25 -0
- package/dist/file-crypto.js +132 -0
- package/dist/file-sha256.d.ts +12 -0
- package/dist/file-sha256.js +143 -0
- package/dist/file-stream-source.d.ts +17 -0
- package/dist/file-stream-source.js +157 -0
- package/dist/files.d.ts +91 -0
- package/dist/files.js +644 -0
- package/dist/hosted-file-request.d.ts +6 -0
- package/dist/hosted-file-request.js +63 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +3 -0
- package/dist/internal-types.d.ts +3 -1
- package/dist/local-file-transport.d.ts +30 -0
- package/dist/local-file-transport.js +367 -0
- package/dist/notifications.js +5 -5
- package/dist/operation-helpers.d.ts +2 -2
- package/dist/operation-helpers.js +22 -18
- package/dist/operation-types.d.ts +3 -4
- package/dist/outcomes.d.ts +51 -0
- package/dist/outcomes.js +168 -0
- package/dist/runtime-utils.d.ts +6 -1
- package/dist/runtime-utils.js +90 -11
- package/dist/selection.js +3 -3
- package/dist/session.d.ts +9 -8
- package/dist/session.js +31 -20
- package/package.json +2 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { CollectionChange, CollectionChangesPage, CollectionDescription, CollectionOperation, CollectionTypeDocument, CreateViewSourceInput, DeleteViewSourceInput, DeleteViewSourceResult, ExecuteViewInput, JsonObject,
|
|
1
|
+
import type { CollectionChange, CollectionChangesPage, CollectionDescription, CollectionOperation, CollectionTypeDocument, CreateViewSourceInput, DeleteViewSourceInput, DeleteViewSourceResult, ExecuteViewInput, JsonObject, ReadViewSourceInput, RecordDocument, SavedViewExecution, SavedViewList, SavedViewSourceDocument, TypePackInstallResult, TypePackProvision, UpdateViewSourceInput } from "@mdbase-dev/connect-protocol";
|
|
2
|
+
import { type CollectionChangesProblemCode, type CollectionDescriptionProblemCode, type CollectionMutationProblemCode, type CollectionQueryProblemCode, type CollectionReadProblemCode, type CollectionTypeProblemCode, type ConnectOutcome } from "./outcomes.js";
|
|
2
3
|
import type { ChangesInput, CreateInput, CreateTypeInput, DeleteInput, DeletePreflightResult, DeleteResult, MdbaseCollectionTransport, MdbaseDesiredTimer, MdbaseTimer, MdbaseTimerList, MdbaseTimerReconciliation, OperationRequestOptions, QueryInput, QueryPage, QueryPagesOptions, QueryResult, ReadInput, ReadTypeInput, RenameInput, RenamePreflightResult, RenameResult, UpdateInput, UpdateTypeInput, WatchOptions } from "./operation-types.js";
|
|
3
4
|
/**
|
|
4
5
|
* Typed collection operations independent of OAuth, HTTP, or storage.
|
|
@@ -9,49 +10,51 @@ import type { ChangesInput, CreateInput, CreateTypeInput, DeleteInput, DeletePre
|
|
|
9
10
|
export declare class MdbaseCollectionClient<Frontmatter extends JsonObject = JsonObject> {
|
|
10
11
|
private readonly transport;
|
|
11
12
|
constructor(transport: MdbaseCollectionTransport);
|
|
12
|
-
operation<Result>(operation: CollectionOperation, input: unknown, options?: OperationRequestOptions): Promise<Result
|
|
13
|
-
describe(): Promise<CollectionDescription
|
|
14
|
-
changes(input?: ChangesInput, options?: OperationRequestOptions): Promise<CollectionChangesPage
|
|
15
|
-
read(input: ReadInput): Promise<
|
|
16
|
-
query(input?: QueryInput, options?: OperationRequestOptions): Promise<
|
|
17
|
-
queryPages(input?: QueryInput, options?: QueryPagesOptions<Frontmatter>): AsyncGenerator<QueryPage<Frontmatter>>;
|
|
18
|
-
queryAll(input?: QueryInput, options?: QueryPagesOptions<Frontmatter>): Promise<QueryResult<Frontmatter>>;
|
|
19
|
-
listViews(): Promise<
|
|
20
|
-
executeView(input: ExecuteViewInput): Promise<
|
|
21
|
-
readViewSource(input: ReadViewSourceInput): Promise<
|
|
22
|
-
createViewSource(input: CreateViewSourceInput): Promise<
|
|
23
|
-
updateViewSource(input: UpdateViewSourceInput): Promise<
|
|
24
|
-
deleteViewSource(input: DeleteViewSourceInput): Promise<
|
|
25
|
-
create(input: CreateInput<Frontmatter>): Promise<
|
|
26
|
-
update(input: UpdateInput<Frontmatter>): Promise<
|
|
27
|
-
delete(input: DeleteInput, options?: OperationRequestOptions): Promise<
|
|
28
|
-
preflightDelete(input: DeleteInput, options?: OperationRequestOptions): Promise<
|
|
29
|
-
rename(input: RenameInput, options?: OperationRequestOptions): Promise<
|
|
30
|
-
preflightRename(input: RenameInput, options?: OperationRequestOptions): Promise<
|
|
31
|
-
validate(input?: JsonObject): Promise<
|
|
32
|
-
readType(input: ReadTypeInput): Promise<
|
|
33
|
-
createType(input: CreateTypeInput): Promise<
|
|
34
|
-
updateType(input: UpdateTypeInput): Promise<
|
|
35
|
-
installTypePack(input: TypePackProvision): Promise<
|
|
36
|
-
listTimers(namespace: string): Promise<MdbaseTimerList
|
|
13
|
+
operation<Result>(operation: CollectionOperation, input: unknown, options?: OperationRequestOptions): Promise<ConnectOutcome<Result>>;
|
|
14
|
+
describe(): Promise<ConnectOutcome<CollectionDescription, CollectionDescriptionProblemCode>>;
|
|
15
|
+
changes(input?: ChangesInput, options?: OperationRequestOptions): Promise<ConnectOutcome<CollectionChangesPage, CollectionChangesProblemCode>>;
|
|
16
|
+
read(input: ReadInput): Promise<ConnectOutcome<RecordDocument<Frontmatter>, CollectionReadProblemCode>>;
|
|
17
|
+
query(input?: QueryInput, options?: OperationRequestOptions): Promise<ConnectOutcome<QueryResult<Frontmatter>, CollectionQueryProblemCode>>;
|
|
18
|
+
queryPages(input?: QueryInput, options?: QueryPagesOptions<Frontmatter>): AsyncGenerator<ConnectOutcome<QueryPage<Frontmatter>, CollectionQueryProblemCode>>;
|
|
19
|
+
queryAll(input?: QueryInput, options?: QueryPagesOptions<Frontmatter>): Promise<ConnectOutcome<QueryResult<Frontmatter>, CollectionQueryProblemCode>>;
|
|
20
|
+
listViews(): Promise<ConnectOutcome<SavedViewList, CollectionReadProblemCode>>;
|
|
21
|
+
executeView(input: ExecuteViewInput): Promise<ConnectOutcome<SavedViewExecution<Frontmatter>, CollectionReadProblemCode>>;
|
|
22
|
+
readViewSource(input: ReadViewSourceInput): Promise<ConnectOutcome<SavedViewSourceDocument, CollectionReadProblemCode>>;
|
|
23
|
+
createViewSource(input: CreateViewSourceInput): Promise<ConnectOutcome<SavedViewSourceDocument, CollectionMutationProblemCode>>;
|
|
24
|
+
updateViewSource(input: UpdateViewSourceInput): Promise<ConnectOutcome<SavedViewSourceDocument, CollectionMutationProblemCode>>;
|
|
25
|
+
deleteViewSource(input: DeleteViewSourceInput): Promise<ConnectOutcome<DeleteViewSourceResult, CollectionMutationProblemCode>>;
|
|
26
|
+
create(input: CreateInput<Frontmatter>): Promise<ConnectOutcome<RecordDocument<Frontmatter>, CollectionMutationProblemCode>>;
|
|
27
|
+
update(input: UpdateInput<Frontmatter>): Promise<ConnectOutcome<RecordDocument<Frontmatter>, CollectionMutationProblemCode>>;
|
|
28
|
+
delete(input: DeleteInput, options?: OperationRequestOptions): Promise<ConnectOutcome<DeleteResult, CollectionMutationProblemCode>>;
|
|
29
|
+
preflightDelete(input: DeleteInput, options?: OperationRequestOptions): Promise<ConnectOutcome<DeletePreflightResult, CollectionMutationProblemCode>>;
|
|
30
|
+
rename(input: RenameInput, options?: OperationRequestOptions): Promise<ConnectOutcome<RenameResult, CollectionMutationProblemCode>>;
|
|
31
|
+
preflightRename(input: RenameInput, options?: OperationRequestOptions): Promise<ConnectOutcome<RenamePreflightResult, CollectionMutationProblemCode>>;
|
|
32
|
+
validate(input?: JsonObject): Promise<ConnectOutcome<JsonObject, CollectionReadProblemCode>>;
|
|
33
|
+
readType(input: ReadTypeInput): Promise<ConnectOutcome<CollectionTypeDocument, CollectionTypeProblemCode>>;
|
|
34
|
+
createType(input: CreateTypeInput): Promise<ConnectOutcome<CollectionTypeDocument, CollectionTypeProblemCode>>;
|
|
35
|
+
updateType(input: UpdateTypeInput): Promise<ConnectOutcome<CollectionTypeDocument, CollectionTypeProblemCode>>;
|
|
36
|
+
installTypePack(input: TypePackProvision): Promise<ConnectOutcome<TypePackInstallResult, CollectionTypeProblemCode>>;
|
|
37
|
+
listTimers(namespace: string): Promise<ConnectOutcome<MdbaseTimerList, CollectionReadProblemCode>>;
|
|
37
38
|
putTimer(input: {
|
|
38
39
|
namespace: string;
|
|
39
40
|
criterion_id: string;
|
|
40
41
|
timer: MdbaseDesiredTimer;
|
|
41
|
-
}): Promise<MdbaseTimer
|
|
42
|
+
}): Promise<ConnectOutcome<MdbaseTimer, CollectionMutationProblemCode>>;
|
|
42
43
|
cancelTimer(input: {
|
|
43
44
|
namespace: string;
|
|
44
45
|
id: string;
|
|
45
46
|
generation?: number;
|
|
46
|
-
}): Promise<{
|
|
47
|
+
}): Promise<ConnectOutcome<{
|
|
47
48
|
namespace: string;
|
|
48
49
|
id: string;
|
|
49
50
|
cancelled: boolean;
|
|
50
|
-
}
|
|
51
|
+
}, CollectionMutationProblemCode>>;
|
|
51
52
|
reconcileTimers(input: {
|
|
52
53
|
namespace: string;
|
|
53
54
|
criterion_id: string;
|
|
54
55
|
timers: MdbaseDesiredTimer[];
|
|
55
|
-
}): Promise<MdbaseTimerReconciliation
|
|
56
|
-
watch(options?: WatchOptions): AsyncGenerator<CollectionChange
|
|
56
|
+
}): Promise<ConnectOutcome<MdbaseTimerReconciliation, CollectionMutationProblemCode>>;
|
|
57
|
+
watch(options?: WatchOptions): AsyncGenerator<ConnectOutcome<CollectionChange, CollectionChangesProblemCode>>;
|
|
58
|
+
private rawOperation;
|
|
59
|
+
private envelopeOperation;
|
|
57
60
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { abortableDelay } from "./async.js";
|
|
2
|
-
import {
|
|
2
|
+
import { connectError, connectProblem, operationProblem } from "./errors.js";
|
|
3
|
+
import { COLLECTION_CHANGES_PROBLEM_CODES, COLLECTION_DESCRIPTION_PROBLEM_CODES, COLLECTION_MUTATION_PROBLEM_CODES, COLLECTION_QUERY_PROBLEM_CODES, COLLECTION_READ_PROBLEM_CODES, COLLECTION_TYPE_PROBLEM_CODES, ALL_CONNECT_PROBLEM_CODES, captureConnectOutcome, connectFailure, connectSuccess } from "./outcomes.js";
|
|
3
4
|
/**
|
|
4
5
|
* Typed collection operations independent of OAuth, HTTP, or storage.
|
|
5
6
|
*
|
|
@@ -12,19 +13,19 @@ export class MdbaseCollectionClient {
|
|
|
12
13
|
this.transport = transport;
|
|
13
14
|
}
|
|
14
15
|
operation(operation, input, options) {
|
|
15
|
-
return this.transport.operation(operation, input, options);
|
|
16
|
+
return captureConnectOutcome(() => this.transport.operation(operation, input, options), ALL_CONNECT_PROBLEM_CODES);
|
|
16
17
|
}
|
|
17
18
|
describe() {
|
|
18
|
-
return this.
|
|
19
|
+
return this.rawOperation("describe", {}, COLLECTION_DESCRIPTION_PROBLEM_CODES);
|
|
19
20
|
}
|
|
20
21
|
changes(input = {}, options) {
|
|
21
|
-
return this.
|
|
22
|
+
return this.rawOperation("changes", input, COLLECTION_CHANGES_PROBLEM_CODES, options);
|
|
22
23
|
}
|
|
23
24
|
read(input) {
|
|
24
|
-
return this.
|
|
25
|
+
return this.envelopeOperation("read", input, COLLECTION_READ_PROBLEM_CODES);
|
|
25
26
|
}
|
|
26
27
|
query(input = {}, options) {
|
|
27
|
-
return this.
|
|
28
|
+
return this.envelopeOperation("query", input, COLLECTION_QUERY_PROBLEM_CODES, options);
|
|
28
29
|
}
|
|
29
30
|
async *queryPages(input = {}, options = {}) {
|
|
30
31
|
const { offset: requestedOffset, limit: requestedLimit, snapshot: requestedSnapshot, ...criteria } = input;
|
|
@@ -35,15 +36,21 @@ export class MdbaseCollectionClient {
|
|
|
35
36
|
let loaded = 0;
|
|
36
37
|
let pageNumber = 0;
|
|
37
38
|
while (!options.signal?.aborted) {
|
|
38
|
-
const
|
|
39
|
+
const queried = await this.query({
|
|
39
40
|
...criteria,
|
|
40
41
|
offset,
|
|
41
42
|
limit: pageNumber === 0 ? firstPageSize : pageSize,
|
|
42
43
|
...(snapshot ? { snapshot } : {})
|
|
43
|
-
}, { signal: options.signal })
|
|
44
|
+
}, { signal: options.signal });
|
|
45
|
+
if (!queried.ok) {
|
|
46
|
+
yield queried;
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const result = queried.value;
|
|
44
50
|
const returnedSnapshot = result.meta?.snapshot;
|
|
45
51
|
if (snapshot && returnedSnapshot && snapshot !== returnedSnapshot) {
|
|
46
|
-
|
|
52
|
+
yield connectFailure(connectProblem("query_snapshot_changed", "The collection query snapshot changed while paging. Refresh the query before continuing."));
|
|
53
|
+
return;
|
|
47
54
|
}
|
|
48
55
|
if (!snapshot && returnedSnapshot)
|
|
49
56
|
snapshot = returnedSnapshot;
|
|
@@ -59,7 +66,7 @@ export class MdbaseCollectionClient {
|
|
|
59
66
|
...(snapshot ? { snapshot } : {})
|
|
60
67
|
};
|
|
61
68
|
options.onProgress?.(page);
|
|
62
|
-
yield page;
|
|
69
|
+
yield connectSuccess(page, queried.diagnostics);
|
|
63
70
|
if (complete)
|
|
64
71
|
return;
|
|
65
72
|
offset += result.results.length;
|
|
@@ -69,11 +76,16 @@ export class MdbaseCollectionClient {
|
|
|
69
76
|
async queryAll(input = {}, options = {}) {
|
|
70
77
|
const results = [];
|
|
71
78
|
let finalPage;
|
|
72
|
-
|
|
79
|
+
const diagnostics = [];
|
|
80
|
+
for await (const outcome of this.queryPages(input, options)) {
|
|
81
|
+
if (!outcome.ok)
|
|
82
|
+
return outcome;
|
|
83
|
+
const page = outcome.value;
|
|
73
84
|
results.push(...page.results);
|
|
74
85
|
finalPage = page;
|
|
86
|
+
diagnostics.push(...outcome.diagnostics);
|
|
75
87
|
}
|
|
76
|
-
return {
|
|
88
|
+
return connectSuccess({
|
|
77
89
|
results,
|
|
78
90
|
meta: {
|
|
79
91
|
...(finalPage?.meta ?? {}),
|
|
@@ -81,70 +93,70 @@ export class MdbaseCollectionClient {
|
|
|
81
93
|
has_more: finalPage ? !finalPage.complete : false,
|
|
82
94
|
...(finalPage?.snapshot ? { snapshot: finalPage.snapshot } : {})
|
|
83
95
|
}
|
|
84
|
-
};
|
|
96
|
+
}, diagnostics);
|
|
85
97
|
}
|
|
86
98
|
listViews() {
|
|
87
|
-
return this.
|
|
99
|
+
return this.envelopeOperation("list_views", {}, COLLECTION_READ_PROBLEM_CODES);
|
|
88
100
|
}
|
|
89
101
|
executeView(input) {
|
|
90
|
-
return this.
|
|
102
|
+
return this.envelopeOperation("execute_view", input, COLLECTION_READ_PROBLEM_CODES);
|
|
91
103
|
}
|
|
92
104
|
readViewSource(input) {
|
|
93
|
-
return this.
|
|
105
|
+
return this.envelopeOperation("read_view_source", input, COLLECTION_READ_PROBLEM_CODES);
|
|
94
106
|
}
|
|
95
107
|
createViewSource(input) {
|
|
96
|
-
return this.
|
|
108
|
+
return this.envelopeOperation("create_view_source", input, COLLECTION_MUTATION_PROBLEM_CODES);
|
|
97
109
|
}
|
|
98
110
|
updateViewSource(input) {
|
|
99
|
-
return this.
|
|
111
|
+
return this.envelopeOperation("update_view_source", input, COLLECTION_MUTATION_PROBLEM_CODES);
|
|
100
112
|
}
|
|
101
113
|
deleteViewSource(input) {
|
|
102
|
-
return this.
|
|
114
|
+
return this.envelopeOperation("delete_view_source", input, COLLECTION_MUTATION_PROBLEM_CODES);
|
|
103
115
|
}
|
|
104
116
|
create(input) {
|
|
105
|
-
return this.
|
|
117
|
+
return this.envelopeOperation("create", input, COLLECTION_MUTATION_PROBLEM_CODES);
|
|
106
118
|
}
|
|
107
119
|
update(input) {
|
|
108
|
-
return this.
|
|
120
|
+
return this.envelopeOperation("update", input, COLLECTION_MUTATION_PROBLEM_CODES);
|
|
109
121
|
}
|
|
110
122
|
delete(input, options) {
|
|
111
|
-
return this.
|
|
123
|
+
return this.envelopeOperation("delete", input, COLLECTION_MUTATION_PROBLEM_CODES, options);
|
|
112
124
|
}
|
|
113
125
|
preflightDelete(input, options) {
|
|
114
|
-
return this.
|
|
126
|
+
return this.envelopeOperation("delete", { ...input, check_backlinks: true, dry_run: true }, COLLECTION_MUTATION_PROBLEM_CODES, options);
|
|
115
127
|
}
|
|
116
128
|
rename(input, options) {
|
|
117
|
-
return this.
|
|
129
|
+
return this.envelopeOperation("rename", input, COLLECTION_MUTATION_PROBLEM_CODES, options);
|
|
118
130
|
}
|
|
119
131
|
preflightRename(input, options) {
|
|
120
|
-
return this.
|
|
132
|
+
return this.envelopeOperation("rename", { ...input, dry_run: true }, COLLECTION_MUTATION_PROBLEM_CODES, options);
|
|
121
133
|
}
|
|
122
134
|
validate(input = {}) {
|
|
123
|
-
return this.
|
|
135
|
+
return this.envelopeOperation("validate", input, COLLECTION_READ_PROBLEM_CODES);
|
|
124
136
|
}
|
|
125
137
|
readType(input) {
|
|
126
|
-
return this.
|
|
138
|
+
return this.envelopeOperation("read_type", input, COLLECTION_TYPE_PROBLEM_CODES);
|
|
127
139
|
}
|
|
128
140
|
createType(input) {
|
|
129
|
-
return this.
|
|
141
|
+
return this.envelopeOperation("create_type", input, COLLECTION_TYPE_PROBLEM_CODES);
|
|
130
142
|
}
|
|
131
143
|
updateType(input) {
|
|
132
|
-
return this.
|
|
144
|
+
return this.envelopeOperation("update_type", input, COLLECTION_TYPE_PROBLEM_CODES);
|
|
133
145
|
}
|
|
134
146
|
installTypePack(input) {
|
|
135
|
-
return this.
|
|
147
|
+
return this.envelopeOperation("install_type_pack", input, COLLECTION_TYPE_PROBLEM_CODES);
|
|
136
148
|
}
|
|
137
149
|
listTimers(namespace) {
|
|
138
|
-
return this.
|
|
150
|
+
return this.rawOperation("list_timers", { namespace }, COLLECTION_READ_PROBLEM_CODES);
|
|
139
151
|
}
|
|
140
152
|
putTimer(input) {
|
|
141
|
-
return this.
|
|
153
|
+
return this.rawOperation("put_timer", input, COLLECTION_MUTATION_PROBLEM_CODES);
|
|
142
154
|
}
|
|
143
155
|
cancelTimer(input) {
|
|
144
|
-
return this.
|
|
156
|
+
return this.rawOperation("cancel_timer", input, COLLECTION_MUTATION_PROBLEM_CODES);
|
|
145
157
|
}
|
|
146
158
|
reconcileTimers(input) {
|
|
147
|
-
return this.
|
|
159
|
+
return this.rawOperation("reconcile_timers", input, COLLECTION_MUTATION_PROBLEM_CODES);
|
|
148
160
|
}
|
|
149
161
|
async *watch(options = {}) {
|
|
150
162
|
let cursor = options.cursor;
|
|
@@ -154,47 +166,81 @@ export class MdbaseCollectionClient {
|
|
|
154
166
|
let connected = false;
|
|
155
167
|
options.onStatus?.({ state: "connecting", ...(cursor === undefined ? {} : { cursor }) });
|
|
156
168
|
while (!options.signal?.aborted) {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const page = await this.changes({ after: cursor, limit: 200 }, { signal: options.signal });
|
|
161
|
-
if (page.reset) {
|
|
162
|
-
const error = new MdbaseConnectError("change_cursor_reset", "The collection change cursor expired. Refresh collection state before subscribing again.");
|
|
163
|
-
options.onStatus?.({ state: "reset_required", cursor, error });
|
|
164
|
-
throw error;
|
|
165
|
-
}
|
|
166
|
-
const recovered = failures > 0;
|
|
167
|
-
failures = 0;
|
|
168
|
-
if (!connected || recovered)
|
|
169
|
-
options.onStatus?.({ state: "connected", cursor, recovered });
|
|
170
|
-
connected = true;
|
|
171
|
-
for (const event of page.events)
|
|
172
|
-
yield event;
|
|
173
|
-
cursor = page.cursor;
|
|
174
|
-
if (!page.has_more)
|
|
175
|
-
await abortableDelay(pollInterval, options.signal);
|
|
176
|
-
}
|
|
177
|
-
catch (error) {
|
|
169
|
+
const changed = await this.changes(cursor === undefined ? {} : { after: cursor, limit: 200 }, { signal: options.signal });
|
|
170
|
+
if (!changed.ok) {
|
|
171
|
+
const problem = changed.problem;
|
|
178
172
|
if (options.signal?.aborted)
|
|
179
173
|
return;
|
|
180
|
-
if (!retry ||
|
|
181
|
-
|
|
174
|
+
if (!retry || problem.recovery !== "retry") {
|
|
175
|
+
yield changed;
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
182
178
|
connected = false;
|
|
183
179
|
failures += 1;
|
|
184
|
-
if (retry.maxAttempts !== undefined && failures > retry.maxAttempts)
|
|
185
|
-
|
|
180
|
+
if (retry.maxAttempts !== undefined && failures > retry.maxAttempts) {
|
|
181
|
+
yield changed;
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
186
184
|
const retryInMs = Math.min(retry.maxDelayMs, Math.round(retry.initialDelayMs * retry.multiplier ** (failures - 1)));
|
|
187
185
|
options.onStatus?.({
|
|
188
186
|
state: "reconnecting",
|
|
189
187
|
...(cursor === undefined ? {} : { cursor }),
|
|
190
188
|
attempt: failures,
|
|
191
189
|
retryInMs,
|
|
192
|
-
|
|
190
|
+
problem
|
|
193
191
|
});
|
|
194
|
-
|
|
192
|
+
try {
|
|
193
|
+
await abortableDelay(retryInMs, options.signal);
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
if (!options.signal?.aborted)
|
|
197
|
+
throw connectError("operation_failed", "Watch retry delay failed unexpectedly.");
|
|
198
|
+
}
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
const page = changed.value;
|
|
202
|
+
if (cursor === undefined) {
|
|
203
|
+
cursor = page.cursor;
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
if (page.reset) {
|
|
207
|
+
const problem = connectProblem("change_cursor_reset", "The collection change cursor expired. Refresh collection state before subscribing again.");
|
|
208
|
+
options.onStatus?.({ state: "reset_required", cursor, problem });
|
|
209
|
+
yield connectFailure(problem);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const recovered = failures > 0;
|
|
213
|
+
failures = 0;
|
|
214
|
+
if (!connected || recovered)
|
|
215
|
+
options.onStatus?.({ state: "connected", cursor, recovered });
|
|
216
|
+
connected = true;
|
|
217
|
+
for (const event of page.events)
|
|
218
|
+
yield connectSuccess(event);
|
|
219
|
+
cursor = page.cursor;
|
|
220
|
+
if (!page.has_more) {
|
|
221
|
+
try {
|
|
222
|
+
await abortableDelay(pollInterval, options.signal);
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
if (!options.signal?.aborted)
|
|
226
|
+
throw connectError("operation_failed", "Watch polling delay failed unexpectedly.");
|
|
227
|
+
}
|
|
195
228
|
}
|
|
196
229
|
}
|
|
197
230
|
}
|
|
231
|
+
rawOperation(operation, input, allowedCodes, options) {
|
|
232
|
+
return captureConnectOutcome(() => this.transport.operation(operation, input, options), allowedCodes);
|
|
233
|
+
}
|
|
234
|
+
async envelopeOperation(operation, input, allowedCodes, options) {
|
|
235
|
+
const transported = await captureConnectOutcome(() => this.transport.operation(operation, input, options), allowedCodes);
|
|
236
|
+
if (!transported.ok)
|
|
237
|
+
return transported;
|
|
238
|
+
const envelope = transported.value;
|
|
239
|
+
if (!envelope.valid) {
|
|
240
|
+
return connectFailure(operationProblem(envelope));
|
|
241
|
+
}
|
|
242
|
+
return connectSuccess(envelope.result, envelope.diagnostics);
|
|
243
|
+
}
|
|
198
244
|
}
|
|
199
245
|
function watchRetryPolicy(options) {
|
|
200
246
|
if (options === false)
|
package/dist/connect.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { MdbaseConnection, type MdbaseAuthorizationOutcome, type MdbaseAuthoriza
|
|
|
3
3
|
import type { MdbaseConnectionInfo } from "./connection-types.js";
|
|
4
4
|
import { type GrantKeyStore } from "./crypto.js";
|
|
5
5
|
import { type Application } from "./internal-types.js";
|
|
6
|
+
import { type AuthorizationProblemCode, type ConnectOutcome, type RegistrationProblemCode } from "./outcomes.js";
|
|
6
7
|
import { MdbaseSession, type MdbaseSessionOptions, type MdbaseUnavailableReason } from "./session.js";
|
|
7
8
|
export interface MdbaseConnectOptions {
|
|
8
9
|
serverUrl: string;
|
|
@@ -26,11 +27,11 @@ export interface MdbaseConnectOptions {
|
|
|
26
27
|
export declare class MdbaseConnect<Frontmatter extends JsonObject = JsonObject> {
|
|
27
28
|
private readonly internals;
|
|
28
29
|
constructor(options: MdbaseConnectOptions);
|
|
29
|
-
register(): Promise<Application
|
|
30
|
-
authorize(options?: MdbaseAuthorizeOptions): Promise<MdbaseAuthorizationOutcome<Frontmatter>>;
|
|
30
|
+
register(): Promise<ConnectOutcome<Application, RegistrationProblemCode>>;
|
|
31
|
+
authorize(options?: MdbaseAuthorizeOptions): Promise<ConnectOutcome<MdbaseAuthorizationOutcome<Frontmatter>, AuthorizationProblemCode>>;
|
|
31
32
|
createSession(options: MdbaseSessionOptions): MdbaseSession<Frontmatter>;
|
|
32
33
|
environment(): MdbaseConnectEnvironment;
|
|
33
|
-
completeAuthorization(callbackUrl?: string): Promise<MdbaseAuthorizationResult<Frontmatter>>;
|
|
34
|
+
completeAuthorization(callbackUrl?: string): Promise<ConnectOutcome<MdbaseAuthorizationResult<Frontmatter>, AuthorizationProblemCode>>;
|
|
34
35
|
connections(): MdbaseConnectionInfo[];
|
|
35
36
|
connection(collectionId: string): MdbaseConnection<Frontmatter> | null;
|
|
36
37
|
unavailableReason(collectionId: string): MdbaseUnavailableReason | null;
|