@xyo-network/module-abstract 2.56.2 → 2.57.4
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/dist/cjs/AbstractModule.js +74 -24
- package/dist/cjs/AbstractModule.js.map +1 -1
- package/dist/cjs/ModuleFactory.js +22 -0
- package/dist/cjs/ModuleFactory.js.map +1 -0
- package/dist/cjs/Resolver/index.js +2 -7
- package/dist/cjs/Resolver/index.js.map +1 -1
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/docs.json +41744 -17299
- package/dist/esm/AbstractModule.js +73 -27
- package/dist/esm/AbstractModule.js.map +1 -1
- package/dist/esm/ModuleFactory.js +22 -0
- package/dist/esm/ModuleFactory.js.map +1 -0
- package/dist/esm/Resolver/index.js +2 -6
- package/dist/esm/Resolver/index.js.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/types/AbstractModule.d.ts +10 -4
- package/dist/types/AbstractModule.d.ts.map +1 -1
- package/dist/types/ModuleFactory.d.ts +16 -0
- package/dist/types/ModuleFactory.d.ts.map +1 -0
- package/dist/types/Resolver/index.d.ts +2 -5
- package/dist/types/Resolver/index.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/lib/duplicateModules.d.ts +27 -1
- package/dist/types/lib/duplicateModules.d.ts.map +1 -1
- package/package.json +21 -20
- package/src/AbstractModule.ts +82 -21
- package/src/ModuleFactory.ts +35 -0
- package/src/Resolver/index.ts +2 -7
- package/src/index.ts +1 -0
- package/typedoc.json +5 -0
package/src/AbstractModule.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { assertEx } from '@xylabs/assert'
|
|
2
|
-
import {
|
|
2
|
+
import { exists } from '@xylabs/exists'
|
|
3
|
+
import { Account, HDWallet } from '@xyo-network/account'
|
|
3
4
|
import { AccountInstance } from '@xyo-network/account-model'
|
|
4
5
|
import { AddressPayload, AddressSchema } from '@xyo-network/address-payload-plugin'
|
|
5
6
|
import { BoundWitnessBuilder } from '@xyo-network/boundwitness-builder'
|
|
@@ -8,7 +9,7 @@ import { ConfigPayload, ConfigSchema } from '@xyo-network/config-payload-plugin'
|
|
|
8
9
|
import {
|
|
9
10
|
AccountModuleParams,
|
|
10
11
|
CreatableModule,
|
|
11
|
-
|
|
12
|
+
CreatableModuleFactory,
|
|
12
13
|
Module,
|
|
13
14
|
ModuleConfig,
|
|
14
15
|
ModuleDiscoverQuerySchema,
|
|
@@ -18,6 +19,7 @@ import {
|
|
|
18
19
|
ModulePreviousHashQuerySchema,
|
|
19
20
|
ModuleQueriedEventArgs,
|
|
20
21
|
ModuleQuery,
|
|
22
|
+
ModuleQueryBase,
|
|
21
23
|
ModuleQueryResult,
|
|
22
24
|
ModuleSubscribeQuerySchema,
|
|
23
25
|
Query,
|
|
@@ -36,12 +38,13 @@ import compact from 'lodash/compact'
|
|
|
36
38
|
import { BaseEmitter } from './BaseEmitter'
|
|
37
39
|
import { ModuleErrorBuilder } from './Error'
|
|
38
40
|
import { duplicateModules, serializableField } from './lib'
|
|
41
|
+
import { ModuleFactory } from './ModuleFactory'
|
|
39
42
|
import { QueryBoundWitnessBuilder, QueryBoundWitnessWrapper } from './Query'
|
|
40
43
|
import { ModuleConfigQueryValidator, Queryable, SupportedQueryValidator } from './QueryValidator'
|
|
41
44
|
import { CompositeModuleResolver } from './Resolver'
|
|
42
45
|
|
|
43
|
-
@creatableModule()
|
|
44
|
-
export class AbstractModule<TParams extends ModuleParams = ModuleParams, TEventData extends ModuleEventData = ModuleEventData>
|
|
46
|
+
// @creatableModule()
|
|
47
|
+
export abstract class AbstractModule<TParams extends ModuleParams = ModuleParams, TEventData extends ModuleEventData = ModuleEventData>
|
|
45
48
|
extends BaseEmitter<TParams, TEventData>
|
|
46
49
|
implements Module<TParams, TEventData>
|
|
47
50
|
{
|
|
@@ -50,10 +53,19 @@ export class AbstractModule<TParams extends ModuleParams = ModuleParams, TEventD
|
|
|
50
53
|
readonly downResolver = new CompositeModuleResolver()
|
|
51
54
|
readonly upResolver = new CompositeModuleResolver()
|
|
52
55
|
|
|
56
|
+
protected readonly _baseModuleQueryAccountPaths: Record<ModuleQueryBase['schema'], string> = {
|
|
57
|
+
'network.xyo.query.module.account.hash.previous': '1',
|
|
58
|
+
'network.xyo.query.module.discover': '2',
|
|
59
|
+
'network.xyo.query.module.subscribe': '3',
|
|
60
|
+
}
|
|
61
|
+
protected readonly _queryAccounts: Record<ModuleQueryBase['schema'], AccountInstance | undefined> = {
|
|
62
|
+
'network.xyo.query.module.account.hash.previous': undefined,
|
|
63
|
+
'network.xyo.query.module.discover': undefined,
|
|
64
|
+
'network.xyo.query.module.subscribe': undefined,
|
|
65
|
+
}
|
|
53
66
|
protected _started = false
|
|
54
67
|
protected readonly account: AccountInstance
|
|
55
68
|
protected readonly moduleConfigQueryValidator: Queryable
|
|
56
|
-
|
|
57
69
|
protected readonly supportedQueryValidator: Queryable
|
|
58
70
|
|
|
59
71
|
constructor(params: TParams) {
|
|
@@ -95,6 +107,16 @@ export class AbstractModule<TParams extends ModuleParams = ModuleParams, TEventD
|
|
|
95
107
|
return [ModuleDiscoverQuerySchema, ModulePreviousHashQuerySchema, ModuleSubscribeQuerySchema]
|
|
96
108
|
}
|
|
97
109
|
|
|
110
|
+
get queryAccountPaths(): Readonly<Record<Query['schema'], string | undefined>> {
|
|
111
|
+
return { ...this._baseModuleQueryAccountPaths, ...this._queryAccountPaths }
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
get queryAccounts(): Readonly<Record<Query['schema'], AccountInstance | undefined>> {
|
|
115
|
+
return this._queryAccounts
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
protected abstract get _queryAccountPaths(): Record<Query['schema'], string>
|
|
119
|
+
|
|
98
120
|
static async create<TModule extends Module>(this: CreatableModule<TModule>, params?: TModule['params']) {
|
|
99
121
|
if (!this.configSchema) {
|
|
100
122
|
throw Error(`Missing configSchema [${params?.config?.schema}][${this.name}]`)
|
|
@@ -113,6 +135,10 @@ export class AbstractModule<TParams extends ModuleParams = ModuleParams, TEventD
|
|
|
113
135
|
return newModule
|
|
114
136
|
}
|
|
115
137
|
|
|
138
|
+
static factory<TModule extends Module>(this: CreatableModule<TModule>, params?: TModule['params']): CreatableModuleFactory<TModule> {
|
|
139
|
+
return ModuleFactory.withParams(this, params)
|
|
140
|
+
}
|
|
141
|
+
|
|
116
142
|
discover(): Promisable<Payload[]> {
|
|
117
143
|
const config = this.config
|
|
118
144
|
const address = new PayloadBuilder<AddressPayload>({ schema: AddressSchema }).fields({ address: this.address, name: this.config.name }).build()
|
|
@@ -127,11 +153,25 @@ export class AbstractModule<TParams extends ModuleParams = ModuleParams, TEventD
|
|
|
127
153
|
}
|
|
128
154
|
|
|
129
155
|
previousHash(): Promisable<Payload[]> {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
156
|
+
// Return array of all addresses and their previous hash
|
|
157
|
+
const queryAccountPreviousHashes = Object.entries(this.queryAccounts)
|
|
158
|
+
.filter((value): value is [string, AccountInstance] => {
|
|
159
|
+
return exists(value[1])
|
|
160
|
+
})
|
|
161
|
+
.map(([name, account]) => {
|
|
162
|
+
const address = account.addressValue.hex
|
|
163
|
+
const previousHash = account.previousHash?.hex
|
|
164
|
+
return { address, name, previousHash, schema: AddressSchema }
|
|
165
|
+
})
|
|
166
|
+
const moduleAccountPreviousHash = new PayloadBuilder<AddressPayload>({ schema: AddressSchema })
|
|
167
|
+
.fields({
|
|
168
|
+
address: this.address,
|
|
169
|
+
name: this.config.name,
|
|
170
|
+
previousHash: this.account.previousHash?.hex,
|
|
171
|
+
schema: AddressSchema,
|
|
172
|
+
})
|
|
173
|
+
.build()
|
|
174
|
+
return [moduleAccountPreviousHash, ...queryAccountPreviousHashes]
|
|
135
175
|
}
|
|
136
176
|
|
|
137
177
|
async query<T extends QueryBoundWitness = QueryBoundWitness, TConfig extends ModuleConfig = ModuleConfig>(
|
|
@@ -164,6 +204,7 @@ export class AbstractModule<TParams extends ModuleParams = ModuleParams, TEventD
|
|
|
164
204
|
|
|
165
205
|
start(_timeout?: number): Promisable<void> {
|
|
166
206
|
this.validateConfig()
|
|
207
|
+
this.initializeQueryAccounts()
|
|
167
208
|
this._started = true
|
|
168
209
|
}
|
|
169
210
|
|
|
@@ -228,23 +269,43 @@ export class AbstractModule<TParams extends ModuleParams = ModuleParams, TEventD
|
|
|
228
269
|
): [QueryBoundWitness, Payload[]] {
|
|
229
270
|
const builder = new QueryBoundWitnessBuilder().payloads(payloads).witness(this.account).query(query)
|
|
230
271
|
const result = (account ? builder.witness(account) : builder).build()
|
|
231
|
-
//this.logger?.debug(`result: ${JSON.stringify(result, null, 2)}`)
|
|
232
272
|
return result
|
|
233
273
|
}
|
|
234
274
|
|
|
235
|
-
protected
|
|
236
|
-
|
|
237
|
-
|
|
275
|
+
protected bindQueryResult<T extends Query | PayloadWrapper<Query>>(
|
|
276
|
+
query: T,
|
|
277
|
+
payloads: Payload[],
|
|
278
|
+
additionalWitnesses: AccountInstance[] = [],
|
|
279
|
+
): PromiseEx<ModuleQueryResult, AccountInstance[]> {
|
|
280
|
+
const builder = new BoundWitnessBuilder().payloads(payloads)
|
|
281
|
+
const queryWitnessAccount = this.queryAccounts[query.schema as ModuleQueryBase['schema']]
|
|
282
|
+
const witnesses = [this.account, queryWitnessAccount, ...additionalWitnesses].filter(exists)
|
|
283
|
+
builder.witnesses(witnesses)
|
|
284
|
+
const result: ModuleQueryResult = [builder.build()[0], payloads]
|
|
285
|
+
return new PromiseEx<ModuleQueryResult, AccountInstance[]>((resolve) => {
|
|
238
286
|
resolve?.(result)
|
|
239
287
|
return result
|
|
240
|
-
},
|
|
241
|
-
return promise
|
|
288
|
+
}, witnesses)
|
|
242
289
|
}
|
|
243
290
|
|
|
244
|
-
protected
|
|
245
|
-
|
|
246
|
-
const
|
|
247
|
-
|
|
291
|
+
protected initializeQueryAccounts() {
|
|
292
|
+
// Ensure distinct/unique wallet paths
|
|
293
|
+
const paths = Object.values(this.queryAccountPaths).filter(exists)
|
|
294
|
+
const distinctPaths = new Set<string>(paths)
|
|
295
|
+
assertEx(distinctPaths.size === paths.length, `${this.config?.name ? this.config.name + ': ' : ''}Duplicate query account paths`)
|
|
296
|
+
// Create an account for query this module supports
|
|
297
|
+
const wallet = this.account as unknown as HDWallet
|
|
298
|
+
if (wallet?.derivePath) {
|
|
299
|
+
for (const key in this.queryAccountPaths) {
|
|
300
|
+
if (Object.prototype.hasOwnProperty.call(this.queryAccountPaths, key)) {
|
|
301
|
+
const query = key as ModuleQueryBase['schema']
|
|
302
|
+
const queryAccountPath = this.queryAccountPaths[query]
|
|
303
|
+
if (queryAccountPath) {
|
|
304
|
+
this._queryAccounts[query] = wallet.derivePath(queryAccountPath)
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
248
309
|
}
|
|
249
310
|
|
|
250
311
|
protected loadAccount(account?: AccountInstance): AccountInstance {
|
|
@@ -288,7 +349,7 @@ export class AbstractModule<TParams extends ModuleParams = ModuleParams, TEventD
|
|
|
288
349
|
const error = ex as Error
|
|
289
350
|
resultPayloads.push(new ModuleErrorBuilder().sources([wrapper.hash]).message(error.message).build())
|
|
290
351
|
}
|
|
291
|
-
return await this.
|
|
352
|
+
return await this.bindQueryResult(typedQuery, resultPayloads, [queryAccount])
|
|
292
353
|
}
|
|
293
354
|
|
|
294
355
|
protected async resolve<TModule extends Module = Module>(filter?: ModuleFilter): Promise<TModule[]> {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Logger } from '@xyo-network/core'
|
|
2
|
+
import { CreatableModule, CreatableModuleFactory, Module } from '@xyo-network/module-model'
|
|
3
|
+
|
|
4
|
+
export interface CreatableModuleDictionary {
|
|
5
|
+
[key: string]: CreatableModuleFactory
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export class ModuleFactory<TModule extends Module> implements CreatableModuleFactory<TModule> {
|
|
9
|
+
configSchema: CreatableModuleFactory<TModule>['configSchema']
|
|
10
|
+
|
|
11
|
+
creatableModule: CreatableModule<TModule>
|
|
12
|
+
|
|
13
|
+
defaultLogger?: Logger | undefined
|
|
14
|
+
|
|
15
|
+
defaultParams?: TModule['params']
|
|
16
|
+
|
|
17
|
+
constructor(creatableModule: CreatableModule<TModule>, params?: TModule['params']) {
|
|
18
|
+
this.creatableModule = creatableModule
|
|
19
|
+
this.defaultParams = params
|
|
20
|
+
this.configSchema = creatableModule.configSchema
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
static withParams<T extends Module>(creatableModule: CreatableModule<T>, params?: T['params']) {
|
|
24
|
+
return new ModuleFactory(creatableModule, params)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
create<T extends Module>(this: CreatableModuleFactory<T>, params?: TModule['params'] | undefined): Promise<T> {
|
|
28
|
+
const factory = this as ModuleFactory<T>
|
|
29
|
+
return factory.creatableModule.create<T>(factory.defaultParams ? { ...factory.defaultParams, ...params } : params)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
factory<T extends Module>(this: CreatableModule<T>, _params?: T['params'] | undefined): CreatableModuleFactory<T> {
|
|
33
|
+
throw new Error('Method not implemented.')
|
|
34
|
+
}
|
|
35
|
+
}
|
package/src/Resolver/index.ts
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
export * from './CompositeModuleResolver'
|
|
2
2
|
export * from './ResolverEventEmitter'
|
|
3
|
-
|
|
4
|
-
/** @deprecated use ModuleResolver */
|
|
5
|
-
class SimpleModuleResolver extends CompositeModuleResolver {}
|
|
6
|
-
|
|
7
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
8
|
-
export { CompositeModuleResolver, SimpleModuleResolver }
|
|
3
|
+
export * from './SimpleModuleResolver'
|
package/src/index.ts
CHANGED