@enbox/dwn-clients 0.4.2 → 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
- // if there is an error, close the subscription and delete it from the connection
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;AAyC5H,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;IAsExC;;;;;OAKG;mBACkB,cAAc;CAmCpC"}
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.2",
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.7",
51
+ "@enbox/dwn-sdk-js": "0.3.8",
52
52
  "ms": "2.1.3"
53
53
  },
54
54
  "devDependencies": {
@@ -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;