@xyo-network/sentinel 2.75.18 → 2.76.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.
- package/dist/browser/AbstractSentinel.d.cts +4 -4
- package/dist/browser/AbstractSentinel.d.cts.map +1 -1
- package/dist/browser/AbstractSentinel.d.mts +4 -4
- package/dist/browser/AbstractSentinel.d.mts.map +1 -1
- package/dist/browser/AbstractSentinel.d.ts +4 -4
- package/dist/browser/AbstractSentinel.d.ts.map +1 -1
- package/dist/browser/Automation.d.cts +2 -2
- package/dist/browser/Automation.d.cts.map +1 -1
- package/dist/browser/Automation.d.mts +2 -2
- package/dist/browser/Automation.d.mts.map +1 -1
- package/dist/browser/Automation.d.ts +2 -2
- package/dist/browser/Automation.d.ts.map +1 -1
- package/dist/browser/MemorySentinel.d.cts +1 -1
- package/dist/browser/MemorySentinel.d.cts.map +1 -1
- package/dist/browser/MemorySentinel.d.mts +1 -1
- package/dist/browser/MemorySentinel.d.mts.map +1 -1
- package/dist/browser/MemorySentinel.d.ts +1 -1
- package/dist/browser/MemorySentinel.d.ts.map +1 -1
- package/dist/browser/index.cjs +64 -46
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.js +68 -51
- package/dist/browser/index.js.map +1 -1
- package/dist/node/AbstractSentinel.d.cts +4 -4
- package/dist/node/AbstractSentinel.d.cts.map +1 -1
- package/dist/node/AbstractSentinel.d.mts +4 -4
- package/dist/node/AbstractSentinel.d.mts.map +1 -1
- package/dist/node/AbstractSentinel.d.ts +4 -4
- package/dist/node/AbstractSentinel.d.ts.map +1 -1
- package/dist/node/Automation.d.cts +2 -2
- package/dist/node/Automation.d.cts.map +1 -1
- package/dist/node/Automation.d.mts +2 -2
- package/dist/node/Automation.d.mts.map +1 -1
- package/dist/node/Automation.d.ts +2 -2
- package/dist/node/Automation.d.ts.map +1 -1
- package/dist/node/MemorySentinel.d.cts +1 -1
- package/dist/node/MemorySentinel.d.cts.map +1 -1
- package/dist/node/MemorySentinel.d.mts +1 -1
- package/dist/node/MemorySentinel.d.mts.map +1 -1
- package/dist/node/MemorySentinel.d.ts +1 -1
- package/dist/node/MemorySentinel.d.ts.map +1 -1
- package/dist/node/index.js +64 -48
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +68 -53
- package/dist/node/index.mjs.map +1 -1
- package/package.json +26 -32
- package/src/AbstractSentinel.ts +30 -28
- package/src/Automation.ts +2 -2
- package/src/MemorySentinel.ts +43 -36
- package/dist/docs.json +0 -60017
package/dist/node/index.js
CHANGED
|
@@ -32,14 +32,17 @@ module.exports = __toCommonJS(src_exports);
|
|
|
32
32
|
|
|
33
33
|
// src/AbstractSentinel.ts
|
|
34
34
|
var import_assert = require("@xylabs/assert");
|
|
35
|
-
var import_lodash = require("@xylabs/lodash");
|
|
36
35
|
var import_boundwitness_builder = require("@xyo-network/boundwitness-builder");
|
|
37
36
|
var import_boundwitness_model = require("@xyo-network/boundwitness-model");
|
|
38
37
|
var import_module_abstract = require("@xyo-network/module-abstract");
|
|
39
38
|
var import_sentinel_model = require("@xyo-network/sentinel-model");
|
|
40
|
-
var import_witness_model = require("@xyo-network/witness-model");
|
|
41
39
|
var AbstractSentinel = class extends import_module_abstract.AbstractModuleInstance {
|
|
42
40
|
history = [];
|
|
41
|
+
_jobPromise;
|
|
42
|
+
get jobPromise() {
|
|
43
|
+
this._jobPromise = this._jobPromise ?? this.generateJob();
|
|
44
|
+
return this._jobPromise;
|
|
45
|
+
}
|
|
43
46
|
get queries() {
|
|
44
47
|
return [import_sentinel_model.SentinelReportQuerySchema, ...super.queries];
|
|
45
48
|
}
|
|
@@ -48,9 +51,6 @@ var AbstractSentinel = class extends import_module_abstract.AbstractModuleInstan
|
|
|
48
51
|
"network.xyo.query.sentinel.report": "1/1"
|
|
49
52
|
};
|
|
50
53
|
}
|
|
51
|
-
addWitness(address) {
|
|
52
|
-
this.config.witnesses = (0, import_lodash.uniq)([...address, ...this.config.witnesses ?? []]);
|
|
53
|
-
}
|
|
54
54
|
async report(inPayloads) {
|
|
55
55
|
this._noOverride("report");
|
|
56
56
|
await this.emit("reportStart", { inPayloads, module: this });
|
|
@@ -61,23 +61,27 @@ var AbstractSentinel = class extends import_module_abstract.AbstractModuleInstan
|
|
|
61
61
|
await this.emit("reportEnd", { boundwitness, inPayloads, module: this, outPayloads });
|
|
62
62
|
return payloads;
|
|
63
63
|
}
|
|
64
|
-
async
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
64
|
+
async generateJob() {
|
|
65
|
+
const job = { tasks: [] };
|
|
66
|
+
let tasks = await Promise.all(
|
|
67
|
+
this.config.tasks.map(async (task) => ({
|
|
68
|
+
input: task.input ?? false,
|
|
69
|
+
module: (0, import_assert.assertEx)(await this.resolve(task.module), `Unable to resolve task module [${task.module}]`)
|
|
70
|
+
}))
|
|
71
|
+
);
|
|
72
|
+
while (tasks.length) {
|
|
73
|
+
const previousTasks = job.tasks.length ? job.tasks[job.tasks.length - 1] : [];
|
|
74
|
+
const newList = (
|
|
75
|
+
//add all tasks that either require no previous input or have the previous input module already added
|
|
76
|
+
tasks.filter(
|
|
77
|
+
(task) => typeof task.input === "boolean" || previousTasks.find((prevTask) => prevTask.module.address === task.input || prevTask.module.config.name === task.input)
|
|
78
|
+
)
|
|
79
|
+
);
|
|
80
|
+
(0, import_assert.assertEx)(newList.length > 0, `Unable to generateJob [${tasks.length}]`);
|
|
81
|
+
job.tasks.push(newList);
|
|
82
|
+
tasks = tasks.filter((task) => !newList.includes(task));
|
|
75
83
|
}
|
|
76
|
-
|
|
77
|
-
var _a2;
|
|
78
|
-
(_a2 = this.logger) == null ? void 0 : _a2.debug(`witnesses:result: ${item.config.schema}`);
|
|
79
|
-
});
|
|
80
|
-
return result;
|
|
84
|
+
return job;
|
|
81
85
|
}
|
|
82
86
|
async queryHandler(query, payloads, queryConfig) {
|
|
83
87
|
const wrapper = import_boundwitness_builder.QueryBoundWitnessWrapper.parseQuery(query, payloads);
|
|
@@ -101,38 +105,50 @@ var AbstractSentinel = class extends import_module_abstract.AbstractModuleInstan
|
|
|
101
105
|
var SentinelAutomationSchema = "network.xyo.automation";
|
|
102
106
|
|
|
103
107
|
// src/MemorySentinel.ts
|
|
104
|
-
var import_assert2 = require("@xylabs/assert");
|
|
105
108
|
var import_promise = require("@xylabs/promise");
|
|
106
|
-
var
|
|
109
|
+
var import_diviner_model = require("@xyo-network/diviner-model");
|
|
107
110
|
var import_sentinel_model2 = require("@xyo-network/sentinel-model");
|
|
111
|
+
var import_witness_model = require("@xyo-network/witness-model");
|
|
108
112
|
var MemorySentinel = class extends AbstractSentinel {
|
|
109
113
|
static configSchemas = [import_sentinel_model2.SentinelConfigSchema];
|
|
110
|
-
async reportHandler(
|
|
114
|
+
async reportHandler(inPayloads = []) {
|
|
111
115
|
await this.started("throw");
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
if (this.config.passthrough) {
|
|
120
|
-
resultPayloads.push(...payloads);
|
|
121
|
-
}
|
|
122
|
-
} catch (ex) {
|
|
123
|
-
(0, import_error.handleError)(ex, (error) => {
|
|
124
|
-
errors.push(error);
|
|
125
|
-
});
|
|
116
|
+
const job = await this.jobPromise;
|
|
117
|
+
let index = 0;
|
|
118
|
+
let previousResults = {};
|
|
119
|
+
while (index < job.tasks.length) {
|
|
120
|
+
const generatedPayloads = await this.generateResults(job.tasks[index], previousResults, inPayloads);
|
|
121
|
+
previousResults = generatedPayloads;
|
|
122
|
+
index++;
|
|
126
123
|
}
|
|
127
|
-
|
|
128
|
-
this.history.push((0, import_assert2.assertEx)(boundWitness));
|
|
129
|
-
return [boundWitness, ...resultPayloads];
|
|
124
|
+
return Object.values(previousResults).flat();
|
|
130
125
|
}
|
|
131
|
-
async generateResults(
|
|
132
|
-
const results = await Promise.allSettled(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
126
|
+
async generateResults(tasks, previousResults, inPayloads) {
|
|
127
|
+
const results = await Promise.allSettled(
|
|
128
|
+
tasks == null ? void 0 : tasks.map(async (task) => {
|
|
129
|
+
const witness = (0, import_witness_model.asWitnessInstance)(task.module);
|
|
130
|
+
const input = task.input ?? false;
|
|
131
|
+
if (witness) {
|
|
132
|
+
return [witness.address, await witness.observe(input === true ? inPayloads : input === false ? [] : previousResults[input])];
|
|
133
|
+
}
|
|
134
|
+
const diviner = (0, import_diviner_model.asDivinerInstance)(task.module);
|
|
135
|
+
if (diviner) {
|
|
136
|
+
return [diviner.address, await diviner.divine(input === true ? inPayloads : input === false ? [] : previousResults[input])];
|
|
137
|
+
}
|
|
138
|
+
throw Error("Unsupported module type");
|
|
139
|
+
})
|
|
140
|
+
);
|
|
141
|
+
const finalResult = {};
|
|
142
|
+
results.filter(import_promise.fulfilled).forEach((result) => {
|
|
143
|
+
const [address, payloads] = result.value;
|
|
144
|
+
finalResult[address] = finalResult[address] ?? [];
|
|
145
|
+
finalResult[address].push(...payloads);
|
|
146
|
+
});
|
|
147
|
+
const errors = results.filter(import_promise.rejected).map((result) => result.reason);
|
|
148
|
+
if (errors.length > 0) {
|
|
149
|
+
throw Error("At least one module failed");
|
|
150
|
+
}
|
|
151
|
+
return finalResult;
|
|
136
152
|
}
|
|
137
153
|
};
|
|
138
154
|
|
|
@@ -181,7 +197,7 @@ var SentinelIntervalAutomationWrapper = class extends import_payload_wrapper.Pay
|
|
|
181
197
|
};
|
|
182
198
|
|
|
183
199
|
// src/SentinelRunner.ts
|
|
184
|
-
var
|
|
200
|
+
var import_assert2 = require("@xylabs/assert");
|
|
185
201
|
var import_payload_wrapper2 = require("@xyo-network/payload-wrapper");
|
|
186
202
|
var SentinelRunner = class {
|
|
187
203
|
_automations = {};
|
|
@@ -227,7 +243,7 @@ var SentinelRunner = class {
|
|
|
227
243
|
await this.start();
|
|
228
244
|
}
|
|
229
245
|
async start() {
|
|
230
|
-
(0,
|
|
246
|
+
(0, import_assert2.assertEx)(this.timeoutId === void 0, "Already started");
|
|
231
247
|
const automation = this.next;
|
|
232
248
|
if (automation) {
|
|
233
249
|
const delay = automation.start - Date.now();
|
package/dist/node/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts","../../src/AbstractSentinel.ts","../../src/Automation.ts","../../src/MemorySentinel.ts","../../src/SentinelIntervalAutomationWrapper.ts","../../src/SentinelRunner.ts","../../src/Wrapper.ts"],"sourcesContent":["export * from './AbstractSentinel'\nexport * from './Automation'\nexport * from './MemorySentinel'\nexport * from './SentinelIntervalAutomationWrapper'\nexport * from './SentinelRunner'\nexport * from './Wrapper'\nexport * from '@xyo-network/sentinel-model'\n","import { assertEx } from '@xylabs/assert'\nimport { uniq } from '@xylabs/lodash'\nimport { QueryBoundWitnessWrapper } from '@xyo-network/boundwitness-builder'\nimport { BoundWitness, isBoundWitness, notBoundWitness, QueryBoundWitness } from '@xyo-network/boundwitness-model'\nimport { AbstractModuleInstance } from '@xyo-network/module-abstract'\nimport { ModuleConfig, ModuleQueryHandlerResult } from '@xyo-network/module-model'\nimport { Payload } from '@xyo-network/payload-model'\nimport {\n CustomSentinelInstance,\n SentinelInstance,\n SentinelModuleEventData,\n SentinelParams,\n SentinelQueryBase,\n SentinelReportQuerySchema,\n} from '@xyo-network/sentinel-model'\nimport { isWitnessInstance, WitnessInstance } from '@xyo-network/witness-model'\n\nexport abstract class AbstractSentinel<\n TParams extends SentinelParams = SentinelParams,\n TEventData extends SentinelModuleEventData<SentinelInstance<TParams>> = SentinelModuleEventData<SentinelInstance<TParams>>,\n >\n extends AbstractModuleInstance<TParams, TEventData>\n implements CustomSentinelInstance<TParams, TEventData>\n{\n history: BoundWitness[] = []\n\n override get queries(): string[] {\n return [SentinelReportQuerySchema, ...super.queries]\n }\n\n protected override get _queryAccountPaths(): Record<SentinelQueryBase['schema'], string> {\n return {\n 'network.xyo.query.sentinel.report': '1/1',\n }\n }\n\n addWitness(address: string[]) {\n this.config.witnesses = uniq([...address, ...(this.config.witnesses ?? [])])\n }\n\n async report(inPayloads?: Payload[]): Promise<Payload[]> {\n this._noOverride('report')\n await this.emit('reportStart', { inPayloads, module: this })\n const payloads = await this.reportHandler(inPayloads)\n //this.logger?.debug(`report:payloads: ${JSON.stringify(payloads, null, 2)}`)\n const boundwitnesses = payloads.filter(isBoundWitness)\n const outPayloads = payloads.filter(notBoundWitness)\n const boundwitness = boundwitnesses.find((bw) => bw.addresses.includes(this.address))\n await this.emit('reportEnd', { boundwitness, inPayloads, module: this, outPayloads })\n return payloads\n }\n\n async witnesses() {\n this.logger?.debug(`witnesses:config:witnesses: ${this.config?.witnesses?.length}`)\n const namesOrAddresses = this.config?.witnesses\n ? Array.isArray(this.config.witnesses)\n ? this.config?.witnesses\n : [this.config.witnesses]\n : undefined\n this.logger?.debug(`witnesses:namesOrAddresses: ${namesOrAddresses?.length}`)\n const result = namesOrAddresses\n ? [\n ...(await this.resolve<WitnessInstance>({ address: namesOrAddresses }, { identity: isWitnessInstance })),\n ...(await this.resolve<WitnessInstance>({ name: namesOrAddresses }, { identity: isWitnessInstance })),\n ]\n : await this.resolve<WitnessInstance>(undefined, { identity: isWitnessInstance })\n\n if (namesOrAddresses && namesOrAddresses.length !== result.length) {\n this.logger?.warn(`Not all witnesses found [Requested: ${namesOrAddresses.length}, Found: ${result.length}]`)\n }\n result.map((item) => {\n this.logger?.debug(`witnesses:result: ${item.config.schema}`)\n })\n\n return result\n }\n\n protected override async queryHandler<T extends QueryBoundWitness = QueryBoundWitness, TConfig extends ModuleConfig = ModuleConfig>(\n query: T,\n payloads?: Payload[],\n queryConfig?: TConfig,\n ): Promise<ModuleQueryHandlerResult> {\n const wrapper = QueryBoundWitnessWrapper.parseQuery<SentinelQueryBase>(query, payloads)\n const queryPayload = await wrapper.getQuery()\n assertEx(this.queryable(query, payloads, queryConfig))\n const resultPayloads: Payload[] = []\n switch (queryPayload.schema) {\n case SentinelReportQuerySchema: {\n resultPayloads.push(...(await this.report(payloads)))\n break\n }\n default: {\n return super.queryHandler(query, payloads)\n }\n }\n return resultPayloads\n }\n\n abstract reportHandler(payloads?: Payload[]): Promise<Payload[]>\n}\n","import { AnyObject } from '@xyo-network/core'\nimport { Payload } from '@xyo-network/payload-model'\n\nexport type SentinelAutomationSchema = 'network.xyo.automation'\nexport const SentinelAutomationSchema: SentinelAutomationSchema = 'network.xyo.automation'\n\nexport type SentinelBaseAutomationPayload<T extends AnyObject = AnyObject> = Payload<\n T & {\n schema: SentinelAutomationSchema\n type?: 'interval' | 'change'\n /** @field The list of witnesses to invoke [all if undefined] */\n witnesses?: string[]\n }\n>\n\nexport type SentinelIntervalAutomationPayload = SentinelBaseAutomationPayload<{\n /** @field epoch after which any reoccurrence stops */\n end?: number\n\n /** @field time between triggers [non-repeating if undefined] */\n frequency?: number\n\n /** @field units for frequency field [hour if undefined] */\n frequencyUnits?: 'second' | 'minute' | 'hour' | 'day'\n\n /** @field remaining triggers [infinite if undefined] */\n remaining?: number\n\n /** @field epoch of the next trigger */\n start: number\n\n type: 'interval'\n}>\n\nexport type SentinelChangeAutomationPayload = SentinelBaseAutomationPayload<{\n type: 'change'\n}>\n\nexport type SentinelAutomationPayload = SentinelIntervalAutomationPayload | SentinelChangeAutomationPayload\n","import { assertEx } from '@xylabs/assert'\nimport { fulfilled, rejected } from '@xylabs/promise'\nimport { handleError } from '@xyo-network/error'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { Payload } from '@xyo-network/payload-model'\nimport {\n SentinelConfig,\n SentinelConfigSchema,\n SentinelInstance,\n SentinelModuleEventData,\n SentinelParams,\n SentinelReportQuerySchema,\n} from '@xyo-network/sentinel-model'\nimport { WitnessInstance } from '@xyo-network/witness-model'\n\nimport { AbstractSentinel } from './AbstractSentinel'\n\nexport type MemorySentinelParams<TConfig extends AnyConfigSchema<SentinelConfig> = AnyConfigSchema<SentinelConfig>> = SentinelParams<TConfig>\n\nexport class MemorySentinel<\n TParams extends MemorySentinelParams = MemorySentinelParams,\n TEventData extends SentinelModuleEventData<SentinelInstance<TParams>> = SentinelModuleEventData<SentinelInstance<TParams>>,\n> extends AbstractSentinel<TParams, TEventData> {\n static override configSchemas = [SentinelConfigSchema]\n\n async reportHandler(payloads: Payload[] = []): Promise<Payload[]> {\n await this.started('throw')\n const errors: Error[] = []\n const allWitnesses = [...(await this.witnesses())]\n const resultPayloads: Payload[] = []\n\n try {\n const [generatedPayloads, generatedErrors] = await this.generateResults(allWitnesses, payloads)\n resultPayloads.push(...generatedPayloads)\n errors.push(...generatedErrors)\n if (this.config.passthrough) {\n resultPayloads.push(...payloads)\n }\n } catch (ex) {\n handleError(ex, (error) => {\n errors.push(error)\n })\n }\n\n const [boundWitness] = await this.bindQueryResult({ schema: SentinelReportQuerySchema }, resultPayloads)\n this.history.push(assertEx(boundWitness))\n return [boundWitness, ...resultPayloads]\n }\n\n private async generateResults(witnesses: WitnessInstance[], inPayloads?: Payload[]): Promise<[Payload[], Error[]]> {\n const results: PromiseSettledResult<Payload[]>[] = await Promise.allSettled(witnesses?.map((witness) => witness.observe(inPayloads)))\n const payloads = results\n .filter(fulfilled)\n .map((result) => result.value)\n .flat()\n const errors = results\n .filter(rejected)\n .map((result) => result.reason)\n .flat()\n // console.log(`payloads: ${JSON.stringify(payloads, null, 2)}`)\n // console.log(`errors: ${JSON.stringify(errors, null, 2)}`)\n return [payloads, errors]\n }\n}\n","import { PayloadWrapper } from '@xyo-network/payload-wrapper'\n\nimport { SentinelIntervalAutomationPayload } from './Automation'\n\nexport class SentinelIntervalAutomationWrapper<\n T extends SentinelIntervalAutomationPayload = SentinelIntervalAutomationPayload,\n> extends PayloadWrapper<T> {\n constructor(payload: T) {\n super(payload)\n }\n\n protected get frequencyMillis() {\n const frequency = this.payload().frequency\n if (frequency === undefined) return Infinity\n switch (this.payload().frequencyUnits ?? 'hour') {\n case 'second':\n return frequency * 1000\n case 'minute':\n return frequency * 60 * 1000\n case 'hour':\n return frequency * 60 * 60 * 1000\n case 'day':\n return frequency * 24 * 60 * 60 * 1000\n }\n }\n\n protected get remaining() {\n //if remaining is not defined, we assume Infinity\n return this.payload().remaining ?? Infinity\n }\n\n next() {\n this.payload().start = this.payload().start + this.frequencyMillis\n this.consumeRemaining()\n this.checkEnd()\n return this\n }\n\n protected checkEnd() {\n if (this.payload().start > (this.payload().end ?? Infinity)) {\n this.payload().start = Infinity\n }\n }\n\n protected consumeRemaining(count = 1) {\n const remaining = this.remaining - count\n this.payload().remaining = remaining\n\n if (remaining <= 0) {\n this.payload().start = Infinity\n }\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Payload } from '@xyo-network/payload-model'\nimport { PayloadWrapper } from '@xyo-network/payload-wrapper'\nimport { SentinelInstance } from '@xyo-network/sentinel-model'\n\nimport { SentinelAutomationPayload, SentinelIntervalAutomationPayload } from './Automation'\nimport { SentinelIntervalAutomationWrapper } from './SentinelIntervalAutomationWrapper'\n\nexport type OnSentinelRunnerTriggerResult = (result: Payload[]) => void\n\nexport class SentinelRunner {\n protected _automations: Record<string, SentinelAutomationPayload> = {}\n protected onTriggerResult: OnSentinelRunnerTriggerResult | undefined\n protected sentinel: SentinelInstance\n protected timeoutId?: NodeJS.Timeout | string | number\n\n constructor(sentinel: SentinelInstance, automations?: SentinelAutomationPayload[], onTriggerResult?: OnSentinelRunnerTriggerResult) {\n this.sentinel = sentinel\n this.onTriggerResult = onTriggerResult\n automations?.forEach((automation) => this.add(automation))\n }\n\n get automations() {\n return this._automations\n }\n\n private get next() {\n return Object.values(this._automations).reduce<SentinelIntervalAutomationPayload | undefined>((previous, current) => {\n if (current.type === 'interval') {\n return current.start < (previous?.start ?? Infinity) ? current : previous\n }\n }, undefined)\n }\n\n async add(automation: SentinelAutomationPayload, restart = true) {\n const hash = await PayloadWrapper.hashAsync(automation)\n this._automations[hash] = automation\n if (restart) await this.restart()\n return hash\n }\n\n find(hash: string) {\n Object.entries(this._automations).find(([key]) => key === hash)\n }\n\n async remove(hash: string, restart = true) {\n delete this._automations[hash]\n if (restart) await this.restart()\n }\n\n removeAll() {\n this.stop()\n this._automations = {}\n }\n\n async restart() {\n this.stop()\n await this.start()\n }\n\n async start() {\n assertEx(this.timeoutId === undefined, 'Already started')\n const automation = this.next\n if (automation) {\n const delay = automation.start - Date.now()\n if (delay < 0) {\n //automation is due, just do it\n await this.trigger(automation)\n } else {\n this.timeoutId = setTimeout(\n async () => {\n this.timeoutId = undefined\n await this.start()\n },\n delay > 0 ? delay : 0,\n )\n }\n }\n }\n\n stop() {\n if (this.timeoutId) {\n clearTimeout(this.timeoutId)\n this.timeoutId = undefined\n }\n }\n\n async update(hash: string, automation: SentinelAutomationPayload, restart = true) {\n await this.remove(hash, false)\n await this.add(automation, false)\n if (restart) await this.restart()\n }\n\n private async trigger(automation: SentinelIntervalAutomationPayload) {\n const wrapper = new SentinelIntervalAutomationWrapper(automation)\n await this.remove(await wrapper.hashAsync(), false)\n wrapper.next()\n await this.add(wrapper.payload(), false)\n const triggerResult = await this.sentinel.report()\n this.onTriggerResult?.(triggerResult)\n await this.start()\n }\n}\n","import { ArchivistInstance } from '@xyo-network/archivist'\nimport { constructableModuleWrapper, ModuleWrapper } from '@xyo-network/module-wrapper'\nimport { Payload } from '@xyo-network/payload-model'\nimport {\n isSentinelInstance,\n isSentinelModule,\n SentinelInstance,\n SentinelModule,\n SentinelReportQuery,\n SentinelReportQuerySchema,\n} from '@xyo-network/sentinel-model'\nimport { WitnessInstance } from '@xyo-network/witness-model'\n\nconstructableModuleWrapper()\nexport class SentinelWrapper<TModule extends SentinelModule = SentinelModule>\n extends ModuleWrapper<TModule>\n implements SentinelInstance<TModule['params']>\n{\n static override instanceIdentityCheck = isSentinelInstance\n static override moduleIdentityCheck = isSentinelModule\n static override requiredQueries = [SentinelReportQuerySchema, ...super.requiredQueries]\n\n archivists(): Promise<ArchivistInstance[]> {\n throw Error('Not supported')\n }\n\n async report(payloads?: Payload[]): Promise<Payload[]> {\n const queryPayload: SentinelReportQuery = { schema: SentinelReportQuerySchema }\n const result = await this.sendQuery(queryPayload, payloads)\n return result\n }\n\n witnesses(): Promise<WitnessInstance[]> {\n throw Error('Not supported')\n }\n}\n"],"mappings":"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","names":["_a","import_assert","import_sentinel_model","import_assert","import_payload_wrapper","import_sentinel_model"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/AbstractSentinel.ts","../../src/Automation.ts","../../src/MemorySentinel.ts","../../src/SentinelIntervalAutomationWrapper.ts","../../src/SentinelRunner.ts","../../src/Wrapper.ts"],"sourcesContent":["export * from './AbstractSentinel'\nexport * from './Automation'\nexport * from './MemorySentinel'\nexport * from './SentinelIntervalAutomationWrapper'\nexport * from './SentinelRunner'\nexport * from './Wrapper'\nexport * from '@xyo-network/sentinel-model'\n","import { assertEx } from '@xylabs/assert'\nimport { QueryBoundWitnessWrapper } from '@xyo-network/boundwitness-builder'\nimport { BoundWitness, isBoundWitness, notBoundWitness, QueryBoundWitness } from '@xyo-network/boundwitness-model'\nimport { AbstractModuleInstance } from '@xyo-network/module-abstract'\nimport { ModuleConfig, ModuleQueryHandlerResult } from '@xyo-network/module-model'\nimport { Payload } from '@xyo-network/payload-model'\nimport {\n CustomSentinelInstance,\n ResolvedSentinelTask,\n SentinelInstance,\n SentinelJob,\n SentinelModuleEventData,\n SentinelParams,\n SentinelQueryBase,\n SentinelReportQuerySchema,\n} from '@xyo-network/sentinel-model'\n\nexport abstract class AbstractSentinel<\n TParams extends SentinelParams = SentinelParams,\n TEventData extends SentinelModuleEventData<SentinelInstance<TParams>> = SentinelModuleEventData<SentinelInstance<TParams>>,\n >\n extends AbstractModuleInstance<TParams, TEventData>\n implements CustomSentinelInstance<TParams, TEventData>\n{\n history: BoundWitness[] = []\n private _jobPromise?: Promise<SentinelJob>\n\n get jobPromise() {\n this._jobPromise = this._jobPromise ?? this.generateJob()\n return this._jobPromise\n }\n\n override get queries(): string[] {\n return [SentinelReportQuerySchema, ...super.queries]\n }\n\n protected override get _queryAccountPaths(): Record<SentinelQueryBase['schema'], string> {\n return {\n 'network.xyo.query.sentinel.report': '1/1',\n }\n }\n\n async report(inPayloads?: Payload[]): Promise<Payload[]> {\n this._noOverride('report')\n await this.emit('reportStart', { inPayloads, module: this })\n const payloads = await this.reportHandler(inPayloads)\n //this.logger?.debug(`report:payloads: ${JSON.stringify(payloads, null, 2)}`)\n const boundwitnesses = payloads.filter(isBoundWitness)\n const outPayloads = payloads.filter(notBoundWitness)\n const boundwitness = boundwitnesses.find((bw) => bw.addresses.includes(this.address))\n await this.emit('reportEnd', { boundwitness, inPayloads, module: this, outPayloads })\n return payloads\n }\n\n protected async generateJob() {\n const job: SentinelJob = { tasks: [] }\n let tasks: ResolvedSentinelTask[] = await Promise.all(\n this.config.tasks.map(async (task) => ({\n input: task.input ?? false,\n module: assertEx(await this.resolve(task.module), `Unable to resolve task module [${task.module}]`),\n })),\n )\n while (tasks.length) {\n const previousTasks = job.tasks.length ? job.tasks[job.tasks.length - 1] : []\n const newList =\n //add all tasks that either require no previous input or have the previous input module already added\n tasks.filter(\n (task) =>\n typeof task.input === 'boolean' ||\n previousTasks.find((prevTask) => prevTask.module.address === task.input || prevTask.module.config.name === task.input),\n )\n assertEx(newList.length > 0, `Unable to generateJob [${tasks.length}]`)\n job.tasks.push(newList)\n //remove the tasks we just added\n tasks = tasks.filter((task) => !newList.includes(task))\n }\n return job\n }\n\n protected override async queryHandler<T extends QueryBoundWitness = QueryBoundWitness, TConfig extends ModuleConfig = ModuleConfig>(\n query: T,\n payloads?: Payload[],\n queryConfig?: TConfig,\n ): Promise<ModuleQueryHandlerResult> {\n const wrapper = QueryBoundWitnessWrapper.parseQuery<SentinelQueryBase>(query, payloads)\n const queryPayload = await wrapper.getQuery()\n assertEx(this.queryable(query, payloads, queryConfig))\n const resultPayloads: Payload[] = []\n switch (queryPayload.schema) {\n case SentinelReportQuerySchema: {\n resultPayloads.push(...(await this.report(payloads)))\n break\n }\n default: {\n return super.queryHandler(query, payloads)\n }\n }\n return resultPayloads\n }\n\n abstract reportHandler(payloads?: Payload[]): Promise<Payload[]>\n}\n","import { AnyObject } from '@xyo-network/core'\nimport { Payload } from '@xyo-network/payload-model'\nimport { SentinelTask } from '@xyo-network/sentinel-model'\n\nexport type SentinelAutomationSchema = 'network.xyo.automation'\nexport const SentinelAutomationSchema: SentinelAutomationSchema = 'network.xyo.automation'\n\nexport type SentinelBaseAutomationPayload<T extends AnyObject = AnyObject> = Payload<\n T & {\n schema: SentinelAutomationSchema\n tasks?: SentinelTask[]\n type?: 'interval' | 'change'\n }\n>\n\nexport type SentinelIntervalAutomationPayload = SentinelBaseAutomationPayload<{\n /** @field epoch after which any reoccurrence stops */\n end?: number\n\n /** @field time between triggers [non-repeating if undefined] */\n frequency?: number\n\n /** @field units for frequency field [hour if undefined] */\n frequencyUnits?: 'second' | 'minute' | 'hour' | 'day'\n\n /** @field remaining triggers [infinite if undefined] */\n remaining?: number\n\n /** @field epoch of the next trigger */\n start: number\n\n type: 'interval'\n}>\n\nexport type SentinelChangeAutomationPayload = SentinelBaseAutomationPayload<{\n type: 'change'\n}>\n\nexport type SentinelAutomationPayload = SentinelIntervalAutomationPayload | SentinelChangeAutomationPayload\n","import { fulfilled, rejected } from '@xylabs/promise'\nimport { Address } from '@xyo-network/core'\nimport { asDivinerInstance } from '@xyo-network/diviner-model'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { Payload } from '@xyo-network/payload-model'\nimport {\n ResolvedSentinelTask,\n SentinelConfig,\n SentinelConfigSchema,\n SentinelInstance,\n SentinelModuleEventData,\n SentinelParams,\n} from '@xyo-network/sentinel-model'\nimport { asWitnessInstance } from '@xyo-network/witness-model'\n\nimport { AbstractSentinel } from './AbstractSentinel'\n\nexport type MemorySentinelParams<TConfig extends AnyConfigSchema<SentinelConfig> = AnyConfigSchema<SentinelConfig>> = SentinelParams<TConfig>\n\nexport class MemorySentinel<\n TParams extends MemorySentinelParams = MemorySentinelParams,\n TEventData extends SentinelModuleEventData<SentinelInstance<TParams>> = SentinelModuleEventData<SentinelInstance<TParams>>,\n> extends AbstractSentinel<TParams, TEventData> {\n static override configSchemas = [SentinelConfigSchema]\n\n async reportHandler(inPayloads: Payload[] = []): Promise<Payload[]> {\n await this.started('throw')\n const job = await this.jobPromise\n\n let index = 0\n let previousResults: Record<Address, Payload[]> = {}\n while (index < job.tasks.length) {\n const generatedPayloads = await this.generateResults(job.tasks[index], previousResults, inPayloads)\n previousResults = generatedPayloads\n index++\n }\n return Object.values(previousResults).flat()\n }\n\n private async generateResults(\n tasks: ResolvedSentinelTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n const results: PromiseSettledResult<[Address, Payload[]]>[] = await Promise.allSettled(\n tasks?.map(async (task) => {\n const witness = asWitnessInstance(task.module)\n const input = task.input ?? false\n if (witness) {\n return [witness.address, await witness.observe(input === true ? inPayloads : input === false ? [] : previousResults[input])]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n return [diviner.address, await diviner.divine(input === true ? inPayloads : input === false ? [] : previousResults[input])]\n }\n throw Error('Unsupported module type')\n }),\n )\n const finalResult: Record<Address, Payload[]> = {}\n results.filter(fulfilled).forEach((result) => {\n const [address, payloads] = result.value\n finalResult[address] = finalResult[address] ?? []\n finalResult[address].push(...payloads)\n })\n const errors = results.filter(rejected).map((result) => result.reason)\n if (errors.length > 0) {\n throw Error('At least one module failed')\n }\n return finalResult\n }\n}\n","import { PayloadWrapper } from '@xyo-network/payload-wrapper'\n\nimport { SentinelIntervalAutomationPayload } from './Automation'\n\nexport class SentinelIntervalAutomationWrapper<\n T extends SentinelIntervalAutomationPayload = SentinelIntervalAutomationPayload,\n> extends PayloadWrapper<T> {\n constructor(payload: T) {\n super(payload)\n }\n\n protected get frequencyMillis() {\n const frequency = this.payload().frequency\n if (frequency === undefined) return Infinity\n switch (this.payload().frequencyUnits ?? 'hour') {\n case 'second':\n return frequency * 1000\n case 'minute':\n return frequency * 60 * 1000\n case 'hour':\n return frequency * 60 * 60 * 1000\n case 'day':\n return frequency * 24 * 60 * 60 * 1000\n }\n }\n\n protected get remaining() {\n //if remaining is not defined, we assume Infinity\n return this.payload().remaining ?? Infinity\n }\n\n next() {\n this.payload().start = this.payload().start + this.frequencyMillis\n this.consumeRemaining()\n this.checkEnd()\n return this\n }\n\n protected checkEnd() {\n if (this.payload().start > (this.payload().end ?? Infinity)) {\n this.payload().start = Infinity\n }\n }\n\n protected consumeRemaining(count = 1) {\n const remaining = this.remaining - count\n this.payload().remaining = remaining\n\n if (remaining <= 0) {\n this.payload().start = Infinity\n }\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Payload } from '@xyo-network/payload-model'\nimport { PayloadWrapper } from '@xyo-network/payload-wrapper'\nimport { SentinelInstance } from '@xyo-network/sentinel-model'\n\nimport { SentinelAutomationPayload, SentinelIntervalAutomationPayload } from './Automation'\nimport { SentinelIntervalAutomationWrapper } from './SentinelIntervalAutomationWrapper'\n\nexport type OnSentinelRunnerTriggerResult = (result: Payload[]) => void\n\nexport class SentinelRunner {\n protected _automations: Record<string, SentinelAutomationPayload> = {}\n protected onTriggerResult: OnSentinelRunnerTriggerResult | undefined\n protected sentinel: SentinelInstance\n protected timeoutId?: NodeJS.Timeout | string | number\n\n constructor(sentinel: SentinelInstance, automations?: SentinelAutomationPayload[], onTriggerResult?: OnSentinelRunnerTriggerResult) {\n this.sentinel = sentinel\n this.onTriggerResult = onTriggerResult\n automations?.forEach((automation) => this.add(automation))\n }\n\n get automations() {\n return this._automations\n }\n\n private get next() {\n return Object.values(this._automations).reduce<SentinelIntervalAutomationPayload | undefined>((previous, current) => {\n if (current.type === 'interval') {\n return current.start < (previous?.start ?? Infinity) ? current : previous\n }\n }, undefined)\n }\n\n async add(automation: SentinelAutomationPayload, restart = true) {\n const hash = await PayloadWrapper.hashAsync(automation)\n this._automations[hash] = automation\n if (restart) await this.restart()\n return hash\n }\n\n find(hash: string) {\n Object.entries(this._automations).find(([key]) => key === hash)\n }\n\n async remove(hash: string, restart = true) {\n delete this._automations[hash]\n if (restart) await this.restart()\n }\n\n removeAll() {\n this.stop()\n this._automations = {}\n }\n\n async restart() {\n this.stop()\n await this.start()\n }\n\n async start() {\n assertEx(this.timeoutId === undefined, 'Already started')\n const automation = this.next\n if (automation) {\n const delay = automation.start - Date.now()\n if (delay < 0) {\n //automation is due, just do it\n await this.trigger(automation)\n } else {\n this.timeoutId = setTimeout(\n async () => {\n this.timeoutId = undefined\n await this.start()\n },\n delay > 0 ? delay : 0,\n )\n }\n }\n }\n\n stop() {\n if (this.timeoutId) {\n clearTimeout(this.timeoutId)\n this.timeoutId = undefined\n }\n }\n\n async update(hash: string, automation: SentinelAutomationPayload, restart = true) {\n await this.remove(hash, false)\n await this.add(automation, false)\n if (restart) await this.restart()\n }\n\n private async trigger(automation: SentinelIntervalAutomationPayload) {\n const wrapper = new SentinelIntervalAutomationWrapper(automation)\n await this.remove(await wrapper.hashAsync(), false)\n wrapper.next()\n await this.add(wrapper.payload(), false)\n const triggerResult = await this.sentinel.report()\n this.onTriggerResult?.(triggerResult)\n await this.start()\n }\n}\n","import { ArchivistInstance } from '@xyo-network/archivist'\nimport { constructableModuleWrapper, ModuleWrapper } from '@xyo-network/module-wrapper'\nimport { Payload } from '@xyo-network/payload-model'\nimport {\n isSentinelInstance,\n isSentinelModule,\n SentinelInstance,\n SentinelModule,\n SentinelReportQuery,\n SentinelReportQuerySchema,\n} from '@xyo-network/sentinel-model'\nimport { WitnessInstance } from '@xyo-network/witness-model'\n\nconstructableModuleWrapper()\nexport class SentinelWrapper<TModule extends SentinelModule = SentinelModule>\n extends ModuleWrapper<TModule>\n implements SentinelInstance<TModule['params']>\n{\n static override instanceIdentityCheck = isSentinelInstance\n static override moduleIdentityCheck = isSentinelModule\n static override requiredQueries = [SentinelReportQuerySchema, ...super.requiredQueries]\n\n archivists(): Promise<ArchivistInstance[]> {\n throw Error('Not supported')\n }\n\n async report(payloads?: Payload[]): Promise<Payload[]> {\n const queryPayload: SentinelReportQuery = { schema: SentinelReportQuerySchema }\n const result = await this.sendQuery(queryPayload, payloads)\n return result\n }\n\n witnesses(): Promise<WitnessInstance[]> {\n throw Error('Not supported')\n }\n}\n"],"mappings":"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","names":["import_sentinel_model","import_assert","import_payload_wrapper","import_sentinel_model"]}
|
package/dist/node/index.mjs
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
// src/AbstractSentinel.ts
|
|
2
2
|
import { assertEx } from "@xylabs/assert";
|
|
3
|
-
import { uniq } from "@xylabs/lodash";
|
|
4
3
|
import { QueryBoundWitnessWrapper } from "@xyo-network/boundwitness-builder";
|
|
5
4
|
import { isBoundWitness, notBoundWitness } from "@xyo-network/boundwitness-model";
|
|
6
5
|
import { AbstractModuleInstance } from "@xyo-network/module-abstract";
|
|
7
6
|
import {
|
|
8
7
|
SentinelReportQuerySchema
|
|
9
8
|
} from "@xyo-network/sentinel-model";
|
|
10
|
-
import { isWitnessInstance } from "@xyo-network/witness-model";
|
|
11
9
|
var AbstractSentinel = class extends AbstractModuleInstance {
|
|
12
10
|
history = [];
|
|
11
|
+
_jobPromise;
|
|
12
|
+
get jobPromise() {
|
|
13
|
+
this._jobPromise = this._jobPromise ?? this.generateJob();
|
|
14
|
+
return this._jobPromise;
|
|
15
|
+
}
|
|
13
16
|
get queries() {
|
|
14
17
|
return [SentinelReportQuerySchema, ...super.queries];
|
|
15
18
|
}
|
|
@@ -18,9 +21,6 @@ var AbstractSentinel = class extends AbstractModuleInstance {
|
|
|
18
21
|
"network.xyo.query.sentinel.report": "1/1"
|
|
19
22
|
};
|
|
20
23
|
}
|
|
21
|
-
addWitness(address) {
|
|
22
|
-
this.config.witnesses = uniq([...address, ...this.config.witnesses ?? []]);
|
|
23
|
-
}
|
|
24
24
|
async report(inPayloads) {
|
|
25
25
|
this._noOverride("report");
|
|
26
26
|
await this.emit("reportStart", { inPayloads, module: this });
|
|
@@ -31,23 +31,27 @@ var AbstractSentinel = class extends AbstractModuleInstance {
|
|
|
31
31
|
await this.emit("reportEnd", { boundwitness, inPayloads, module: this, outPayloads });
|
|
32
32
|
return payloads;
|
|
33
33
|
}
|
|
34
|
-
async
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
34
|
+
async generateJob() {
|
|
35
|
+
const job = { tasks: [] };
|
|
36
|
+
let tasks = await Promise.all(
|
|
37
|
+
this.config.tasks.map(async (task) => ({
|
|
38
|
+
input: task.input ?? false,
|
|
39
|
+
module: assertEx(await this.resolve(task.module), `Unable to resolve task module [${task.module}]`)
|
|
40
|
+
}))
|
|
41
|
+
);
|
|
42
|
+
while (tasks.length) {
|
|
43
|
+
const previousTasks = job.tasks.length ? job.tasks[job.tasks.length - 1] : [];
|
|
44
|
+
const newList = (
|
|
45
|
+
//add all tasks that either require no previous input or have the previous input module already added
|
|
46
|
+
tasks.filter(
|
|
47
|
+
(task) => typeof task.input === "boolean" || previousTasks.find((prevTask) => prevTask.module.address === task.input || prevTask.module.config.name === task.input)
|
|
48
|
+
)
|
|
49
|
+
);
|
|
50
|
+
assertEx(newList.length > 0, `Unable to generateJob [${tasks.length}]`);
|
|
51
|
+
job.tasks.push(newList);
|
|
52
|
+
tasks = tasks.filter((task) => !newList.includes(task));
|
|
45
53
|
}
|
|
46
|
-
|
|
47
|
-
var _a2;
|
|
48
|
-
(_a2 = this.logger) == null ? void 0 : _a2.debug(`witnesses:result: ${item.config.schema}`);
|
|
49
|
-
});
|
|
50
|
-
return result;
|
|
54
|
+
return job;
|
|
51
55
|
}
|
|
52
56
|
async queryHandler(query, payloads, queryConfig) {
|
|
53
57
|
const wrapper = QueryBoundWitnessWrapper.parseQuery(query, payloads);
|
|
@@ -71,41 +75,52 @@ var AbstractSentinel = class extends AbstractModuleInstance {
|
|
|
71
75
|
var SentinelAutomationSchema = "network.xyo.automation";
|
|
72
76
|
|
|
73
77
|
// src/MemorySentinel.ts
|
|
74
|
-
import { assertEx as assertEx2 } from "@xylabs/assert";
|
|
75
78
|
import { fulfilled, rejected } from "@xylabs/promise";
|
|
76
|
-
import {
|
|
79
|
+
import { asDivinerInstance } from "@xyo-network/diviner-model";
|
|
77
80
|
import {
|
|
78
|
-
SentinelConfigSchema
|
|
79
|
-
SentinelReportQuerySchema as SentinelReportQuerySchema2
|
|
81
|
+
SentinelConfigSchema
|
|
80
82
|
} from "@xyo-network/sentinel-model";
|
|
83
|
+
import { asWitnessInstance } from "@xyo-network/witness-model";
|
|
81
84
|
var MemorySentinel = class extends AbstractSentinel {
|
|
82
85
|
static configSchemas = [SentinelConfigSchema];
|
|
83
|
-
async reportHandler(
|
|
86
|
+
async reportHandler(inPayloads = []) {
|
|
84
87
|
await this.started("throw");
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (this.config.passthrough) {
|
|
93
|
-
resultPayloads.push(...payloads);
|
|
94
|
-
}
|
|
95
|
-
} catch (ex) {
|
|
96
|
-
handleError(ex, (error) => {
|
|
97
|
-
errors.push(error);
|
|
98
|
-
});
|
|
88
|
+
const job = await this.jobPromise;
|
|
89
|
+
let index = 0;
|
|
90
|
+
let previousResults = {};
|
|
91
|
+
while (index < job.tasks.length) {
|
|
92
|
+
const generatedPayloads = await this.generateResults(job.tasks[index], previousResults, inPayloads);
|
|
93
|
+
previousResults = generatedPayloads;
|
|
94
|
+
index++;
|
|
99
95
|
}
|
|
100
|
-
|
|
101
|
-
this.history.push(assertEx2(boundWitness));
|
|
102
|
-
return [boundWitness, ...resultPayloads];
|
|
96
|
+
return Object.values(previousResults).flat();
|
|
103
97
|
}
|
|
104
|
-
async generateResults(
|
|
105
|
-
const results = await Promise.allSettled(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
98
|
+
async generateResults(tasks, previousResults, inPayloads) {
|
|
99
|
+
const results = await Promise.allSettled(
|
|
100
|
+
tasks == null ? void 0 : tasks.map(async (task) => {
|
|
101
|
+
const witness = asWitnessInstance(task.module);
|
|
102
|
+
const input = task.input ?? false;
|
|
103
|
+
if (witness) {
|
|
104
|
+
return [witness.address, await witness.observe(input === true ? inPayloads : input === false ? [] : previousResults[input])];
|
|
105
|
+
}
|
|
106
|
+
const diviner = asDivinerInstance(task.module);
|
|
107
|
+
if (diviner) {
|
|
108
|
+
return [diviner.address, await diviner.divine(input === true ? inPayloads : input === false ? [] : previousResults[input])];
|
|
109
|
+
}
|
|
110
|
+
throw Error("Unsupported module type");
|
|
111
|
+
})
|
|
112
|
+
);
|
|
113
|
+
const finalResult = {};
|
|
114
|
+
results.filter(fulfilled).forEach((result) => {
|
|
115
|
+
const [address, payloads] = result.value;
|
|
116
|
+
finalResult[address] = finalResult[address] ?? [];
|
|
117
|
+
finalResult[address].push(...payloads);
|
|
118
|
+
});
|
|
119
|
+
const errors = results.filter(rejected).map((result) => result.reason);
|
|
120
|
+
if (errors.length > 0) {
|
|
121
|
+
throw Error("At least one module failed");
|
|
122
|
+
}
|
|
123
|
+
return finalResult;
|
|
109
124
|
}
|
|
110
125
|
};
|
|
111
126
|
|
|
@@ -154,7 +169,7 @@ var SentinelIntervalAutomationWrapper = class extends PayloadWrapper {
|
|
|
154
169
|
};
|
|
155
170
|
|
|
156
171
|
// src/SentinelRunner.ts
|
|
157
|
-
import { assertEx as
|
|
172
|
+
import { assertEx as assertEx2 } from "@xylabs/assert";
|
|
158
173
|
import { PayloadWrapper as PayloadWrapper2 } from "@xyo-network/payload-wrapper";
|
|
159
174
|
var SentinelRunner = class {
|
|
160
175
|
_automations = {};
|
|
@@ -200,7 +215,7 @@ var SentinelRunner = class {
|
|
|
200
215
|
await this.start();
|
|
201
216
|
}
|
|
202
217
|
async start() {
|
|
203
|
-
|
|
218
|
+
assertEx2(this.timeoutId === void 0, "Already started");
|
|
204
219
|
const automation = this.next;
|
|
205
220
|
if (automation) {
|
|
206
221
|
const delay = automation.start - Date.now();
|
|
@@ -246,18 +261,18 @@ import { constructableModuleWrapper, ModuleWrapper } from "@xyo-network/module-w
|
|
|
246
261
|
import {
|
|
247
262
|
isSentinelInstance,
|
|
248
263
|
isSentinelModule,
|
|
249
|
-
SentinelReportQuerySchema as
|
|
264
|
+
SentinelReportQuerySchema as SentinelReportQuerySchema2
|
|
250
265
|
} from "@xyo-network/sentinel-model";
|
|
251
266
|
constructableModuleWrapper();
|
|
252
267
|
var SentinelWrapper = class extends ModuleWrapper {
|
|
253
268
|
static instanceIdentityCheck = isSentinelInstance;
|
|
254
269
|
static moduleIdentityCheck = isSentinelModule;
|
|
255
|
-
static requiredQueries = [
|
|
270
|
+
static requiredQueries = [SentinelReportQuerySchema2, ...super.requiredQueries];
|
|
256
271
|
archivists() {
|
|
257
272
|
throw Error("Not supported");
|
|
258
273
|
}
|
|
259
274
|
async report(payloads) {
|
|
260
|
-
const queryPayload = { schema:
|
|
275
|
+
const queryPayload = { schema: SentinelReportQuerySchema2 };
|
|
261
276
|
const result = await this.sendQuery(queryPayload, payloads);
|
|
262
277
|
return result;
|
|
263
278
|
}
|
package/dist/node/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/AbstractSentinel.ts","../../src/Automation.ts","../../src/MemorySentinel.ts","../../src/SentinelIntervalAutomationWrapper.ts","../../src/SentinelRunner.ts","../../src/Wrapper.ts","../../src/index.ts"],"sourcesContent":["import { assertEx } from '@xylabs/assert'\nimport { uniq } from '@xylabs/lodash'\nimport { QueryBoundWitnessWrapper } from '@xyo-network/boundwitness-builder'\nimport { BoundWitness, isBoundWitness, notBoundWitness, QueryBoundWitness } from '@xyo-network/boundwitness-model'\nimport { AbstractModuleInstance } from '@xyo-network/module-abstract'\nimport { ModuleConfig, ModuleQueryHandlerResult } from '@xyo-network/module-model'\nimport { Payload } from '@xyo-network/payload-model'\nimport {\n CustomSentinelInstance,\n SentinelInstance,\n SentinelModuleEventData,\n SentinelParams,\n SentinelQueryBase,\n SentinelReportQuerySchema,\n} from '@xyo-network/sentinel-model'\nimport { isWitnessInstance, WitnessInstance } from '@xyo-network/witness-model'\n\nexport abstract class AbstractSentinel<\n TParams extends SentinelParams = SentinelParams,\n TEventData extends SentinelModuleEventData<SentinelInstance<TParams>> = SentinelModuleEventData<SentinelInstance<TParams>>,\n >\n extends AbstractModuleInstance<TParams, TEventData>\n implements CustomSentinelInstance<TParams, TEventData>\n{\n history: BoundWitness[] = []\n\n override get queries(): string[] {\n return [SentinelReportQuerySchema, ...super.queries]\n }\n\n protected override get _queryAccountPaths(): Record<SentinelQueryBase['schema'], string> {\n return {\n 'network.xyo.query.sentinel.report': '1/1',\n }\n }\n\n addWitness(address: string[]) {\n this.config.witnesses = uniq([...address, ...(this.config.witnesses ?? [])])\n }\n\n async report(inPayloads?: Payload[]): Promise<Payload[]> {\n this._noOverride('report')\n await this.emit('reportStart', { inPayloads, module: this })\n const payloads = await this.reportHandler(inPayloads)\n //this.logger?.debug(`report:payloads: ${JSON.stringify(payloads, null, 2)}`)\n const boundwitnesses = payloads.filter(isBoundWitness)\n const outPayloads = payloads.filter(notBoundWitness)\n const boundwitness = boundwitnesses.find((bw) => bw.addresses.includes(this.address))\n await this.emit('reportEnd', { boundwitness, inPayloads, module: this, outPayloads })\n return payloads\n }\n\n async witnesses() {\n this.logger?.debug(`witnesses:config:witnesses: ${this.config?.witnesses?.length}`)\n const namesOrAddresses = this.config?.witnesses\n ? Array.isArray(this.config.witnesses)\n ? this.config?.witnesses\n : [this.config.witnesses]\n : undefined\n this.logger?.debug(`witnesses:namesOrAddresses: ${namesOrAddresses?.length}`)\n const result = namesOrAddresses\n ? [\n ...(await this.resolve<WitnessInstance>({ address: namesOrAddresses }, { identity: isWitnessInstance })),\n ...(await this.resolve<WitnessInstance>({ name: namesOrAddresses }, { identity: isWitnessInstance })),\n ]\n : await this.resolve<WitnessInstance>(undefined, { identity: isWitnessInstance })\n\n if (namesOrAddresses && namesOrAddresses.length !== result.length) {\n this.logger?.warn(`Not all witnesses found [Requested: ${namesOrAddresses.length}, Found: ${result.length}]`)\n }\n result.map((item) => {\n this.logger?.debug(`witnesses:result: ${item.config.schema}`)\n })\n\n return result\n }\n\n protected override async queryHandler<T extends QueryBoundWitness = QueryBoundWitness, TConfig extends ModuleConfig = ModuleConfig>(\n query: T,\n payloads?: Payload[],\n queryConfig?: TConfig,\n ): Promise<ModuleQueryHandlerResult> {\n const wrapper = QueryBoundWitnessWrapper.parseQuery<SentinelQueryBase>(query, payloads)\n const queryPayload = await wrapper.getQuery()\n assertEx(this.queryable(query, payloads, queryConfig))\n const resultPayloads: Payload[] = []\n switch (queryPayload.schema) {\n case SentinelReportQuerySchema: {\n resultPayloads.push(...(await this.report(payloads)))\n break\n }\n default: {\n return super.queryHandler(query, payloads)\n }\n }\n return resultPayloads\n }\n\n abstract reportHandler(payloads?: Payload[]): Promise<Payload[]>\n}\n","import { AnyObject } from '@xyo-network/core'\nimport { Payload } from '@xyo-network/payload-model'\n\nexport type SentinelAutomationSchema = 'network.xyo.automation'\nexport const SentinelAutomationSchema: SentinelAutomationSchema = 'network.xyo.automation'\n\nexport type SentinelBaseAutomationPayload<T extends AnyObject = AnyObject> = Payload<\n T & {\n schema: SentinelAutomationSchema\n type?: 'interval' | 'change'\n /** @field The list of witnesses to invoke [all if undefined] */\n witnesses?: string[]\n }\n>\n\nexport type SentinelIntervalAutomationPayload = SentinelBaseAutomationPayload<{\n /** @field epoch after which any reoccurrence stops */\n end?: number\n\n /** @field time between triggers [non-repeating if undefined] */\n frequency?: number\n\n /** @field units for frequency field [hour if undefined] */\n frequencyUnits?: 'second' | 'minute' | 'hour' | 'day'\n\n /** @field remaining triggers [infinite if undefined] */\n remaining?: number\n\n /** @field epoch of the next trigger */\n start: number\n\n type: 'interval'\n}>\n\nexport type SentinelChangeAutomationPayload = SentinelBaseAutomationPayload<{\n type: 'change'\n}>\n\nexport type SentinelAutomationPayload = SentinelIntervalAutomationPayload | SentinelChangeAutomationPayload\n","import { assertEx } from '@xylabs/assert'\nimport { fulfilled, rejected } from '@xylabs/promise'\nimport { handleError } from '@xyo-network/error'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { Payload } from '@xyo-network/payload-model'\nimport {\n SentinelConfig,\n SentinelConfigSchema,\n SentinelInstance,\n SentinelModuleEventData,\n SentinelParams,\n SentinelReportQuerySchema,\n} from '@xyo-network/sentinel-model'\nimport { WitnessInstance } from '@xyo-network/witness-model'\n\nimport { AbstractSentinel } from './AbstractSentinel'\n\nexport type MemorySentinelParams<TConfig extends AnyConfigSchema<SentinelConfig> = AnyConfigSchema<SentinelConfig>> = SentinelParams<TConfig>\n\nexport class MemorySentinel<\n TParams extends MemorySentinelParams = MemorySentinelParams,\n TEventData extends SentinelModuleEventData<SentinelInstance<TParams>> = SentinelModuleEventData<SentinelInstance<TParams>>,\n> extends AbstractSentinel<TParams, TEventData> {\n static override configSchemas = [SentinelConfigSchema]\n\n async reportHandler(payloads: Payload[] = []): Promise<Payload[]> {\n await this.started('throw')\n const errors: Error[] = []\n const allWitnesses = [...(await this.witnesses())]\n const resultPayloads: Payload[] = []\n\n try {\n const [generatedPayloads, generatedErrors] = await this.generateResults(allWitnesses, payloads)\n resultPayloads.push(...generatedPayloads)\n errors.push(...generatedErrors)\n if (this.config.passthrough) {\n resultPayloads.push(...payloads)\n }\n } catch (ex) {\n handleError(ex, (error) => {\n errors.push(error)\n })\n }\n\n const [boundWitness] = await this.bindQueryResult({ schema: SentinelReportQuerySchema }, resultPayloads)\n this.history.push(assertEx(boundWitness))\n return [boundWitness, ...resultPayloads]\n }\n\n private async generateResults(witnesses: WitnessInstance[], inPayloads?: Payload[]): Promise<[Payload[], Error[]]> {\n const results: PromiseSettledResult<Payload[]>[] = await Promise.allSettled(witnesses?.map((witness) => witness.observe(inPayloads)))\n const payloads = results\n .filter(fulfilled)\n .map((result) => result.value)\n .flat()\n const errors = results\n .filter(rejected)\n .map((result) => result.reason)\n .flat()\n // console.log(`payloads: ${JSON.stringify(payloads, null, 2)}`)\n // console.log(`errors: ${JSON.stringify(errors, null, 2)}`)\n return [payloads, errors]\n }\n}\n","import { PayloadWrapper } from '@xyo-network/payload-wrapper'\n\nimport { SentinelIntervalAutomationPayload } from './Automation'\n\nexport class SentinelIntervalAutomationWrapper<\n T extends SentinelIntervalAutomationPayload = SentinelIntervalAutomationPayload,\n> extends PayloadWrapper<T> {\n constructor(payload: T) {\n super(payload)\n }\n\n protected get frequencyMillis() {\n const frequency = this.payload().frequency\n if (frequency === undefined) return Infinity\n switch (this.payload().frequencyUnits ?? 'hour') {\n case 'second':\n return frequency * 1000\n case 'minute':\n return frequency * 60 * 1000\n case 'hour':\n return frequency * 60 * 60 * 1000\n case 'day':\n return frequency * 24 * 60 * 60 * 1000\n }\n }\n\n protected get remaining() {\n //if remaining is not defined, we assume Infinity\n return this.payload().remaining ?? Infinity\n }\n\n next() {\n this.payload().start = this.payload().start + this.frequencyMillis\n this.consumeRemaining()\n this.checkEnd()\n return this\n }\n\n protected checkEnd() {\n if (this.payload().start > (this.payload().end ?? Infinity)) {\n this.payload().start = Infinity\n }\n }\n\n protected consumeRemaining(count = 1) {\n const remaining = this.remaining - count\n this.payload().remaining = remaining\n\n if (remaining <= 0) {\n this.payload().start = Infinity\n }\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Payload } from '@xyo-network/payload-model'\nimport { PayloadWrapper } from '@xyo-network/payload-wrapper'\nimport { SentinelInstance } from '@xyo-network/sentinel-model'\n\nimport { SentinelAutomationPayload, SentinelIntervalAutomationPayload } from './Automation'\nimport { SentinelIntervalAutomationWrapper } from './SentinelIntervalAutomationWrapper'\n\nexport type OnSentinelRunnerTriggerResult = (result: Payload[]) => void\n\nexport class SentinelRunner {\n protected _automations: Record<string, SentinelAutomationPayload> = {}\n protected onTriggerResult: OnSentinelRunnerTriggerResult | undefined\n protected sentinel: SentinelInstance\n protected timeoutId?: NodeJS.Timeout | string | number\n\n constructor(sentinel: SentinelInstance, automations?: SentinelAutomationPayload[], onTriggerResult?: OnSentinelRunnerTriggerResult) {\n this.sentinel = sentinel\n this.onTriggerResult = onTriggerResult\n automations?.forEach((automation) => this.add(automation))\n }\n\n get automations() {\n return this._automations\n }\n\n private get next() {\n return Object.values(this._automations).reduce<SentinelIntervalAutomationPayload | undefined>((previous, current) => {\n if (current.type === 'interval') {\n return current.start < (previous?.start ?? Infinity) ? current : previous\n }\n }, undefined)\n }\n\n async add(automation: SentinelAutomationPayload, restart = true) {\n const hash = await PayloadWrapper.hashAsync(automation)\n this._automations[hash] = automation\n if (restart) await this.restart()\n return hash\n }\n\n find(hash: string) {\n Object.entries(this._automations).find(([key]) => key === hash)\n }\n\n async remove(hash: string, restart = true) {\n delete this._automations[hash]\n if (restart) await this.restart()\n }\n\n removeAll() {\n this.stop()\n this._automations = {}\n }\n\n async restart() {\n this.stop()\n await this.start()\n }\n\n async start() {\n assertEx(this.timeoutId === undefined, 'Already started')\n const automation = this.next\n if (automation) {\n const delay = automation.start - Date.now()\n if (delay < 0) {\n //automation is due, just do it\n await this.trigger(automation)\n } else {\n this.timeoutId = setTimeout(\n async () => {\n this.timeoutId = undefined\n await this.start()\n },\n delay > 0 ? delay : 0,\n )\n }\n }\n }\n\n stop() {\n if (this.timeoutId) {\n clearTimeout(this.timeoutId)\n this.timeoutId = undefined\n }\n }\n\n async update(hash: string, automation: SentinelAutomationPayload, restart = true) {\n await this.remove(hash, false)\n await this.add(automation, false)\n if (restart) await this.restart()\n }\n\n private async trigger(automation: SentinelIntervalAutomationPayload) {\n const wrapper = new SentinelIntervalAutomationWrapper(automation)\n await this.remove(await wrapper.hashAsync(), false)\n wrapper.next()\n await this.add(wrapper.payload(), false)\n const triggerResult = await this.sentinel.report()\n this.onTriggerResult?.(triggerResult)\n await this.start()\n }\n}\n","import { ArchivistInstance } from '@xyo-network/archivist'\nimport { constructableModuleWrapper, ModuleWrapper } from '@xyo-network/module-wrapper'\nimport { Payload } from '@xyo-network/payload-model'\nimport {\n isSentinelInstance,\n isSentinelModule,\n SentinelInstance,\n SentinelModule,\n SentinelReportQuery,\n SentinelReportQuerySchema,\n} from '@xyo-network/sentinel-model'\nimport { WitnessInstance } from '@xyo-network/witness-model'\n\nconstructableModuleWrapper()\nexport class SentinelWrapper<TModule extends SentinelModule = SentinelModule>\n extends ModuleWrapper<TModule>\n implements SentinelInstance<TModule['params']>\n{\n static override instanceIdentityCheck = isSentinelInstance\n static override moduleIdentityCheck = isSentinelModule\n static override requiredQueries = [SentinelReportQuerySchema, ...super.requiredQueries]\n\n archivists(): Promise<ArchivistInstance[]> {\n throw Error('Not supported')\n }\n\n async report(payloads?: Payload[]): Promise<Payload[]> {\n const queryPayload: SentinelReportQuery = { schema: SentinelReportQuerySchema }\n const result = await this.sendQuery(queryPayload, payloads)\n return result\n }\n\n witnesses(): Promise<WitnessInstance[]> {\n throw Error('Not supported')\n }\n}\n","export * from './AbstractSentinel'\nexport * from './Automation'\nexport * from './MemorySentinel'\nexport * from './SentinelIntervalAutomationWrapper'\nexport * from './SentinelRunner'\nexport * from './Wrapper'\nexport * from '@xyo-network/sentinel-model'\n"],"mappings":";AAAA,SAAS,gBAAgB;AACzB,SAAS,YAAY;AACrB,SAAS,gCAAgC;AACzC,SAAuB,gBAAgB,uBAA0C;AACjF,SAAS,8BAA8B;AAGvC;AAAA,EAME;AAAA,OACK;AACP,SAAS,yBAA0C;AAE5C,IAAe,mBAAf,cAIG,uBAEV;AAAA,EACE,UAA0B,CAAC;AAAA,EAE3B,IAAa,UAAoB;AAC/B,WAAO,CAAC,2BAA2B,GAAG,MAAM,OAAO;AAAA,EACrD;AAAA,EAEA,IAAuB,qBAAkE;AACvF,WAAO;AAAA,MACL,qCAAqC;AAAA,IACvC;AAAA,EACF;AAAA,EAEA,WAAW,SAAmB;AAC5B,SAAK,OAAO,YAAY,KAAK,CAAC,GAAG,SAAS,GAAI,KAAK,OAAO,aAAa,CAAC,CAAE,CAAC;AAAA,EAC7E;AAAA,EAEA,MAAM,OAAO,YAA4C;AACvD,SAAK,YAAY,QAAQ;AACzB,UAAM,KAAK,KAAK,eAAe,EAAE,YAAY,QAAQ,KAAK,CAAC;AAC3D,UAAM,WAAW,MAAM,KAAK,cAAc,UAAU;AAEpD,UAAM,iBAAiB,SAAS,OAAO,cAAc;AACrD,UAAM,cAAc,SAAS,OAAO,eAAe;AACnD,UAAM,eAAe,eAAe,KAAK,CAAC,OAAO,GAAG,UAAU,SAAS,KAAK,OAAO,CAAC;AACpF,UAAM,KAAK,KAAK,aAAa,EAAE,cAAc,YAAY,QAAQ,MAAM,YAAY,CAAC;AACpF,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,YAAY;AApDpB;AAqDI,eAAK,WAAL,mBAAa,MAAM,gCAA+B,gBAAK,WAAL,mBAAa,cAAb,mBAAwB,MAAM;AAChF,UAAM,qBAAmB,UAAK,WAAL,mBAAa,aAClC,MAAM,QAAQ,KAAK,OAAO,SAAS,KACjC,UAAK,WAAL,mBAAa,YACb,CAAC,KAAK,OAAO,SAAS,IACxB;AACJ,eAAK,WAAL,mBAAa,MAAM,+BAA+B,qDAAkB,MAAM;AAC1E,UAAM,SAAS,mBACX;AAAA,MACE,GAAI,MAAM,KAAK,QAAyB,EAAE,SAAS,iBAAiB,GAAG,EAAE,UAAU,kBAAkB,CAAC;AAAA,MACtG,GAAI,MAAM,KAAK,QAAyB,EAAE,MAAM,iBAAiB,GAAG,EAAE,UAAU,kBAAkB,CAAC;AAAA,IACrG,IACA,MAAM,KAAK,QAAyB,QAAW,EAAE,UAAU,kBAAkB,CAAC;AAElF,QAAI,oBAAoB,iBAAiB,WAAW,OAAO,QAAQ;AACjE,iBAAK,WAAL,mBAAa,KAAK,uCAAuC,iBAAiB,MAAM,YAAY,OAAO,MAAM;AAAA,IAC3G;AACA,WAAO,IAAI,CAAC,SAAS;AAtEzB,UAAAA;AAuEM,OAAAA,MAAA,KAAK,WAAL,gBAAAA,IAAa,MAAM,qBAAqB,KAAK,OAAO,MAAM;AAAA,IAC5D,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEA,MAAyB,aACvB,OACA,UACA,aACmC;AACnC,UAAM,UAAU,yBAAyB,WAA8B,OAAO,QAAQ;AACtF,UAAM,eAAe,MAAM,QAAQ,SAAS;AAC5C,aAAS,KAAK,UAAU,OAAO,UAAU,WAAW,CAAC;AACrD,UAAM,iBAA4B,CAAC;AACnC,YAAQ,aAAa,QAAQ;AAAA,MAC3B,KAAK,2BAA2B;AAC9B,uBAAe,KAAK,GAAI,MAAM,KAAK,OAAO,QAAQ,CAAE;AACpD;AAAA,MACF;AAAA,MACA,SAAS;AACP,eAAO,MAAM,aAAa,OAAO,QAAQ;AAAA,MAC3C;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAGF;;;AC/FO,IAAM,2BAAqD;;;ACJlE,SAAS,YAAAC,iBAAgB;AACzB,SAAS,WAAW,gBAAgB;AACpC,SAAS,mBAAmB;AAG5B;AAAA,EAEE;AAAA,EAIA,6BAAAC;AAAA,OACK;AAOA,IAAM,iBAAN,cAGG,iBAAsC;AAAA,EAC9C,OAAgB,gBAAgB,CAAC,oBAAoB;AAAA,EAErD,MAAM,cAAc,WAAsB,CAAC,GAAuB;AAChE,UAAM,KAAK,QAAQ,OAAO;AAC1B,UAAM,SAAkB,CAAC;AACzB,UAAM,eAAe,CAAC,GAAI,MAAM,KAAK,UAAU,CAAE;AACjD,UAAM,iBAA4B,CAAC;AAEnC,QAAI;AACF,YAAM,CAAC,mBAAmB,eAAe,IAAI,MAAM,KAAK,gBAAgB,cAAc,QAAQ;AAC9F,qBAAe,KAAK,GAAG,iBAAiB;AACxC,aAAO,KAAK,GAAG,eAAe;AAC9B,UAAI,KAAK,OAAO,aAAa;AAC3B,uBAAe,KAAK,GAAG,QAAQ;AAAA,MACjC;AAAA,IACF,SAAS,IAAI;AACX,kBAAY,IAAI,CAAC,UAAU;AACzB,eAAO,KAAK,KAAK;AAAA,MACnB,CAAC;AAAA,IACH;AAEA,UAAM,CAAC,YAAY,IAAI,MAAM,KAAK,gBAAgB,EAAE,QAAQC,2BAA0B,GAAG,cAAc;AACvG,SAAK,QAAQ,KAAKC,UAAS,YAAY,CAAC;AACxC,WAAO,CAAC,cAAc,GAAG,cAAc;AAAA,EACzC;AAAA,EAEA,MAAc,gBAAgB,WAA8B,YAAuD;AACjH,UAAM,UAA6C,MAAM,QAAQ,WAAW,uCAAW,IAAI,CAAC,YAAY,QAAQ,QAAQ,UAAU,EAAE;AACpI,UAAM,WAAW,QACd,OAAO,SAAS,EAChB,IAAI,CAAC,WAAW,OAAO,KAAK,EAC5B,KAAK;AACR,UAAM,SAAS,QACZ,OAAO,QAAQ,EACf,IAAI,CAAC,WAAW,OAAO,MAAM,EAC7B,KAAK;AAGR,WAAO,CAAC,UAAU,MAAM;AAAA,EAC1B;AACF;;;AC/DA,SAAS,sBAAsB;AAIxB,IAAM,oCAAN,cAEG,eAAkB;AAAA,EAC1B,YAAY,SAAY;AACtB,UAAM,OAAO;AAAA,EACf;AAAA,EAEA,IAAc,kBAAkB;AAC9B,UAAM,YAAY,KAAK,QAAQ,EAAE;AACjC,QAAI,cAAc;AAAW,aAAO;AACpC,YAAQ,KAAK,QAAQ,EAAE,kBAAkB,QAAQ;AAAA,MAC/C,KAAK;AACH,eAAO,YAAY;AAAA,MACrB,KAAK;AACH,eAAO,YAAY,KAAK;AAAA,MAC1B,KAAK;AACH,eAAO,YAAY,KAAK,KAAK;AAAA,MAC/B,KAAK;AACH,eAAO,YAAY,KAAK,KAAK,KAAK;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,IAAc,YAAY;AAExB,WAAO,KAAK,QAAQ,EAAE,aAAa;AAAA,EACrC;AAAA,EAEA,OAAO;AACL,SAAK,QAAQ,EAAE,QAAQ,KAAK,QAAQ,EAAE,QAAQ,KAAK;AACnD,SAAK,iBAAiB;AACtB,SAAK,SAAS;AACd,WAAO;AAAA,EACT;AAAA,EAEU,WAAW;AACnB,QAAI,KAAK,QAAQ,EAAE,SAAS,KAAK,QAAQ,EAAE,OAAO,WAAW;AAC3D,WAAK,QAAQ,EAAE,QAAQ;AAAA,IACzB;AAAA,EACF;AAAA,EAEU,iBAAiB,QAAQ,GAAG;AACpC,UAAM,YAAY,KAAK,YAAY;AACnC,SAAK,QAAQ,EAAE,YAAY;AAE3B,QAAI,aAAa,GAAG;AAClB,WAAK,QAAQ,EAAE,QAAQ;AAAA,IACzB;AAAA,EACF;AACF;;;ACpDA,SAAS,YAAAC,iBAAgB;AAEzB,SAAS,kBAAAC,uBAAsB;AAQxB,IAAM,iBAAN,MAAqB;AAAA,EAChB,eAA0D,CAAC;AAAA,EAC3D;AAAA,EACA;AAAA,EACA;AAAA,EAEV,YAAY,UAA4B,aAA2C,iBAAiD;AAClI,SAAK,WAAW;AAChB,SAAK,kBAAkB;AACvB,+CAAa,QAAQ,CAAC,eAAe,KAAK,IAAI,UAAU;AAAA,EAC1D;AAAA,EAEA,IAAI,cAAc;AAChB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAY,OAAO;AACjB,WAAO,OAAO,OAAO,KAAK,YAAY,EAAE,OAAsD,CAAC,UAAU,YAAY;AACnH,UAAI,QAAQ,SAAS,YAAY;AAC/B,eAAO,QAAQ,UAAS,qCAAU,UAAS,YAAY,UAAU;AAAA,MACnE;AAAA,IACF,GAAG,MAAS;AAAA,EACd;AAAA,EAEA,MAAM,IAAI,YAAuC,UAAU,MAAM;AAC/D,UAAM,OAAO,MAAMC,gBAAe,UAAU,UAAU;AACtD,SAAK,aAAa,IAAI,IAAI;AAC1B,QAAI;AAAS,YAAM,KAAK,QAAQ;AAChC,WAAO;AAAA,EACT;AAAA,EAEA,KAAK,MAAc;AACjB,WAAO,QAAQ,KAAK,YAAY,EAAE,KAAK,CAAC,CAAC,GAAG,MAAM,QAAQ,IAAI;AAAA,EAChE;AAAA,EAEA,MAAM,OAAO,MAAc,UAAU,MAAM;AACzC,WAAO,KAAK,aAAa,IAAI;AAC7B,QAAI;AAAS,YAAM,KAAK,QAAQ;AAAA,EAClC;AAAA,EAEA,YAAY;AACV,SAAK,KAAK;AACV,SAAK,eAAe,CAAC;AAAA,EACvB;AAAA,EAEA,MAAM,UAAU;AACd,SAAK,KAAK;AACV,UAAM,KAAK,MAAM;AAAA,EACnB;AAAA,EAEA,MAAM,QAAQ;AACZ,IAAAC,UAAS,KAAK,cAAc,QAAW,iBAAiB;AACxD,UAAM,aAAa,KAAK;AACxB,QAAI,YAAY;AACd,YAAM,QAAQ,WAAW,QAAQ,KAAK,IAAI;AAC1C,UAAI,QAAQ,GAAG;AAEb,cAAM,KAAK,QAAQ,UAAU;AAAA,MAC/B,OAAO;AACL,aAAK,YAAY;AAAA,UACf,YAAY;AACV,iBAAK,YAAY;AACjB,kBAAM,KAAK,MAAM;AAAA,UACnB;AAAA,UACA,QAAQ,IAAI,QAAQ;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO;AACL,QAAI,KAAK,WAAW;AAClB,mBAAa,KAAK,SAAS;AAC3B,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,MAAc,YAAuC,UAAU,MAAM;AAChF,UAAM,KAAK,OAAO,MAAM,KAAK;AAC7B,UAAM,KAAK,IAAI,YAAY,KAAK;AAChC,QAAI;AAAS,YAAM,KAAK,QAAQ;AAAA,EAClC;AAAA,EAEA,MAAc,QAAQ,YAA+C;AA7FvE;AA8FI,UAAM,UAAU,IAAI,kCAAkC,UAAU;AAChE,UAAM,KAAK,OAAO,MAAM,QAAQ,UAAU,GAAG,KAAK;AAClD,YAAQ,KAAK;AACb,UAAM,KAAK,IAAI,QAAQ,QAAQ,GAAG,KAAK;AACvC,UAAM,gBAAgB,MAAM,KAAK,SAAS,OAAO;AACjD,eAAK,oBAAL,8BAAuB;AACvB,UAAM,KAAK,MAAM;AAAA,EACnB;AACF;;;ACrGA,SAAS,4BAA4B,qBAAqB;AAE1D;AAAA,EACE;AAAA,EACA;AAAA,EAIA,6BAAAC;AAAA,OACK;AAGP,2BAA2B;AACpB,IAAM,kBAAN,cACG,cAEV;AAAA,EACE,OAAgB,wBAAwB;AAAA,EACxC,OAAgB,sBAAsB;AAAA,EACtC,OAAgB,kBAAkB,CAACA,4BAA2B,GAAG,MAAM,eAAe;AAAA,EAEtF,aAA2C;AACzC,UAAM,MAAM,eAAe;AAAA,EAC7B;AAAA,EAEA,MAAM,OAAO,UAA0C;AACrD,UAAM,eAAoC,EAAE,QAAQA,2BAA0B;AAC9E,UAAM,SAAS,MAAM,KAAK,UAAU,cAAc,QAAQ;AAC1D,WAAO;AAAA,EACT;AAAA,EAEA,YAAwC;AACtC,UAAM,MAAM,eAAe;AAAA,EAC7B;AACF;;;AC7BA,cAAc;","names":["_a","assertEx","SentinelReportQuerySchema","SentinelReportQuerySchema","assertEx","assertEx","PayloadWrapper","PayloadWrapper","assertEx","SentinelReportQuerySchema"]}
|
|
1
|
+
{"version":3,"sources":["../../src/AbstractSentinel.ts","../../src/Automation.ts","../../src/MemorySentinel.ts","../../src/SentinelIntervalAutomationWrapper.ts","../../src/SentinelRunner.ts","../../src/Wrapper.ts","../../src/index.ts"],"sourcesContent":["import { assertEx } from '@xylabs/assert'\nimport { QueryBoundWitnessWrapper } from '@xyo-network/boundwitness-builder'\nimport { BoundWitness, isBoundWitness, notBoundWitness, QueryBoundWitness } from '@xyo-network/boundwitness-model'\nimport { AbstractModuleInstance } from '@xyo-network/module-abstract'\nimport { ModuleConfig, ModuleQueryHandlerResult } from '@xyo-network/module-model'\nimport { Payload } from '@xyo-network/payload-model'\nimport {\n CustomSentinelInstance,\n ResolvedSentinelTask,\n SentinelInstance,\n SentinelJob,\n SentinelModuleEventData,\n SentinelParams,\n SentinelQueryBase,\n SentinelReportQuerySchema,\n} from '@xyo-network/sentinel-model'\n\nexport abstract class AbstractSentinel<\n TParams extends SentinelParams = SentinelParams,\n TEventData extends SentinelModuleEventData<SentinelInstance<TParams>> = SentinelModuleEventData<SentinelInstance<TParams>>,\n >\n extends AbstractModuleInstance<TParams, TEventData>\n implements CustomSentinelInstance<TParams, TEventData>\n{\n history: BoundWitness[] = []\n private _jobPromise?: Promise<SentinelJob>\n\n get jobPromise() {\n this._jobPromise = this._jobPromise ?? this.generateJob()\n return this._jobPromise\n }\n\n override get queries(): string[] {\n return [SentinelReportQuerySchema, ...super.queries]\n }\n\n protected override get _queryAccountPaths(): Record<SentinelQueryBase['schema'], string> {\n return {\n 'network.xyo.query.sentinel.report': '1/1',\n }\n }\n\n async report(inPayloads?: Payload[]): Promise<Payload[]> {\n this._noOverride('report')\n await this.emit('reportStart', { inPayloads, module: this })\n const payloads = await this.reportHandler(inPayloads)\n //this.logger?.debug(`report:payloads: ${JSON.stringify(payloads, null, 2)}`)\n const boundwitnesses = payloads.filter(isBoundWitness)\n const outPayloads = payloads.filter(notBoundWitness)\n const boundwitness = boundwitnesses.find((bw) => bw.addresses.includes(this.address))\n await this.emit('reportEnd', { boundwitness, inPayloads, module: this, outPayloads })\n return payloads\n }\n\n protected async generateJob() {\n const job: SentinelJob = { tasks: [] }\n let tasks: ResolvedSentinelTask[] = await Promise.all(\n this.config.tasks.map(async (task) => ({\n input: task.input ?? false,\n module: assertEx(await this.resolve(task.module), `Unable to resolve task module [${task.module}]`),\n })),\n )\n while (tasks.length) {\n const previousTasks = job.tasks.length ? job.tasks[job.tasks.length - 1] : []\n const newList =\n //add all tasks that either require no previous input or have the previous input module already added\n tasks.filter(\n (task) =>\n typeof task.input === 'boolean' ||\n previousTasks.find((prevTask) => prevTask.module.address === task.input || prevTask.module.config.name === task.input),\n )\n assertEx(newList.length > 0, `Unable to generateJob [${tasks.length}]`)\n job.tasks.push(newList)\n //remove the tasks we just added\n tasks = tasks.filter((task) => !newList.includes(task))\n }\n return job\n }\n\n protected override async queryHandler<T extends QueryBoundWitness = QueryBoundWitness, TConfig extends ModuleConfig = ModuleConfig>(\n query: T,\n payloads?: Payload[],\n queryConfig?: TConfig,\n ): Promise<ModuleQueryHandlerResult> {\n const wrapper = QueryBoundWitnessWrapper.parseQuery<SentinelQueryBase>(query, payloads)\n const queryPayload = await wrapper.getQuery()\n assertEx(this.queryable(query, payloads, queryConfig))\n const resultPayloads: Payload[] = []\n switch (queryPayload.schema) {\n case SentinelReportQuerySchema: {\n resultPayloads.push(...(await this.report(payloads)))\n break\n }\n default: {\n return super.queryHandler(query, payloads)\n }\n }\n return resultPayloads\n }\n\n abstract reportHandler(payloads?: Payload[]): Promise<Payload[]>\n}\n","import { AnyObject } from '@xyo-network/core'\nimport { Payload } from '@xyo-network/payload-model'\nimport { SentinelTask } from '@xyo-network/sentinel-model'\n\nexport type SentinelAutomationSchema = 'network.xyo.automation'\nexport const SentinelAutomationSchema: SentinelAutomationSchema = 'network.xyo.automation'\n\nexport type SentinelBaseAutomationPayload<T extends AnyObject = AnyObject> = Payload<\n T & {\n schema: SentinelAutomationSchema\n tasks?: SentinelTask[]\n type?: 'interval' | 'change'\n }\n>\n\nexport type SentinelIntervalAutomationPayload = SentinelBaseAutomationPayload<{\n /** @field epoch after which any reoccurrence stops */\n end?: number\n\n /** @field time between triggers [non-repeating if undefined] */\n frequency?: number\n\n /** @field units for frequency field [hour if undefined] */\n frequencyUnits?: 'second' | 'minute' | 'hour' | 'day'\n\n /** @field remaining triggers [infinite if undefined] */\n remaining?: number\n\n /** @field epoch of the next trigger */\n start: number\n\n type: 'interval'\n}>\n\nexport type SentinelChangeAutomationPayload = SentinelBaseAutomationPayload<{\n type: 'change'\n}>\n\nexport type SentinelAutomationPayload = SentinelIntervalAutomationPayload | SentinelChangeAutomationPayload\n","import { fulfilled, rejected } from '@xylabs/promise'\nimport { Address } from '@xyo-network/core'\nimport { asDivinerInstance } from '@xyo-network/diviner-model'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { Payload } from '@xyo-network/payload-model'\nimport {\n ResolvedSentinelTask,\n SentinelConfig,\n SentinelConfigSchema,\n SentinelInstance,\n SentinelModuleEventData,\n SentinelParams,\n} from '@xyo-network/sentinel-model'\nimport { asWitnessInstance } from '@xyo-network/witness-model'\n\nimport { AbstractSentinel } from './AbstractSentinel'\n\nexport type MemorySentinelParams<TConfig extends AnyConfigSchema<SentinelConfig> = AnyConfigSchema<SentinelConfig>> = SentinelParams<TConfig>\n\nexport class MemorySentinel<\n TParams extends MemorySentinelParams = MemorySentinelParams,\n TEventData extends SentinelModuleEventData<SentinelInstance<TParams>> = SentinelModuleEventData<SentinelInstance<TParams>>,\n> extends AbstractSentinel<TParams, TEventData> {\n static override configSchemas = [SentinelConfigSchema]\n\n async reportHandler(inPayloads: Payload[] = []): Promise<Payload[]> {\n await this.started('throw')\n const job = await this.jobPromise\n\n let index = 0\n let previousResults: Record<Address, Payload[]> = {}\n while (index < job.tasks.length) {\n const generatedPayloads = await this.generateResults(job.tasks[index], previousResults, inPayloads)\n previousResults = generatedPayloads\n index++\n }\n return Object.values(previousResults).flat()\n }\n\n private async generateResults(\n tasks: ResolvedSentinelTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n const results: PromiseSettledResult<[Address, Payload[]]>[] = await Promise.allSettled(\n tasks?.map(async (task) => {\n const witness = asWitnessInstance(task.module)\n const input = task.input ?? false\n if (witness) {\n return [witness.address, await witness.observe(input === true ? inPayloads : input === false ? [] : previousResults[input])]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n return [diviner.address, await diviner.divine(input === true ? inPayloads : input === false ? [] : previousResults[input])]\n }\n throw Error('Unsupported module type')\n }),\n )\n const finalResult: Record<Address, Payload[]> = {}\n results.filter(fulfilled).forEach((result) => {\n const [address, payloads] = result.value\n finalResult[address] = finalResult[address] ?? []\n finalResult[address].push(...payloads)\n })\n const errors = results.filter(rejected).map((result) => result.reason)\n if (errors.length > 0) {\n throw Error('At least one module failed')\n }\n return finalResult\n }\n}\n","import { PayloadWrapper } from '@xyo-network/payload-wrapper'\n\nimport { SentinelIntervalAutomationPayload } from './Automation'\n\nexport class SentinelIntervalAutomationWrapper<\n T extends SentinelIntervalAutomationPayload = SentinelIntervalAutomationPayload,\n> extends PayloadWrapper<T> {\n constructor(payload: T) {\n super(payload)\n }\n\n protected get frequencyMillis() {\n const frequency = this.payload().frequency\n if (frequency === undefined) return Infinity\n switch (this.payload().frequencyUnits ?? 'hour') {\n case 'second':\n return frequency * 1000\n case 'minute':\n return frequency * 60 * 1000\n case 'hour':\n return frequency * 60 * 60 * 1000\n case 'day':\n return frequency * 24 * 60 * 60 * 1000\n }\n }\n\n protected get remaining() {\n //if remaining is not defined, we assume Infinity\n return this.payload().remaining ?? Infinity\n }\n\n next() {\n this.payload().start = this.payload().start + this.frequencyMillis\n this.consumeRemaining()\n this.checkEnd()\n return this\n }\n\n protected checkEnd() {\n if (this.payload().start > (this.payload().end ?? Infinity)) {\n this.payload().start = Infinity\n }\n }\n\n protected consumeRemaining(count = 1) {\n const remaining = this.remaining - count\n this.payload().remaining = remaining\n\n if (remaining <= 0) {\n this.payload().start = Infinity\n }\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Payload } from '@xyo-network/payload-model'\nimport { PayloadWrapper } from '@xyo-network/payload-wrapper'\nimport { SentinelInstance } from '@xyo-network/sentinel-model'\n\nimport { SentinelAutomationPayload, SentinelIntervalAutomationPayload } from './Automation'\nimport { SentinelIntervalAutomationWrapper } from './SentinelIntervalAutomationWrapper'\n\nexport type OnSentinelRunnerTriggerResult = (result: Payload[]) => void\n\nexport class SentinelRunner {\n protected _automations: Record<string, SentinelAutomationPayload> = {}\n protected onTriggerResult: OnSentinelRunnerTriggerResult | undefined\n protected sentinel: SentinelInstance\n protected timeoutId?: NodeJS.Timeout | string | number\n\n constructor(sentinel: SentinelInstance, automations?: SentinelAutomationPayload[], onTriggerResult?: OnSentinelRunnerTriggerResult) {\n this.sentinel = sentinel\n this.onTriggerResult = onTriggerResult\n automations?.forEach((automation) => this.add(automation))\n }\n\n get automations() {\n return this._automations\n }\n\n private get next() {\n return Object.values(this._automations).reduce<SentinelIntervalAutomationPayload | undefined>((previous, current) => {\n if (current.type === 'interval') {\n return current.start < (previous?.start ?? Infinity) ? current : previous\n }\n }, undefined)\n }\n\n async add(automation: SentinelAutomationPayload, restart = true) {\n const hash = await PayloadWrapper.hashAsync(automation)\n this._automations[hash] = automation\n if (restart) await this.restart()\n return hash\n }\n\n find(hash: string) {\n Object.entries(this._automations).find(([key]) => key === hash)\n }\n\n async remove(hash: string, restart = true) {\n delete this._automations[hash]\n if (restart) await this.restart()\n }\n\n removeAll() {\n this.stop()\n this._automations = {}\n }\n\n async restart() {\n this.stop()\n await this.start()\n }\n\n async start() {\n assertEx(this.timeoutId === undefined, 'Already started')\n const automation = this.next\n if (automation) {\n const delay = automation.start - Date.now()\n if (delay < 0) {\n //automation is due, just do it\n await this.trigger(automation)\n } else {\n this.timeoutId = setTimeout(\n async () => {\n this.timeoutId = undefined\n await this.start()\n },\n delay > 0 ? delay : 0,\n )\n }\n }\n }\n\n stop() {\n if (this.timeoutId) {\n clearTimeout(this.timeoutId)\n this.timeoutId = undefined\n }\n }\n\n async update(hash: string, automation: SentinelAutomationPayload, restart = true) {\n await this.remove(hash, false)\n await this.add(automation, false)\n if (restart) await this.restart()\n }\n\n private async trigger(automation: SentinelIntervalAutomationPayload) {\n const wrapper = new SentinelIntervalAutomationWrapper(automation)\n await this.remove(await wrapper.hashAsync(), false)\n wrapper.next()\n await this.add(wrapper.payload(), false)\n const triggerResult = await this.sentinel.report()\n this.onTriggerResult?.(triggerResult)\n await this.start()\n }\n}\n","import { ArchivistInstance } from '@xyo-network/archivist'\nimport { constructableModuleWrapper, ModuleWrapper } from '@xyo-network/module-wrapper'\nimport { Payload } from '@xyo-network/payload-model'\nimport {\n isSentinelInstance,\n isSentinelModule,\n SentinelInstance,\n SentinelModule,\n SentinelReportQuery,\n SentinelReportQuerySchema,\n} from '@xyo-network/sentinel-model'\nimport { WitnessInstance } from '@xyo-network/witness-model'\n\nconstructableModuleWrapper()\nexport class SentinelWrapper<TModule extends SentinelModule = SentinelModule>\n extends ModuleWrapper<TModule>\n implements SentinelInstance<TModule['params']>\n{\n static override instanceIdentityCheck = isSentinelInstance\n static override moduleIdentityCheck = isSentinelModule\n static override requiredQueries = [SentinelReportQuerySchema, ...super.requiredQueries]\n\n archivists(): Promise<ArchivistInstance[]> {\n throw Error('Not supported')\n }\n\n async report(payloads?: Payload[]): Promise<Payload[]> {\n const queryPayload: SentinelReportQuery = { schema: SentinelReportQuerySchema }\n const result = await this.sendQuery(queryPayload, payloads)\n return result\n }\n\n witnesses(): Promise<WitnessInstance[]> {\n throw Error('Not supported')\n }\n}\n","export * from './AbstractSentinel'\nexport * from './Automation'\nexport * from './MemorySentinel'\nexport * from './SentinelIntervalAutomationWrapper'\nexport * from './SentinelRunner'\nexport * from './Wrapper'\nexport * from '@xyo-network/sentinel-model'\n"],"mappings":"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","names":["assertEx","PayloadWrapper","PayloadWrapper","assertEx","SentinelReportQuerySchema"]}
|