@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.
- package/dist/lib/browser/{chunk-VHS3XEIX.mjs → chunk-IKP53CBQ.mjs} +51 -18
- package/dist/lib/browser/{chunk-VHS3XEIX.mjs.map → chunk-IKP53CBQ.mjs.map} +3 -3
- package/dist/lib/browser/edge-ws-muxer.mjs +1 -1
- package/dist/lib/browser/index.mjs +566 -350
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +61 -16
- package/dist/lib/browser/testing/index.mjs.map +4 -4
- package/dist/lib/node-esm/{chunk-HGQUUFIJ.mjs → chunk-DR5YNW5K.mjs} +51 -18
- package/dist/lib/node-esm/{chunk-HGQUUFIJ.mjs.map → chunk-DR5YNW5K.mjs.map} +3 -3
- package/dist/lib/node-esm/edge-ws-muxer.mjs +1 -1
- package/dist/lib/node-esm/index.mjs +566 -350
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +61 -16
- package/dist/lib/node-esm/testing/index.mjs.map +4 -4
- package/dist/types/src/edge-client.d.ts +15 -15
- package/dist/types/src/edge-client.d.ts.map +1 -1
- package/dist/types/src/edge-http-client.d.ts +52 -30
- package/dist/types/src/edge-http-client.d.ts.map +1 -1
- package/dist/types/src/edge-http-client.test.d.ts +2 -0
- package/dist/types/src/edge-http-client.test.d.ts.map +1 -0
- package/dist/types/src/edge-ws-connection.d.ts +1 -0
- package/dist/types/src/edge-ws-connection.d.ts.map +1 -1
- package/dist/types/src/edge-ws-muxer.d.ts.map +1 -1
- package/dist/types/src/http-client.d.ts +22 -0
- package/dist/types/src/http-client.d.ts.map +1 -0
- package/dist/types/src/http-client.test.d.ts +2 -0
- package/dist/types/src/http-client.test.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +4 -3
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/testing/index.d.ts +1 -0
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/testing/test-server.d.ts +9 -0
- package/dist/types/src/testing/test-server.d.ts.map +1 -0
- package/dist/types/src/testing/test-utils.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +21 -14
- package/src/edge-client.ts +40 -40
- package/src/edge-http-client.test.ts +22 -0
- package/src/edge-http-client.ts +330 -140
- package/src/edge-ws-connection.ts +11 -3
- package/src/edge-ws-muxer.ts +1 -1
- package/src/http-client.test.ts +55 -0
- package/src/http-client.ts +67 -0
- package/src/index.ts +4 -3
- package/src/testing/index.ts +1 -0
- package/src/testing/test-server.ts +45 -0
- package/src/testing/test-utils.ts +2 -2
- package/src/websocket.test.ts +1 -1
- package/dist/lib/node/chunk-XNHBUTNB.cjs +0 -317
- package/dist/lib/node/chunk-XNHBUTNB.cjs.map +0 -7
- package/dist/lib/node/edge-ws-muxer.cjs +0 -33
- package/dist/lib/node/edge-ws-muxer.cjs.map +0 -7
- package/dist/lib/node/index.cjs +0 -1060
- package/dist/lib/node/index.cjs.map +0 -7
- package/dist/lib/node/meta.json +0 -1
- package/dist/lib/node/testing/index.cjs +0 -169
- 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
|
+
"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.
|
|
45
|
-
"@dxos/context": "0.8.
|
|
46
|
-
"@dxos/
|
|
47
|
-
"@dxos/debug": "0.8.
|
|
48
|
-
"@dxos/invariant": "0.8.
|
|
49
|
-
"@dxos/
|
|
50
|
-
"@dxos/
|
|
51
|
-
"@dxos/
|
|
52
|
-
"@dxos/
|
|
53
|
-
"@dxos/
|
|
54
|
-
"@dxos/
|
|
55
|
-
"@dxos/util": "0.8.
|
|
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.
|
|
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"
|
package/src/edge-client.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
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()
|
|
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)
|
|
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
|
-
|
|
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)
|
|
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
|
+
});
|