@xyo-network/module-abstract 2.64.7 → 2.64.9

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 (43) hide show
  1. package/dist/cjs/AbstractIndirectModule.js +411 -0
  2. package/dist/cjs/AbstractIndirectModule.js.map +1 -0
  3. package/dist/cjs/AbstractModule.js +25 -340
  4. package/dist/cjs/AbstractModule.js.map +1 -1
  5. package/dist/cjs/QueryValidator/SupportedQueryValidator.js.map +1 -1
  6. package/dist/cjs/Resolver/CompositeModuleResolver.js +2 -3
  7. package/dist/cjs/Resolver/CompositeModuleResolver.js.map +1 -1
  8. package/dist/cjs/Resolver/ResolverEventEmitter.js.map +1 -1
  9. package/dist/cjs/Resolver/SimpleModuleResolver.js.map +1 -1
  10. package/dist/cjs/lib/duplicateModules.js.map +1 -1
  11. package/dist/docs.json +4495 -3879
  12. package/dist/esm/AbstractIndirectModule.js +373 -0
  13. package/dist/esm/AbstractIndirectModule.js.map +1 -0
  14. package/dist/esm/AbstractModule.js +17 -322
  15. package/dist/esm/AbstractModule.js.map +1 -1
  16. package/dist/esm/QueryValidator/SupportedQueryValidator.js.map +1 -1
  17. package/dist/esm/Resolver/CompositeModuleResolver.js +2 -3
  18. package/dist/esm/Resolver/CompositeModuleResolver.js.map +1 -1
  19. package/dist/esm/Resolver/ResolverEventEmitter.js.map +1 -1
  20. package/dist/esm/Resolver/SimpleModuleResolver.js.map +1 -1
  21. package/dist/esm/lib/duplicateModules.js.map +1 -1
  22. package/dist/types/AbstractIndirectModule.d.ts +66 -0
  23. package/dist/types/AbstractIndirectModule.d.ts.map +1 -0
  24. package/dist/types/AbstractModule.d.ts +7 -55
  25. package/dist/types/AbstractModule.d.ts.map +1 -1
  26. package/dist/types/QueryValidator/SupportedQueryValidator.d.ts +4 -4
  27. package/dist/types/QueryValidator/SupportedQueryValidator.d.ts.map +1 -1
  28. package/dist/types/Resolver/CompositeModuleResolver.d.ts +5 -5
  29. package/dist/types/Resolver/CompositeModuleResolver.d.ts.map +1 -1
  30. package/dist/types/Resolver/ResolverEventEmitter.d.ts +2 -2
  31. package/dist/types/Resolver/ResolverEventEmitter.d.ts.map +1 -1
  32. package/dist/types/Resolver/SimpleModuleResolver.d.ts +5 -5
  33. package/dist/types/Resolver/SimpleModuleResolver.d.ts.map +1 -1
  34. package/dist/types/lib/duplicateModules.d.ts +2 -2
  35. package/dist/types/lib/duplicateModules.d.ts.map +1 -1
  36. package/package.json +24 -24
  37. package/src/AbstractIndirectModule.ts +497 -0
  38. package/src/AbstractModule.ts +20 -421
  39. package/src/QueryValidator/SupportedQueryValidator.ts +3 -3
  40. package/src/Resolver/CompositeModuleResolver.ts +9 -10
  41. package/src/Resolver/ResolverEventEmitter.ts +5 -5
  42. package/src/Resolver/SimpleModuleResolver.ts +11 -11
  43. package/src/lib/duplicateModules.ts +2 -2
@@ -1,445 +1,44 @@
1
1
  import { assertEx } from '@xylabs/assert'
2
- import { exists } from '@xylabs/exists'
3
- import { HDWallet } from '@xyo-network/account'
4
2
  import { AccountInstance } from '@xyo-network/account-model'
