@dxos/edge-client 0.8.3 → 0.8.4-main.1da679c

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.
Files changed (59) hide show
  1. package/dist/lib/browser/{chunk-VHS3XEIX.mjs → chunk-IKP53CBQ.mjs} +51 -18
  2. package/dist/lib/browser/{chunk-VHS3XEIX.mjs.map → chunk-IKP53CBQ.mjs.map} +3 -3
  3. package/dist/lib/browser/edge-ws-muxer.mjs +1 -1
  4. package/dist/lib/browser/index.mjs +566 -350
  5. package/dist/lib/browser/index.mjs.map +4 -4
  6. package/dist/lib/browser/meta.json +1 -1
  7. package/dist/lib/browser/testing/index.mjs +61 -16
  8. package/dist/lib/browser/testing/index.mjs.map +4 -4
  9. package/dist/lib/node-esm/{chunk-HGQUUFIJ.mjs → chunk-DR5YNW5K.mjs} +51 -18
  10. package/dist/lib/node-esm/{chunk-HGQUUFIJ.mjs.map → chunk-DR5YNW5K.mjs.map} +3 -3
  11. package/dist/lib/node-esm/edge-ws-muxer.mjs +1 -1
  12. package/dist/lib/node-esm/index.mjs +566 -350
  13. package/dist/lib/node-esm/index.mjs.map +4 -4
  14. package/dist/lib/node-esm/meta.json +1 -1
  15. package/dist/lib/node-esm/testing/index.mjs +61 -16
  16. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  17. package/dist/types/src/edge-client.d.ts +15 -15
  18. package/dist/types/src/edge-client.d.ts.map +1 -1
  19. package/dist/types/src/edge-http-client.d.ts +52 -30
  20. package/dist/types/src/edge-http-client.d.ts.map +1 -1
  21. package/dist/types/src/edge-http-client.test.d.ts +2 -0
  22. package/dist/types/src/edge-http-client.test.d.ts.map +1 -0
  23. package/dist/types/src/edge-ws-connection.d.ts +1 -0
  24. package/dist/types/src/edge-ws-connection.d.ts.map +1 -1
  25. package/dist/types/src/edge-ws-muxer.d.ts.map +1 -1
  26. package/dist/types/src/http-client.d.ts +22 -0
  27. package/dist/types/src/http-client.d.ts.map +1 -0
  28. package/dist/types/src/http-client.test.d.ts +2 -0
  29. package/dist/types/src/http-client.test.d.ts.map +1 -0
  30. package/dist/types/src/index.d.ts +4 -3
  31. package/dist/types/src/index.d.ts.map +1 -1
  32. package/dist/types/src/testing/index.d.ts +1 -0
  33. package/dist/types/src/testing/index.d.ts.map +1 -1
  34. package/dist/types/src/testing/test-server.d.ts +9 -0
  35. package/dist/types/src/testing/test-server.d.ts.map +1 -0
  36. package/dist/types/src/testing/test-utils.d.ts.map +1 -1
  37. package/dist/types/tsconfig.tsbuildinfo +1 -1
  38. package/package.json +21 -14
  39. package/src/edge-client.ts +40 -40
  40. package/src/edge-http-client.test.ts +22 -0
  41. package/src/edge-http-client.ts +330 -140
  42. package/src/edge-ws-connection.ts +11 -3
  43. package/src/edge-ws-muxer.ts +1 -1
  44. package/src/http-client.test.ts +55 -0
  45. package/src/http-client.ts +67 -0
  46. package/src/index.ts +4 -3
  47. package/src/testing/index.ts +1 -0
  48. package/src/testing/test-server.ts +45 -0
  49. package/src/testing/test-utils.ts +2 -2
  50. package/src/websocket.test.ts +1 -1
  51. package/dist/lib/node/chunk-XNHBUTNB.cjs +0 -317
  52. package/dist/lib/node/chunk-XNHBUTNB.cjs.map +0 -7
  53. package/dist/lib/node/edge-ws-muxer.cjs +0 -33
  54. package/dist/lib/node/edge-ws-muxer.cjs.map +0 -7
  55. package/dist/lib/node/index.cjs +0 -1060
  56. package/dist/lib/node/index.cjs.map +0 -7
  57. package/dist/lib/node/meta.json +0 -1
  58. package/dist/lib/node/testing/index.cjs +0 -169
  59. package/dist/lib/node/testing/index.cjs.map +0 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/edge-client",
