@xyo-network/module-wrapper 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/module-wrapper",
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": {
@@ -30,35 +30,51 @@
30
30
  "types": "dist/neutral/index.d.ts",
31
31
  "files": [
32
32
  "dist",
33
- "src",
34
33
  "!**/*.bench.*",
35
34
  "!**/*.spec.*",
36
- "!**/*.test.*"
35
+ "!**/*.test.*",
36
+ "README.md"
37
37
  ],
38
38
  "dependencies": {
39
- "@xyo-network/account-model": "~5.3.20",
40
- "@xyo-network/boundwitness-builder": "~5.3.20",
41
- "@xyo-network/boundwitness-model": "~5.3.20",
42
- "@xyo-network/boundwitness-wrapper": "~5.3.20",
43
- "@xyo-network/manifest-model": "~5.3.20",
44
- "@xyo-network/module-model": "~5.3.20",
45
- "@xyo-network/payload-model": "~5.3.20",
46
- "lru-cache": "^11.2.7"
39
+ "lru-cache": "~11.2.7",
40
+ "@xyo-network/boundwitness-builder": "~5.3.24",
41
+ "@xyo-network/account-model": "~5.3.24",
42
+ "@xyo-network/boundwitness-model": "~5.3.24",
43
+ "@xyo-network/boundwitness-wrapper": "~5.3.24",
44
+ "@xyo-network/module-model": "~5.3.24",
45
+ "@xyo-network/manifest-model": "~5.3.24",
46
+ "@xyo-network/payload-model": "~5.3.24"
47
47
  },
48
48
  "devDependencies": {
49
- "@xylabs/sdk-js": "^5.0.90",
50
- "@xylabs/ts-scripts-common": "~7.5.6",
51
- "@xylabs/ts-scripts-yarn3": "~7.5.6",
52
- "@xylabs/tsconfig": "~7.5.6",
49
+ "@opentelemetry/api": "^1.9.1",
50
+ "@types/node": "^25.5.0",
51
+ "@xylabs/sdk-js": "^5.0.93",
52
+ "@xylabs/ts-scripts-common": "~7.6.16",
53
+ "@xylabs/ts-scripts-pnpm": "~7.6.16",
54
+ "@xylabs/tsconfig": "~7.6.16",
55
+ "acorn": "^8.16.0",
56
+ "axios": "^1.14.0",
57
+ "esbuild": "^0.28.0",
58
+ "ethers": "^6.16.0",
59
+ "lru-cache": "^11.2.7",
60
+ "tslib": "^2.8.1",
53
61
  "typescript": "~5.9.3",
54
- "zod": "^4.3.6"
62
+ "zod": "^4.3.6",
63
+ "@xyo-network/account-model": "~5.3.24",
64
+ "@xyo-network/boundwitness-builder": "~5.3.24",
65
+ "@xyo-network/boundwitness-model": "~5.3.24",
66
+ "@xyo-network/boundwitness-wrapper": "~5.3.24",
67
+ "@xyo-network/manifest-model": "~5.3.24",
68
+ "@xyo-network/module-model": "~5.3.24",
69
+ "@xyo-network/payload-model": "~5.3.24"
55
70
  },
56
71
  "peerDependencies": {
57
72
  "@xylabs/sdk-js": "^5",
73
+ "ethers": "^6",
58
74
  "tslib": "^2.8.1",
59
75
  "zod": "^4"
60
76
  },
61
77
  "publishConfig": {
62
78
  "access": "public"
63
79
  }
