@spider-mesh/ws 1.0.146 → 2.0.38
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 +240 -0
- package/build/examples/websocket-client.d.ts +1 -0
- package/build/examples/websocket-client.js +18 -0
- package/build/examples/websocket-client.js.map +1 -0
- package/build/examples/websocket-e2e-client.d.ts +1 -0
- package/build/examples/websocket-e2e-client.js +38 -0
- package/build/examples/websocket-e2e-client.js.map +1 -0
- package/build/examples/websocket-e2e-matrix-client.d.ts +1 -0
- package/build/examples/websocket-e2e-matrix-client.js +68 -0
- package/build/examples/websocket-e2e-matrix-client.js.map +1 -0
- package/build/examples/websocket-e2e-matrix-provider.d.ts +1 -0
- package/build/examples/websocket-e2e-matrix-provider.js +42 -0
- package/build/examples/websocket-e2e-matrix-provider.js.map +1 -0
- package/build/examples/websocket-e2e-matrix-test.d.ts +1 -0
- package/build/examples/websocket-e2e-matrix-test.js +85 -0
- package/build/examples/websocket-e2e-matrix-test.js.map +1 -0
- package/build/examples/websocket-e2e-provider.d.ts +1 -0
- package/build/examples/websocket-e2e-provider.js +23 -0
- package/build/examples/websocket-e2e-provider.js.map +1 -0
- package/build/examples/websocket-e2e-reverse-client.d.ts +1 -0
- package/build/examples/websocket-e2e-reverse-client.js +23 -0
- package/build/examples/websocket-e2e-reverse-client.js.map +1 -0
- package/build/examples/websocket-e2e-reverse-server.d.ts +1 -0
- package/build/examples/websocket-e2e-reverse-server.js +38 -0
- package/build/examples/websocket-e2e-reverse-server.js.map +1 -0
- package/build/examples/websocket-e2e-reverse-test.d.ts +1 -0
- package/build/examples/websocket-e2e-reverse-test.js +85 -0
- package/build/examples/websocket-e2e-reverse-test.js.map +1 -0
- package/build/examples/websocket-e2e-round-robin-client.d.ts +1 -0
- package/build/examples/websocket-e2e-round-robin-client.js +42 -0
- package/build/examples/websocket-e2e-round-robin-client.js.map +1 -0
- package/build/examples/websocket-e2e-round-robin-test.d.ts +1 -0
- package/build/examples/websocket-e2e-round-robin-test.js +93 -0
- package/build/examples/websocket-e2e-round-robin-test.js.map +1 -0
- package/build/examples/websocket-e2e-test.d.ts +1 -0
- package/build/examples/websocket-e2e-test.js +85 -0
- package/build/examples/websocket-e2e-test.js.map +1 -0
- package/build/examples/websocket-provider.d.ts +1 -0
- package/build/examples/websocket-provider.js +21 -0
- package/build/examples/websocket-provider.js.map +1 -0
- package/build/examples/websocket-server.d.ts +1 -0
- package/build/examples/websocket-server.js +6 -0
- package/build/examples/websocket-server.js.map +1 -0
- package/build/examples/websocket-smoke-test.d.ts +1 -0
- package/build/examples/websocket-smoke-test.js +170 -0
- package/build/examples/websocket-smoke-test.js.map +1 -0
- package/build/src/WebsocketRelayServer.d.ts +24 -0
- package/build/src/WebsocketRelayServer.js +239 -0
- package/build/src/WebsocketRelayServer.js.map +1 -0
- package/build/src/WebsocketTransporter.d.ts +28 -0
- package/build/src/WebsocketTransporter.js +276 -0
- package/build/src/WebsocketTransporter.js.map +1 -0
- package/build/src/index.d.ts +1 -1
- package/build/src/index.js +1 -1
- package/build/src/index.js.map +1 -1
- package/build/src/relay-server.d.ts +1 -0
- package/build/src/relay-server.js +2 -0
- package/build/src/relay-server.js.map +1 -0
- package/build/src/websocketProtocol.d.ts +52 -0
- package/build/src/websocketProtocol.js +39 -0
- package/build/src/websocketProtocol.js.map +1 -0
- package/build/tests/helpers/runBunScript.d.ts +6 -0
- package/build/tests/helpers/runBunScript.js +46 -0
- package/build/tests/helpers/runBunScript.js.map +1 -0
- package/build/tests/websocket-spidermesh-matrix.e2e.test.d.ts +1 -0
- package/build/tests/websocket-spidermesh-matrix.e2e.test.js +13 -0
- package/build/tests/websocket-spidermesh-matrix.e2e.test.js.map +1 -0
- package/build/tests/websocket-spidermesh-reverse.e2e.test.d.ts +1 -0
- package/build/tests/websocket-spidermesh-reverse.e2e.test.js +9 -0
- package/build/tests/websocket-spidermesh-reverse.e2e.test.js.map +1 -0
- package/build/tests/websocket-spidermesh-round-robin.e2e.test.d.ts +1 -0
- package/build/tests/websocket-spidermesh-round-robin.e2e.test.js +20 -0
- package/build/tests/websocket-spidermesh-round-robin.e2e.test.js.map +1 -0
- package/build/tests/websocket-spidermesh.e2e.test.d.ts +1 -0
- package/build/tests/websocket-spidermesh.e2e.test.js +9 -0
- package/build/tests/websocket-spidermesh.e2e.test.js.map +1 -0
- package/build/tests/websocket-transporter.e2e.test.d.ts +1 -0
- package/build/tests/websocket-transporter.e2e.test.js +9 -0
- package/build/tests/websocket-transporter.e2e.test.js.map +1 -0
- package/build/tsconfig.tsbuildinfo +1 -0
- package/package.json +29 -15
- package/tsconfig.json +7 -7
- package/build/src/SpiderMeshWebsocketTransporter.d.ts +0 -16
- package/build/src/SpiderMeshWebsocketTransporter.js +0 -159
- package/build/src/SpiderMeshWebsocketTransporter.js.map +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# Spider Mesh WS
|
|
2
|
+
|
|
3
|
+
`@spider-mesh/ws` is the official WebSocket package for Spider Mesh.
|
|
4
|
+
|
|
5
|
+
It contains two pieces:
|
|
6
|
+
|
|
7
|
+
- `WebsocketTransporter`: the built-in transporter used by application nodes for RPC, discovery, and pubsub.
|
|
8
|
+
- `WebsocketRelayServer`: the relay process that forwards WebSocket traffic between nodes.
|
|
9
|
+
|
|
10
|
+
This package is intentionally separate from `@spider-mesh/core`.
|
|
11
|
+
|
|
12
|
+
The core package stays runtime-agnostic, while `@spider-mesh/ws` contains the Node.js/Bun-specific WebSocket implementation based on `ws` and MsgPack.
|
|
13
|
+
|
|
14
|
+
## What This Package Does
|
|
15
|
+
|
|
16
|
+
Use `@spider-mesh/ws` when you want the built-in WebSocket transport instead of writing a custom transporter.
|
|
17
|
+
|
|
18
|
+
The package provides:
|
|
19
|
+
|
|
20
|
+
- binary WebSocket frames encoded with `@msgpack/msgpack`
|
|
21
|
+
- RPC request, response, and cancel forwarding
|
|
22
|
+
- node discovery propagation through relay hello and offline events
|
|
23
|
+
- pubsub publish, subscribe, and unsubscribe forwarding
|
|
24
|
+
- reconnect and heartbeat handling in the client transporter
|
|
25
|
+
- a dedicated relay server entry at `@spider-mesh/ws/relay-server`
|
|
26
|
+
|
|
27
|
+
## When To Use It
|
|
28
|
+
|
|
29
|
+
Use this package when:
|
|
30
|
+
|
|
31
|
+
- your runtime is Node.js or Bun
|
|
32
|
+
- you want an official ready-to-use Spider Mesh transport
|
|
33
|
+
- you want one relay process that many providers and clients can connect to
|
|
34
|
+
|
|
35
|
+
Do not use this package as the default import source for runtime-agnostic APIs.
|
|
36
|
+
|
|
37
|
+
- Import `SpiderMesh`, `Microservice`, and `RemoteServiceLinker` from `@spider-mesh/core`
|
|
38
|
+
- Import `WebsocketTransporter` from `@spider-mesh/ws`
|
|
39
|
+
- Import `WebsocketRelayServer` from `@spider-mesh/ws/relay-server`
|
|
40
|
+
|
|
41
|
+
## Install
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
bun add @spider-mesh/core @spider-mesh/ws rxjs reflect-metadata
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Keep `@spider-mesh/ws` and `@spider-mesh/core` on matching published versions so transporter/runtime contracts stay aligned.
|
|
48
|
+
|
|
49
|
+
This package is ESM-only.
|
|
50
|
+
|
|
51
|
+
## Export Surface
|
|
52
|
+
|
|
53
|
+
Main entry:
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
import { WebsocketTransporter } from '@spider-mesh/ws'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Relay server entry:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import { WebsocketRelayServer } from '@spider-mesh/ws/relay-server'
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Recommended full import shape:
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import { SpiderMesh, Microservice, RemoteServiceLinker } from '@spider-mesh/core'
|
|
69
|
+
import { WebsocketTransporter } from '@spider-mesh/ws'
|
|
70
|
+
import { WebsocketRelayServer } from '@spider-mesh/ws/relay-server'
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Runtime Support
|
|
74
|
+
|
|
75
|
+
| Runtime | `@spider-mesh/ws` | `@spider-mesh/ws/relay-server` |
|
|
76
|
+
| --- | --- | --- |
|
|
77
|
+
| Node.js | Supported | Supported |
|
|
78
|
+
| Bun | Supported | Supported |
|
|
79
|
+
| Browser | Not recommended | Not supported |
|
|
80
|
+
| React Native | Not recommended | Not supported |
|
|
81
|
+
|
|
82
|
+
If you need React Native or browser support, keep using `@spider-mesh/core` and provide a runtime-appropriate custom transporter.
|
|
83
|
+
|
|
84
|
+
## Architecture
|
|
85
|
+
|
|
86
|
+
Typical deployment shape:
|
|
87
|
+
|
|
88
|
+
1. Start one relay process with `WebsocketRelayServer`.
|
|
89
|
+
2. Start provider nodes with `WebsocketTransporter` and local `@Microservice()` classes.
|
|
90
|
+
3. Start client nodes with `WebsocketTransporter` and `RemoteServiceLinker.link()`.
|
|
91
|
+
4. In clients, wait for discovery before the first RPC call.
|
|
92
|
+
|
|
93
|
+
Conceptually:
|
|
94
|
+
|
|
95
|
+
- `@spider-mesh/core` owns the runtime and service model
|
|
96
|
+
- `@spider-mesh/ws` owns WebSocket transport and relay behavior
|
|
97
|
+
- the relay server forwards frames, but does not host application services
|
|
98
|
+
|
|
99
|
+
## Quick Start
|
|
100
|
+
|
|
101
|
+
### 1. Start a relay server
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
import { WebsocketRelayServer } from '@spider-mesh/ws/relay-server'
|
|
105
|
+
|
|
106
|
+
const server = new WebsocketRelayServer({
|
|
107
|
+
host: '127.0.0.1',
|
|
108
|
+
port: 8787,
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
console.log(`WebSocket relay listening on ws://127.0.0.1:${server.port}`)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### 2. Start a provider
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
import { Microservice, SpiderMesh } from '@spider-mesh/core'
|
|
118
|
+
import { WebsocketTransporter } from '@spider-mesh/ws'
|
|
119
|
+
|
|
120
|
+
const transporter = new WebsocketTransporter({
|
|
121
|
+
heartbeatIntervalMs: 5000,
|
|
122
|
+
reconnectIntervalMs: 1000,
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
transporter.connect('ws://127.0.0.1:8787')
|
|
126
|
+
|
|
127
|
+
@Microservice()
|
|
128
|
+
class GreetingService {
|
|
129
|
+
async hello(name: string) {
|
|
130
|
+
return `hello ${name}`
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
new GreetingService()
|
|
135
|
+
new SpiderMesh({ transporters: [transporter] })
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### 3. Start a client
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
import { RemoteServiceLinker, SpiderMesh } from '@spider-mesh/core'
|
|
142
|
+
import { WebsocketTransporter } from '@spider-mesh/ws'
|
|
143
|
+
|
|
144
|
+
const transporter = new WebsocketTransporter({
|
|
145
|
+
heartbeatIntervalMs: 5000,
|
|
146
|
+
reconnectIntervalMs: 1000,
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
transporter.connect('ws://127.0.0.1:8787')
|
|
150
|
+
|
|
151
|
+
type GreetingService = {
|
|
152
|
+
hello(name: string): Promise<string>
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const mesh = new SpiderMesh({ transporters: [transporter] })
|
|
156
|
+
const greeter = RemoteServiceLinker.link<GreetingService>(mesh, {
|
|
157
|
+
service: 'GreetingService',
|
|
158
|
+
timeout: 5000,
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
await greeter.wait()
|
|
162
|
+
console.log(await greeter.hello('world'))
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Transporter Options
|
|
166
|
+
|
|
167
|
+
`WebsocketTransporter` supports these options:
|
|
168
|
+
|
|
169
|
+
- `heartbeatIntervalMs`: interval between WebSocket ping frames
|
|
170
|
+
- `reconnectIntervalMs`: delay before reconnect attempts after disconnect
|
|
171
|
+
- `unsubscribeDelayMs`: delay before unsubscribe is sent after the last local subscriber leaves a topic
|
|
172
|
+
|
|
173
|
+
It also exposes `status$` as `BehaviorSubject<Map<string, string>>` so callers can observe per-relay connection state transitions such as `connecting`, `connected`, `error`, and `not_connected`.
|
|
174
|
+
|
|
175
|
+
Example:
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
const transporter = new WebsocketTransporter({
|
|
179
|
+
heartbeatIntervalMs: 5000,
|
|
180
|
+
reconnectIntervalMs: 1000,
|
|
181
|
+
unsubscribeDelayMs: 10000,
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
transporter.status$.subscribe(statuses => {
|
|
185
|
+
console.log(statuses.get('ws://127.0.0.1:8787'))
|
|
186
|
+
})
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Behavioral Notes
|
|
190
|
+
|
|
191
|
+
- RPC frames are forwarded as binary MsgPack payloads.
|
|
192
|
+
- Observable-returning RPC handlers are supported.
|
|
193
|
+
- Discovery is driven by relay `hello` and `offline` synchronization.
|
|
194
|
+
- Pubsub subscriptions are tracked by topic on the relay.
|
|
195
|
+
- Relay startup should happen before providers and clients.
|
|
196
|
+
- `WebsocketRelayServer` is a relay, not an application runtime.
|
|
197
|
+
|
|
198
|
+
## Development Scripts
|
|
199
|
+
|
|
200
|
+
From this package directory:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
bun run build
|
|
204
|
+
bun run test:websocket
|
|
205
|
+
bun run test:websocket:e2e
|
|
206
|
+
bun run test:websocket:e2e:matrix
|
|
207
|
+
bun run test:websocket:e2e:reverse
|
|
208
|
+
bun run test:e2e
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Examples:
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
bun run example:websocket:server
|
|
215
|
+
bun run example:websocket:provider
|
|
216
|
+
bun run example:websocket:client
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Examples To Read First
|
|
220
|
+
|
|
221
|
+
Canonical examples in this package:
|
|
222
|
+
|
|
223
|
+
- `examples/websocket-server.ts`
|
|
224
|
+
- `examples/websocket-provider.ts`
|
|
225
|
+
- `examples/websocket-client.ts`
|
|
226
|
+
- `examples/websocket-e2e-test.ts`
|
|
227
|
+
- `examples/websocket-e2e-matrix-test.ts`
|
|
228
|
+
- `examples/websocket-e2e-round-robin-test.ts`
|
|
229
|
+
|
|
230
|
+
Use these as the preferred implementation references when writing app code or generating code with AI tools.
|
|
231
|
+
|
|
232
|
+
## Relationship With Core
|
|
233
|
+
|
|
234
|
+
Keep these responsibilities separate:
|
|
235
|
+
|
|
236
|
+
- `@spider-mesh/core`: service runtime, decorators, remote linking, shared contracts
|
|
237
|
+
- `@spider-mesh/ws`: built-in WebSocket transporter
|
|
238
|
+
- `@spider-mesh/ws/relay-server`: dedicated relay process
|
|
239
|
+
|
|
240
|
+
If you are not specifically implementing WebSocket transport, default to `@spider-mesh/core`.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { RemoteServiceLinker, SpiderMesh } from '@spider-mesh/core';
|
|
2
|
+
import { WebsocketTransporter } from '../src/index.js';
|
|
3
|
+
const wsUrl = process.env.WS_URL || 'ws://127.0.0.1:8787';
|
|
4
|
+
const transporter = new WebsocketTransporter({
|
|
5
|
+
heartbeatIntervalMs: 5000,
|
|
6
|
+
reconnectIntervalMs: 1000,
|
|
7
|
+
});
|
|
8
|
+
transporter.connect(wsUrl);
|
|
9
|
+
const mesh = new SpiderMesh({ transporters: [transporter] });
|
|
10
|
+
const greeter = RemoteServiceLinker.link(mesh, {
|
|
11
|
+
service: 'GreetingService',
|
|
12
|
+
timeout: 5000,
|
|
13
|
+
});
|
|
14
|
+
await greeter.wait();
|
|
15
|
+
greeter.hello('websocket client').subscribe(message => {
|
|
16
|
+
console.log(message);
|
|
17
|
+
});
|
|
18
|
+
//# sourceMappingURL=websocket-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket-client.js","sourceRoot":"","sources":["../../examples/websocket-client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAEtD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,qBAAqB,CAAA;AAEzD,MAAM,WAAW,GAAG,IAAI,oBAAoB,CAAC;IACzC,mBAAmB,EAAE,IAAI;IACzB,mBAAmB,EAAE,IAAI;CAC5B,CAAC,CAAA;AACF,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAM1B,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AAC5D,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,CAAkB,IAAI,EAAE;IAC5D,OAAO,EAAE,iBAAiB;IAC1B,OAAO,EAAE,IAAI;CAChB,CAAC,CAAA;AAEF,MAAM,OAAO,CAAC,IAAI,EAAE,CAAA;AAEpB,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE;IAClD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;AACxB,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { firstValueFrom, timeout } from 'rxjs';
|
|
2
|
+
import { RemoteServiceLinker, SpiderMesh } from '@spider-mesh/core';
|
|
3
|
+
import { WebsocketTransporter } from '../src/index.js';
|
|
4
|
+
const wsUrl = process.env.WS_URL || 'ws://127.0.0.1:8787';
|
|
5
|
+
const transporterOptions = {
|
|
6
|
+
heartbeatIntervalMs: 1000,
|
|
7
|
+
reconnectIntervalMs: 500,
|
|
8
|
+
};
|
|
9
|
+
const transporter = new WebsocketTransporter(transporterOptions);
|
|
10
|
+
transporter.connect(wsUrl);
|
|
11
|
+
console.log('WebSocket e2e client connected');
|
|
12
|
+
async function main() {
|
|
13
|
+
const mesh = new SpiderMesh({ transporters: [transporter] });
|
|
14
|
+
const greeter = RemoteServiceLinker.link(mesh, {
|
|
15
|
+
service: 'GreetingService',
|
|
16
|
+
timeout: 3000,
|
|
17
|
+
retry: 2,
|
|
18
|
+
});
|
|
19
|
+
const guard = setTimeout(() => {
|
|
20
|
+
console.error('WebSocket e2e client timed out');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}, 10000);
|
|
23
|
+
try {
|
|
24
|
+
await greeter.wait(() => mesh.listRpcNodes('GreetingService').length > 0);
|
|
25
|
+
const result = await firstValueFrom(greeter.hello('websocket e2e').pipe(timeout(5000)));
|
|
26
|
+
console.log(result);
|
|
27
|
+
process.exit(0);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
console.error(error);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
clearTimeout(guard);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
await main();
|
|
38
|
+
//# sourceMappingURL=websocket-e2e-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket-e2e-client.js","sourceRoot":"","sources":["../../examples/websocket-e2e-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,OAAO,EAAmB,MAAM,MAAM,CAAA;AAC/D,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAEtD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,qBAAqB,CAAA;AACzD,MAAM,kBAAkB,GAAG;IACvB,mBAAmB,EAAE,IAAI;IACzB,mBAAmB,EAAE,GAAG;CAC3B,CAAA;AAED,MAAM,WAAW,GAAG,IAAI,oBAAoB,CAAC,kBAAkB,CAAC,CAAA;AAChE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAC1B,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAA;AAM7C,KAAK,UAAU,IAAI;IACf,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;IAC5D,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,CAAkB,IAAI,EAAE;QAC5D,OAAO,EAAE,iBAAiB;QAC1B,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,CAAC;KACX,CAAC,CAAA;IAEF,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;QAC1B,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAA;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC,EAAE,KAAK,CAAC,CAAA;IAET,IAAI,CAAC;QACD,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QACzE,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACvF,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC;YAAS,CAAC;QACP,YAAY,CAAC,KAAK,CAAC,CAAA;IACvB,CAAC;AACL,CAAC;AAED,MAAM,IAAI,EAAE,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Observable, firstValueFrom, lastValueFrom, timeout, toArray } from 'rxjs';
|
|
2
|
+
import { RemoteServiceLinker, SpiderMesh } from '@spider-mesh/core';
|
|
3
|
+
import { WebsocketTransporter } from '../src/index.js';
|
|
4
|
+
const wsUrl = process.env.WS_URL || 'ws://127.0.0.1:8787';
|
|
5
|
+
const transporterOptions = {
|
|
6
|
+
heartbeatIntervalMs: 1000,
|
|
7
|
+
reconnectIntervalMs: 500,
|
|
8
|
+
};
|
|
9
|
+
const transporter = new WebsocketTransporter(transporterOptions);
|
|
10
|
+
transporter.connect(wsUrl);
|
|
11
|
+
console.log('WebSocket matrix e2e client connected');
|
|
12
|
+
async function expectError(label, run, expectedMessage) {
|
|
13
|
+
try {
|
|
14
|
+
const result = run();
|
|
15
|
+
if (result instanceof Observable) {
|
|
16
|
+
await firstValueFrom(result.pipe(timeout(5000)));
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
await result;
|
|
20
|
+
}
|
|
21
|
+
throw new Error(`${label} did not fail`);
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
const message = typeof error === 'object' && error && 'message' in error ? String(error.message) : String(error);
|
|
25
|
+
if (message !== expectedMessage) {
|
|
26
|
+
throw new Error(`${label} expected ${expectedMessage} but got ${message}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
async function main() {
|
|
31
|
+
const mesh = new SpiderMesh({ transporters: [transporter] });
|
|
32
|
+
const service = RemoteServiceLinker.link(mesh, {
|
|
33
|
+
service: 'RpcMatrixService',
|
|
34
|
+
timeout: 3000,
|
|
35
|
+
retry: 2,
|
|
36
|
+
});
|
|
37
|
+
const guard = setTimeout(() => {
|
|
38
|
+
console.error('WebSocket matrix e2e client timed out');
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}, 15000);
|
|
41
|
+
try {
|
|
42
|
+
await service.wait(() => mesh.listRpcNodes('RpcMatrixService').length > 0);
|
|
43
|
+
const syncValue = await service.syncValue('case-sync');
|
|
44
|
+
const asyncValue = await service.asyncValue('case-async');
|
|
45
|
+
const syncObservable = await lastValueFrom(service.syncObservable('case-sync-observable').pipe(timeout(5000), toArray()));
|
|
46
|
+
const asyncObservable = await lastValueFrom(service.asyncObservable('case-async-observable').pipe(timeout(5000), toArray()));
|
|
47
|
+
await expectError('syncError', () => service.syncError(), 'sync-error');
|
|
48
|
+
await expectError('asyncError', () => service.asyncError(), 'async-error');
|
|
49
|
+
await expectError('observableError', () => firstValueFrom(service.observableError().pipe(timeout(5000))), 'observable-error');
|
|
50
|
+
console.log(JSON.stringify({
|
|
51
|
+
syncValue,
|
|
52
|
+
asyncValue,
|
|
53
|
+
syncObservable,
|
|
54
|
+
asyncObservable,
|
|
55
|
+
errors: ['sync-error', 'async-error', 'observable-error']
|
|
56
|
+
}));
|
|
57
|
+
process.exit(0);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.error(error);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
clearTimeout(guard);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
await main();
|
|
68
|
+
//# sourceMappingURL=websocket-e2e-matrix-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket-e2e-matrix-client.js","sourceRoot":"","sources":["../../examples/websocket-e2e-matrix-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { concat, of, throwError } from 'rxjs';
|
|
3
|
+
import { delay } from 'rxjs/operators';
|
|
4
|
+
import { Microservice, SpiderMesh } from '@spider-mesh/core';
|
|
5
|
+
import { WebsocketTransporter } from '../src/index.js';
|
|
6
|
+
const wsUrl = process.env.WS_URL || 'ws://127.0.0.1:8787';
|
|
7
|
+
const transporter = new WebsocketTransporter({
|
|
8
|
+
heartbeatIntervalMs: 1000,
|
|
9
|
+
reconnectIntervalMs: 500,
|
|
10
|
+
});
|
|
11
|
+
transporter.connect(wsUrl);
|
|
12
|
+
let RpcMatrixService = class RpcMatrixService {
|
|
13
|
+
syncValue(name) {
|
|
14
|
+
return `sync:${name}`;
|
|
15
|
+
}
|
|
16
|
+
async asyncValue(name) {
|
|
17
|
+
return `async:${name}`;
|
|
18
|
+
}
|
|
19
|
+
syncObservable(name) {
|
|
20
|
+
return concat(of(`sync-observable:${name}:1`), of(`sync-observable:${name}:2`).pipe(delay(10)));
|
|
21
|
+
}
|
|
22
|
+
async asyncObservable(name) {
|
|
23
|
+
return concat(of(`async-observable:${name}:1`).pipe(delay(10)), of(`async-observable:${name}:2`).pipe(delay(10)));
|
|
24
|
+
}
|
|
25
|
+
syncError() {
|
|
26
|
+
throw new Error('sync-error');
|
|
27
|
+
}
|
|
28
|
+
async asyncError() {
|
|
29
|
+
throw new Error('async-error');
|
|
30
|
+
}
|
|
31
|
+
observableError() {
|
|
32
|
+
return throwError(() => new Error('observable-error'));
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
RpcMatrixService = __decorate([
|
|
36
|
+
Microservice({ role: 'provider', mode: 'matrix-e2e' })
|
|
37
|
+
], RpcMatrixService);
|
|
38
|
+
new RpcMatrixService();
|
|
39
|
+
new SpiderMesh({ transporters: [transporter] });
|
|
40
|
+
console.log(`WebSocket matrix e2e provider ready at ${wsUrl}`);
|
|
41
|
+
setInterval(() => undefined, 1000);
|
|
42
|
+
//# sourceMappingURL=websocket-e2e-matrix-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket-e2e-matrix-provider.js","sourceRoot":"","sources":["../../examples/websocket-e2e-matrix-provider.ts"],"names":[],"mappings":";AAAA,OAAO,EAAc,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,MAAM,CAAA;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAEtD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,qBAAqB,CAAA;AAEzD,MAAM,WAAW,GAAG,IAAI,oBAAoB,CAAC;IACzC,mBAAmB,EAAE,IAAI;IACzB,mBAAmB,EAAE,GAAG;CAC3B,CAAC,CAAA;AACF,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAG1B,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;IAClB,SAAS,CAAC,IAAY;QAClB,OAAO,QAAQ,IAAI,EAAE,CAAA;IACzB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,IAAY;QACzB,OAAO,SAAS,IAAI,EAAE,CAAA;IAC1B,CAAC;IAED,cAAc,CAAC,IAAY;QACvB,OAAO,MAAM,CACT,EAAE,CAAC,mBAAmB,IAAI,IAAI,CAAC,EAC/B,EAAE,CAAC,mBAAmB,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAClD,CAAA;IACL,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,IAAY;QAC9B,OAAO,MAAM,CACT,EAAE,CAAC,oBAAoB,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAChD,EAAE,CAAC,oBAAoB,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CACnD,CAAA;IACL,CAAC;IAED,SAAS;QACL,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAA;IACjC,CAAC;IAED,KAAK,CAAC,UAAU;QACZ,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAA;IAClC,CAAC;IAED,eAAe;QACX,OAAO,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAA;IAC1D,CAAC;CACJ,CAAA;AAlCK,gBAAgB;IADrB,YAAY,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;GACjD,gBAAgB,CAkCrB;AAED,IAAI,gBAAgB,EAAE,CAAA;AACtB,IAAI,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AAE/C,OAAO,CAAC,GAAG,CAAC,0CAA0C,KAAK,EAAE,CAAC,CAAA;AAE9D,WAAW,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
const cwd = new URL('..', import.meta.url);
|
|
3
|
+
const port = 9400 + Math.floor(Math.random() * 200);
|
|
4
|
+
const wsUrl = `ws://127.0.0.1:${port}`;
|
|
5
|
+
const started = [];
|
|
6
|
+
function start(name, file, env) {
|
|
7
|
+
const child = spawn('bun', ['run', file], {
|
|
8
|
+
cwd,
|
|
9
|
+
env: {
|
|
10
|
+
...process.env,
|
|
11
|
+
...env,
|
|
12
|
+
},
|
|
13
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
14
|
+
});
|
|
15
|
+
started.push({ child, name });
|
|
16
|
+
return child;
|
|
17
|
+
}
|
|
18
|
+
function waitForOutput(child, matcher, timeoutMs, name) {
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
const stdoutStream = child.stdout;
|
|
21
|
+
const stderrStream = child.stderr;
|
|
22
|
+
if (!stdoutStream || !stderrStream) {
|
|
23
|
+
reject(new Error(`${name} is missing piped stdout/stderr`));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
let stdout = '';
|
|
27
|
+
let stderr = '';
|
|
28
|
+
const cleanup = () => {
|
|
29
|
+
clearTimeout(timeout);
|
|
30
|
+
stdoutStream.off('data', onStdout);
|
|
31
|
+
stderrStream.off('data', onStderr);
|
|
32
|
+
child.off('exit', onExit);
|
|
33
|
+
};
|
|
34
|
+
const timeout = setTimeout(() => {
|
|
35
|
+
cleanup();
|
|
36
|
+
reject(new Error(`${name} timed out after ${timeoutMs}ms\nstdout:\n${stdout}\nstderr:\n${stderr}`));
|
|
37
|
+
}, timeoutMs);
|
|
38
|
+
const onStdout = (chunk) => {
|
|
39
|
+
stdout += chunk.toString();
|
|
40
|
+
if (matcher.test(stdout)) {
|
|
41
|
+
cleanup();
|
|
42
|
+
resolve(stdout);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
const onStderr = (chunk) => {
|
|
46
|
+
stderr += chunk.toString();
|
|
47
|
+
};
|
|
48
|
+
const onExit = (code) => {
|
|
49
|
+
cleanup();
|
|
50
|
+
reject(new Error(`${name} exited before expected output, code=${code}\nstdout:\n${stdout}\nstderr:\n${stderr}`));
|
|
51
|
+
};
|
|
52
|
+
stdoutStream.on('data', onStdout);
|
|
53
|
+
stderrStream.on('data', onStderr);
|
|
54
|
+
child.on('exit', onExit);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
async function stopAll() {
|
|
58
|
+
const pending = [...started];
|
|
59
|
+
started.length = 0;
|
|
60
|
+
await Promise.allSettled(pending.map(({ child }) => new Promise(resolve => {
|
|
61
|
+
if (child.exitCode !== null || child.killed) {
|
|
62
|
+
resolve();
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
child.once('exit', () => resolve());
|
|
66
|
+
child.kill('SIGTERM');
|
|
67
|
+
})));
|
|
68
|
+
}
|
|
69
|
+
async function main() {
|
|
70
|
+
const relay = start('relay', 'examples/websocket-server.ts', { WS_PORT: `${port}` });
|
|
71
|
+
await waitForOutput(relay, /listening on/, 5000, 'relay');
|
|
72
|
+
const provider = start('provider', 'examples/websocket-e2e-matrix-provider.ts', { WS_URL: wsUrl });
|
|
73
|
+
await waitForOutput(provider, /matrix e2e provider ready/, 5000, 'provider');
|
|
74
|
+
const client = start('client', 'examples/websocket-e2e-matrix-client.ts', { WS_URL: wsUrl });
|
|
75
|
+
await waitForOutput(client, /matrix e2e client connected/, 5000, 'client');
|
|
76
|
+
const output = await waitForOutput(client, /"syncValue":"sync:case-sync"/, 15000, 'client');
|
|
77
|
+
console.log(output.trim());
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
await main();
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
await stopAll();
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=websocket-e2e-matrix-test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket-e2e-matrix-test.js","sourceRoot":"","sources":["../../examples/websocket-e2e-matrix-test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { Microservice, SpiderMesh } from '@spider-mesh/core';
|
|
3
|
+
import { WebsocketTransporter } from '../src/index.js';
|
|
4
|
+
const wsUrl = process.env.WS_URL || 'ws://127.0.0.1:8787';
|
|
5
|
+
const providerId = process.env.PROVIDER_ID || 'provider';
|
|
6
|
+
const transporter = new WebsocketTransporter({
|
|
7
|
+
heartbeatIntervalMs: 1000,
|
|
8
|
+
reconnectIntervalMs: 500,
|
|
9
|
+
});
|
|
10
|
+
transporter.connect(wsUrl);
|
|
11
|
+
let GreetingService = class GreetingService {
|
|
12
|
+
async hello(name) {
|
|
13
|
+
return `hello ${name} from ${providerId}`;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
GreetingService = __decorate([
|
|
17
|
+
Microservice({ role: 'provider', mode: 'e2e' })
|
|
18
|
+
], GreetingService);
|
|
19
|
+
new GreetingService();
|
|
20
|
+
new SpiderMesh({ transporters: [transporter] });
|
|
21
|
+
console.log(`WebSocket e2e provider ready at ${wsUrl} (${providerId})`);
|
|
22
|
+
setInterval(() => undefined, 1000);
|
|
23
|
+
//# sourceMappingURL=websocket-e2e-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket-e2e-provider.js","sourceRoot":"","sources":["../../examples/websocket-e2e-provider.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAEtD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,qBAAqB,CAAA;AACzD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,UAAU,CAAA;AAExD,MAAM,WAAW,GAAG,IAAI,oBAAoB,CAAC;IACzC,mBAAmB,EAAE,IAAI;IACzB,mBAAmB,EAAE,GAAG;CAC3B,CAAC,CAAA;AACF,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAG1B,IAAM,eAAe,GAArB,MAAM,eAAe;IACjB,KAAK,CAAC,KAAK,CAAC,IAAY;QACpB,OAAO,SAAS,IAAI,SAAS,UAAU,EAAE,CAAA;IAC7C,CAAC;CACJ,CAAA;AAJK,eAAe;IADpB,YAAY,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;GAC1C,eAAe,CAIpB;AAED,IAAI,eAAe,EAAE,CAAA;AACrB,IAAI,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AAE/C,OAAO,CAAC,GAAG,CAAC,mCAAmC,KAAK,KAAK,UAAU,GAAG,CAAC,CAAA;AAEvE,WAAW,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { Microservice, SpiderMesh } from '@spider-mesh/core';
|
|
3
|
+
import { WebsocketTransporter } from '../src/index.js';
|
|
4
|
+
const wsUrl = process.env.WS_URL || 'ws://127.0.0.1:8787';
|
|
5
|
+
const transporterOptions = {
|
|
6
|
+
heartbeatIntervalMs: 1000,
|
|
7
|
+
reconnectIntervalMs: 500,
|
|
8
|
+
};
|
|
9
|
+
const transporter = new WebsocketTransporter(transporterOptions);
|
|
10
|
+
transporter.connect(wsUrl);
|
|
11
|
+
console.log('WebSocket reverse e2e client connected');
|
|
12
|
+
let ClientResponderService = class ClientResponderService {
|
|
13
|
+
async helloFromServer(name) {
|
|
14
|
+
return `hello ${name} from client`;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
ClientResponderService = __decorate([
|
|
18
|
+
Microservice({ role: 'client', mode: 'reverse-e2e' })
|
|
19
|
+
], ClientResponderService);
|
|
20
|
+
new ClientResponderService();
|
|
21
|
+
new SpiderMesh({ transporters: [transporter] });
|
|
22
|
+
setInterval(() => undefined, 1000);
|
|
23
|
+
//# sourceMappingURL=websocket-e2e-reverse-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket-e2e-reverse-client.js","sourceRoot":"","sources":["../../examples/websocket-e2e-reverse-client.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAEtD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,qBAAqB,CAAA;AACzD,MAAM,kBAAkB,GAAG;IACvB,mBAAmB,EAAE,IAAI;IACzB,mBAAmB,EAAE,GAAG;CAC3B,CAAA;AAED,MAAM,WAAW,GAAG,IAAI,oBAAoB,CAAC,kBAAkB,CAAC,CAAA;AAChE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAC1B,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAA;AAGrD,IAAM,sBAAsB,GAA5B,MAAM,sBAAsB;IACxB,KAAK,CAAC,eAAe,CAAC,IAAY;QAC9B,OAAO,SAAS,IAAI,cAAc,CAAA;IACtC,CAAC;CACJ,CAAA;AAJK,sBAAsB;IAD3B,YAAY,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;GAChD,sBAAsB,CAI3B;AAED,IAAI,sBAAsB,EAAE,CAAA;AAC5B,IAAI,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AAE/C,WAAW,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { firstValueFrom, timeout } from 'rxjs';
|
|
2
|
+
import { RemoteServiceLinker, SpiderMesh } from '@spider-mesh/core';
|
|
3
|
+
import { WebsocketTransporter } from '../src/index.js';
|
|
4
|
+
const wsUrl = process.env.WS_URL || 'ws://127.0.0.1:8787';
|
|
5
|
+
const transporterOptions = {
|
|
6
|
+
heartbeatIntervalMs: 1000,
|
|
7
|
+
reconnectIntervalMs: 500,
|
|
8
|
+
};
|
|
9
|
+
const transporter = new WebsocketTransporter(transporterOptions);
|
|
10
|
+
transporter.connect(wsUrl);
|
|
11
|
+
console.log('WebSocket reverse e2e server connected');
|
|
12
|
+
async function main() {
|
|
13
|
+
const mesh = new SpiderMesh({ transporters: [transporter] });
|
|
14
|
+
const responder = RemoteServiceLinker.link(mesh, {
|
|
15
|
+
service: 'ClientResponderService',
|
|
16
|
+
timeout: 3000,
|
|
17
|
+
retry: 2,
|
|
18
|
+
});
|
|
19
|
+
const guard = setTimeout(() => {
|
|
20
|
+
console.error('WebSocket reverse e2e server timed out');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}, 10000);
|
|
23
|
+
try {
|
|
24
|
+
await responder.wait(() => mesh.listRpcNodes('ClientResponderService').length > 0);
|
|
25
|
+
const result = await firstValueFrom(responder.helloFromServer('from server').pipe(timeout(5000)));
|
|
26
|
+
console.log(result);
|
|
27
|
+
process.exit(0);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
console.error(error);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
clearTimeout(guard);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
await main();
|
|
38
|
+
//# sourceMappingURL=websocket-e2e-reverse-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket-e2e-reverse-server.js","sourceRoot":"","sources":["../../examples/websocket-e2e-reverse-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,OAAO,EAAmB,MAAM,MAAM,CAAA;AAC/D,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAEtD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,qBAAqB,CAAA;AAEzD,MAAM,kBAAkB,GAAG;IACvB,mBAAmB,EAAE,IAAI;IACzB,mBAAmB,EAAE,GAAG;CAC3B,CAAA;AAED,MAAM,WAAW,GAAG,IAAI,oBAAoB,CAAC,kBAAkB,CAAC,CAAA;AAChE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAC1B,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAA;AAMrD,KAAK,UAAU,IAAI;IACf,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;IAC5D,MAAM,SAAS,GAAG,mBAAmB,CAAC,IAAI,CAAyB,IAAI,EAAE;QACrE,OAAO,EAAE,wBAAwB;QACjC,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,CAAC;KACX,CAAC,CAAA;IAEF,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;QAC1B,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAA;QACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC,EAAE,KAAK,CAAC,CAAA;IAET,IAAI,CAAC;QACD,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,wBAAwB,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAClF,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,SAAS,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC;YAAS,CAAC;QACP,YAAY,CAAC,KAAK,CAAC,CAAA;IACvB,CAAC;AACL,CAAC;AAED,MAAM,IAAI,EAAE,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|