3
- "version": "0.8.3",
3
+ "version": "0.8.4-main.1da679c",
4
4
  "description": "EDGE Client",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -10,16 +10,19 @@
10
10
  "type": "module",
11
11
  "exports": {
12
12
  ".": {
13
+ "source": "./src/index.ts",
13
14
  "types": "./dist/types/src/index.d.ts",
14
15
  "browser": "./dist/lib/browser/index.mjs",
15
16
  "node": "./dist/lib/node-esm/index.mjs"
16
17
  },
17
18
  "./muxer": {
19
+ "source": "./src/edge-ws-muxer.ts",
18
20
  "types": "./dist/types/src/edge-ws-muxer.d.ts",
19
21
  "browser": "./dist/lib/browser/edge-ws-muxer.mjs",
20
22
  "node": "./dist/lib/node-esm/edge-ws-muxer.mjs"
21
23
  },
22
24
  "./testing": {
25
+ "source": "./src/testing/index.ts",
23
26
  "types": "./dist/types/src/testing/index.d.ts",
24
27
  "browser": "./dist/lib/browser/testing/index.mjs",
25
28
  "node": "./dist/lib/node-esm/testing/index.mjs"
@@ -39,23 +42,27 @@
39
42
  "README.md"
40
43
  ],
41
44
  "dependencies": {
45
+ "@effect/platform": "^0.90.2",
42
46
  "isomorphic-ws": "^5.0.0",
43
47
  "ws": "^8.14.2",
44
- "@dxos/async": "0.8.3",
45
- "@dxos/context": "0.8.3",
46
- "@dxos/credentials": "0.8.3",
47
- "@dxos/debug": "0.8.3",
48
- "@dxos/invariant": "0.8.3",
49
- "@dxos/keys": "0.8.3",
50
- "@dxos/keyring": "0.8.3",
51
- "@dxos/log": "0.8.3",
52
- "@dxos/crypto": "0.8.3",
53
- "@dxos/node-std": "0.8.3",
54
- "@dxos/protocols": "0.8.3",
55
- "@dxos/util": "0.8.3"
48
+ "@dxos/async": "0.8.4-main.1da679c",
49
+ "@dxos/context": "0.8.4-main.1da679c",
50
+ "@dxos/crypto": "0.8.4-main.1da679c",
51
+ "@dxos/debug": "0.8.4-main.1da679c",
52
+ "@dxos/invariant": "0.8.4-main.1da679c",
53
+ "@dxos/keyring": "0.8.4-main.1da679c",
54
+ "@dxos/credentials": "0.8.4-main.1da679c",
55
+ "@dxos/keys": "0.8.4-main.1da679c",
56
+ "@dxos/log": "0.8.4-main.1da679c",
57
+ "@dxos/protocols": "0.8.4-main.1da679c",
58
+ "@dxos/node-std": "0.8.4-main.1da679c",
59
+ "@dxos/util": "0.8.4-main.1da679c"
56
60
  },
57
61
  "devDependencies": {
58
- "@dxos/test-utils": "0.8.3"
62
+ "@dxos/test-utils": "0.8.4-main.1da679c"
63
+ },
64
+ "peerDependencies": {
65
+ "effect": "^3.13.3"
59
66
  },
60
67
  "publishConfig": {
61
68
  "access": "public"
@@ -2,8 +2,8 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { Trigger, scheduleMicroTask, TriggerState, PersistentLifecycle, Event } from '@dxos/async';
6
- import { Resource, type Lifecycle } from '@dxos/context';
5
+ import { Event, PersistentLifecycle, Trigger, TriggerState, scheduleMicroTask } from '@dxos/async';
6
+ import { type Lifecycle, Resource } from '@dxos/context';
7
7
  import { log, logInfo } from '@dxos/log';
8
8
  import { type Message } from '@dxos/protocols/buf/dxos/edge/messenger_pb';
9
9
  import { EdgeStatus } from '@dxos/protocols/proto/dxos/client/services';
@@ -20,6 +20,13 @@ const DEFAULT_TIMEOUT = 10_000;
20
20
  export type MessageListener = (message: Message) => void;
21
21
  export type ReconnectListener = () => void;
22
22
 
23
+ export type MessengerConfig = {
24
+ socketEndpoint: string;
25
+ timeout?: number;
26
+ protocol?: Protocol;
27
+ disableAuth?: boolean;
28
+ };
29
+
23
30
  export interface EdgeConnection extends Required<Lifecycle> {
24
31
  statusChanged: Event<EdgeStatus>;
25
32
  get info(): any;
@@ -28,18 +35,11 @@ export interface EdgeConnection extends Required<Lifecycle> {
28
35
  get isOpen(): boolean;
29
36
  get status(): EdgeStatus;
30
37
  setIdentity(identity: EdgeIdentity): void;
38
+ send(message: Message): Promise<void>;
31
39
  onMessage(listener: MessageListener): () => void;
32
40
  onReconnected(listener: ReconnectListener): () => void;
33
- send(message: Message): Promise<void>;
34
41
  }
35
42
 
36
- export type MessengerConfig = {
37
- socketEndpoint: string;
38
- timeout?: number;
39
- protocol?: Protocol;
40
- disableAuth?: boolean;
41
- };
42
-
43
43
  /**
44
44
  * Messenger client for EDGE:
45
45
  * - While open, uses PersistentLifecycle to keep an open EdgeWsConnection, reconnecting on failures.
@@ -80,7 +80,7 @@ export class EdgeClient extends Resource implements EdgeConnection {
80
80
  };
81
81
  }
82
82
 
83
- get status(): EdgeStatus {
83
+ get status() {
84
84
  return Boolean(this._currentConnection) && this._ready.state === TriggerState.RESOLVED
85
85
  ? EdgeStatus.CONNECTED
86
86
  : EdgeStatus.NOT_CONNECTED;
@@ -94,7 +94,7 @@ export class EdgeClient extends Resource implements EdgeConnection {
94
94
  return this._identity.peerKey;
95
95
  }
96
96
 
97
- setIdentity(identity: EdgeIdentity): void {
97
+ setIdentity(identity: EdgeIdentity) {
98
98
  if (identity.identityKey !== this._identity.identityKey || identity.peerKey !== this._identity.peerKey) {
99
99
  log('Edge identity changed', { identity, oldIdentity: this._identity });
100
100
  this._identity = identity;
@@ -103,12 +103,36 @@ export class EdgeClient extends Resource implements EdgeConnection {
103
103
  }
104
104
  }
105
105
 
106
- public onMessage(listener: MessageListener): () => void {
106
+ /**
107
+ * Send message.
108
+ * NOTE: The message is guaranteed to be delivered but the service must respond with a message to confirm processing.
109
+ */
110
+ public async send(message: Message) {
111
+ if (this._ready.state !== TriggerState.RESOLVED) {
112
+ log('waiting for websocket');
113
+ await this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT });
114
+ }
115
+
116
+ if (!this._currentConnection) {
117
+ throw new EdgeConnectionClosedError();
118
+ }
119
+
120
+ if (
121
+ message.source &&
122
+ (message.source.peerKey !== this._identity.peerKey || message.source.identityKey !== this.identityKey)
123
+ ) {
124
+ throw new EdgeIdentityChangedError();
125
+ }
126
+
127
+ this._currentConnection.send(message);
128
+ }
129
+
130
+ public onMessage(listener: MessageListener) {
107
131
  this._messageListeners.add(listener);
108
132
  return () => this._messageListeners.delete(listener);
109
133
  }
110
134
 
111
- public onReconnected(listener: () => void): () => void {
135
+ public onReconnected(listener: () => void) {
112
136
  this._reconnectListeners.add(listener);
113
137
  if (this._ready.state === TriggerState.RESOLVED) {
114
138
  // Microtask so that listener is always called asynchronously, no matter the state of the ready trigger
@@ -123,6 +147,7 @@ export class EdgeClient extends Resource implements EdgeConnection {
123
147
  }
124
148
  });
125
149
  }
150
+
126
151
  return () => this._reconnectListeners.delete(listener);
127
152
  }