5
- import { AddressPayload, AddressSchema } from '@xyo-network/address-payload-plugin'
6
- import { ArchivistModule } from '@xyo-network/archivist-model'
7
- import { BoundWitnessBuilder } from '@xyo-network/boundwitness-builder'
8
- import { BoundWitness } from '@xyo-network/boundwitness-model'
9
- import { ConfigPayload, ConfigSchema } from '@xyo-network/config-payload-plugin'
10
- import { handleErrorAsync } from '@xyo-network/error'
11
- import { ModuleManifestPayload, ModuleManifestPayloadSchema } from '@xyo-network/manifest-model'
12
- import {
13
- AccountModuleParams,
14
- AddressPreviousHashPayload,
15
- AddressPreviousHashSchema,
16
- CreatableModule,
17
- CreatableModuleFactory,
18
- IndividualArchivistConfig,
19
- Module,
20
- ModuleAddressQuerySchema,
21
- ModuleConfig,
22
- ModuleDiscoverQuerySchema,
23
- ModuleError,
24
- ModuleEventData,
25
- ModuleFilter,
26
- ModuleParams,
27
- ModuleQueriedEventArgs,
28
- ModuleQuery,
29
- ModuleQueryBase,
30
- ModuleQueryResult,
31
- ModuleSubscribeQuerySchema,
32
- Query,
33
- QueryBoundWitness,
34
- SchemaString,
35
- WalletModuleParams,
36
- } from '@xyo-network/module-model'
37
- import { PayloadBuilder } from '@xyo-network/payload-builder'
3
+ import { ModuleManifestPayload } from '@xyo-network/manifest-model'
4
+ import { AddressPreviousHashPayload, Module, ModuleDescriptionPayload, ModuleEventData, ModuleParams } from '@xyo-network/module-model'
38
5
  import { Payload } from '@xyo-network/payload-model'
39
- import { PayloadWrapper } from '@xyo-network/payload-wrapper'
40
- import { Promisable, PromiseEx } from '@xyo-network/promise'
41
- import { QueryPayload, QuerySchema } from '@xyo-network/query-payload-plugin'
42
- import { IdLogger } from '@xyo-network/shared'
43
- import compact from 'lodash/compact'
44
6
 
45
- import { BaseEmitter } from './BaseEmitter'
46
- import { ModuleErrorBuilder } from './Error'
47
- import { duplicateModules, serializableField } from './lib'
48
- import { ModuleFactory } from './ModuleFactory'
49
- import { QueryBoundWitnessBuilder, QueryBoundWitnessWrapper } from './Query'
50
- import { ModuleConfigQueryValidator, Queryable, SupportedQueryValidator } from './QueryValidator'
51
- import { CompositeModuleResolver } from './Resolver'
7
+ import { AbstractIndirectModule } from './AbstractIndirectModule'
52
8
 
53
9
  export abstract class AbstractModule<TParams extends ModuleParams = ModuleParams, TEventData extends ModuleEventData = ModuleEventData>
54
- extends BaseEmitter<TParams, TEventData>
10
+ extends AbstractIndirectModule<TParams, TEventData>
55
11
  implements Module<TParams, TEventData>