64
- }
80
+ }
@@ -1,482 +0,0 @@
1
- import {
2
- Address, assertEx,
3
- Base,
4
- CreatableName, EventAnyListener, EventListener,
5
- exists,
6
- isDefined, Logger,
7
- Promisable, PromiseEx,
8
- } from '@xylabs/sdk-js'
9
- import { AccountInstance } from '@xyo-network/account-model'
10
- import { QueryBoundWitnessBuilder } from '@xyo-network/boundwitness-builder'
11
- import { QueryBoundWitness } from '@xyo-network/boundwitness-model'
12
- import { BoundWitnessWrapper } from '@xyo-network/boundwitness-wrapper'
13
- import { ModuleManifestPayload } from '@xyo-network/manifest-model'
14
- import {
15
- AddressPreviousHashPayload,
16
- AddressPreviousHashSchema,
17
- asAttachableModuleInstance,
18
- asModuleInstance,
19
- AttachableModuleInstance,
20
- duplicateModules,
21
- InstanceTypeCheck,
22
- isModuleInstance,
23
- isQueryableModule,
24
- ModuleAddressQuery,
25
- ModuleAddressQuerySchema,
26
- ModuleFilterOptions,
27
- ModuleIdentifier,
28
- ModuleInstance,
29
- ModuleManifestQuery,
30
- ModuleManifestQuerySchema,
31
- ModuleQueryResult,
32
- ModuleResolverInstance,
33
- ModuleStateQuery,
34
- ModuleStateQuerySchema,
35
- ModuleStatus,
36
- ObjectResolverPriority,
37
- QueryableModule,
38
- QueryableModuleTypeCheck,
39
- } from '@xyo-network/module-model'
40
- import {
41
- ModuleError, ModuleErrorSchema, Payload, Query,
42
- } from '@xyo-network/payload-model'
43
- import { LRUCache } from 'lru-cache'
44
-
45
- import type { ModuleWrapperParams } from './models.ts'
46
-
47
- export type ConstructableModuleWrapper<TWrapper extends ModuleWrapper> = {
48
- defaultLogger?: Logger
49
- instanceIdentityCheck: InstanceTypeCheck
50
- moduleIdentityCheck: QueryableModuleTypeCheck
51
- requiredQueries: string[]
52
- new (params: ModuleWrapperParams<TWrapper['mod']>): TWrapper
53
-
54
- canWrap(mod: QueryableModule | undefined): boolean
55
-
56
- is<TModuleWrapper extends ModuleWrapper>(
57
- this: ConstructableModuleWrapper<TModuleWrapper>,
58
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
59
- wrapper?: any,
60
- ): wrapper is TModuleWrapper
61
-
62
- tryWrap<TModuleWrapper extends ModuleWrapper>(
63
- this: ConstructableModuleWrapper<TModuleWrapper>,
64
- mod: QueryableModule | undefined,
65
- account: AccountInstance,
66
- checkIdentity?: boolean,
67
- ): TModuleWrapper | undefined
68
-
69
- wrap<TModuleWrapper extends ModuleWrapper>(
70
- this: ConstructableModuleWrapper<TModuleWrapper>,
71
- mod: QueryableModule | undefined,
72
- account: AccountInstance,
73
- checkIdentity?: boolean,
74
- ): TModuleWrapper
75
- }
76
-
77
- export function constructableModuleWrapper<TWrapper extends ModuleWrapper>() {
78
- return <U extends ConstructableModuleWrapper<TWrapper>>(constructor: U) => {
79
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
80
- constructor
81
- }
82
- }
83
-
84
- @constructableModuleWrapper()
85
- export class ModuleWrapper<TWrappedModule extends QueryableModule = QueryableModule>
86
- extends Base<Exclude<Omit<TWrappedModule['params'], 'config'> & { config: Exclude<TWrappedModule['params']['config'], undefined> }, undefined>>
87
- implements AttachableModuleInstance<TWrappedModule['params'], TWrappedModule['eventData']> {
88
- static readonly instanceIdentityCheck: InstanceTypeCheck = isModuleInstance
89
- static readonly moduleIdentityCheck: QueryableModuleTypeCheck = isQueryableModule
90
- static readonly requiredQueries: string[] = [ModuleStateQuerySchema]
91
-
92
- eventData = {} as TWrappedModule['eventData']
93
-
94
- protected readonly cachedCalls = new LRUCache<string, Payload[]>({
95
- max: 1000, ttl: 1000 * 60, ttlAutopurge: true,
96
- })
97
-
98
- protected readonly wrapperParams: ModuleWrapperParams<TWrappedModule>
99
-
100
- private _parents: ModuleInstance[] = []
101
- private _status: ModuleStatus = 'wrapped'
102
-
103
- constructor(params: ModuleWrapperParams<TWrappedModule>) {
104
- const mutatedWrapperParams = { ...params } as ModuleWrapperParams<TWrappedModule>
105
- const mutatedParams = { ...params.mod.params, config: { ...params.mod.params.config } } as Exclude<
106
- Omit<TWrappedModule['params'], 'config'> & { config: Exclude<TWrappedModule['params']['config'], undefined> },
107
- undefined
108
- >
109
-
110
- // set the root params to the wrapped mod params
111
- super(mutatedParams)
112
-
113
- this.wrapperParams = mutatedWrapperParams
114
- }
115
-
116
- get account() {
117
- return this.wrapperParams.account
118
- }
119
-
120
- get additionalSigners() {
121
- return this.wrapperParams.additionalSigners ?? []
122
- }
123
-
124
- get address() {
125
- return this.mod.address
126
- }
127
-
128
- get config() {
129
- return this.mod.config as Exclude<TWrappedModule['params']['config'], undefined>
130
- }
131
-
132
- get downResolver(): ModuleResolverInstance {
133
- // Should we be allowing this?
134
- const instance: AttachableModuleInstance | undefined = asAttachableModuleInstance(this.mod)
135
- if (instance) {
136
- return instance.downResolver as ModuleResolverInstance
137
- }
138
- throw new Error('Unsupported')
139
- }
140
-
141
- get id() {
142
- return this.mod.id
143
- }
144
-
145
- get mod() {
146
- return this.wrapperParams.mod
147
- }
148
-
149
- get modName() {
150
- return this.mod.modName
151
- }
152
-
153
- get name() {
154
- return 'ModuleWrapper' as CreatableName
155
- }
156
-
157
- get priority() {
158
- return ObjectResolverPriority.Low
159
- }
160
-
161
- get privateResolver(): ModuleResolverInstance {
162
- // Should we be allowing this?
163
- const instance = asAttachableModuleInstance(this.mod)
164
- if (instance) {
165
- return instance.privateResolver as ModuleResolverInstance
166
- }
167
- throw new Error('Unsupported')
168
- }
169
-
170
- get queries(): string[] {
171
- return this.mod.queries
172
- }
173
-
174
- get status() {
175
- return this._status
176
- }
177
-
178
- get upResolver(): ModuleResolverInstance {
179
- // Should we be allowing this?
180
- const instance = asAttachableModuleInstance(this.mod)
181
- if (instance) {
182
- return instance.upResolver as ModuleResolverInstance
183
- }
184
- throw new Error('Unsupported')
185
- }
186
-
187
- protected set status(value: ModuleStatus) {
188
- this._status = value
189
- }
190
-
191
- static canWrap(mod?: QueryableModule) {
192
- return !!mod && this.moduleIdentityCheck(mod)
193
- }
194
-
195
- static hasRequiredQueries(mod: QueryableModule) {
196
- return this.missingRequiredQueries(mod).length === 0
197
- }
198
-
199
- static is<TModuleWrapper extends ModuleWrapper>(
200
- this: ConstructableModuleWrapper<TModuleWrapper>,
201
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
202
- wrapper: any,
203
- ): wrapper is TModuleWrapper {
204
- return wrapper instanceof this
205
- }
206
-
207
- static missingRequiredQueries(mod: QueryableModule): string[] {
208
- const modQueries = mod.queries
209
- return (
210
- this.requiredQueries.map((query) => {
211
- return modQueries.includes(query) ? null : query
212
- })
213
- ).filter(exists)
214
- }
215
-
216
- static tryWrap<TModuleWrapper extends ModuleWrapper>(
217
- this: ConstructableModuleWrapper<TModuleWrapper>,
218
- mod: QueryableModule | undefined,
219
- account: AccountInstance,
220
- checkIdentity = true,
221
- ): TModuleWrapper | undefined {
222
- if (!checkIdentity || this.canWrap(mod)) {
223
- return new this({ account, mod: mod as TModuleWrapper['mod'] })
224
- }
225
- }
226
-
227
- static with<TModuleWrapper extends ModuleWrapper, R extends Promisable<void> = void>(
228
- this: ConstructableModuleWrapper<TModuleWrapper>,
229
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
230
- mod: any,
231
-
232
- closure: (mod: TModuleWrapper) => R,
233
- ): R | undefined {
234
- return this.is(mod) ? closure(mod) : undefined
235
- }
236
-
237
- static wrap<TModuleWrapper extends ModuleWrapper>(
238
- this: ConstructableModuleWrapper<TModuleWrapper>,
239
- mod: QueryableModule | undefined,
240
- account: AccountInstance,
241
- checkIdentity = true,
242
- ): TModuleWrapper {
243
- assertEx(!checkIdentity || (mod && this.moduleIdentityCheck(mod)), () => `Passed mod failed identity check: ${mod?.config?.schema}`)
244
- return assertEx(this.tryWrap(mod, account, checkIdentity), () => 'Unable to wrap mod as ModuleWrapper')
245
- }
246
-
247
- addParent(mod: ModuleInstance) {
248
- const existingEntry = this._parents.find(parent => parent.address === mod.address)
249
- if (!existingEntry) {
250
- this._parents.push(mod)
251
- }
252
- }
253
-
254
- async addressPreviousHash(): Promise<AddressPreviousHashPayload> {
255
- const queryPayload: ModuleAddressQuery = { schema: ModuleAddressQuerySchema }
256
- return assertEx(
257
- (await this.sendQuery(queryPayload)).find(payload => payload.schema === AddressPreviousHashSchema) as AddressPreviousHashPayload,
258
- () => 'Result did not include correct payload',
259
- )
260
- }
261
-
262
- clearListeners(eventNames: Parameters<TWrappedModule['clearListeners']>[0]) {
263
- return this.mod.clearListeners(eventNames)
264
- }
265
-
266
- emit(eventName: Parameters<TWrappedModule['emit']>[0], eventArgs: Parameters<TWrappedModule['emit']>[1]) {
267
- return this.mod.emit(eventName, eventArgs)
268
- }
269
-
270
- emitSerial(eventName: Parameters<TWrappedModule['emitSerial']>[0], eventArgs: Parameters<TWrappedModule['emitSerial']>[1]) {
271
- return this.mod.emitSerial(eventName, eventArgs)
272
- }
273
-
274
- listenerCount(eventNames: Parameters<TWrappedModule['listenerCount']>[0]) {
275
- return this.mod.listenerCount(eventNames)
276
- }
277
-
278
- async manifest(maxDepth?: number): Promise<ModuleManifestPayload> {
279
- const queryPayload: ModuleManifestQuery = { schema: ModuleManifestQuerySchema, ...(maxDepth === undefined ? {} : { maxDepth }) }
280
- return (await this.sendQuery(queryPayload))[0] as ModuleManifestPayload
281
- }
282
-
283
- async manifestQuery(account: AccountInstance, maxDepth?: number): Promise<ModuleQueryResult<ModuleManifestPayload>> {
284
- const queryPayload: ModuleManifestQuery = { schema: ModuleManifestQuerySchema, ...(maxDepth === undefined ? {} : { maxDepth }) }
285
- return await this.sendQueryRaw(queryPayload, undefined, account)
286
- }
287
-
288
- async moduleAddress(): Promise<AddressPreviousHashPayload[]> {
289
- const queryPayload: ModuleAddressQuery = { schema: ModuleAddressQuerySchema }
290
- return (await this.sendQuery(queryPayload)) as AddressPreviousHashPayload[]
291
- }
292
-
293
- off<TEventName extends keyof TWrappedModule['eventData']>(
294
- eventNames: TEventName,
295
- listener: EventListener<TWrappedModule['eventData'][TEventName]>,
296
- ) {
297
- return this.mod.off(eventNames, listener)
298
- }
299
-
300
- offAny(listener: EventAnyListener) {
301
- return this.mod.offAny(listener)
302
- }
303
-
304
- on<TEventName extends keyof TWrappedModule['eventData']>(eventNames: TEventName, listener: EventListener<TWrappedModule['eventData'][TEventName]>) {
305
- return this.mod.on(eventNames, listener)
306
- }
307
-
308
- onAny(listener: EventAnyListener) {
309
- return this.mod.onAny(listener)
310
- }
311
-
312
- once<TEventName extends keyof TWrappedModule['eventData']>(
313
- eventName: TEventName,
314
- listener: EventListener<TWrappedModule['eventData'][TEventName]>,
315
- ) {
316
- return this.mod.once(eventName, listener)
317
- }
318
-
319
- parents(): Promisable<ModuleInstance[]> {
320
- return this._parents
321
- }
322
-
323
- async previousHash(): Promise<string | undefined> {
324
- const queryPayload: ModuleAddressQuery = { schema: ModuleAddressQuerySchema }
325
- return ((await this.sendQuery(queryPayload)).pop() as AddressPreviousHashPayload).previousHash
326
- }
327
-
328
- async previousHashQuery(account?: AccountInstance): Promise<ModuleQueryResult<AddressPreviousHashPayload>> {
329
- const queryPayload: ModuleAddressQuery = { schema: ModuleAddressQuerySchema }
330
- return await this.sendQueryRaw(queryPayload, undefined, account)
331
- }
332
-
333
- async privateChildren(): Promise<ModuleInstance[]> {
334
- if (isModuleInstance(this.mod)) {
335
- return await this.mod.privateChildren()
336
- }
337
- return []
338
- }
339
-
340
- async publicChildren(): Promise<ModuleInstance[]> {
341
- if (isModuleInstance(this.mod)) {
342
- return await this.mod.publicChildren()
343
- }
344
- return []
345
- }
346
-
347
- async query<T extends QueryBoundWitness = QueryBoundWitness>(query: T, payloads?: Payload[]): Promise<ModuleQueryResult> {
348
- return await this.mod.query(query, payloads)
349
- }
350
-
351
- queryable<T extends QueryBoundWitness = QueryBoundWitness>(query: T, payloads?: Payload[]) {
352
- return this.mod.queryable(query, payloads)
353
- }
354
-
355
- removeParent(address: Address) {
356
- this._parents = this._parents.filter(item => item.address !== address)
357
- }
358
-
359
- /** @deprecated do not pass undefined. If trying to get all, pass '*' */
360
- async resolve<T extends ModuleInstance = ModuleInstance>(): Promise<T[]>
361
- async resolve<T extends ModuleInstance = ModuleInstance>(all: '*', options?: ModuleFilterOptions<T>): Promise<T[]>
362
- async resolve<T extends ModuleInstance = ModuleInstance>(
363
- id: ModuleIdentifier,
364
- options?: ModuleFilterOptions<T> | undefined,
365
- ): Promise<ModuleInstance>
366
- async resolve<T extends ModuleInstance = ModuleInstance>(
367
- id: ModuleIdentifier = '*',
368
- options?: ModuleFilterOptions<T>,
369
- ): Promise<T | T[] | undefined> {
370
- const instance = asModuleInstance(this.mod)
371
- if (instance?.['resolve']) {
372
- if (id === '*') {
373
- return await instance.resolve<T>('*', options)
374
- }
375
- switch (typeof id) {
376
- case 'string': {
377
- return await instance.resolve<T>(id, options)
378
- }
379
- default: {
380
- return
381
- }
382
- }
383
- }
384
- return typeof id === 'string' && id !== '*' ? undefined : []
385
- }
386
-
387
- async resolvePrivate<T extends ModuleInstance = ModuleInstance>(all: '*', options?: ModuleFilterOptions<T>): Promise<T[]>
388
- async resolvePrivate<T extends ModuleInstance = ModuleInstance>(id: ModuleIdentifier, options?: ModuleFilterOptions<T>): Promise<T | undefined>
389
- async resolvePrivate<T extends ModuleInstance = ModuleInstance>(
390
- id: ModuleIdentifier,
391
- _options?: ModuleFilterOptions<T>,
392
- ): Promise<T | T[] | undefined> {
393
- if (id === '*') return await Promise.resolve([])
394
- }
395
-
396
- async siblings(): Promise<ModuleInstance[]> {
397
- return (await Promise.all((await this.parents()).map(parent => parent.publicChildren()))).flat().filter(duplicateModules)
398
- }
399
-
400
- start(): Promise<boolean> {
401
- throw new Error('Cannot start a wrapped module')
402
- }
403
-
404
- async state(): Promise<Payload[]> {
405
- const cachedResult = this.cachedCalls.get('state')
406
- if (cachedResult) {
407
- return cachedResult
408
- }
409
- const queryPayload: ModuleStateQuery = { schema: ModuleStateQuerySchema }
410
- const result = await this.sendQuery(queryPayload)
411
- this.cachedCalls.set('state', result)
412
- return result
413
- }
414
-
415
- async stateQuery(_account: AccountInstance): Promise<ModuleQueryResult> {
416
- const queryPayload: ModuleStateQuery = { schema: ModuleStateQuerySchema }
417
- return await this.sendQueryRaw(queryPayload)
418
- }
419
-
420
- stop(): Promise<boolean> {
421
- throw new Error('Cannot stop a wrapped module')
422
- }
423
-
424
- protected bindQuery<T extends Query>(
425
- query: T,
426
- payloads?: Payload[],
427
- account = this.account,
428
- additionalSigners = this.additionalSigners,
429
- ): PromiseEx<[QueryBoundWitness, Payload[], ModuleError[]], AccountInstance> {
430
- // eslint-disable-next-line @typescript-eslint/no-misused-promises
431
- return new PromiseEx<[QueryBoundWitness, Payload[], ModuleError[]], AccountInstance>(async (resolve) => {
432
- const result = await this.bindQueryInternal(query, payloads, account, additionalSigners)
433
- resolve?.(result)
434
- return result
435
- }, account)
436
- }
437
-
438
- protected async bindQueryInternal<T extends Query>(
439
- query: T,
440
- payloads?: Payload[],
441
- account = this.account,
442
- additionalSigners = this.additionalSigners,
443
- ): Promise<[QueryBoundWitness, Payload[], ModuleError[]]> {
444
- const builder = new QueryBoundWitnessBuilder().payloads(payloads).query(query)
445
- const accounts = [account, ...additionalSigners].filter(exists)
446
- return await (accounts.length > 0 ? builder.signers(accounts) : builder).build()
447
- }
448
-
449
- protected filterErrors([bw, payloads]: ModuleQueryResult): ModuleError[] {
450
- const wrapper = BoundWitnessWrapper.wrap(bw, payloads)
451
- return wrapper.payloadsBySchema<ModuleError>(ModuleErrorSchema)
452
- }
453
-
454
- protected async sendQuery<T extends Query, P extends Payload = Payload, R extends Payload = Payload>(
455
- queryPayload: T,
456
- payloads?: P[],
457
- ): Promise<R[]> {
458
- const queryResults = await this.sendQueryRaw(queryPayload, payloads)
459
- const [, resultPayloads, errors] = queryResults
460
-
461
- /* TODO: Figure out what to do with the returning BW. Should we store them in a queue in case the caller wants to see them? */
462
-
463
- if (isDefined(errors) && errors.length > 0) {
464
- /* TODO: Figure out how to rollup multiple Errors */
465
- throw errors[0]
466
- }
467
-
468
- return resultPayloads as R[]
469
- }
470
-
471
- protected async sendQueryRaw<T extends Query, P extends Payload = Payload, R extends Payload = Payload>(
472
- queryPayload: T,
473
- payloads?: P[],
474
- account?: AccountInstance,
475
- ): Promise<ModuleQueryResult<R>> {
476
- // Bind them
477
- const query = await this.bindQuery(queryPayload, payloads, account)
478
-
479
- // Send them off
480
- return (await this.query(query[0], query[1])) as ModuleQueryResult<R>
481
- }
482
- }
package/src/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export * from './models.ts'
2
- export * from './ModuleWrapper.ts'
package/src/models.ts DELETED
@@ -1,9 +0,0 @@
1
- import type { BaseParams } from '@xylabs/sdk-js'
2
- import type { AccountInstance } from '@xyo-network/account-model'
3
- import type { QueryableModule } from '@xyo-network/module-model'
4
-
5
- export type ModuleWrapperParams<TWrappedModule extends QueryableModule = QueryableModule> = BaseParams<{
6
- account: AccountInstance
7
- additionalSigners?: AccountInstance[]
8
- mod: TWrappedModule
9
- }>