@spider-mesh/core 2.0.29 → 2.0.35

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 (79) hide show
  1. package/README.md +573 -0
  2. package/build/src/RemoteService.d.ts +1 -1
  3. package/build/src/RemoteService.js.map +1 -1
  4. package/build/src/SpiderMesh.d.ts +2 -2
  5. package/build/src/SpiderMesh.js +267 -120
  6. package/build/src/SpiderMesh.js.map +1 -1
  7. package/build/src/decorators/Microservice.d.ts +1 -1
  8. package/build/src/decorators/Microservice.js.map +1 -1
  9. package/build/src/helpers/GetIps.js +15 -8
  10. package/build/src/helpers/GetIps.js.map +1 -1
  11. package/build/src/helpers/LimitConcurrency.js +5 -2
  12. package/build/src/helpers/LimitConcurrency.js.map +1 -1
  13. package/build/src/helpers/MicroserviceException.d.ts +4 -15
  14. package/build/src/helpers/MicroserviceException.js +1 -25
  15. package/build/src/helpers/MicroserviceException.js.map +1 -1
  16. package/build/src/index.d.ts +1 -0
  17. package/build/src/types.d.ts +102 -0
  18. package/build/src/types.js +2 -0
  19. package/build/src/types.js.map +1 -0
  20. package/build/tsconfig.tsbuildinfo +1 -1
  21. package/package.json +4 -4
  22. package/tsconfig.json +3 -1
  23. package/build/src/abstract/DiscoveryTransporter.d.ts +0 -5
  24. package/build/src/abstract/DiscoveryTransporter.js +0 -3
  25. package/build/src/abstract/DiscoveryTransporter.js.map +0 -1
  26. package/build/src/abstract/PubsubTransporter.d.ts +0 -11
  27. package/build/src/abstract/PubsubTransporter.js +0 -3
  28. package/build/src/abstract/PubsubTransporter.js.map +0 -1
  29. package/build/src/abstract/RemoteService.d.ts +0 -35
  30. package/build/src/abstract/RemoteService.js +0 -107
  31. package/build/src/abstract/RemoteService.js.map +0 -1
  32. package/build/src/abstract/RpcTransporter.d.ts +0 -30
  33. package/build/src/abstract/RpcTransporter.js +0 -3
  34. package/build/src/abstract/RpcTransporter.js.map +0 -1
  35. package/build/src/abstract/SpiderMeshNode.d.ts +0 -18
  36. package/build/src/abstract/SpiderMeshNode.js +0 -2
  37. package/build/src/abstract/SpiderMeshNode.js.map +0 -1
  38. package/build/src/abstracts/DiscoveryTransporter.d.ts +0 -5
  39. package/build/src/abstracts/DiscoveryTransporter.js +0 -3
  40. package/build/src/abstracts/DiscoveryTransporter.js.map +0 -1
  41. package/build/src/abstracts/PubsubTransporter.d.ts +0 -11
  42. package/build/src/abstracts/PubsubTransporter.js +0 -3
  43. package/build/src/abstracts/PubsubTransporter.js.map +0 -1
  44. package/build/src/abstracts/RemoteService.d.ts +0 -38
  45. package/build/src/abstracts/RemoteService.js +0 -105
  46. package/build/src/abstracts/RemoteService.js.map +0 -1
  47. package/build/src/abstracts/RpcTransporter.d.ts +0 -30
  48. package/build/src/abstracts/RpcTransporter.js +0 -3
  49. package/build/src/abstracts/RpcTransporter.js.map +0 -1
  50. package/build/src/abstracts/SpiderMeshNode.d.ts +0 -18
  51. package/build/src/abstracts/SpiderMeshNode.js +0 -2
  52. package/build/src/abstracts/SpiderMeshNode.js.map +0 -1
  53. package/build/src/helpers/MicroserviceNotFound copy.d.ts +0 -5
  54. package/build/src/helpers/MicroserviceNotFound copy.js +0 -8
  55. package/build/src/helpers/MicroserviceNotFound copy.js.map +0 -1
  56. package/build/src/helpers/MicroserviceNotFound.d.ts +0 -5
  57. package/build/src/helpers/MicroserviceNotFound.js +0 -8
  58. package/build/src/helpers/MicroserviceNotFound.js.map +0 -1
  59. package/build/src/helpers/MicroserviceOfflineException.d.ts +0 -5
  60. package/build/src/helpers/MicroserviceOfflineException.js +0 -8
  61. package/build/src/helpers/MicroserviceOfflineException.js.map +0 -1
  62. package/build/src/helpers/MicroserviceRpcTimeout.d.ts +0 -5
  63. package/build/src/helpers/MicroserviceRpcTimeout.js +0 -8
  64. package/build/src/helpers/MicroserviceRpcTimeout.js.map +0 -1
  65. package/build/src/interfaces/DiscoveryTransporter.d.ts +0 -5
  66. package/build/src/interfaces/DiscoveryTransporter.js +0 -3
  67. package/build/src/interfaces/DiscoveryTransporter.js.map +0 -1
  68. package/build/src/interfaces/PubsubTransporter.d.ts +0 -11
  69. package/build/src/interfaces/PubsubTransporter.js +0 -3
  70. package/build/src/interfaces/PubsubTransporter.js.map +0 -1
  71. package/build/src/interfaces/RemoteService.d.ts +0 -35
  72. package/build/src/interfaces/RemoteService.js +0 -107
  73. package/build/src/interfaces/RemoteService.js.map +0 -1
  74. package/build/src/interfaces/RpcTransporter.d.ts +0 -30
  75. package/build/src/interfaces/RpcTransporter.js +0 -3
  76. package/build/src/interfaces/RpcTransporter.js.map +0 -1
  77. package/build/src/interfaces/SpiderMeshNode.d.ts +0 -18
  78. package/build/src/interfaces/SpiderMeshNode.js +0 -2
  79. package/build/src/interfaces/SpiderMeshNode.js.map +0 -1
