@enbox/dwn-clients 0.4.1 → 0.4.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.
|
@@ -10,6 +10,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
import { CryptoUtils } from '@enbox/crypto';
|
|
11
11
|
import { JsonRpcSocket } from './json-rpc-socket.js';
|
|
12
12
|
import { createJsonRpcAck, createJsonRpcRequest, createJsonRpcSubscriptionRequest } from './json-rpc.js';
|
|
13
|
+
function shouldReplaceLastCursor(current, candidate) {
|
|
14
|
+
if (current === undefined) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
if (candidate.streamId !== current.streamId || candidate.epoch !== current.epoch) {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
return BigInt(candidate.position) > BigInt(current.position);
|
|
21
|
+
}
|
|
13
22
|
export class WebSocketDwnRpcClient {
|
|
14
23
|
get transportProtocols() { return ['ws:', 'wss:']; }
|
|
15
24
|
sendDwnRequest(request) {
|
|
@@ -89,23 +98,34 @@ export class WebSocketDwnRpcClient {
|
|
|
89
98
|
const subscriptionId = CryptoUtils.randomUuid();
|
|
90
99
|
const request = createJsonRpcSubscriptionRequest(requestId, 'rpc.subscribe.dwn.processMessage', { target, message }, subscriptionId);
|
|
91
100
|
const { socket, subscriptions } = connection;
|
|
101
|
+
let terminalSubscriptionError = false;
|
|
102
|
+
const closeSubscription = (subscription) => {
|
|
103
|
+
Promise.resolve(subscription.close()).catch(() => { });
|
|
104
|
+
};
|
|
105
|
+
const closeTrackedSubscription = () => {
|
|
106
|
+
terminalSubscriptionError = true;
|
|
107
|
+
const tracked = subscriptions.get(subscriptionId);
|
|
108
|
+
if (tracked) {
|
|
109
|
+
closeSubscription(tracked.subscription);
|
|
110
|
+
}
|
|
111
|
+
subscriptions.delete(subscriptionId);
|
|
112
|
+
};
|
|
92
113
|
const { response, close } = yield socket.subscribe(request, (response) => {
|
|
93
114
|
const { result, error } = response;
|
|
94
115
|
if (error) {
|
|
95
|
-
|
|
96
|
-
const tracked = subscriptions.get(subscriptionId);
|
|
97
|
-
if (tracked) {
|
|
98
|
-
tracked.subscription.close();
|
|
99
|
-
}
|
|
100
|
-
subscriptions.delete(subscriptionId);
|
|
116
|
+
closeTrackedSubscription();
|
|
101
117
|
return;
|
|
102
118
|
}
|
|
103
119
|
const subscriptionMessage = result.subscription;
|
|
104
120
|
handler(subscriptionMessage);
|
|
121
|
+
if (subscriptionMessage.type === 'error') {
|
|
122
|
+
closeTrackedSubscription();
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
105
125
|
// Track the latest cursor for reconnection.
|
|
106
126
|
if ('cursor' in subscriptionMessage && subscriptionMessage.cursor) {
|
|
107
127
|
const tracked = subscriptions.get(subscriptionId);
|
|
108
|
-
if (tracked) {
|
|
128
|
+
if (tracked && shouldReplaceLastCursor(tracked.lastCursor, subscriptionMessage.cursor)) {
|
|
109
129
|
tracked.lastCursor = subscriptionMessage.cursor;
|
|
110
130
|
}
|
|
111
131
|
// Send rpc.ack to advance the server's flow-control window.
|
|
@@ -118,7 +138,12 @@ export class WebSocketDwnRpcClient {
|
|
|
118
138
|
}
|
|
119
139
|
const { reply } = result;
|
|
120
140
|
if (reply.subscription && close) {
|
|
141
|
+
let closed = false;
|
|
121
142
|
const wrappedClose = () => __awaiter(this, void 0, void 0, function* () {
|
|
143
|
+
if (closed) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
closed = true;
|
|
122
147
|
subscriptions.delete(subscriptionId);
|
|
123
148
|
yield close();
|
|
124
149
|
});
|
|
@@ -129,8 +154,13 @@ export class WebSocketDwnRpcClient {
|
|
|
129
154
|
handler,
|
|
130
155
|
resubscribeFactory,
|
|
131
156
|
};
|
|
132
|
-
subscriptions.set(subscriptionId, tracked);
|
|
133
157
|
reply.subscription.close = wrappedClose;
|
|
158
|
+
if (terminalSubscriptionError) {
|
|
159
|
+
Promise.resolve(wrappedClose()).catch(() => { });
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
subscriptions.set(subscriptionId, tracked);
|
|
163
|
+
}
|
|
134
164
|
}
|
|
135
165
|
return reply;
|
|
136
166
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-socket-clients.js","sourceRoot":"","sources":["../../src/web-socket-clients.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"web-socket-clients.js","sourceRoot":"","sources":["../../src/web-socket-clients.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,7 +19,7 @@ export type TransportReconnected = {
|
|
|
19
19
|
export type TransportMessage = TransportDisconnected | TransportReconnecting | TransportReconnected;
|
|
20
20
|
/**
|
|
21
21
|
* The full set of messages a subscription handler can receive — DWN-level
|
|
22
|
-
* events (`event`, `eose`) plus transport lifecycle notifications
|
|
22
|
+
* events (`event`, `eose`, `error`) plus transport lifecycle notifications
|
|
23
23
|
* (`disconnected`, `reconnecting`, `reconnected`).
|
|
24
24
|
*
|
|
25
25
|
* For local DWN processing the handler only receives `SubscriptionMessage`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-socket-clients.d.ts","sourceRoot":"","sources":["../../src/web-socket-clients.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,cAAc,EAA8C,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"web-socket-clients.d.ts","sourceRoot":"","sources":["../../src/web-socket-clients.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,cAAc,EAA8C,MAAM,oBAAoB,CAAC;AAqD5H,qBAAa,qBAAsB,YAAW,MAAM;IAClD,IAAW,kBAAkB,IAAI,MAAM,EAAE,CAA4B;IAErE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAuC;IAEpE,cAAc,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IA+BrE;;OAEG;mBACkB,gBAAgB;mBAkChB,cAAc;mBAiBd,mBAAmB;IA2FxC;;;;;OAKG;mBACkB,cAAc;CAmCpC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enbox/dwn-clients",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/esm/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@enbox/common": "0.1.1",
|
|
50
50
|
"@enbox/crypto": "0.1.1",
|
|
51
|
-
"@enbox/dwn-sdk-js": "0.3.
|
|
51
|
+
"@enbox/dwn-sdk-js": "0.3.8",
|
|
52
52
|
"ms": "2.1.3"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
package/src/dwn-rpc-types.ts
CHANGED
|
@@ -7,7 +7,7 @@ export interface SerializableDwnMessage {
|
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
8
8
|
// Transport-layer subscription message types
|
|
9
9
|
//
|
|
10
|
-
// These extend the DWN SDK's `SubscriptionMessage` union (`event | eose`)
|
|
10
|
+
// These extend the DWN SDK's `SubscriptionMessage` union (`event | eose | error`)
|
|
11
11
|
// with connection lifecycle notifications synthesized by the transport layer
|
|
12
12
|
// (e.g. WebSocket client). The DWN SDK / EventLog never produces these.
|
|
13
13
|
// ---------------------------------------------------------------------------
|
|
@@ -33,7 +33,7 @@ export type TransportMessage = TransportDisconnected | TransportReconnecting | T
|
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
35
|
* The full set of messages a subscription handler can receive — DWN-level
|
|
36
|
-
* events (`event`, `eose`) plus transport lifecycle notifications
|
|
36
|
+
* events (`event`, `eose`, `error`) plus transport lifecycle notifications
|
|
37
37
|
* (`disconnected`, `reconnecting`, `reconnected`).
|
|
38
38
|
*
|
|
39
39
|
* For local DWN processing the handler only receives `SubscriptionMessage`.
|
|
@@ -39,6 +39,18 @@ interface SocketConnection {
|
|
|
39
39
|
url: string;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
function shouldReplaceLastCursor(current: ProgressToken | undefined, candidate: ProgressToken): boolean {
|
|
43
|
+
if (current === undefined) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (candidate.streamId !== current.streamId || candidate.epoch !== current.epoch) {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return BigInt(candidate.position) > BigInt(current.position);
|
|
52
|
+
}
|
|
53
|
+
|
|
42
54
|
export class WebSocketDwnRpcClient implements DwnRpc {
|
|
43
55
|
public get transportProtocols(): string[] { return ['ws:', 'wss:']; }
|
|
44
56
|
// a map of dwn host to WebSocket connection
|
|
@@ -143,27 +155,39 @@ export class WebSocketDwnRpcClient implements DwnRpc {
|
|
|
143
155
|
);
|
|
144
156
|
|
|
145
157
|
const { socket, subscriptions } = connection;
|
|
158
|
+
let terminalSubscriptionError = false;
|
|
159
|
+
const closeSubscription = (subscription: MessageSubscription): void => {
|
|
160
|
+
Promise.resolve(subscription.close()).catch(() => {});
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
const closeTrackedSubscription = (): void => {
|
|
164
|
+
terminalSubscriptionError = true;
|
|
165
|
+
const tracked = subscriptions.get(subscriptionId);
|
|
166
|
+
if (tracked) {
|
|
167
|
+
closeSubscription(tracked.subscription);
|
|
168
|
+
}
|
|
169
|
+
subscriptions.delete(subscriptionId);
|
|
170
|
+
};
|
|
171
|
+
|
|
146
172
|
const { response, close } = await socket.subscribe(request, (response) => {
|
|
147
173
|
const { result, error } = response;
|
|
148
174
|
if (error) {
|
|
149
|
-
|
|
150
|
-
// if there is an error, close the subscription and delete it from the connection
|
|
151
|
-
const tracked = subscriptions.get(subscriptionId);
|
|
152
|
-
if (tracked) {
|
|
153
|
-
tracked.subscription.close();
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
subscriptions.delete(subscriptionId);
|
|
175
|
+
closeTrackedSubscription();
|
|
157
176
|
return;
|
|
158
177
|
}
|
|
159
178
|
|
|
160
179
|
const subscriptionMessage = result.subscription as SubscriptionMessage;
|
|
161
180
|
handler(subscriptionMessage);
|
|
162
181
|
|
|
182
|
+
if (subscriptionMessage.type === 'error') {
|
|
183
|
+
closeTrackedSubscription();
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
163
187
|
// Track the latest cursor for reconnection.
|
|
164
188
|
if ('cursor' in subscriptionMessage && subscriptionMessage.cursor) {
|
|
165
189
|
const tracked = subscriptions.get(subscriptionId);
|
|
166
|
-
if (tracked) {
|
|
190
|
+
if (tracked && shouldReplaceLastCursor(tracked.lastCursor, subscriptionMessage.cursor)) {
|
|
167
191
|
tracked.lastCursor = subscriptionMessage.cursor;
|
|
168
192
|
}
|
|
169
193
|
|
|
@@ -179,7 +203,12 @@ export class WebSocketDwnRpcClient implements DwnRpc {
|
|
|
179
203
|
|
|
180
204
|
const { reply } = result as { reply: UnionMessageReply };
|
|
181
205
|
if (reply.subscription && close) {
|
|
206
|
+
let closed = false;
|
|
182
207
|
const wrappedClose = async (): Promise<void> => {
|
|
208
|
+
if (closed) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
closed = true;
|
|
183
212
|
subscriptions.delete(subscriptionId);
|
|
184
213
|
await close();
|
|
185
214
|
};
|
|
@@ -192,8 +221,12 @@ export class WebSocketDwnRpcClient implements DwnRpc {
|
|
|
192
221
|
resubscribeFactory,
|
|
193
222
|
};
|
|
194
223
|
|
|
195
|
-
subscriptions.set(subscriptionId, tracked);
|
|
196
224
|
reply.subscription.close = wrappedClose;
|
|
225
|
+
if (terminalSubscriptionError) {
|
|
226
|
+
Promise.resolve(wrappedClose()).catch(() => {});
|
|
227
|
+
} else {
|
|
228
|
+
subscriptions.set(subscriptionId, tracked);
|
|
229
|
+
}
|
|
197
230
|
}
|
|
198
231
|
|
|
199
232
|
return reply;
|