@xyo-network/bridge-http 3.13.0 → 3.14.1

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.
@@ -1,41 +0,0 @@
1
- import { Server } from 'node:http';
2
- import { Address } from '@xylabs/hex';
3
- import { QueryBoundWitness } from '@xyo-network/boundwitness-model';
4
- import { BridgeExposeOptions, BridgeParams, BridgeUnexposeOptions } from '@xyo-network/bridge-model';
5
- import { AnyConfigSchema, ModuleInstance, ModuleQueryResult } from '@xyo-network/module-model';
6
- import { Payload } from '@xyo-network/payload-model';
7
- import express, { Application, Request, Response } from 'express';
8
- import { HttpBridgeBase } from './HttpBridgeBase.ts';
9
- import { HttpBridgeConfig } from './HttpBridgeConfig.ts';
10
- /**
11
- * The type of the path parameters for the address path.
12
- */
13
- type AddressPathParams = {
14
- address: Address;
15
- };
16
- /**
17
- * The type of the request body for the address path.
18
- */
19
- type PostAddressRequestBody = [QueryBoundWitness, undefined | Payload[]];
20
- export interface HttpBridgeParams extends BridgeParams<AnyConfigSchema<HttpBridgeConfig>> {
21
- }
22
- export declare class HttpBridge<TParams extends HttpBridgeParams> extends HttpBridgeBase<TParams> {
23
- protected _app?: Application;
24
- protected _exposedModules: WeakRef<ModuleInstance>[];
25
- protected _server?: Server;
26
- protected get app(): express.Application;
27
- exposeChild(mod: ModuleInstance, options?: BridgeExposeOptions | undefined): Promise<ModuleInstance[]>;
28
- exposeHandler(address: Address, options?: BridgeExposeOptions | undefined): Promise<ModuleInstance[]>;
29
- exposedHandler(): Address[];
30
- startHandler(): Promise<boolean>;
31
- stopHandler(_timeout?: number | undefined): Promise<boolean>;
32
- unexposeHandler(address: Address, options?: BridgeUnexposeOptions | undefined): Promise<ModuleInstance[]>;
33
- protected callLocalModule(address: Address, query: QueryBoundWitness, payloads: Payload[]): Promise<ModuleQueryResult | null>;
34
- protected handleGet(req: Request<AddressPathParams, ModuleQueryResult, PostAddressRequestBody>, res: Response): Promise<void>;
35
- protected handlePost(req: Request<AddressPathParams, ModuleQueryResult, PostAddressRequestBody>, res: Response): Promise<express.Response<any, Record<string, any>> | undefined>;
36
- protected initializeApp(): import(".store/@types-express-serve-static-core-npm-5.0.6-e41caf262c/package").Express;
37
- protected startHttpServer(): Promise<boolean>;
38
- protected stopHttpServer(): Promise<boolean>;
39
- }
40
- export {};
41
- //# sourceMappingURL=HttpBridgeFull.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"HttpBridgeFull.d.ts","sourceRoot":"","sources":["../../src/HttpBridgeFull.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAalC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAErC,OAAO,EAAuB,iBAAiB,EAAE,MAAM,iCAAiC,CAAA;AACxF,OAAO,EACL,mBAAmB,EAAE,YAAY,EAAE,qBAAqB,EACzD,MAAM,2BAA2B,CAAA;AAElC,OAAO,EACL,eAAe,EAAmB,cAAc,EAAE,iBAAiB,EACpE,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AACpD,OAAO,OAAO,EAAE,EACd,WAAW,EAAE,OAAO,EAAE,QAAQ,EAC/B,MAAM,SAAS,CAAA;AAGhB,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAExD;;GAEG;AACH,KAAK,iBAAiB,GAAG;IACvB,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AAED;;GAEG;AACH,KAAK,sBAAsB,GAAG,CAAC,iBAAiB,EAAE,SAAS,GAAG,OAAO,EAAE,CAAC,CAAA;AASxE,MAAM,WAAW,gBAAiB,SAAQ,YAAY,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAC;CAAG;AAE5F,qBACa,UAAU,CAAC,OAAO,SAAS,gBAAgB,CAAE,SAAQ,cAAc,CAAC,OAAO,CAAC;IACvF,SAAS,CAAC,IAAI,CAAC,EAAE,WAAW,CAAA;IAC5B,SAAS,CAAC,eAAe,EAAE,OAAO,CAAC,cAAc,CAAC,EAAE,CAAK;IACzD,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IAE1B,SAAS,KAAK,GAAG,wBAGhB;IAEK,WAAW,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,SAAS,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAgB7F,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,SAAS,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAY3G,cAAc,IAAI,OAAO,EAAE;IAIrB,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC;IAIhC,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;IAI5D,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,SAAS,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;cAkBxG,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;cAKnH,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,sBAAsB,CAAC,EAAE,GAAG,EAAE,QAAQ;cAoBnG,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,sBAAsB,CAAC,EAAE,GAAG,EAAE,QAAQ;IA4BpH,SAAS,CAAC,aAAa;IAgCvB,SAAS,CAAC,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAQ7C,SAAS,CAAC,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;CAiB7C"}
@@ -1,3 +0,0 @@
1
- export * from './HttpBridgeClientOnly.ts';
2
- export * from './HttpBridgeConfig.ts';
3
- //# sourceMappingURL=index-client.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-client.d.ts","sourceRoot":"","sources":["../../src/index-client.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAA;AACzC,cAAc,uBAAuB,CAAA"}
@@ -1,10 +0,0 @@
1
- import { BridgeParams } from '@xyo-network/bridge-model'
2
- import { AnyConfigSchema, creatableModule } from '@xyo-network/module-model'
3
-
4
- import { HttpBridgeBase } from './HttpBridgeBase.ts'
5
- import { HttpBridgeConfig } from './HttpBridgeConfig.ts'
6
-
7
- export interface HttpBridgeParams extends BridgeParams<AnyConfigSchema<HttpBridgeConfig>> {}
8
-
9
- @creatableModule()
10
- export class HttpBridge<TParams extends HttpBridgeParams> extends HttpBridgeBase<TParams> {}
@@ -1,233 +0,0 @@
1
- import { Server } from 'node:http'
2
-
3
- import { assertEx } from '@xylabs/assert'
4
- import { exists } from '@xylabs/exists'
5
- import {
6
- asyncHandler,
7
- customPoweredByHeader,
8
- disableCaseSensitiveRouting,
9
- disableExpressDefaultPoweredByHeader,
10
- jsonBodyParser,
11
- responseProfiler,
12
- useRequestCounters,
13
- } from '@xylabs/express'
14
- import { Address } from '@xylabs/hex'
15
- import { toJsonString } from '@xylabs/object'
16
- import { isQueryBoundWitness, QueryBoundWitness } from '@xyo-network/boundwitness-model'
17
- import {
18
- BridgeExposeOptions, BridgeParams, BridgeUnexposeOptions,
19
- } from '@xyo-network/bridge-model'
20
- // import { standardResponses } from '@xyo-network/express-node-middleware'
21
- import {
22
- AnyConfigSchema, creatableModule, ModuleInstance, ModuleQueryResult, resolveAddressToInstanceUp,
23
- } from '@xyo-network/module-model'
24
- import { Payload } from '@xyo-network/payload-model'
25
- import express, {
26
- Application, Request, Response,
27
- } from 'express'
28
- import { StatusCodes } from 'http-status-codes'
29
-
30
- import { HttpBridgeBase } from './HttpBridgeBase.ts'
31
- import { HttpBridgeConfig } from './HttpBridgeConfig.ts'
32
-
33
- /**
34
- * The type of the path parameters for the address path.
35
- */
36
- type AddressPathParams = {
37
- address: Address
38
- }
39
-
40
- /**
41
- * The type of the request body for the address path.
42
- */
43
- type PostAddressRequestBody = [QueryBoundWitness, undefined | Payload[]]
44
-
45
- // TODO: This does not match the error response shape of the legacy bridge BUT it its the
46
- // shape this bridge is currently returning. Massage this into the standard
47
- // error shape constructed via middleware.
48
- /* type ErrorResponseBody = {
49
- error: string
50
- } */
51
-
52
- export interface HttpBridgeParams extends BridgeParams<AnyConfigSchema<HttpBridgeConfig>> {}
53
-
54
- @creatableModule()
55
- export class HttpBridge<TParams extends HttpBridgeParams> extends HttpBridgeBase<TParams> {
56
- protected _app?: Application
57
- protected _exposedModules: WeakRef<ModuleInstance>[] = []
58
- protected _server?: Server
59
-
60
- protected get app() {
61
- if (!this._app) this._app = this.initializeApp()
62
- return assertEx(this._app, () => 'App not initialized')
63
- }
64
-
65
- async exposeChild(mod: ModuleInstance, options?: BridgeExposeOptions | undefined): Promise<ModuleInstance[]> {
66
- const { maxDepth = 5 } = options ?? {}
67
- assertEx(this.config.host, () => 'Not configured as a host')
68
- this._exposedModules.push(new WeakRef(mod))
69
- const children = maxDepth > 0 ? ((await mod.publicChildren?.()) ?? []) : []
70
- this.logger.log(`childrenToExpose [${mod.id}][${mod.address}]: ${toJsonString(children.map(child => child.id))}`)
71
- const exposedChildren = (await Promise.all(children.map(child => this.exposeChild(child, { maxDepth: maxDepth - 1, required: false }))))
72
- .flat()
73
- .filter(exists)
74
- const allExposed = [mod, ...exposedChildren]
75
-
76
- for (const exposedMod of allExposed) this.logger?.log(`exposed: ${exposedMod.address} [${mod.id}]`)
77
-
78
- return allExposed
79
- }
80
-
81
- override async exposeHandler(address: Address, options?: BridgeExposeOptions | undefined): Promise<ModuleInstance[]> {
82
- const { required = true } = options ?? {}
83
- const mod = await resolveAddressToInstanceUp(this, address)
84
- if (required && !mod) {
85
- throw new Error(`Unable to find required module: ${address}`)
86
- }
87
- if (mod) {
88
- return this.exposeChild(mod, options)
89
- }
90
- return []
91
- }
92
-
93
- override exposedHandler(): Address[] {
94
- return this._exposedModules.map(ref => ref.deref()?.address).filter(exists)
95
- }
96
-
97
- override async startHandler(): Promise<boolean> {
98
- return (await super.startHandler()) && (await this.startHttpServer())
99
- }
100
-
101
- override async stopHandler(_timeout?: number | undefined): Promise<boolean> {
102
- return (await super.stopHandler()) && (await this.stopHttpServer())
103
- }
104
-
105
- override async unexposeHandler(address: Address, options?: BridgeUnexposeOptions | undefined): Promise<ModuleInstance[]> {
106
- const { maxDepth = 2, required = true } = options ?? {}
107
- assertEx(this.config.host, () => 'Not configured as a host')
108
- const mod = this._exposedModules.find(ref => ref.deref()?.address === address)?.deref()
109
- assertEx(!required || mod, () => `Module not exposed: ${address}`)
110
- this._exposedModules = this._exposedModules.filter(ref => ref.deref()?.address !== address)
111
- if (mod) {
112
- const children = maxDepth > 0 ? ((await mod.publicChildren?.()) ?? []) : []
113
- const exposedChildren = (
114
- await Promise.all(children.map(child => this.unexposeHandler(child.address, { maxDepth: maxDepth - 1, required: false })))
115
- )
116
- .flat()
117
- .filter(exists)
118
- return [mod, ...exposedChildren]
119
- }
120
- return []
121
- }
122
-
123
- protected async callLocalModule(address: Address, query: QueryBoundWitness, payloads: Payload[]): Promise<ModuleQueryResult | null> {
124
- const mod = this._exposedModules.find(ref => ref.deref()?.address === address)?.deref()
125
- return mod ? await mod.query(query, payloads) : null
126
- }
127
-
128
- protected async handleGet(req: Request<AddressPathParams, ModuleQueryResult, PostAddressRequestBody>, res: Response) {
129
- const { address } = req.params
130
- try {
131
- if (address == this.address) {
132
- res.json(await this.stateQuery(this.account))
133
- } else {
134
- const mod = this._exposedModules.find(ref => ref.deref()?.address === address)?.deref()
135
- // TODO: Use standard errors middleware
136
- if (mod) {
137
- res.json(await mod.stateQuery(this.account))
138
- } else {
139
- res.status(StatusCodes.NOT_FOUND).json({ error: 'Module not found' })
140
- }
141
- }
142
- } catch (ex) {
143
- // TODO: Sanitize message
144
- res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({ error: (ex as Error).message })
145
- }
146
- }
147
-
148
- protected async handlePost(req: Request<AddressPathParams, ModuleQueryResult, PostAddressRequestBody>, res: Response) {
149
- const { address } = req.params
150
- const [bw, payloads = []] = Array.isArray(req.body) ? req.body : []
151
- const query = isQueryBoundWitness(bw) ? bw : undefined
152
- if (!query) {
153
- // TODO: Use standard errors middleware
154
- res.status(StatusCodes.BAD_REQUEST).json({ error: 'No query provided' })
155
- return
156
- }
157
- try {
158
- if (address == this.address) {
159
- const result = await this.query(query, payloads)
160
- return res.json(result)
161
- } else {
162
- const result = await this.callLocalModule(address, query, payloads)
163
- // TODO: Use standard errors middleware
164
- if (result === null) {
165
- res.status(StatusCodes.NOT_FOUND).json({ error: 'Module not found' })
166
- } else {
167
- res.json(result)
168
- }
169
- }
170
- } catch (ex) {
171
- // TODO: Sanitize message
172
- res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({ error: (ex as Error).message })
173
- }
174
- }
175
-
176
- protected initializeApp() {
177
- // Create the express app
178
- const app = express()
179
-
180
- // Add middleware
181
- app.use(responseProfiler)
182
- app.use(jsonBodyParser)
183
- // removed for now since this causes a cycle
184
- // app.use(standardResponses)
185
- disableExpressDefaultPoweredByHeader(app)
186
- app.use(customPoweredByHeader)
187
- disableCaseSensitiveRouting(app)
188
- useRequestCounters(app)
189
-
190
- // Add routes
191
- // Redirect all requests to the root to this module's address
192
- app.get('/', (_req, res) => res.redirect(StatusCodes.MOVED_TEMPORARILY, `/${this.address}`))
193
- app.post('/', (_req, res) => res.redirect(StatusCodes.TEMPORARY_REDIRECT, `/${this.address}`))
194
-
195
- app.get<AddressPathParams, ModuleQueryResult>(
196
- '/:address',
197
-
198
- asyncHandler(async (req, res) => await this.handleGet(req, res)),
199
- )
200
- app.post<AddressPathParams, ModuleQueryResult, PostAddressRequestBody>(
201
- '/:address',
202
-
203
- asyncHandler(async (req, res) => { await this.handlePost(req, res) }),
204
- )
205
- return app
206
- }
207
-
208
- protected startHttpServer(): Promise<boolean> {
209
- if (this.config.host) {
210
- assertEx(!this._server, () => 'Server already started')
211
- this._server = this.app.listen(this.config.host?.port ?? 3030)
212
- }
213
- return Promise.resolve(true)
214
- }
215
-
216
- protected stopHttpServer(): Promise<boolean> {
217
- if (this.config.host) {
218
- return new Promise((resolve, reject) => {
219
- if (this._server) {
220
- this._server.close((err) => {
221
- if (err) {
222
- reject(err)
223
- } else {
224
- this._server = undefined
225
- resolve(true)
226
- }
227
- })
228
- }
229
- })
230
- }
231
- return Promise.resolve(true)
232
- }
233
- }
@@ -1,2 +0,0 @@
1
- export * from './HttpBridgeClientOnly.ts'
2
- export * from './HttpBridgeConfig.ts'
@@ -1,62 +0,0 @@
1
- import '@xylabs/vitest-extended'
2
-
3
- import {
4
- beforeEach,
5
- describe, expect, it,
6
- } from 'vitest'
7
-
8
- import { HttpBridgeConfigSchema } from '../HttpBridgeConfig.ts'
9
- import type { HttpBridgeParams } from '../HttpBridgeFull.ts'
10
- import { HttpBridge } from '../HttpBridgeFull.ts'
11
-
12
- describe('HttpBridge', () => {
13
- let httpBridge: HttpBridge<HttpBridgeParams>
14
-
15
- beforeEach(async () => {
16
- httpBridge = await HttpBridge.create({
17
- account: 'random',
18
- config: {
19
- name: 'TestBridge', nodeUrl: 'http://localhost:8080', schema: HttpBridgeConfigSchema, security: { allowAnonymous: true },
20
- },
21
- })
22
- })
23
-
24
- it('should create an instance of HttpBridge', () => {
25
- expect(httpBridge).toBeInstanceOf(HttpBridge)
26
- })
27
-
28
- it('should have axios instance', () => {
29
- expect(httpBridge.axios).toBeDefined()
30
- })
31
-
32
- it('should have nodeUrl defined', () => {
33
- expect(httpBridge.clientUrl).toBe('http://localhost:8080')
34
- })
35
-
36
- it('should have resolver defined', () => {
37
- expect(httpBridge.resolver).toBeDefined()
38
- })
39
-
40
- it('should return correct moduleUrl', () => {
41
- const address = '0x1234'
42
- expect(httpBridge.moduleUrl(address).toString()).toBe('http://localhost:8080/0x1234')
43
- })
44
-
45
- it('should throw error on call to exposeHandler', async () => {
46
- try {
47
- await httpBridge.exposeHandler('test')
48
- expect('').toBe('exposeHandler should have thrown an error')
49
- } catch (error) {
50
- expect(error).toBeInstanceOf(Error)
51
- }
52
- })
53
-
54
- it('should throw error on call to unexposeHandler', async () => {
55
- try {
56
- await httpBridge.unexposeHandler('test')
57
- expect('').toBe('unexposeHandler should have thrown an error')
58
- } catch (error) {
59
- expect(error).toBeInstanceOf(Error)
60
- }
61
- })
62
- })
@@ -1,155 +0,0 @@
1
- import '@xylabs/vitest-extended'
2
-
3
- import type { ModuleDescriptionPayload } from '@xyo-network/module-model'
4
- import { ModuleDescriptionSchema } from '@xyo-network/module-model'
5
- import { MemoryNode } from '@xyo-network/node-memory'
6
- import { asAttachableNodeInstance } from '@xyo-network/node-model'
7
- import { isPayloadOfSchemaType } from '@xyo-network/payload-model'
8
- import { getPort } from 'get-port-please'
9
- import {
10
- beforeAll,
11
- beforeEach,
12
- describe, expect, it,
13
- } from 'vitest'
14
-
15
- import type { HttpBridgeConfig } from '../HttpBridgeConfig.ts'
16
- import { HttpBridgeConfigSchema } from '../HttpBridgeConfig.ts'
17
- import type { HttpBridgeParams } from '../HttpBridgeFull.ts'
18
- import { HttpBridge } from '../HttpBridgeFull.ts'
19
-
20
- const account = 'random'
21
- const schema = HttpBridgeConfigSchema
22
- const security = { allowAnonymous: true }
23
-
24
- /**
25
- * @group module
26
- * @group bridge
27
- */
28
- describe('HttpBridge', () => {
29
- let port: number
30
- let url: string
31
- let hostBridge: HttpBridge<HttpBridgeParams>
32
- let clientBridge: HttpBridge<HttpBridgeParams>
33
- let hostNode: MemoryNode
34
- let clientNode: MemoryNode
35
- let hostSibling: MemoryNode
36
- let clientSibling: MemoryNode
37
- let hostDescendent: MemoryNode
38
- let clientDescendent: MemoryNode
39
-
40
- beforeAll(async () => {
41
- // Create Host/Client Nodes
42
- hostNode = await MemoryNode.create({ account })
43
- clientNode = await MemoryNode.create({ account })
44
-
45
- // Create Host/Client Bridges
46
- port = await getPort()
47
- url = `http://localhost:${port}`
48
-
49
- const host: HttpBridgeConfig['host'] = { port }
50
- const client: HttpBridgeConfig['client'] = { discoverRoots: 'start', url }
51
- hostBridge = await HttpBridge.create({
52
- account,
53
- config: {
54
- host, name: 'TestBridgeHost', schema, security,
55
- },
56
- })
57
- clientBridge = await HttpBridge.create({
58
- account,
59
- config: {
60
- client, name: 'TestBridgeClient', schema, security,
61
- },
62
- })
63
-
64
- // Register Host/Client Bridges
65
- await hostNode.register(hostBridge)
66
- await hostNode.attach(hostBridge.address, true)
67
- await clientNode.register(clientBridge)
68
- await clientNode.attach(clientBridge.address, true)
69
-
70
- // Create Host/Client Sibling Nodes
71
- hostSibling = await MemoryNode.create({ account })
72
- clientSibling = await MemoryNode.create({ account })
73
-
74
- // Register Host/Client Siblings
75
- await hostNode.register(hostSibling)
76
- await hostNode.attach(hostSibling.address, true)
77
- await clientNode.register(clientSibling)
78
- await clientNode.attach(clientSibling.address, true)
79
-
80
- // Create Host/Client Descendent Nodes
81
- hostDescendent = await MemoryNode.create({ account })
82
- clientDescendent = await MemoryNode.create({ account })
83
-
84
- // Register Host/Client Siblings
85
- await hostSibling.register(hostDescendent)
86
- await hostSibling.attach(hostDescendent.address, true)
87
- await clientSibling.register(clientDescendent)
88
- await clientSibling.attach(clientDescendent.address, true)
89
- })
90
-
91
- describe('exposed module behavior', () => {
92
- const cases: [string, () => MemoryNode][] = [
93
- ['parent', () => hostNode],
94
- ['sibling', () => hostSibling],
95
- ['descendent', () => hostDescendent],
96
- ]
97
- describe.each(cases)('with %s module', (_, getSutModule) => {
98
- let exposedMod: MemoryNode
99
- beforeEach(() => {
100
- exposedMod = getSutModule()
101
- })
102
- describe('before expose', () => {
103
- it('should not be exposed', async () => {
104
- expect(await hostBridge.exposed()).toBeEmpty()
105
- })
106
- it('should not be resolvable', async () => {
107
- expect(await clientBridge.resolve(exposedMod.address)).toBeUndefined()
108
- })
109
- })
110
- describe('after expose', () => {
111
- beforeEach(async () => {
112
- await hostBridge.expose(exposedMod.address)
113
- })
114
- it('should be exposed on host', async () => {
115
- expect((await hostBridge.exposed()).includes(exposedMod.address)).toBeTrue()
116
- })
117
- it.skip('should be resolvable from client', async () => {
118
- // TODO: Implement .connect on HttpBridge and call here before resolving
119
- const result = await clientBridge.resolve(exposedMod.address)
120
- expect(result).toBeDefined()
121
- expect(asAttachableNodeInstance(result, () => `Failed to resolve correct object type [${result?.constructor.name}]`)).toBeDefined()
122
- })
123
- it.skip('should be queryable from client', async () => {
124
- const bridgedHostedModule = await clientBridge.resolve(exposedMod.address)
125
- expect(bridgedHostedModule).toBeDefined()
126
-
127
- const bridgedHostedNode = asAttachableNodeInstance(
128
- bridgedHostedModule,
129
- () => `Failed to resolve correct object type [${bridgedHostedModule?.constructor.name}]`,
130
- )
131
-
132
- if (bridgedHostedNode) {
133
- const state = await bridgedHostedNode.state()
134
- const description = state.find(isPayloadOfSchemaType<ModuleDescriptionPayload>(ModuleDescriptionSchema))
135
- expect(description?.children).toBeArray()
136
- expect(description?.queries).toBeArray()
137
- expect(description?.queries?.length).toBeGreaterThan(0)
138
- }
139
- })
140
- })
141
- describe('after unexpose', () => {
142
- beforeEach(async () => {
143
- await hostBridge.expose(exposedMod.address)
144
- await hostBridge.unexpose(exposedMod.address)
145
- })
146
- it('should not be exposed', async () => {
147
- expect(await hostBridge.exposed()).toBeEmpty()
148
- })
149
- it('should not be resolvable', async () => {
150
- expect(await clientBridge.resolve(exposedMod.address)).toBeUndefined()
151
- })
152
- })
153
- })
154
- })
155
- })