package/README.md ADDED
@@ -0,0 +1,573 @@
1
+ # Spider Mesh Core
2
+
3
+ `@spider-mesh/core` is a lightweight TypeScript microservice core for service-to-service RPC, pubsub events, and node discovery with pluggable transporters.
4
+
5
+ It provides:
6
+
7
+ - Decorator-based local service registration
8
+ - Typed remote service linking through a Proxy
9
+ - Stream-first RPC over transporter-managed byte delivery
10
+ - Discovery and pubsub integration through simple transporter contracts
11
+ - Transporter contracts that can be implemented directly or consumed through companion transport packages such as `@spider-mesh/tcp` and `@spider-mesh/ws`
12
+ - NestJS adapters for exposing and consuming services
13
+
14
+ ## Package Boundary
15
+
16
+ Spider Mesh is now split into two main package layers:
17
+
18
+ - `@spider-mesh/core`: runtime-agnostic service runtime, decorators, linking, and shared contracts
19
+ - companion transport packages: concrete transport implementations such as `@spider-mesh/tcp` and `@spider-mesh/ws`
20
+
21
+ If you are reading this package first, the practical rule is simple:
22
+
23
+ - stay in `@spider-mesh/core` for service code and runtime code
24
+ - add a companion transport package only when you explicitly need a concrete transport implementation
25
+
26
+ ## Install
27
+
28
+ ```bash
29
+ bun add @spider-mesh/core rxjs reflect-metadata
30
+ ```
31
+
32
+ This package is ESM-only.
33
+
34
+ ## AI Usage Guide
35
+
36
+ Use this section as the canonical decision guide when generating code with AI tools.
37
+
38
+ ### Environment support matrix
39
+
40
+ | Runtime | `@spider-mesh/core` | `@spider-mesh/tcp` | `@spider-mesh/ws` |
41
+ | --- | --- | --- | --- |
42
+ | Node.js | Supported | Supported | Supported |
43
+ | Bun | Supported | Supported | Supported |
44
+ | Browser | Partially supported, depends on your custom transporter | Not recommended | Not recommended |
45
+ | React Native | Supported for the core entry only | Not recommended | Not recommended |
46
+
47
+ ### Recommended imports
48
+
49
+ Use these imports exactly.
50
+
51
+ - Core runtime, decorators, RPC linking, NestJS helpers: `import { ... } from '@spider-mesh/core'`
52
+ - Shared transporter contracts and runtime APIs: `import { ... } from '@spider-mesh/core'`
53
+ - Companion TCP transport implementation when needed: `import { Http2Rpc, Http2Pubsub, UdpDiscovery } from '@spider-mesh/tcp'`
54
+ - Companion WebSocket transport implementation when needed: `import { WebsocketTransporter } from '@spider-mesh/ws'`
55
+
56
+ ### When to use what
57
+
58
+ - Use `SpiderMesh` when you need a local runtime that can expose services, discover nodes, publish events, or call remote services.
59
+ - Use `@Microservice()` on local classes that should be callable remotely.
60
+ - Use `RemoteServiceLinker.link()` when you need a typed remote proxy for another service.
61
+ - Use transporter contracts from `@spider-mesh/core` when you are implementing or typing your own transport.
62
+ - Use `@spider-mesh/tcp` or `@spider-mesh/ws` when you want a companion transport package.
63
+ - Use a custom transporter when the runtime is not Node.js or Bun, or when you need a different protocol.
64
+
65
+ ### Do and don't
66
+
67
+ Do:
68
+
69
+ - Import runtime-agnostic APIs from `@spider-mesh/core`.
70
+ - Import transporter contracts from `@spider-mesh/core` when you need transport typing.
71
+ - Use a companion transport package such as `@spider-mesh/tcp` or `@spider-mesh/ws` when you need a ready-made transport implementation.
72
+ - Wait for remote service availability with `wait()` before making calls in startup flows.
73
+ - Treat the files under `examples/` as canonical usage references.
74
+
75
+ Don't:
76
+
77
+ - Do not assume `@spider-mesh/core` exports every concrete transporter.
78
+ - Do not assume `@spider-mesh/tcp` is React Native-ready.
79
+ - Do not assume `@spider-mesh/ws` is React Native-ready.
80
+ - Do not couple service code to a single transport package unless that is intentional.
81
+ - Do not call remote services before the target service has been discovered unless you intentionally rely on retry behavior.
82
+
83
+ ### Canonical recipes
84
+
85
+ Provider recipe:
86
+
87
+ 1. Import `Microservice` and `SpiderMesh` from `@spider-mesh/core`.
88
+ 2. Choose a concrete transporter implementation, for example from `@spider-mesh/tcp` or `@spider-mesh/ws`.
89
+ 3. Define a class and decorate it with `@Microservice()`.
90
+ 4. Instantiate the service class.
91
+ 5. Create `new SpiderMesh({ transporters: [transporter] })`.
92
+
93
+ Client recipe:
94
+
95
+ 1. Import `SpiderMesh` and `RemoteServiceLinker` from `@spider-mesh/core`.
96
+ 2. Choose a concrete transporter implementation, for example from `@spider-mesh/tcp` or `@spider-mesh/ws`.
97
+ 3. Create `new SpiderMesh({ transporters: [transporter] })`.
98
+ 4. Create a typed remote proxy with `RemoteServiceLinker.link()`.
99
+ 5. Call `await proxy.wait()` before the first RPC call.
100
+
101
+ Companion transport package recipes:
102
+
103
+ TCP:
104
+
105
+ 1. Import `UdpDiscovery`, `Http2Rpc`, and `Http2Pubsub` from `@spider-mesh/tcp`.
106
+ 2. Add those transporters to `new SpiderMesh({ transporters: [...] })`.
107
+ 3. Let the TCP package handle discovery, RPC, and pubsub transport.
108
+
109
+ WebSocket:
110
+
111
+ 1. Import `WebsocketTransporter` from `@spider-mesh/ws`.
112
+ 2. Add that transporter to `new SpiderMesh({ transporters: [...] })`.
113
+ 3. Run `WebsocketRelayServer` from `@spider-mesh/ws/relay-server` when using the WebSocket companion package.
114
+
115
+ ### AI-safe assumptions
116
+
117
+ An AI agent should assume the following unless the codebase says otherwise:
118
+
119
+ - The root package entry is the safe default for shared runtime APIs.
120
+ - Concrete transports are opt-in through companion packages or custom implementations.
121
+ - Transporter contracts come from the core package.
122
+ - The companion TCP and WebSocket packages are sibling transport options for Node.js and Bun runtimes.
123
+ - If the target runtime is React Native, prefer the core APIs and a runtime-appropriate custom transporter.
124
+
125
+ ## Core Model
126
+
127
+ `SpiderMesh` is the runtime coordinator.
128
+
129
+ It keeps track of:
130
+
131
+ - The current node metadata
132
+ - Local service instances registered in the process
133
+ - Remote nodes discovered from discovery transporters
134
+ - RPC-capable nodes for each service
135
+ - RPC pending and running stream state
136
+ - Pubsub, RPC, and discovery transporters
137
+
138
+ ## Quick Start
139
+
140
+ ### 1. Define a local microservice
141
+
142
+ ```ts
143
+ import { BeforeMicroserviceOnline, Microservice } from '@spider-mesh/core'
144
+
145
+ @Microservice({ version: '1.0.0' })
146
+ export class UserService {
147
+ private ready = false
148
+
149
+ @BeforeMicroserviceOnline()
150
+ async warmup() {
151
+ this.ready = true
152
+ }
153
+
154
+ async getUser(id: string) {
155
+ if (!this.ready) throw new Error('Service not ready')
156
+ return { id, name: 'Ada' }
157
+ }
158
+ }
159
+ ```
160
+
161
+ `@Microservice()` registers the instance into Spider Mesh when the class is constructed.
162
+
163
+ `@BeforeMicroserviceOnline()` marks async setup methods that must complete before the service is exposed in local metadata.
164
+
165
+ ### 2. Create the runtime
166
+
167
+ ```ts
168
+ import { SpiderMesh } from '@spider-mesh/core'
169
+ import { MdnsDiscoveryTransporter } from './transporters/MdnsDiscoveryTransporter.js'
170
+ import { RedisRpcTransporter } from './transporters/RedisRpcTransporter.js'
171
+ import { RedisPubsubTransporter } from './transporters/RedisPubsubTransporter.js'
172
+
173
+ const mesh = new SpiderMesh({
174
+ transporters: [
175
+ MdnsDiscoveryTransporter,
176
+ RedisRpcTransporter,
177
+ RedisPubsubTransporter,
178
+ ],
179
+ })
180
+ ```
181
+
182
+ Transporter capability is inferred by method shape:
183
+
184
+ - `send()` means RPC transporter
185
+ - `publish()` means pubsub transporter
186
+ - `broadcast()` means discovery transporter
187
+
188
+ You can pass either transporter classes or already-created transporter instances into `transporters`.
189
+
190
+ ### 2a. Use companion transport packages
191
+
192
+ Spider Mesh can work with companion transport packages such as `@spider-mesh/tcp` and `@spider-mesh/ws`.
193
+
194
+ The root package entry exports the runtime-agnostic APIs and shared transporter contracts. Concrete transport implementations can be imported from companion packages when needed.
195
+
196
+ Create a runtime using the TCP package:
197
+
198
+ ```ts
199
+ import { SpiderMesh } from '@spider-mesh/core'
200
+ import { Http2Pubsub, Http2Rpc, UdpDiscovery } from '@spider-mesh/tcp'
201
+
202
+ const mesh = new SpiderMesh({
203
+ transporters: [
204
+ new UdpDiscovery(),
205
+ new Http2Rpc(),
206
+ new Http2Pubsub(),
207
+ ],
208
+ })
209
+ ```
210
+
211
+ Or use the WebSocket package:
212
+
213
+ ```ts
214
+ import { SpiderMesh } from '@spider-mesh/core'
215
+ import { WebsocketTransporter } from '@spider-mesh/ws'
216
+
217
+ const transporter = new WebsocketTransporter({
218
+ heartbeatIntervalMs: 5000,
219
+ reconnectIntervalMs: 1000,
220
+ })
221
+
222
+ transporter.connect('ws://127.0.0.1:8787')
223
+
224
+ const mesh = new SpiderMesh({
225
+ transporters: [transporter],
226
+ })
227
+ ```
228
+
229
+ Both patterns keep service/runtime code in `@spider-mesh/core` while delegating concrete transport behavior to a companion package.
230
+
231
+ ### 2b. Minimal working startup order
232
+
233
+ When using a discovery-based transport package, the canonical startup order is:
234
+
235
+ 1. Start one or more provider processes that register local `@Microservice()` classes.
236
+ 2. Start client processes.
237
+ 3. Wait for discovery to converge.
238
+ 4. In clients, call `await remote.wait()` before the first remote method call.
239
+
240
+ If an AI agent needs one default operational pattern, use this startup order.
241
+
242
+ ### 3. Call a remote service
243
+
244
+ ```ts
245
+ import { RemoteServiceLinker } from '@spider-mesh/core'
246
+
247
+ type UserServiceContract = {
248
+ getUser(id: string): Promise<{ id: string; name: string }>
249
+ }
250
+
251
+ const users = RemoteServiceLinker.link<UserServiceContract>(mesh, {
252
+ service: 'UserService',
253
+ })
254
+
255
+ await users.wait()
256
+
257
+ const user = await users.getUser('42')
258
+ console.log(user.name)
259
+ ```
260
+
261
+ Remote methods are exposed through a typed Proxy.
262
+
263
+ ## RPC Behavior
264
+
265
+ ### Awaitable observable calls
266
+
267
+ Remote method calls return an RxJS observable that is also awaitable.
268
+
269
+ ```ts
270
+ const user = await users.getUser('42')
271
+ ```
272
+
273
+ ```ts
274
+ users.getUser('42').subscribe(user => {
275
+ console.log(user)
276
+ })
277
+ ```
278
+
279
+ ### Stream-first RPC
280
+
281
+ Spider Mesh treats every RPC response as a stream.
282
+
283
+ - If a local method returns an `Observable`, each emission is forwarded to the caller.
284
+ - If a local method returns a `Promise` or plain value, it is sent as one `data` event with `completed: true`.
285
+ - If the caller unsubscribes early, Spider Mesh sends a `cancel` packet so the remote node can stop the running stream.
286
+
287
+ ### Per-link defaults
288
+
289
+ ```ts
290
+ const resilientUsers = users.set({
291
+ timeout: 3000,
292
+ retry: 2,
293
+ fallback: { id: 'fallback', name: 'Unknown' },
294
+ })
295
+
296
+ const user = await resilientUsers.getUser('42')
297
+ ```
298
+
299
+ Supported RPC options:
300
+
301
+ - `service`: remote service name
302
+ - `method`: remote method name
303
+ - `args`: positional arguments
304
+ - `timeout`: timeout per inactivity window in milliseconds
305
+ - `retry`: retry count for offline errors
306
+ - `fallback`: fallback value when the call fails
307
+ - `node_id`: force routing to a specific node
308
+ - `ip`: force routing to a specific node IP
309
+
310
+ ### Waiting and watching
311
+
312
+ ```ts
313
+ await users.wait(nodes => nodes.length >= 2)
314
+
315
+ users.watch().subscribe(nodes => {
316
+ console.log(nodes.map(node => node.node_id))
317
+ })
318
+
319
+ console.log(users.nodes)
320
+ ```
321
+
322
+ `wait()` resolves when a service availability condition is met.
323
+
324
+ `watch()` streams matching nodes whenever topology changes.
325
+
326
+ `nodes` returns the current RPC-capable node list for that service.
327
+
328
+ ### Fan-out calls across all nodes
329
+
330
+ ```ts
331
+ users.__batch__getUser('42').subscribe(result => {
332
+ console.log(result)
333
+ })
334
+ ```
335
+
336
+ Each emission is either:
337
+
338
+ - `{ node, data }`
339
+ - `{ node, error }`
340
+
341
+ ## Events
342
+
343
+ `SpiderMesh.linkEvent()` binds a topic using the event class name.
344
+
345
+ ```ts
346
+ class UserCreatedEvent {
347
+ constructor(
348
+ public readonly id: string,
349
+ public readonly email: string,
350
+ ) {}
351
+ }
352
+
353
+ const userCreated = mesh.linkEvent(UserCreatedEvent)
354
+
355
+ await userCreated.publish(new UserCreatedEvent('42', 'ada@example.com'))
356
+
357
+ userCreated.listen().subscribe(event => {
358
+ console.log(event.id)
359
+ })
360
+ ```
361
+
362
+ ## NestJS Integration
363
+
364
+ ### Register `SpiderMesh` as a provider
365
+
366
+ ```ts
367
+ import { Module } from '@nestjs/common'
368
+ import { SpiderMesh } from '@spider-mesh/core'
369
+ import { MdnsDiscoveryTransporter } from './transporters/MdnsDiscoveryTransporter.js'
370
+ import { RedisRpcTransporter } from './transporters/RedisRpcTransporter.js'
371
+ import { RedisPubsubTransporter } from './transporters/RedisPubsubTransporter.js'
372
+
373
+ @Module({
374
+ providers: [
375
+ SpiderMesh.asProvider({
376
+ transporters: [
377
+ MdnsDiscoveryTransporter,
378
+ RedisRpcTransporter,
379
+ RedisPubsubTransporter,
380
+ ],
381
+ }),
382
+ ],
383
+ exports: [SpiderMesh],
384
+ })
385
+ export class MeshModule {}
386
+ ```
387
+
388
+ ### Expose a NestJS service as a microservice
389
+
390
+ ```ts
391
+ import { Injectable, Module } from '@nestjs/common'
392
+ import { NestJSExposeMicroservice } from '@spider-mesh/core'
393
+
394
+ @Injectable()
395
+ export class BillingService {
396
+ async charge(orderId: string) {
397
+ return { orderId, status: 'ok' }
398
+ }
399
+ }
400
+
401
+ @Module({
402
+ providers: [
403
+ BillingService,
404
+ NestJSExposeMicroservice(BillingService, { boundedContext: 'billing' }),
405
+ ],
406
+ })
407
+ export class BillingModule {}
408
+ ```
409
+
410
+ ### Inject a remote service proxy in NestJS
411
+
412
+ ```ts
413
+ import { Inject, Injectable, Module } from '@nestjs/common'
414
+ import { NestJSLinkMicroservice } from '@spider-mesh/core'
415
+
416
+ class BillingService {
417
+ charge(orderId: string): Promise<{ orderId: string; status: string }> {
418
+ throw new Error('typing only')
419
+ }
420
+ }
421
+
422
+ @Injectable()
423
+ export class CheckoutService {
424
+ constructor(
425
+ @Inject(BillingService)
426
+ private readonly billing: BillingService,
427
+ ) {}
428
+
429
+ async checkout(orderId: string) {
430
+ return this.billing.charge(orderId)
431
+ }
432
+ }
433
+
434
+ @Module({
435
+ providers: [
436
+ NestJSLinkMicroservice(BillingService),
437
+ CheckoutService,
438
+ ],
439
+ })
440
+ export class CheckoutModule {}
441
+ ```
442
+
443
+ ### Inject an event binding in NestJS
444
+
445
+ ```ts
446
+ import { Inject, Injectable, Module } from '@nestjs/common'
447
+ import { NestJSLinkEvent } from '@spider-mesh/core'
448
+
449
+ class UserCreatedEvent {
450
+ constructor(public readonly id: string) {}
451
+ }
452
+
453
+ @Injectable()
454
+ export class AuditService {
455
+ constructor(
456
+ @Inject(UserCreatedEvent)
457
+ private readonly userCreated: {
458
+ publish(data: UserCreatedEvent): Promise<void>
459
+ listen(): any
460
+ },
461
+ ) {}
462
+ }
463
+
464
+ @Module({
465
+ providers: [
466
+ NestJSLinkEvent(UserCreatedEvent),
467
+ AuditService,
468
+ ],
469
+ })
470
+ export class AuditModule {}
471
+ ```
472
+
473
+ ## Transporter Contract
474
+
475
+ Concrete transport implementations can live in companion packages such as `@spider-mesh/tcp` and `@spider-mesh/ws`, or in your own application code.
476
+
477
+ You can also provide your own classes that implement one or more transporter contracts exported by `@spider-mesh/core`.
478
+
479
+ ### Public API map
480
+
481
+ - `SpiderMesh`: runtime coordinator for services, events, discovery, and transporters
482
+ - `RemoteServiceLinker.link()`: creates a typed remote proxy
483
+ - `@Microservice()`: exposes a local class instance as a remote service
484
+ - `SpiderMesh.linkEvent()`: creates a topic binding for publish and subscribe
485
+ - `RpcTransporter`: RPC transporter contract
486
+ - `DiscoveryTransporter`: discovery transporter contract
487
+ - `PubsubTransporter`: pubsub transporter contract
488
+
489
+ ### RPC transporter
490
+
491
+ ```ts
492
+ type RpcTransporter = Observable<RpcEvent> & {
493
+ send(data: RpcPacket, node: SpiderMeshNode): Promise<void>
494
+ }
495
+ ```
496
+
497
+ The RPC observable can emit:
498
+
499
+ - `rpc`: inbound RPC packet with the source node attached
500
+ - `offline`: node offline event
501
+ - `endpoints`: transporter metadata to attach to the current node
502
+
503
+ The internal RPC wire protocol supports:
504
+
505
+ - `request`
506
+ - `response`
507
+ - `cancel`
508
+
509
+ `response` packets can carry:
510
+
511
+ - `data`
512
+ - `error`
513
+ - `completed`
514
+
515
+ ### Discovery transporter
516
+
517
+ ```ts
518
+ type DiscoveryTransporter = Observable<DiscoveryEvent> & {
519
+ broadcast(
520
+ data: MdnsMessage<NodeMetadata>,
521
+ ips: string[],
522
+ ): Promise<void>
523
+ }
524
+ ```
525
+
526
+ Discovery transporters stream remote node snapshots into the mesh, and `SpiderMesh` itself calls `broadcast()` whenever local node metadata changes.
527
+
528
+ ### Pubsub transporter
529
+
530
+ ```ts
531
+ type PubsubTransporter = {
532
+ publish<T>(topic: string, data: T): Promise<void>
533
+ listen<T>(topic: string): Observable<T>
534
+ }
535
+ ```
536
+
537
+ ## Error Model
538
+
539
+ The core defines these error codes for RPC flows:
540
+
541
+ - `MICROSERVICE_OFFLINE`
542
+ - `MICROSERVICE_NOT_FOUND`
543
+ - `MICROSERVICE_RPC_TIMEOUT`
544
+
545
+ ## Environment Variables
546
+
547
+ - `SPIDERMESH_NAMESPACE`: namespace of the current node, default `default`
548
+ - `SPIDERMESH_NODE_HOSTNAME`: optional hostname attached to node metadata
549
+
550
+ ## Helpers
551
+
552
+ The package also exports:
553
+
554
+ - `LimitConcurrency(limit)` and `LimitConcurrentRunning(limit)` for throttling async method execution
555
+ - `randomUUID()` for Node.js, browser, and React Native compatible UUID generation
556
+ - `MicroserviceException` types for common RPC error codes
557
+
558
+ ## Build
559
+
560
+ ```bash
561
+ bun run build
562
+ ```
563
+
564
+ ## Notes
565
+
566
+ - Local services are registered when their class instances are constructed.
567
+ - Service identity is based on the class name.
568
+ - Event topic identity is based on the event class name.
569
+ - RPC target selection is round-robin unless you force `node_id` or `ip`.
570
+ - `SpiderMesh` owns RPC stream lifecycle, timeout, retry, and cancel behavior.
571
+ - Transporters focus on byte transport, pubsub topic IO, and discovery broadcasts.
572
+ - The root package entry intentionally focuses on runtime-agnostic APIs and shared contracts.
573
+ - If an AI agent is uncertain which import to use, prefer `@spider-mesh/core` first, then opt into a companion transport package such as `@spider-mesh/tcp` or `@spider-mesh/ws` only when a concrete transport is needed.
@@ -1,6 +1,6 @@
1
- import { RpcOptions, SpiderMeshNode } from "@spider-mesh/types";
2
1
  import { Observable } from "rxjs";
