@xyo-network/bridge-websocket 5.3.20 → 5.3.24

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xyo-network/bridge-websocket",
3
- "version": "5.3.20",
3
+ "version": "5.3.24",
4
4
  "description": "Primary SDK for using XYO Protocol 2.0",
5
5
  "homepage": "https://xyo.network",
6
6
  "bugs": {
@@ -38,46 +38,63 @@
38
38
  "types": "dist/neutral/index.d.ts",
39
39
  "files": [
40
40
  "dist",
41
- "src",
42
41
  "!**/*.bench.*",
43
42
  "!**/*.spec.*",
44
- "!**/*.test.*"
43
+ "!**/*.test.*",
44
+ "README.md"
45
45
  ],
46
46
  "dependencies": {
47
- "@xyo-network/account": "~5.3.20",
48
- "@xyo-network/boundwitness-model": "~5.3.20",
49
- "@xyo-network/bridge-abstract": "~5.3.20",
50
- "@xyo-network/bridge-model": "~5.3.20",
51
- "@xyo-network/config-payload-plugin": "~5.3.20",
52
- "@xyo-network/module-model": "~5.3.20",
53
- "@xyo-network/payload-model": "~5.3.20",
54
47
  "async-mutex": "~0.5.0",
55
- "lru-cache": "^11.2.7"
48
+ "lru-cache": "~11.2.7",
49
+ "@xyo-network/account": "~5.3.24",
50
+ "@xyo-network/bridge-abstract": "~5.3.24",
51
+ "@xyo-network/bridge-model": "~5.3.24",
52
+ "@xyo-network/config-payload-plugin": "~5.3.24",
53
+ "@xyo-network/boundwitness-model": "~5.3.24",
54
+ "@xyo-network/payload-model": "~5.3.24",
55
+ "@xyo-network/module-model": "~5.3.24"
56
56
  },
57
57
  "devDependencies": {
58
- "@xylabs/sdk-js": "^5.0.90",
59
- "@xylabs/ts-scripts-common": "~7.5.6",
60
- "@xylabs/ts-scripts-yarn3": "~7.5.6",
61
- "@xylabs/tsconfig": "~7.5.6",
62
- "@xylabs/vitest-extended": "~5.0.90",
63
- "@xyo-network/account": "~5.3.20",
64
- "@xyo-network/archivist-model": "~5.3.20",
65
- "@xyo-network/node-memory": "~5.3.20",
66
- "@xyo-network/node-model": "~5.3.20",
67
- "@xyo-network/payload-builder": "~5.3.20",
68
- "@xyo-network/payload-wrapper": "~5.3.20",
58
+ "@opentelemetry/api": "^1.9.1",
59
+ "@types/node": "^25.5.0",
60
+ "@xylabs/sdk-js": "^5.0.93",
61
+ "@xylabs/ts-scripts-common": "~7.6.16",
62
+ "@xylabs/ts-scripts-pnpm": "~7.6.16",
63
+ "@xylabs/tsconfig": "~7.6.16",
64
+ "@xylabs/vitest-extended": "~5.0.93",
65
+ "acorn": "^8.16.0",
66
+ "async-mutex": "~0.5.0",
67
+ "axios": "^1.14.0",
68
+ "esbuild": "^0.28.0",
69
+ "ethers": "^6.16.0",
70
+ "lru-cache": "~11.2.7",
69
71
  "socket.io": "~4.8.3",
70
72
  "socket.io-client": "~4.8.3",
73
+ "tslib": "^2.8.1",
71
74
  "typescript": "~5.9.3",
75
+ "vite": "^8.0.3",
72
76
  "vitest": "~4.1.2",
73
- "zod": "^4.3.6"
77
+ "zod": "^4.3.6",
78
+ "@xyo-network/boundwitness-model": "~5.3.24",
79
+ "@xyo-network/bridge-abstract": "~5.3.24",
80
+ "@xyo-network/account": "~5.3.24",
81
+ "@xyo-network/archivist-model": "~5.3.24",
82
+ "@xyo-network/bridge-model": "~5.3.24",
83
+ "@xyo-network/config-payload-plugin": "~5.3.24",
84
+ "@xyo-network/module-model": "~5.3.24",
85
+ "@xyo-network/payload-builder": "~5.3.24",
86
+ "@xyo-network/node-model": "~5.3.24",
87
+ "@xyo-network/payload-model": "~5.3.24",
88
+ "@xyo-network/payload-wrapper": "~5.3.24",
89
+ "@xyo-network/node-memory": "~5.3.24"
74
90
  },
75
91
  "peerDependencies": {
76
92
  "@xylabs/sdk-js": "^5",
93
+ "ethers": "^6",
77
94
  "socket.io": "^4",
78
95
  "tslib": "^2.8.1"
79
96
  },
80
97
  "publishConfig": {
81
98
  "access": "public"
82
99
  }
83
- }
100
+ }
package/src/Bridge.ts DELETED
@@ -1,89 +0,0 @@
1
- import { createServer as createHttpServer, Server as HttpServer } from 'node:http'
2
-
3
- import {
4
- Address, assertEx, Promisable,
5
- } from '@xylabs/sdk-js'
6
- import { BridgeExposeOptions, BridgeModule } from '@xyo-network/bridge-model'
7
- import {
8
- AnyConfigSchema, creatableModule, ModuleInstance,
9
- } from '@xyo-network/module-model'
10
- import { Payload } from '@xyo-network/payload-model'
11
- import { Server, Socket } from 'socket.io'
12
-
13
- import { WebsocketClientBridge } from './ClientBridge.ts'
14
- import { WebsocketBridgeConfig } from './Config.ts'
15
- import { WebsocketBridgeParams } from './Params.ts'
16
-
17
- export const BridgeCommands = {
18
- join: 'join',
19
- query: 'query',
20
- }
21
-
22
- const DEFAULT_HOST_PORT = 8080
23
-
24
- @creatableModule()
25
- export class WebsocketBridge<
26
- TParams extends WebsocketBridgeParams<AnyConfigSchema<WebsocketBridgeConfig>> = WebsocketBridgeParams<WebsocketBridgeConfig>,
27
- >
28
- extends WebsocketClientBridge<TParams>
29
- implements BridgeModule<TParams> {
30
- httpServer?: HttpServer
31
- server?: Server
32
-
33
- get host() {
34
- return this.config.host
35
- }
36
-
37
- override exposeHandler(_id: string, _options?: BridgeExposeOptions | undefined): Promisable<ModuleInstance[]> {
38
- throw new Error('Unsupported')
39
- }
40
-
41
- override exposedHandler(): Promisable<Address[]> {
42
- throw new Error('Unsupported')
43
- }
44
-
45
- override async startHandler() {
46
- if (this.host) {
47
- this.startServer()
48
- }
49
- await super.startHandler()
50
- }
51
-
52
- override async stopHandler() {
53
- if (this.host) {
54
- await this.stopServer()
55
- }
56
- await super.stopHandler()
57
- }
58
-
59
- private startServer() {
60
- if (this.httpServer) {
61
- throw new Error('Http Server already started')
62
- }
63
- if (this.server) {
64
- throw new Error('Socket Server already started')
65
- }
66
- const host = assertEx(this.host, () => 'No Host Configured')
67
- this.httpServer = createHttpServer() as HttpServer
68
- this.server = new Server(this.httpServer)
69
-
70
- this.server.on('connection', (socket: Socket) => {
71
- socket.on(BridgeCommands.join, async (address: Address) => {
72
- await socket.join(address)
73
- console.log(`User ${socket.id} has connected to module ${address}`)
74
- })
75
-
76
- socket.on(BridgeCommands.query, ({ address, query }: { address: Address; query: Payload[] }) => {
77
- socket.to(address).emit('message', query)
78
- })
79
- })
80
- this.httpServer.listen(host.port ?? DEFAULT_HOST_PORT)
81
- }
82
-
83
- private async stopServer() {
84
- await this.server?.close()
85
- this.server = undefined
86
- this.httpServer?.close()
87
- this.httpServer = undefined
88
- }
89
- }
@@ -1,114 +0,0 @@
1
- import {
2
- Address, assertEx, Promisable,
3
- } from '@xylabs/sdk-js'
4
- import { QueryBoundWitness } from '@xyo-network/boundwitness-model'
5
- import { AbstractBridge } from '@xyo-network/bridge-abstract'
6
- import {
7
- BridgeExposeOptions, BridgeModule, BridgeUnexposeOptions,
8
- } from '@xyo-network/bridge-model'
9
- import {
10
- creatableModule, ModuleInstance, ModuleQueryResult,
11
- } from '@xyo-network/module-model'
12
- import { Payload, Schema } from '@xyo-network/payload-model'
13
- import { Semaphore } from 'async-mutex'
14
- import { LRUCache } from 'lru-cache'
15
-
16
- import { WebsocketBridgeConfigSchema } from './Config.ts'
17
- import { WebsocketBridgeQuerySender } from './ModuleProxy/index.ts'
18
- import { WebsocketBridgeParams } from './Params.ts'
19
- import { WebsocketBridgeModuleResolver } from './WebsocketBridgeModuleResolver.ts'
20
-
21
- @creatableModule()
22
- export class WebsocketClientBridge<TParams extends WebsocketBridgeParams = WebsocketBridgeParams>
23
- extends AbstractBridge<TParams>
24
- implements BridgeModule<TParams>, WebsocketBridgeQuerySender {
25
- static override readonly configSchemas: Schema[] = [...super.configSchemas, WebsocketBridgeConfigSchema]
26
- static override readonly defaultConfigSchema: Schema = WebsocketBridgeConfigSchema
27
- protected static defaultFailureRetryTime = 1000 * 60
28
- protected static defaultMaxConnections = 4
29
- protected static defaultMaxPayloadSizeWarning = 256 * 256
30
- protected static maxFailureCacheSize = 1000
31
-
32
- private _failureTimeCache = new LRUCache<Address, number>({ max: WebsocketClientBridge.maxFailureCacheSize })
33
- private _querySemaphore?: Semaphore
34
-
35
- private _resolver?: WebsocketBridgeModuleResolver
36
-
37
- get client() {
38
- return this.config.client
39
- }
40
-
41
- get failureRetryTime() {
42
- return this.client?.failureRetryTime ?? WebsocketClientBridge.defaultFailureRetryTime
43
- }
44
-
45
- get maxConnections() {
46
- return this.client?.maxConnections ?? WebsocketClientBridge.defaultMaxConnections
47
- }
48
-
49
- get maxPayloadSizeWarning() {
50
- return this.client?.maxPayloadSizeWarning ?? WebsocketClientBridge.defaultMaxPayloadSizeWarning
51
- }
52
-
53
- get querySemaphore() {
54
- this._querySemaphore = this._querySemaphore ?? new Semaphore(this.maxConnections)
55
- return this._querySemaphore
56
- }
57
-
58
- override get resolver() {
59
- this._resolver
60
- = this._resolver
61
- ?? new WebsocketBridgeModuleResolver({
62
- archiving: { ...this.archiving, resolveArchivists: this.resolveArchivingArchivists.bind(this) },
63
- bridge: this,
64
- querySender: this,
65
- root: this,
66
- wrapperAccount: this.account,
67
- })
68
- return this._resolver
69
- }
70
-
71
- get url() {
72
- return assertEx(this.config.client?.url, () => 'No Url Set')
73
- }
74
-
75
- override exposeHandler(_id: string, _options?: BridgeExposeOptions | undefined): Promisable<ModuleInstance[]> {
76
- throw new Error('Unsupported')
77
- }
78
-
79
- override exposedHandler(): Promisable<Address[]> {
80
- throw new Error('Unsupported')
81
- }
82
-
83
- async getRoots(): Promise<ModuleInstance[]> {
84
- return await Promise.resolve([])
85
- }
86
-
87
- async sendBridgeQuery<TOut extends Payload = Payload, TQuery extends QueryBoundWitness = QueryBoundWitness, TIn extends Payload = Payload>(
88
- targetAddress: Address,
89
- _query: TQuery,
90
- _payloads?: TIn[],
91
- ): Promise<ModuleQueryResult<TOut>> {
92
- const lastFailureTime = this._failureTimeCache.get(targetAddress)
93
- if (lastFailureTime !== undefined) {
94
- const now = Date.now()
95
- const timeSincePreviousFailure = now - lastFailureTime
96
- if (timeSincePreviousFailure > this.failureRetryTime) {
97
- throw new Error(`target module failed recently [${targetAddress}] [${timeSincePreviousFailure}ms ago]`)
98
- }
99
- this._failureTimeCache.delete(targetAddress)
100
- }
101
- try {
102
- await this.querySemaphore.acquire()
103
- throw new Error('Unsupported')
104
- } catch (ex) {
105
- throw ex as Error
106
- } finally {
107
- this.querySemaphore.release()
108
- }
109
- }
110
-
111
- override unexposeHandler(_id: string, _options?: BridgeUnexposeOptions | undefined): Promisable<ModuleInstance[]> {
112
- throw new Error('Unsupported')
113
- }
114
- }
package/src/Config.ts DELETED
@@ -1,24 +0,0 @@
1
- import type { EmptyObject } from '@xylabs/sdk-js'
2
- import type { BridgeConfig } from '@xyo-network/bridge-model'
3
- import type { Schema } from '@xyo-network/payload-model'
4
- import { asSchema } from '@xyo-network/payload-model'
5
-
6
- export const WebsocketBridgeConfigSchema = asSchema('network.xyo.bridge.websocket.config', true)
7
- export type WebsocketBridgeConfigSchema = typeof WebsocketBridgeConfigSchema
8
-
9
- export type WebsocketBridgeConfig<TConfig extends EmptyObject = EmptyObject, TSchema extends string | void = void> = BridgeConfig<
10
- {
11
- schema: WebsocketBridgeConfigSchema
12
- } & TConfig,
13
- TSchema extends Schema ? TSchema : WebsocketBridgeConfigSchema,
14
- {
15
- failureRetryTime?: number
16
- failureTimeCacheMax?: number
17
- maxConnections?: number
18
- maxPayloadSizeWarning?: number
19
- url: string
20
- },
21
- {
22
- port?: number
23
- }
24
- >
@@ -1,34 +0,0 @@
1
- import type { Address } from '@xylabs/sdk-js'
2
- import type { QueryBoundWitness } from '@xyo-network/boundwitness-model'
3
- import type { ModuleProxyParams } from '@xyo-network/bridge-abstract'
4
- import { AbstractModuleProxy } from '@xyo-network/bridge-abstract'
5
- import {
6
- creatableModule, type ModuleInstance, type ModuleQueryResult,
7
- } from '@xyo-network/module-model'
8
- import type { Payload } from '@xyo-network/payload-model'
9
-
10
- export interface WebsocketBridgeQuerySender {
11
- sendBridgeQuery: <TOut extends Payload = Payload, TQuery extends QueryBoundWitness = QueryBoundWitness, TIn extends Payload = Payload>(
12
- targetAddress: Address,
13
- query: TQuery,
14
- payloads?: TIn[],
15
- ) => Promise<ModuleQueryResult<TOut>>
16
- }
17
-
18
- export type WebsocketModuleProxyParams = ModuleProxyParams & {
19
- querySender: WebsocketBridgeQuerySender
20
- }
21
-
22
- @creatableModule()
23
- export class WebsocketModuleProxy<
24
- TWrappedModule extends ModuleInstance = ModuleInstance,
25
- TParams extends Omit<WebsocketModuleProxyParams, 'config'> & { config: TWrappedModule['config'] } = Omit<WebsocketModuleProxyParams, 'config'> & {
26
- config: TWrappedModule['config']
27
- },
28
- >
29
- extends AbstractModuleProxy<TWrappedModule, TParams>
30
- implements ModuleInstance<TParams, TWrappedModule['eventData']> {
31
- async proxyQueryHandler<T extends QueryBoundWitness = QueryBoundWitness>(query: T, payloads: Payload[] = []): Promise<ModuleQueryResult> {
32
- return await this.params.querySender.sendBridgeQuery(this.params.moduleAddress, query, payloads)
33
- }
34
- }
@@ -1 +0,0 @@
1
- export * from './ModuleProxy.ts'
package/src/Params.ts DELETED
@@ -1,7 +0,0 @@
1
- import type { BridgeParams } from '@xyo-network/bridge-model'
2
- import type { AnyConfigSchema } from '@xyo-network/module-model'
3
-
4
- import type { WebsocketBridgeConfig } from './Config.ts'
5
-
6
- export type WebsocketBridgeParams<TConfig extends AnyConfigSchema<WebsocketBridgeConfig> = AnyConfigSchema<WebsocketBridgeConfig>>
7
- = BridgeParams<TConfig>
@@ -1,88 +0,0 @@
1
- import type { Address, CreatableName } from '@xylabs/sdk-js'
2
- import { assertEx, isAddress } from '@xylabs/sdk-js'
3
- import { Account } from '@xyo-network/account'
4
- import type { BridgeModuleResolverParams } from '@xyo-network/bridge-abstract'
5
- import { AbstractBridgeModuleResolver, wrapModuleWithType } from '@xyo-network/bridge-abstract'
6
- import type { ConfigPayload } from '@xyo-network/config-payload-plugin'
7
- import { ConfigSchema } from '@xyo-network/config-payload-plugin'
8
- import type {
9
- ModuleConfig,
10
- ModuleFilterOptions,
11
- ModuleIdentifier,
12
- ModuleInstance,
13
- } from '@xyo-network/module-model'
14
- import {
15
- asModuleInstance,
16
- ModuleConfigSchema,
17
- ResolveHelper,
18
- } from '@xyo-network/module-model'
19
-
20
- import type { WebsocketBridgeQuerySender, WebsocketModuleProxyParams } from './ModuleProxy/index.ts'
21
- import { WebsocketModuleProxy } from './ModuleProxy/index.ts'
22
-
23
- export interface WebsocketBridgeModuleResolverParams extends BridgeModuleResolverParams {
24
- querySender: WebsocketBridgeQuerySender
25
- }
26
-
27
- export class WebsocketBridgeModuleResolver<
28
- T extends WebsocketBridgeModuleResolverParams = WebsocketBridgeModuleResolverParams,
29
- > extends AbstractBridgeModuleResolver<T> {
30
- get querySender() {
31
- return this.params.querySender
32
- }
33
-
34
- override async resolveHandler<T extends ModuleInstance = ModuleInstance>(id: ModuleIdentifier, options?: ModuleFilterOptions<T>): Promise<T[]> {
35
- const parentResult = await super.resolveHandler(id, options)
36
- if (parentResult) {
37
- return parentResult
38
- }
39
- if (id === '*') {
40
- return []
41
- }
42
- const idParts = id.split(':')
43
- const untransformedFirstPart = assertEx(idParts.shift(), () => `Invalid module identifier: ${id}`)
44
- const firstPart = await ResolveHelper.transformModuleIdentifier(untransformedFirstPart)
45
- const moduleAddress = firstPart as Address
46
- assertEx(isAddress(firstPart), () => `Invalid module address: ${firstPart}`)
47
- const remainderParts = idParts.join(':')
48
- const params: WebsocketModuleProxyParams = {
49
- name: 'WebsocketBridgeModuleResolver' as CreatableName,
50
- account: await Account.random(),
51
- config: { schema: ModuleConfigSchema },
52
- host: this,
53
- moduleAddress,
54
- querySender: this.querySender,
55
- }
56
-
57
- this.logger?.debug(`creating HttpProxy [${moduleAddress}] ${id}`)
58
-
59
- const proxy = await WebsocketModuleProxy.create(params)
60
- // calling state here to get the config
61
- if (proxy) {
62
- const state = await proxy.state()
63
- if (state) {
64
- const configSchema = (state.find(payload => payload.schema === ConfigSchema) as ConfigPayload | undefined)?.config
65
- const config = assertEx(
66
- state.find(payload => payload.schema === configSchema),
67
- () => 'Unable to locate config',
68
- ) as ModuleConfig
69
- proxy.setConfig(config)
70
- }
71
- }
72
-
73
- await proxy.start()
74
-
75
- const wrapped = assertEx(wrapModuleWithType(proxy, await Account.random()) as unknown as T, () => `Failed to wrapModuleWithType [${id}]`)
76
- const instance = assertEx(asModuleInstance<T>(wrapped, {}), () => `Failed to asModuleInstance [${id}]`)
77
- proxy.upResolver.add(instance)
78
- proxy.downResolver.add(instance)
79
-
80
- if (remainderParts.length > 0) {
81
- const result = await wrapped.resolve<T>(remainderParts, options)
82
- return result ? [result] : []
83
- }
84
-
85
- // console.log(`resolved: ${proxy.address} [${wrapped.constructor.name}] [${as.constructor.name}]`)
86
- return [instance]
87
- }
88
- }
@@ -1,4 +0,0 @@
1
- import { WebsocketClientBridge } from './ClientBridge.ts'
2
- export * from './Config.ts'
3
-
4
- export class WebsocketBridge extends WebsocketClientBridge {}
package/src/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export * from './Bridge.ts'
2
- export * from './Config.ts'
@@ -1,31 +0,0 @@
1
- import { createServer as createHttpServer } from 'node:http'
2
-
3
- import type { Address } from '@xylabs/sdk-js'
4
- import type { Socket } from 'socket.io'
5
- import { Server } from 'socket.io'
6
-
7
- export const BridgeCommands = {
8
- bridge: 'bridge',
9
- sendMessage: 'send message',
10
- }
11
-
12
- export const createServer = (port: number) => {
13
- const httpServer = createHttpServer()
14
- const io = new Server(httpServer)
15
-
16
- io.on('connection', (socket: Socket) => {
17
- socket.on(BridgeCommands.bridge, async (address: Address) => {
18
- await socket.join(address)
19
- console.log(`User ${socket.id} has connected to module ${address}`)
20
- })
21
-
22
- socket.on(BridgeCommands.sendMessage, ({ address, query }: { address: Address; query: string }) => {
23
- socket.to(address).emit('message', query)
24
- })
25
- })
26
-
27
- return {
28
- start: () => httpServer.listen(port),
29
- stop: () => httpServer.close(),
30
- }
31
- }