128
153
 
@@ -200,7 +225,6 @@ export class EdgeClient extends Resource implements EdgeConnection {
200
225
  // Race with restartRequired so that restart is not blocked by _connect execution.
201
226
  // Wait on ready to attempt a reconnect if it times out.
202
227
  await Promise.race([this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT }), restartRequired]);
203
-
204
228
  return connection;
205
229
  }
206
230
 
@@ -237,30 +261,6 @@ export class EdgeClient extends Resource implements EdgeConnection {
237
261
  }
238
262
  }
239
263
 
240
- /**
241
- * Send message.
242
- * NOTE: The message is guaranteed to be delivered but the service must respond with a message to confirm processing.
243
- */
244
- public async send(message: Message): Promise<void> {
245
- if (this._ready.state !== TriggerState.RESOLVED) {
246
- log('waiting for websocket to become ready');
247
- await this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT });
248
- }
249
-
250
- if (!this._currentConnection) {
251
- throw new EdgeConnectionClosedError();
252
- }
253
-
254
- if (
255
- message.source &&
256
- (message.source.peerKey !== this._identity.peerKey || message.source.identityKey !== this.identityKey)
257
- ) {
258
- throw new EdgeIdentityChangedError();
259
- }
260
-
261
- this._currentConnection.send(message);
262
- }
263
-
264
264
  private async _createAuthHeader(path: string): Promise<string | undefined> {
265
265
  const httpUrl = new URL(path, this._baseHttpUrl);
266
266
  httpUrl.protocol = getEdgeUrlWithProtocol(this._baseWsUrl.toString(), 'http');
@@ -277,7 +277,7 @@ export class EdgeClient extends Resource implements EdgeConnection {
277
277
  }
278
278
 
279
279
  const encodePresentationWsAuthHeader = (encodedPresentation: Uint8Array): string => {
280
- // = and / characters are not allowed in the WebSocket subprotocol header.
280
+ // '=' and '/' characters are not allowed in the WebSocket subprotocol header.
281
281
  const encodedToken = Buffer.from(encodedPresentation).toString('base64').replace(/=*$/, '').replaceAll('/', '|');
282
282
  return `base64url.bearer.authorization.dxos.org.${encodedToken}`;
283
283
  };
@@ -0,0 +1,22 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { describe, it } from 'vitest';
6
+
7
+ import { createEphemeralEdgeIdentity } from './auth';
8
+ import { EdgeHttpClient } from './edge-http-client';
9
+
10
+ // TODO(burdon): Factor out config.
11
+ const DEV_SERVER = 'https://edge.dxos.workers.dev';
12
+
13
+ describe.skipIf(process.env.CI)('EdgeHttpClient', () => {
14
+ it.only('should get status', async ({ expect }) => {
15
+ const client = new EdgeHttpClient(DEV_SERVER);
16
+ const identity = await createEphemeralEdgeIdentity();
17
+ client.setIdentity(identity);
18
+
19
+ const result = await client.getStatus();
20
+ expect(result).toBeDefined();
21
+ });
22
+ });