3
2
  import { ServiceChecker, SpiderMesh } from "./SpiderMesh.js";
3
+ import { RpcOptions, SpiderMeshNode } from "./types.js";
4
4
  export type IsUnknown<T, A, B> = unknown extends T ? ([T] extends [unknown] ? A : B) : B;
5
5
  export type RemoteServiceOptions = Partial<RpcOptions<any>> & {
6
6
  service: string;
@@ -1 +1 @@
1
- {"version":3,"file":"RemoteService.js","sourceRoot":"","sources":["../../src/RemoteService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RemoteService.js","sourceRoot":"","sources":["../../src/RemoteService.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { Observable } from "rxjs";
2
- import { SpiderMeshNode, RpcTransporter, PubsubTransporter, DiscoveryTransporter, RpcOptions } from '@spider-mesh/types';
2
+ import { SpiderMeshNode, RpcTransporter, PubsubTransporter, DiscoveryTransporter, RpcOptions } from './types.js';
3
3
  export type HelloEvent = SpiderMeshNode & {
4
4
  back?: boolean;
5
5
  };
@@ -11,7 +11,7 @@ export type NodesMap = {
11
11
  export type SpiderMeshOptions = {
12
12
  transporters: Array<{
13
13
  new (): RpcTransporter | PubsubTransporter | DiscoveryTransporter;
14
- }>;
14
+ } | RpcTransporter | PubsubTransporter | DiscoveryTransporter>;
15
15
  };
16
16
  export declare class SpiderMesh {
17
17
  #private;