56
12
  {
57
- static configSchemas: string[]
58
-
59
- protected static privateConstructorKey = Date.now().toString()
60
-
61
- readonly downResolver = new CompositeModuleResolver()
62
- readonly upResolver = new CompositeModuleResolver()
63
-
64
- protected _account: AccountInstance | undefined = undefined
65
- protected readonly _baseModuleQueryAccountPaths: Record<ModuleQueryBase['schema'], string> = {
66
- 'network.xyo.query.module.address': '1',
67
- 'network.xyo.query.module.discover': '2',
68
- 'network.xyo.query.module.subscribe': '3',
69
- }
70
- protected readonly _queryAccounts: Record<ModuleQueryBase['schema'], AccountInstance | undefined> = {
71
- 'network.xyo.query.module.address': undefined,
72
- 'network.xyo.query.module.discover': undefined,
73
- 'network.xyo.query.module.subscribe': undefined,
74
- }
75
- protected _started = false
76
- protected readonly moduleConfigQueryValidator: Queryable
77
- protected readonly supportedQueryValidator: Queryable
78
-
79
13
  constructor(privateConstructorKey: string, params: TParams) {
80
14
  assertEx(AbstractModule.privateConstructorKey === privateConstructorKey, 'Use create function instead of constructor')
81
15
  // Clone params to prevent mutation of the incoming object
82
16
  const mutatedParams = { ...params } as TParams
83
- super(mutatedParams)
84
-
85
- this.supportedQueryValidator = new SupportedQueryValidator(this as Module).queryable
86
- this.moduleConfigQueryValidator = new ModuleConfigQueryValidator(mutatedParams?.config).queryable
87
- }
88
-
89
- static get configSchema(): string {
90
- return this.configSchemas[0]
91
- }
92
-
93
- get account() {
94
- return assertEx(this._account, 'Missing account')
95
- }
96
-
97
- get address() {
98
- return this.account.address
99
- }
100
-
101
- get allowAnonymous() {
102
- return !!this.config.security?.allowAnonymous
103
- }
104
-
105
- get config(): TParams['config'] {
106
- return this.params.config
107
- }
108
-
109
- get ephemeralQueryAccountEnabled(): boolean {
110
- return !!this.params.ephemeralQueryAccountEnabled
111
- }
112
-
113
- get queries(): string[] {
114
- return [ModuleDiscoverQuerySchema, ModuleAddressQuerySchema, ModuleSubscribeQuerySchema]
115
- }
116
-
117
- get queryAccountPaths(): Readonly<Record<Query['schema'], string | undefined>> {
118
- return { ...this._baseModuleQueryAccountPaths, ...this._queryAccountPaths }
119
- }
120
-
121
- get queryAccounts(): Readonly<Record<Query['schema'], AccountInstance | undefined>> {
122
- return this._queryAccounts
123
- }
124
-
125
- protected abstract get _queryAccountPaths(): Record<Query['schema'], string>
126
-
127
- static async create<TModule extends Module>(this: CreatableModule<TModule>, params?: TModule['params']) {
128
- if (!this.configSchemas || this.configSchemas.length === 0) {
129
- throw Error(`Missing configSchema [${params?.config?.schema}][${this.name}]`)
130
- }
131
- const schema: string = params?.config?.schema ?? this.configSchema
132
- const allowedSchemas: string[] = this.configSchemas
133
-
134
- assertEx(
135
- allowedSchemas.filter((allowedSchema) => allowedSchema === schema).length > 0,
136
- `Bad Config Schema [Received ${schema}] [Expected ${JSON.stringify(allowedSchemas)}]`,
137
- )
138
- const mutatedConfig: TModule['params']['config'] = { ...params?.config, schema }
139
- params?.logger?.debug(`config: ${JSON.stringify(mutatedConfig, null, 2)}`)
140
- const mutatedParams = { ...params, config: mutatedConfig } as TModule['params']
141
- const newModule = new this(AbstractModule.privateConstructorKey, mutatedParams)
142
- await newModule.loadAccount?.()
143
- await newModule.start?.()
144
- return newModule
145
- }
146
-
147
- static factory<TModule extends Module>(this: CreatableModule<TModule>, params?: TModule['params']): CreatableModuleFactory<TModule> {
148
- return ModuleFactory.withParams(this, params)
149
- }
150
-
151
- addressPreviousHash(): Promisable<AddressPreviousHashPayload> {
152
- return { address: this.address, previousHash: this._account?.previousHash, schema: AddressPreviousHashSchema }
153
- }
154
-
155
- discover(): Promisable<Payload[]> {
156
- const config = this.config
157
- const address = new PayloadBuilder<AddressPayload>({ schema: AddressSchema }).fields({ address: this.address, name: this.config.name }).build()
158
- const queries = this.queries.map((query) => {
159
- return new PayloadBuilder<QueryPayload>({ schema: QuerySchema }).fields({ query }).build()
160
- })
161
- const configSchema: ConfigPayload = {
162
- config: config.schema,
163
- schema: ConfigSchema,
164
- }
165
- return compact([config, configSchema, address, ...queries])
17
+ super(privateConstructorKey, mutatedParams)
166
18
  }
167
19
 
168
- async loadAccount() {
169
- if (!this._account) {
170
- const activeLogger = this.params.logger ?? AbstractModule.defaultLogger
171
- let { account } = this.params as AccountModuleParams<TParams['config']>
172
- const { wallet, accountDerivationPath } = this.params as WalletModuleParams<TParams['config']>
173
- if (wallet) {
174
- account = assertEx(accountDerivationPath ? await wallet.derivePath(accountDerivationPath) : wallet, 'Failed to derive account from path')
175
- }
176
- this.params.logger = activeLogger ? new IdLogger(activeLogger, () => `0x${account.address}`) : undefined
177
- if (!account) console.warn(`AbstractModule.loadAccount: No account provided - Creating Random account [${this.config.schema}]`)
178
- this._account = account ?? (await HDWallet.random())
179
- }
180
- this.downResolver.add(this as Module)
181
- return this._account
20
+ /* make it public */
21
+ override async addressPreviousHash(): Promise<AddressPreviousHashPayload> {
22
+ return await super.addressPreviousHash()
182
23
  }
183
24
 
184
- manifest(): Promisable<ModuleManifestPayload> {
185
- const name = assertEx(this.config.name, 'Calling manifest on un-named module is not supported')
186
- return { config: { name, ...this.config }, schema: ModuleManifestPayloadSchema }
25
+ /* make it public */
26
+ override async describe(): Promise<ModuleDescriptionPayload> {
27
+ return await super.describe()
187
28
  }
188
29
 
189
- moduleAddressQuery(): Promisable<(AddressPayload | AddressPreviousHashPayload)[]> {
190
- // Return array of all addresses and their previous hash
191
- const queryAccounts = Object.entries(this.queryAccounts)
192
- .filter((value): value is [string, AccountInstance] => {
193
- return exists(value[1])
194
- })
195
- .map(([name, account]) => {
196
- const address = account.address
197
- const previousHash = account.previousHash
198
- return [
199
- { address, name, schema: AddressSchema },
200
- { address, previousHash, schema: AddressPreviousHashSchema },
201
- ]
202
- })
203
- const address = this.address
204
- const name = this.config.name
205
- const previousHash = this.address
206
- const moduleAccount = name ? { address, name, schema: AddressSchema } : { address, schema: AddressSchema }
207
- const moduleAccountPreviousHash = previousHash
208
- ? { address, previousHash, schema: AddressPreviousHashSchema }
209
- : { address, schema: AddressPreviousHashSchema }
210
- return [moduleAccount, moduleAccountPreviousHash, ...queryAccounts].flat()
30
+ /* make it public */
31
+ override async discover(): Promise<Payload[]> {
32
+ return await super.discover()
211
33
  }
212
34
 
213
- async query<T extends QueryBoundWitness = QueryBoundWitness, TConfig extends ModuleConfig = ModuleConfig>(
214
- query: T,
215
- payloads?: Payload[],
216
- queryConfig?: TConfig,
217
- ): Promise<ModuleQueryResult> {
218
- this.started('throw')
219
- const result = await this.queryHandler(assertEx(QueryBoundWitnessWrapper.unwrap(query)), payloads, queryConfig)
220
-
221
- const args: ModuleQueriedEventArgs = { module: this as Module, payloads, query, result }
222
- await this.emit('moduleQueried', args)
223
-
224
- return result
225
- }
226
-
227
- queryable<T extends QueryBoundWitness = QueryBoundWitness, TConfig extends ModuleConfig = ModuleConfig>(
228
- query: T,
229
- payloads?: Payload[],
230
- queryConfig?: TConfig,
231
- ): boolean {
232
- if (!this.started('warn')) return false
233
- const configValidator = queryConfig
234
- ? new ModuleConfigQueryValidator(Object.assign({}, this.config, queryConfig)).queryable
235
- : this.moduleConfigQueryValidator
236
- const validators = [this.supportedQueryValidator, configValidator]
237
-
238
- return validators.every((validator) => validator(query, payloads))
239
- }
240
-
241
- async start(_timeout?: number): Promise<void> {
242
- this.validateConfig()
243
- await this.initializeQueryAccounts()
244
- this._started = true
245
- }
246
-
247
- started(notStartedAction?: 'error' | 'throw' | 'warn' | 'log' | 'none') {
248
- if (!this._started) {
249
- switch (notStartedAction) {
250
- case 'throw':
251
- throw Error(`Module not Started [${this.address}]`)
252
- case 'warn':
253
- this.logger?.warn('Module not started')
254
- break
255
- case 'error':
256
- this.logger?.error('Module not started')
257
- break
258
- case 'none':
259
- break
260
- case 'log':
261
- default:
262
- this.logger?.log('Module not started')
263
- }
264
- }
265
- return this._started
35
+ /* make it public */
36
+ override async manifest(): Promise<ModuleManifestPayload> {
37
+ return await super.manifest()
266
38
  }
267
39
 
268
- subscribe(_queryAccount?: AccountInstance) {
269
- return
270
- }
271
-
272
- protected bindHashes(hashes: string[], schema: SchemaString[], account?: AccountInstance) {
273
- const promise = new PromiseEx((resolve) => {
274
- const result = this.bindHashesInternal(hashes, schema, account)
275
- resolve?.(result)
276
- return result
277
- }, account)
278
- return promise
279
- }
280
-
281
- protected async bindHashesInternal(hashes: string[], schema: SchemaString[], account?: AccountInstance): Promise<BoundWitness> {
282
- const builder = new BoundWitnessBuilder().hashes(hashes, schema).witness(this.account)
283
- const result = (await (account ? builder.witness(account) : builder).build())[0]
284
- this.logger?.debug(`result: ${JSON.stringify(result, null, 2)}`)
285
- return result
286
- }
287
-
288
- protected bindQuery<T extends Query | PayloadWrapper<Query>>(
289
- query: T,
290
- payloads?: Payload[],
291
- account?: AccountInstance,
292
- ): PromiseEx<[QueryBoundWitness, Payload[], Payload[]], AccountInstance> {
293
- const promise = new PromiseEx<[QueryBoundWitness, Payload[], Payload[]], AccountInstance>(async (resolve) => {
294
- const result = await this.bindQueryInternal(query, payloads, account)
295
- resolve?.(result)
296
- return result
297
- }, account)
298
- return promise
299
- }
300
-
301
- protected async bindQueryInternal<T extends Query | PayloadWrapper<Query>>(
302
- query: T,
303
- payloads?: Payload[],
304
- account?: AccountInstance,
305
- ): Promise<[QueryBoundWitness, Payload[], Payload[]]> {
306
- const builder = new QueryBoundWitnessBuilder().payloads(payloads).witness(this.account).query(query)
307
- const result = await (account ? builder.witness(account) : builder).build()
308
- return result
309
- }
310
-
311
- protected async bindQueryResult<T extends Query | PayloadWrapper<Query>>(
312
- query: T,
313
- payloads: Payload[],
314
- additionalWitnesses: AccountInstance[] = [],
315
- errors?: ModuleError[],
316
- ): Promise<[ModuleQueryResult, AccountInstance[]]> {
317
- const builder = new BoundWitnessBuilder().payloads(payloads).errors(errors)
318
- const queryWitnessAccount = this.queryAccounts[query.schema as ModuleQueryBase['schema']]
319
- const witnesses = [this.account, queryWitnessAccount, ...additionalWitnesses].filter(exists)
320
- builder.witnesses(witnesses)
321
- const result: ModuleQueryResult = [(await builder.build())[0], payloads, errors ?? []]
322
- return [result, witnesses]
323
- }
324
-
325
- protected commitArchivist = () => this.getArchivist('commit')
326
-
327
- protected async initializeQueryAccounts() {
328
- // Ensure distinct/unique wallet paths
329
- const paths = Object.values(this.queryAccountPaths).filter(exists)
330
- const distinctPaths = new Set<string>(paths)
331
- assertEx(distinctPaths.size === paths.length, `${this.config?.name ? this.config.name + ': ' : ''}Duplicate query account paths`)
332
- // Create an account for query this module supports
333
- const wallet = this.account as unknown as HDWallet
334
- if (wallet?.derivePath) {
335
- for (const key in this.queryAccountPaths) {
336
- if (Object.prototype.hasOwnProperty.call(this.queryAccountPaths, key)) {
337
- const query = key as ModuleQueryBase['schema']
338
- const queryAccountPath = this.queryAccountPaths[query]
339
- if (queryAccountPath) {
340
- this._queryAccounts[query] = await wallet.derivePath?.(queryAccountPath)
341
- }
342
- }
343
- }
344
- }
345
- }
346
-
347
- protected async queryHandler<T extends QueryBoundWitness = QueryBoundWitness, TConfig extends ModuleConfig = ModuleConfig>(
348
- query: T,
349
- payloads?: Payload[],
350
- queryConfig?: TConfig,
351
- ): Promise<ModuleQueryResult> {
352
- this.started('throw')
353
- const wrapper = QueryBoundWitnessWrapper.parseQuery<ModuleQuery>(query, payloads)
354
- if (!this.allowAnonymous) {
355
- if (query.addresses.length === 0) {
356
- console.warn(`Anonymous Queries not allowed, but running anyway [${this.config.name}], [${this.address}]`)
357
- }
358
- }
359
- const queryPayload = await wrapper.getQuery()
360
- assertEx(this.queryable(query, payloads, queryConfig))
361
- const resultPayloads: Payload[] = []
362
- const errorPayloads: ModuleError[] = []
363
- const queryAccount = this.ephemeralQueryAccountEnabled ? await HDWallet.random() : undefined
364
- try {
365
- switch (queryPayload.schema) {
366
- case ModuleDiscoverQuerySchema: {
367
- resultPayloads.push(...(await this.discover()))
368
- break
369
- }
370
- case ModuleAddressQuerySchema: {
371
- resultPayloads.push(...(await this.moduleAddressQuery()))
372
- break
373
- }
374
- case ModuleSubscribeQuerySchema: {
375
- this.subscribe(queryAccount)
376
- break
377
- }
378
- default:
379
- console.error(`Unsupported Query [${(queryPayload as Payload).schema}]`)
380
- }
381
- } catch (ex) {
382
- await handleErrorAsync(ex, async (error) => {
383
- errorPayloads.push(
384
- new ModuleErrorBuilder()
385
- .sources([await wrapper.hashAsync()])
386
- .name(this.config.name ?? '<Unknown>')
387
- .query(query.schema)
388
- .message(error.message)
389
- .build(),
390
- )
391
- })
392
- }
393
- return (await this.bindQueryResult(queryPayload, resultPayloads, queryAccount ? [queryAccount] : [], errorPayloads))[0]
394
- }
395
-
396
- protected readArchivist = () => this.getArchivist('read')
397
-
398
- protected async resolve<TModule extends Module = Module>(filter?: ModuleFilter): Promise<TModule[]> {
399
- return [...(await this.upResolver.resolve<TModule>(filter)), ...(await this.downResolver.resolve<TModule>(filter))].filter(duplicateModules)
400
- }
401
-
402
- protected stop(_timeout?: number): Promisable<this> {
403
- this._started = false
404
- return this
405
- }
406
-
407
- protected validateConfig(config?: unknown, parents: string[] = []): boolean {
408
- return Object.entries(config ?? this.config ?? {}).reduce((valid, [key, value]) => {
409
- switch (typeof value) {
410
- case 'function':
411
- this.logger?.warn(`Fields of type function not allowed in config [${parents?.join('.')}.${key}]`)
412
- return false
413
- case 'object': {
414
- if (Array.isArray(value)) {
415
- return (
416
- value.reduce((valid, value) => {
417
- return this.validateConfig(value, [...parents, key]) && valid
418
- }, true) && valid
419
- )
420
- }
421
-
422
- if (!serializableField(value)) {
423
- this.logger?.warn(`Fields that are not serializable to JSON are not allowed in config [${parents?.join('.')}.${key}]`)
424
- return false
425
- }
426
- return value ? this.validateConfig(value, [...parents, key]) && valid : true
427
- }
428
- default:
429
- return valid
430
- }
431
- }, true)
432
- }
433
-
434
- protected writeArchivist = () => this.getArchivist('write')
435
-
436
- private async getArchivist(kind: keyof IndividualArchivistConfig): Promise<ArchivistModule | undefined> {
437
- if (!this.config.archivist) return undefined
438
- const filter =
439
- typeof this.config.archivist === 'string' || this.config.archivist instanceof String
440
- ? (this.config.archivist as string)
441
- : (this.config?.archivist?.[kind] as string)
442
- const resolved = await this.upResolver.resolveOne(filter)
443
- return resolved ? (resolved as ArchivistModule) : undefined
40
+ /* make it public */
41
+ override subscribe(_queryAccount?: AccountInstance) {
42
+ return super.subscribe()
444
43
  }
445
44
  }
@@ -1,11 +1,11 @@
1
- import { Module, ModuleQuery, QueryBoundWitness } from '@xyo-network/module-model'
1
+ import { IndirectModule, ModuleQuery, QueryBoundWitness } from '@xyo-network/module-model'
2
2
  import { Payload } from '@xyo-network/payload-model'
3
3
 
4
4
  import { QueryBoundWitnessWrapper } from '../Query'
5
5
  import { Queryable, QueryValidator } from './QueryValidator'
6
6
 
7
7
  export const isQuerySupportedByModule = async <T extends QueryBoundWitness = QueryBoundWitness>(
8
- mod: Module,
8
+ mod: IndirectModule,
9
9
  query: T,
10
10
  payloads?: Payload[],
11
11
  ): Promise<boolean> => {
@@ -15,7 +15,7 @@ export const isQuerySupportedByModule = async <T extends QueryBoundWitness = Que
15
15
  }
16
16
 
17
17
  export class SupportedQueryValidator implements QueryValidator {
18
- constructor(protected readonly mod: Module) {}
18
+ constructor(protected readonly mod: IndirectModule) {}
19
19
  queryable: Queryable = (query, payloads) => {
20
20
  return isQuerySupportedByModule(this.mod, query, payloads)
21
21
  }
@@ -1,6 +1,6 @@
1
1
  import { fulfilled } from '@xylabs/promise'
2
2
  import { Base, BaseParams } from '@xyo-network/core'
3
- import { Module, ModuleFilter, ModuleRepository, ModuleResolver } from '@xyo-network/module-model'
3
+ import { IndirectModule, ModuleFilter, ModuleRepository, ModuleResolver } from '@xyo-network/module-model'
4
4
 
5
5
  import { duplicateModules } from '../lib'
6
6
  import { SimpleModuleResolver } from './SimpleModuleResolver'
@@ -20,9 +20,9 @@ export class CompositeModuleResolver extends Base implements ModuleRepository, M
20
20
  return true
21
21
  }
22
22
 
23
- add(module: Module): this
24
- add(module: Module[]): this
25
- add(module: Module | Module[]): this {
23
+ add(module: IndirectModule): this
24
+ add(module: IndirectModule[]): this
25
+ add(module: IndirectModule | IndirectModule[]): this {
26
26
  if (Array.isArray(module)) {
27
27
  module.forEach((module) => this.addSingleModule(module))
28
28
  } else {
@@ -50,10 +50,9 @@ export class CompositeModuleResolver extends Base implements ModuleRepository, M
50
50
  return this
51
51
  }
52
52
 
53
- async resolve<T extends Module = Module>(filter?: ModuleFilter): Promise<T[]> {
54
- const modules = this.resolvers.map((resolver) => resolver.resolve(filter))
55
- const settled = await Promise.allSettled(modules)
56
- const result = settled
53
+ async resolve<T extends IndirectModule = IndirectModule>(filter?: ModuleFilter): Promise<T[]> {
54
+ const modules = await Promise.allSettled(this.resolvers.map((resolver) => resolver.resolve(filter)))
55
+ const result = modules
57
56
  .filter(fulfilled)
58
57
  .map((r) => r.value)
59
58
  .flat()
@@ -61,7 +60,7 @@ export class CompositeModuleResolver extends Base implements ModuleRepository, M
61
60
  return result as T[]
62
61
  }
63
62
 
64
- async resolveOne<T extends Module = Module>(addressOrName: string): Promise<T | undefined> {
63
+ async resolveOne<T extends IndirectModule = IndirectModule>(addressOrName: string): Promise<T | undefined> {
65
64
  for (let i = 0; i < this.resolvers.length; i++) {
66
65
  const resolver = this.resolvers[i]
67
66
  const result = await resolver.resolveOne<T>(addressOrName)
@@ -70,7 +69,7 @@ export class CompositeModuleResolver extends Base implements ModuleRepository, M
70
69
  return undefined
71
70
  }
72
71
 
73
- private addSingleModule(module?: Module) {
72
+ private addSingleModule(module?: IndirectModule) {
74
73
  if (module) {
75
74
  this.localResolver.add(module)
76
75
  }
@@ -1,8 +1,8 @@
1
- import { Module, ModuleFilter, ModuleResolver } from '@xyo-network/module-model'
1
+ import { IndirectModule, ModuleFilter, ModuleResolver } from '@xyo-network/module-model'
2
2
 
3
3
  export interface ModuleResolvedEventArgs {
4
4
  filter?: ModuleFilter
5
- module: Module
5
+ module: IndirectModule
6
6
  }
7
7
 
8
8
  export interface ResolverEventEmitter {
@@ -18,7 +18,7 @@ const getMixin = <T extends ModuleResolver = ModuleResolver>(resolver: T) => {
18
18
  listeners.map((listener) => listener(args))
19
19
  return true
20
20
  }
21
- const onModuleResolved = (module: Module, filter?: ModuleFilter) => {
21
+ const onModuleResolved = (module: IndirectModule, filter?: ModuleFilter) => {
22
22
  const args = { filter, module }
23
23
  emit('moduleResolved', args)
24
24
  }
@@ -31,8 +31,8 @@ const getMixin = <T extends ModuleResolver = ModuleResolver>(resolver: T) => {
31
31
  on: (event: 'moduleResolved', listener: (args: ModuleResolvedEventArgs) => void) => {
32
32
  listeners.push(listener)
33
33
  },
34
- resolve: async (filter?: ModuleFilter): Promise<Module[]> => {
35
- const modules: Module[] = await originalResolve(filter)
34
+ resolve: async (filter?: ModuleFilter): Promise<IndirectModule[]> => {
35
+ const modules: IndirectModule[] = await originalResolve(filter)
36
36
  await Promise.allSettled(modules.map((mod) => onModuleResolved(mod, filter)))
37
37
  return modules
38
38
  },
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  AddressModuleFilter,
3
- Module,
3
+ IndirectModule,
4
4
  ModuleFilter,
5
5
  ModuleRepository,
6
6
  ModuleResolver,
@@ -14,15 +14,15 @@ import flatten from 'lodash/flatten'
14
14
  //This class is now package private (not exported from index.ts)
15
15
  export class SimpleModuleResolver implements ModuleRepository {
16
16
  private addressToName: Record<string, string> = {}
17
- private modules: Record<string, Module> = {}
17
+ private modules: Record<string, IndirectModule> = {}
18
18
 
19
19
  get isModuleResolver() {
20
20
  return true
21
21
  }
22
22
 
23
- add(module: Module): this
24
- add(module: Module[]): this
25
- add(module: Module | Module[]): this {
23
+ add(module: IndirectModule): this
24
+ add(module: IndirectModule[]): this
25
+ add(module: IndirectModule | IndirectModule[]): this {
26
26
  if (Array.isArray(module)) {
27
27
  module.forEach((module) => this.addSingleModule(module))
28
28
  } else {
@@ -48,7 +48,7 @@ export class SimpleModuleResolver implements ModuleRepository {
48
48
  throw 'Removing resolvers not supported'
49
49
  }
50
50
 
51
- resolve<T extends Module = Module>(filter?: ModuleFilter): Promisable<T[]> {
51
+ resolve<T extends IndirectModule = IndirectModule>(filter?: ModuleFilter): Promisable<T[]> {
52
52
  const filteredByName: T[] = this.resolveByName<T>(Object.values(this.modules) as T[], (filter as NameModuleFilter)?.name)
53
53
 
54
54
  const filteredByAddress: T[] = (filter as AddressModuleFilter)?.address
@@ -62,7 +62,7 @@ export class SimpleModuleResolver implements ModuleRepository {
62
62
  return filteredByQuery
63
63
  }
64
64
 
65
- resolveOne<T extends Module = Module>(filter: string): Promisable<T | undefined> {
65
+ resolveOne<T extends IndirectModule = IndirectModule>(filter: string): Promisable<T | undefined> {
66
66
  const allModules = Object.values(this.modules) as T[]
67
67
  for (const resolutionMethod of [this.resolveByAddress, this.resolveByName]) {
68
68
  const filtered: T[] = resolutionMethod(allModules, [filter])
@@ -71,7 +71,7 @@ export class SimpleModuleResolver implements ModuleRepository {
71
71
  return undefined
72
72
  }
73
73
 
74
- private addSingleModule(module?: Module) {
74
+ private addSingleModule(module?: IndirectModule) {
75
75
  if (module) {
76
76
  this.modules[module.address] = module
77
77
  }
@@ -89,7 +89,7 @@ export class SimpleModuleResolver implements ModuleRepository {
89
89
  }
90
90
  }
91
91
 
92
- private resolveByAddress<T extends Module = Module>(modules: T[], address?: string[]): T[] {
92
+ private resolveByAddress<T extends IndirectModule = IndirectModule>(modules: T[], address?: string[]): T[] {
93
93
  return address
94
94
  ? compact(
95
95
  flatten(
@@ -101,14 +101,14 @@ export class SimpleModuleResolver implements ModuleRepository {
101
101
  : modules
102
102
  }
103
103
 
104
- private resolveByName<T extends Module = Module>(modules: T[], name?: string[]): T[] {
104
+ private resolveByName<T extends IndirectModule = IndirectModule>(modules: T[], name?: string[]): T[] {
105
105
  if (name) {
106
106
  return compact(name.map((name) => modules.filter((module) => module.config.name === name)).flat())
107
107
  }
108
108
  return modules
109
109
  }
110
110
 
111
- private resolveByQuery<T extends Module = Module>(modules: T[], query?: string[][]): T[] {
111
+ private resolveByQuery<T extends IndirectModule = IndirectModule>(modules: T[], query?: string[][]): T[] {
112
112
  return query
113
113
  ? compact(
114
114
  modules.filter((module) =>
@@ -1,4 +1,4 @@
1
- import { Module } from '@xyo-network/module-model'
1
+ import { IndirectModule } from '@xyo-network/module-model'
2
2
 
3
3
  /**
4
4
  * Used to filter duplicates from an array of modules
@@ -9,6 +9,6 @@ import { Module } from '@xyo-network/module-model'
9
9
  * @returns True if the Module's address is the first occurrence of
10
10
  * that address in the array, false otherwise
11
11
  */
12
- export const duplicateModules = (value: Module, index: number, array: Module[]): value is Module => {
12
+ export const duplicateModules = (value: IndirectModule, index: number, array: IndirectModule[]): value is IndirectModule => {
13
13
  return array.findIndex((v) => v.address === value.address) === index
14
14
  }