@xyo-network/sentinel-memory 2.89.0-rc.1 → 2.89.0-rc.10
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/SentinelRunner.d.cts.map +1 -1
- package/dist/browser/SentinelRunner.d.mts.map +1 -1
- package/dist/browser/SentinelRunner.d.ts.map +1 -1
- package/dist/browser/index.cjs +5 -4
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.js +5 -4
- package/dist/browser/index.js.map +1 -1
- package/dist/node/SentinelRunner.d.cts.map +1 -1
- package/dist/node/SentinelRunner.d.mts.map +1 -1
- package/dist/node/SentinelRunner.d.ts.map +1 -1
- package/dist/node/index.cjs +5 -4
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.js +5 -4
- package/dist/node/index.js.map +1 -1
- package/package.json +20 -18
- package/src/SentinelRunner.ts +6 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SentinelRunner.d.ts","sourceRoot":"","sources":["../../src/SentinelRunner.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"SentinelRunner.d.ts","sourceRoot":"","sources":["../../src/SentinelRunner.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AACpD,OAAO,EAEL,yBAAyB,EACzB,gBAAgB,EAEjB,MAAM,6BAA6B,CAAA;AAIpC,MAAM,MAAM,6BAA6B,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;AAEvE,qBAAa,cAAc;IACzB,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAK;IACtE,SAAS,CAAC,eAAe,EAAE,6BAA6B,GAAG,SAAS,CAAA;IACpE,SAAS,CAAC,QAAQ,EAAE,gBAAgB,CAAA;IACpC,SAAS,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;gBAE1C,QAAQ,EAAE,gBAAgB,EAAE,WAAW,CAAC,EAAE,yBAAyB,EAAE,EAAE,eAAe,CAAC,EAAE,6BAA6B;IAMlI,IAAI,WAAW,8CAEd;IAED,OAAO,KAAK,IAAI,GASf;IAEK,GAAG,CAAC,UAAU,EAAE,yBAAyB,EAAE,OAAO,UAAO;IAO/D,IAAI,CAAC,IAAI,EAAE,MAAM;IAIX,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,UAAO;IAKzC,SAAS;IAKH,OAAO;IAKP,KAAK;IAyBX,IAAI;IAOE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,yBAAyB,EAAE,OAAO,UAAO;YAMlE,OAAO;CAStB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SentinelRunner.d.ts","sourceRoot":"","sources":["../../src/SentinelRunner.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"SentinelRunner.d.ts","sourceRoot":"","sources":["../../src/SentinelRunner.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AACpD,OAAO,EAEL,yBAAyB,EACzB,gBAAgB,EAEjB,MAAM,6BAA6B,CAAA;AAIpC,MAAM,MAAM,6BAA6B,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;AAEvE,qBAAa,cAAc;IACzB,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAK;IACtE,SAAS,CAAC,eAAe,EAAE,6BAA6B,GAAG,SAAS,CAAA;IACpE,SAAS,CAAC,QAAQ,EAAE,gBAAgB,CAAA;IACpC,SAAS,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;gBAE1C,QAAQ,EAAE,gBAAgB,EAAE,WAAW,CAAC,EAAE,yBAAyB,EAAE,EAAE,eAAe,CAAC,EAAE,6BAA6B;IAMlI,IAAI,WAAW,8CAEd;IAED,OAAO,KAAK,IAAI,GASf;IAEK,GAAG,CAAC,UAAU,EAAE,yBAAyB,EAAE,OAAO,UAAO;IAO/D,IAAI,CAAC,IAAI,EAAE,MAAM;IAIX,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,UAAO;IAKzC,SAAS;IAKH,OAAO;IAKP,KAAK;IAyBX,IAAI;IAOE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,yBAAyB,EAAE,OAAO,UAAO;YAMlE,OAAO;CAStB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SentinelRunner.d.ts","sourceRoot":"","sources":["../../src/SentinelRunner.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"SentinelRunner.d.ts","sourceRoot":"","sources":["../../src/SentinelRunner.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AACpD,OAAO,EAEL,yBAAyB,EACzB,gBAAgB,EAEjB,MAAM,6BAA6B,CAAA;AAIpC,MAAM,MAAM,6BAA6B,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;AAEvE,qBAAa,cAAc;IACzB,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAK;IACtE,SAAS,CAAC,eAAe,EAAE,6BAA6B,GAAG,SAAS,CAAA;IACpE,SAAS,CAAC,QAAQ,EAAE,gBAAgB,CAAA;IACpC,SAAS,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;gBAE1C,QAAQ,EAAE,gBAAgB,EAAE,WAAW,CAAC,EAAE,yBAAyB,EAAE,EAAE,eAAe,CAAC,EAAE,6BAA6B;IAMlI,IAAI,WAAW,8CAEd;IAED,OAAO,KAAK,IAAI,GASf;IAEK,GAAG,CAAC,UAAU,EAAE,yBAAyB,EAAE,OAAO,UAAO;IAO/D,IAAI,CAAC,IAAI,EAAE,MAAM;IAIX,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,UAAO;IAKzC,SAAS;IAKH,OAAO;IAKP,KAAK;IAyBX,IAAI;IAOE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,yBAAyB,EAAE,OAAO,UAAO;YAMlE,OAAO;CAStB"}
|
package/dist/browser/index.cjs
CHANGED
|
@@ -36,7 +36,8 @@ var import_witness_model = require("@xyo-network/witness-model");
|
|
|
36
36
|
|
|
37
37
|
// src/SentinelRunner.ts
|
|
38
38
|
var import_assert = require("@xylabs/assert");
|
|
39
|
-
var
|
|
39
|
+
var import_forget = require("@xylabs/forget");
|
|
40
|
+
var import_payload_builder = require("@xyo-network/payload-builder");
|
|
40
41
|
var import_sentinel_model = require("@xyo-network/sentinel-model");
|
|
41
42
|
|
|
42
43
|
// src/SentinelIntervalAutomationWrapper.ts
|
|
@@ -125,7 +126,7 @@ var SentinelRunner = class {
|
|
|
125
126
|
this.onTriggerResult = onTriggerResult;
|
|
126
127
|
if (automations)
|
|
127
128
|
for (const automation of automations)
|
|
128
|
-
this.add(automation);
|
|
129
|
+
(0, import_forget.forget)(this.add(automation));
|
|
129
130
|
}
|
|
130
131
|
get automations() {
|
|
131
132
|
return this._automations;
|
|
@@ -139,7 +140,7 @@ var SentinelRunner = class {
|
|
|
139
140
|
}, void 0);
|
|
140
141
|
}
|
|
141
142
|
async add(automation, restart = true) {
|
|
142
|
-
const hash = await
|
|
143
|
+
const hash = await import_payload_builder.PayloadBuilder.dataHash(automation);
|
|
143
144
|
this._automations[hash] = automation;
|
|
144
145
|
if (restart)
|
|
145
146
|
await this.restart();
|
|
@@ -195,7 +196,7 @@ var SentinelRunner = class {
|
|
|
195
196
|
}
|
|
196
197
|
async trigger(automation) {
|
|
197
198
|
const wrapper = new SentinelIntervalAutomationWrapper(automation);
|
|
198
|
-
await this.remove(await wrapper.
|
|
199
|
+
await this.remove(await wrapper.dataHash(), false);
|
|
199
200
|
wrapper.next();
|
|
200
201
|
await this.add(wrapper.jsonPayload(), false);
|
|
201
202
|
const triggerResult = await this.sentinel.report();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts","../../src/MemorySentinel.ts","../../src/SentinelRunner.ts","../../src/SentinelIntervalAutomationWrapper.ts"],"sourcesContent":["export * from './MemorySentinel'\nexport * from './SentinelIntervalAutomationWrapper'\nexport * from './SentinelRunner'\n","import { Address } from '@xylabs/hex'\nimport { fulfilled, rejected } from '@xylabs/promise'\nimport { asDivinerInstance } from '@xyo-network/diviner-model'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { Payload } from '@xyo-network/payload-model'\nimport { AbstractSentinel } from '@xyo-network/sentinel-abstract'\nimport {\n asSentinelInstance,\n ResolvedTask,\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 { SentinelRunner } from './SentinelRunner'\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 private runner?: SentinelRunner\n\n async reportHandler(inPayloads: Payload[] = []): Promise<Payload[]> {\n await this.started('throw')\n this.logger?.debug(`reportHandler:in: ${JSON.stringify(inPayloads)}`)\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 const result = Object.values(previousResults).flat()\n this.logger?.debug(`reportHandler:out: ${JSON.stringify(result)}`)\n return result\n }\n\n override async start(timeout?: number | undefined): Promise<boolean> {\n if (await super.start(timeout)) {\n if ((this.config.automations?.length ?? 0) > 0) {\n this.runner = new SentinelRunner(this, this.config.automations)\n await this.runner.start()\n }\n return true\n }\n return false\n }\n\n override async stop(timeout?: number | undefined): Promise<boolean> {\n if (this.runner) {\n this.runner.stop()\n this.runner = undefined\n }\n return await super.stop(timeout)\n }\n\n private async generateResults(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n this.logger?.debug(`generateResults:tasks: ${JSON.stringify(tasks.length)}`)\n this.logger?.debug(`generateResults:previous: ${JSON.stringify(previousResults)}`)\n this.logger?.debug(`generateResults:in: ${JSON.stringify(inPayloads)}`)\n const results: PromiseSettledResult<[Address, Payload[]]>[] = await Promise.allSettled(\n tasks?.map(async (task) => {\n const input = task.input ?? false\n const inPayloadsFound =\n input === true ? inPayloads : input === false ? [] : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n const witness = asWitnessInstance(task.module)\n if (witness) {\n const observed = await witness.observe(inPayloadsFound)\n this.logger?.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`)\n return [witness.address, observed]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n const divined = await diviner.divine(inPayloadsFound)\n this.logger?.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`)\n return [diviner.address, divined]\n }\n const sentinel = asSentinelInstance(task.module)\n if (sentinel) {\n const reported = await sentinel.report(inPayloadsFound)\n this.logger?.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`)\n return [sentinel.address, reported]\n }\n throw new Error('Unsupported module type')\n }),\n )\n const finalResult: Record<Address, Payload[]> = {}\n for (const result of results.filter(fulfilled)) {\n const [address, payloads] = result.value\n finalResult[address] = finalResult[address] ?? []\n finalResult[address].push(...payloads)\n }\n if (this.throwErrors) {\n const errors = results.filter(rejected).map((result) => result.reason)\n if (errors.length > 0) {\n throw new Error('At least one module failed')\n }\n }\n this.logger?.debug(`generateResults:out: ${JSON.stringify(finalResult)}`)\n return finalResult\n }\n\n private async inputAddresses(input: string | string[]): Promise<string[]> {\n if (Array.isArray(input)) {\n return (await Promise.all(input.map(async (inputItem) => await this.inputAddresses(inputItem)))).flat()\n } else {\n const resolved = await this.resolve(input)\n return resolved ? [resolved.address] : []\n }\n }\n\n private processPreviousResults(payloads: Record<string, Payload[]>, inputs: string[]) {\n return inputs.flatMap((input) => payloads[input] ?? [])\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Payload } from '@xyo-network/payload-model'\nimport { PayloadWrapper } from '@xyo-network/payload-wrapper'\nimport {\n isSentinelIntervalAutomation,\n SentinelAutomationPayload,\n SentinelInstance,\n SentinelIntervalAutomationPayload,\n} from '@xyo-network/sentinel-model'\n\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 if (automations) for (const automation of automations) this.add(automation)\n }\n\n get automations() {\n return this._automations\n }\n\n private get next() {\n // eslint-disable-next-line unicorn/no-array-reduce\n return Object.values(this._automations).reduce<SentinelAutomationPayload | undefined>((previous, current) => {\n if (isSentinelIntervalAutomation(current) && isSentinelIntervalAutomation(previous)) {\n return current.start < (previous?.start ?? Number.POSITIVE_INFINITY) ? current : previous\n }\n return current\n // eslint-disable-next-line unicorn/no-useless-undefined\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 // NOTE: Keep async to match module start signature\n await Promise.resolve()\n assertEx(this.timeoutId === undefined, 'Already started')\n const automation = this.next\n if (isSentinelIntervalAutomation(automation)) {\n const now = Date.now()\n const start = Math.max(automation.start ?? now, now)\n const delay = Math.max(start - now, 0)\n if (delay < Number.POSITIVE_INFINITY) {\n this.timeoutId = setTimeout(async () => {\n try {\n // Run the automation\n await this.trigger(automation)\n this.stop()\n } finally {\n // No matter what start the next automation\n await this.start()\n }\n }, delay)\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.jsonPayload(), false)\n const triggerResult = await this.sentinel.report()\n this.onTriggerResult?.(triggerResult)\n // await this.start()\n }\n}\n","import { PayloadWrapper } from '@xyo-network/payload-wrapper'\nimport { SentinelIntervalAutomationPayload } from '@xyo-network/sentinel-model'\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.jsonPayload().frequency\n if (frequency === undefined) return Number.POSITIVE_INFINITY\n const frequencyUnits = this.jsonPayload().frequencyUnits\n switch (frequencyUnits ?? 'hour') {\n case 'second': {\n return frequency * 1000\n }\n case 'minute': {\n return frequency * 60 * 1000\n }\n case 'hour': {\n return frequency * 60 * 60 * 1000\n }\n case 'day': {\n return frequency * 24 * 60 * 60 * 1000\n }\n default: {\n return Number.POSITIVE_INFINITY\n }\n }\n }\n\n protected get remaining() {\n return this.jsonPayload().remaining ?? Number.POSITIVE_INFINITY\n }\n\n next() {\n const now = Date.now()\n const previousStart = this.jsonPayload()?.start ?? now\n const start = Math.max(previousStart, now)\n const nextStart = start + this.frequencyMillis\n this.setStart(nextStart)\n this.consumeRemaining()\n this.checkEnd()\n return this\n }\n\n protected checkEnd() {\n if (this.jsonPayload().start > (this.jsonPayload().end ?? Number.POSITIVE_INFINITY)) {\n this.setStart(Number.POSITIVE_INFINITY)\n }\n }\n\n protected consumeRemaining(count = 1) {\n const remaining = Math.max(this.remaining - count, 0)\n this.setRemaining(remaining)\n if (remaining <= 0) this.setStart(Number.POSITIVE_INFINITY)\n }\n\n /**\n * Sets the remaining of the wrapped automation\n * @param remaining The remaining time in milliseconds\n */\n protected setRemaining(remaining: number) {\n this.obj.remaining = remaining\n }\n\n /**\n * Sets the start of the wrapped automation\n * @param start The start time in milliseconds\n */\n protected setStart(start: number) {\n this.obj.start = start\n }\n}\n"],"mappings":"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","names":["import_sentinel_model","import_payload_wrapper","SentinelIntervalAutomationWrapper","PayloadWrapper","constructor","payload","frequencyMillis","frequency","jsonPayload","undefined","Number","POSITIVE_INFINITY","frequencyUnits","remaining","next","now","Date","previousStart","start","Math","max","nextStart","setStart","consumeRemaining","checkEnd","end","count","setRemaining","obj","SentinelRunner","_automations","onTriggerResult","sentinel","timeoutId","constructor","automations","automation","add","next","Object","values","reduce","previous","current","isSentinelIntervalAutomation","start","Number","POSITIVE_INFINITY","undefined","restart","hash","PayloadWrapper","hashAsync","find","entries","key","remove","removeAll","stop","Promise","resolve","assertEx","now","Date","Math","max","delay","setTimeout","trigger","clearTimeout","update","wrapper","SentinelIntervalAutomationWrapper","jsonPayload","triggerResult","report","MemorySentinel","AbstractSentinel","configSchemas","SentinelConfigSchema","runner","reportHandler","inPayloads","started","logger","debug","JSON","stringify","job","jobPromise","index","previousResults","tasks","length","generatedPayloads","generateResults","result","Object","values","flat","start","timeout","config","automations","SentinelRunner","stop","undefined","results","Promise","allSettled","map","task","input","inPayloadsFound","processPreviousResults","inputAddresses","witness","asWitnessInstance","module","observed","observe","id","address","diviner","asDivinerInstance","divined","divine","sentinel","asSentinelInstance","reported","report","Error","finalResult","filter","fulfilled","payloads","value","push","throwErrors","errors","rejected","reason","Array","isArray","all","inputItem","resolved","resolve","inputs","flatMap"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/MemorySentinel.ts","../../src/SentinelRunner.ts","../../src/SentinelIntervalAutomationWrapper.ts"],"sourcesContent":["export * from './MemorySentinel'\nexport * from './SentinelIntervalAutomationWrapper'\nexport * from './SentinelRunner'\n","import { Address } from '@xylabs/hex'\nimport { fulfilled, rejected } from '@xylabs/promise'\nimport { asDivinerInstance } from '@xyo-network/diviner-model'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { Payload } from '@xyo-network/payload-model'\nimport { AbstractSentinel } from '@xyo-network/sentinel-abstract'\nimport {\n asSentinelInstance,\n ResolvedTask,\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 { SentinelRunner } from './SentinelRunner'\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 private runner?: SentinelRunner\n\n async reportHandler(inPayloads: Payload[] = []): Promise<Payload[]> {\n await this.started('throw')\n this.logger?.debug(`reportHandler:in: ${JSON.stringify(inPayloads)}`)\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 const result = Object.values(previousResults).flat()\n this.logger?.debug(`reportHandler:out: ${JSON.stringify(result)}`)\n return result\n }\n\n override async start(timeout?: number | undefined): Promise<boolean> {\n if (await super.start(timeout)) {\n if ((this.config.automations?.length ?? 0) > 0) {\n this.runner = new SentinelRunner(this, this.config.automations)\n await this.runner.start()\n }\n return true\n }\n return false\n }\n\n override async stop(timeout?: number | undefined): Promise<boolean> {\n if (this.runner) {\n this.runner.stop()\n this.runner = undefined\n }\n return await super.stop(timeout)\n }\n\n private async generateResults(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n this.logger?.debug(`generateResults:tasks: ${JSON.stringify(tasks.length)}`)\n this.logger?.debug(`generateResults:previous: ${JSON.stringify(previousResults)}`)\n this.logger?.debug(`generateResults:in: ${JSON.stringify(inPayloads)}`)\n const results: PromiseSettledResult<[Address, Payload[]]>[] = await Promise.allSettled(\n tasks?.map(async (task) => {\n const input = task.input ?? false\n const inPayloadsFound =\n input === true ? inPayloads : input === false ? [] : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n const witness = asWitnessInstance(task.module)\n if (witness) {\n const observed = await witness.observe(inPayloadsFound)\n this.logger?.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`)\n return [witness.address, observed]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n const divined = await diviner.divine(inPayloadsFound)\n this.logger?.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`)\n return [diviner.address, divined]\n }\n const sentinel = asSentinelInstance(task.module)\n if (sentinel) {\n const reported = await sentinel.report(inPayloadsFound)\n this.logger?.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`)\n return [sentinel.address, reported]\n }\n throw new Error('Unsupported module type')\n }),\n )\n const finalResult: Record<Address, Payload[]> = {}\n for (const result of results.filter(fulfilled)) {\n const [address, payloads] = result.value\n finalResult[address] = finalResult[address] ?? []\n finalResult[address].push(...payloads)\n }\n if (this.throwErrors) {\n const errors = results.filter(rejected).map((result) => result.reason)\n if (errors.length > 0) {\n throw new Error('At least one module failed')\n }\n }\n this.logger?.debug(`generateResults:out: ${JSON.stringify(finalResult)}`)\n return finalResult\n }\n\n private async inputAddresses(input: string | string[]): Promise<string[]> {\n if (Array.isArray(input)) {\n return (await Promise.all(input.map(async (inputItem) => await this.inputAddresses(inputItem)))).flat()\n } else {\n const resolved = await this.resolve(input)\n return resolved ? [resolved.address] : []\n }\n }\n\n private processPreviousResults(payloads: Record<string, Payload[]>, inputs: string[]) {\n return inputs.flatMap((input) => payloads[input] ?? [])\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { forget } from '@xylabs/forget'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport { Payload } from '@xyo-network/payload-model'\nimport {\n isSentinelIntervalAutomation,\n SentinelAutomationPayload,\n SentinelInstance,\n SentinelIntervalAutomationPayload,\n} from '@xyo-network/sentinel-model'\n\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 if (automations) for (const automation of automations) forget(this.add(automation))\n }\n\n get automations() {\n return this._automations\n }\n\n private get next() {\n // eslint-disable-next-line unicorn/no-array-reduce\n return Object.values(this._automations).reduce<SentinelAutomationPayload | undefined>((previous, current) => {\n if (isSentinelIntervalAutomation(current) && isSentinelIntervalAutomation(previous)) {\n return current.start < (previous?.start ?? Number.POSITIVE_INFINITY) ? current : previous\n }\n return current\n // eslint-disable-next-line unicorn/no-useless-undefined\n }, undefined)\n }\n\n async add(automation: SentinelAutomationPayload, restart = true) {\n const hash = await PayloadBuilder.dataHash(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 // NOTE: Keep async to match module start signature\n await Promise.resolve()\n assertEx(this.timeoutId === undefined, 'Already started')\n const automation = this.next\n if (isSentinelIntervalAutomation(automation)) {\n const now = Date.now()\n const start = Math.max(automation.start ?? now, now)\n const delay = Math.max(start - now, 0)\n if (delay < Number.POSITIVE_INFINITY) {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.timeoutId = setTimeout(async () => {\n try {\n // Run the automation\n await this.trigger(automation)\n this.stop()\n } finally {\n // No matter what start the next automation\n await this.start()\n }\n }, delay)\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.dataHash(), false)\n wrapper.next()\n await this.add(wrapper.jsonPayload(), false)\n const triggerResult = await this.sentinel.report()\n this.onTriggerResult?.(triggerResult)\n // await this.start()\n }\n}\n","import { PayloadWrapper } from '@xyo-network/payload-wrapper'\nimport { SentinelIntervalAutomationPayload } from '@xyo-network/sentinel-model'\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.jsonPayload().frequency\n if (frequency === undefined) return Number.POSITIVE_INFINITY\n const frequencyUnits = this.jsonPayload().frequencyUnits\n switch (frequencyUnits ?? 'hour') {\n case 'second': {\n return frequency * 1000\n }\n case 'minute': {\n return frequency * 60 * 1000\n }\n case 'hour': {\n return frequency * 60 * 60 * 1000\n }\n case 'day': {\n return frequency * 24 * 60 * 60 * 1000\n }\n default: {\n return Number.POSITIVE_INFINITY\n }\n }\n }\n\n protected get remaining() {\n return this.jsonPayload().remaining ?? Number.POSITIVE_INFINITY\n }\n\n next() {\n const now = Date.now()\n const previousStart = this.jsonPayload()?.start ?? now\n const start = Math.max(previousStart, now)\n const nextStart = start + this.frequencyMillis\n this.setStart(nextStart)\n this.consumeRemaining()\n this.checkEnd()\n return this\n }\n\n protected checkEnd() {\n if (this.jsonPayload().start > (this.jsonPayload().end ?? Number.POSITIVE_INFINITY)) {\n this.setStart(Number.POSITIVE_INFINITY)\n }\n }\n\n protected consumeRemaining(count = 1) {\n const remaining = Math.max(this.remaining - count, 0)\n this.setRemaining(remaining)\n if (remaining <= 0) this.setStart(Number.POSITIVE_INFINITY)\n }\n\n /**\n * Sets the remaining of the wrapped automation\n * @param remaining The remaining time in milliseconds\n */\n protected setRemaining(remaining: number) {\n this.obj.remaining = remaining\n }\n\n /**\n * Sets the start of the wrapped automation\n * @param start The start time in milliseconds\n */\n protected setStart(start: number) {\n this.obj.start = start\n }\n}\n"],"mappings":"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","names":["import_sentinel_model","SentinelIntervalAutomationWrapper","PayloadWrapper","constructor","payload","frequencyMillis","frequency","jsonPayload","undefined","Number","POSITIVE_INFINITY","frequencyUnits","remaining","next","now","Date","previousStart","start","Math","max","nextStart","setStart","consumeRemaining","checkEnd","end","count","setRemaining","obj","SentinelRunner","_automations","onTriggerResult","sentinel","timeoutId","constructor","automations","automation","forget","add","next","Object","values","reduce","previous","current","isSentinelIntervalAutomation","start","Number","POSITIVE_INFINITY","undefined","restart","hash","PayloadBuilder","dataHash","find","entries","key","remove","removeAll","stop","Promise","resolve","assertEx","now","Date","Math","max","delay","setTimeout","trigger","clearTimeout","update","wrapper","SentinelIntervalAutomationWrapper","jsonPayload","triggerResult","report","MemorySentinel","AbstractSentinel","configSchemas","SentinelConfigSchema","runner","reportHandler","inPayloads","started","logger","debug","JSON","stringify","job","jobPromise","index","previousResults","tasks","length","generatedPayloads","generateResults","result","Object","values","flat","start","timeout","config","automations","SentinelRunner","stop","undefined","results","Promise","allSettled","map","task","input","inPayloadsFound","processPreviousResults","inputAddresses","witness","asWitnessInstance","module","observed","observe","id","address","diviner","asDivinerInstance","divined","divine","sentinel","asSentinelInstance","reported","report","Error","finalResult","filter","fulfilled","payloads","value","push","throwErrors","errors","rejected","reason","Array","isArray","all","inputItem","resolved","resolve","inputs","flatMap"]}
|
package/dist/browser/index.js
CHANGED
|
@@ -10,7 +10,8 @@ import { asWitnessInstance } from "@xyo-network/witness-model";
|
|
|
10
10
|
|
|
11
11
|
// src/SentinelRunner.ts
|
|
12
12
|
import { assertEx } from "@xylabs/assert";
|
|
13
|
-
import {
|
|
13
|
+
import { forget } from "@xylabs/forget";
|
|
14
|
+
import { PayloadBuilder } from "@xyo-network/payload-builder";
|
|
14
15
|
import { isSentinelIntervalAutomation } from "@xyo-network/sentinel-model";
|
|
15
16
|
|
|
16
17
|
// src/SentinelIntervalAutomationWrapper.ts
|
|
@@ -99,7 +100,7 @@ var SentinelRunner = class {
|
|
|
99
100
|
this.onTriggerResult = onTriggerResult;
|
|
100
101
|
if (automations)
|
|
101
102
|
for (const automation of automations)
|
|
102
|
-
this.add(automation);
|
|
103
|
+
forget(this.add(automation));
|
|
103
104
|
}
|
|
104
105
|
get automations() {
|
|
105
106
|
return this._automations;
|
|
@@ -113,7 +114,7 @@ var SentinelRunner = class {
|
|
|
113
114
|
}, void 0);
|
|
114
115
|
}
|
|
115
116
|
async add(automation, restart = true) {
|
|
116
|
-
const hash = await
|
|
117
|
+
const hash = await PayloadBuilder.dataHash(automation);
|
|
117
118
|
this._automations[hash] = automation;
|
|
118
119
|
if (restart)
|
|
119
120
|
await this.restart();
|
|
@@ -169,7 +170,7 @@ var SentinelRunner = class {
|
|
|
169
170
|
}
|
|
170
171
|
async trigger(automation) {
|
|
171
172
|
const wrapper = new SentinelIntervalAutomationWrapper(automation);
|
|
172
|
-
await this.remove(await wrapper.
|
|
173
|
+
await this.remove(await wrapper.dataHash(), false);
|
|
173
174
|
wrapper.next();
|
|
174
175
|
await this.add(wrapper.jsonPayload(), false);
|
|
175
176
|
const triggerResult = await this.sentinel.report();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/MemorySentinel.ts","../../src/SentinelRunner.ts","../../src/SentinelIntervalAutomationWrapper.ts"],"sourcesContent":["import { Address } from '@xylabs/hex'\nimport { fulfilled, rejected } from '@xylabs/promise'\nimport { asDivinerInstance } from '@xyo-network/diviner-model'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { Payload } from '@xyo-network/payload-model'\nimport { AbstractSentinel } from '@xyo-network/sentinel-abstract'\nimport {\n asSentinelInstance,\n ResolvedTask,\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 { SentinelRunner } from './SentinelRunner'\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 private runner?: SentinelRunner\n\n async reportHandler(inPayloads: Payload[] = []): Promise<Payload[]> {\n await this.started('throw')\n this.logger?.debug(`reportHandler:in: ${JSON.stringify(inPayloads)}`)\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 const result = Object.values(previousResults).flat()\n this.logger?.debug(`reportHandler:out: ${JSON.stringify(result)}`)\n return result\n }\n\n override async start(timeout?: number | undefined): Promise<boolean> {\n if (await super.start(timeout)) {\n if ((this.config.automations?.length ?? 0) > 0) {\n this.runner = new SentinelRunner(this, this.config.automations)\n await this.runner.start()\n }\n return true\n }\n return false\n }\n\n override async stop(timeout?: number | undefined): Promise<boolean> {\n if (this.runner) {\n this.runner.stop()\n this.runner = undefined\n }\n return await super.stop(timeout)\n }\n\n private async generateResults(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n this.logger?.debug(`generateResults:tasks: ${JSON.stringify(tasks.length)}`)\n this.logger?.debug(`generateResults:previous: ${JSON.stringify(previousResults)}`)\n this.logger?.debug(`generateResults:in: ${JSON.stringify(inPayloads)}`)\n const results: PromiseSettledResult<[Address, Payload[]]>[] = await Promise.allSettled(\n tasks?.map(async (task) => {\n const input = task.input ?? false\n const inPayloadsFound =\n input === true ? inPayloads : input === false ? [] : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n const witness = asWitnessInstance(task.module)\n if (witness) {\n const observed = await witness.observe(inPayloadsFound)\n this.logger?.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`)\n return [witness.address, observed]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n const divined = await diviner.divine(inPayloadsFound)\n this.logger?.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`)\n return [diviner.address, divined]\n }\n const sentinel = asSentinelInstance(task.module)\n if (sentinel) {\n const reported = await sentinel.report(inPayloadsFound)\n this.logger?.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`)\n return [sentinel.address, reported]\n }\n throw new Error('Unsupported module type')\n }),\n )\n const finalResult: Record<Address, Payload[]> = {}\n for (const result of results.filter(fulfilled)) {\n const [address, payloads] = result.value\n finalResult[address] = finalResult[address] ?? []\n finalResult[address].push(...payloads)\n }\n if (this.throwErrors) {\n const errors = results.filter(rejected).map((result) => result.reason)\n if (errors.length > 0) {\n throw new Error('At least one module failed')\n }\n }\n this.logger?.debug(`generateResults:out: ${JSON.stringify(finalResult)}`)\n return finalResult\n }\n\n private async inputAddresses(input: string | string[]): Promise<string[]> {\n if (Array.isArray(input)) {\n return (await Promise.all(input.map(async (inputItem) => await this.inputAddresses(inputItem)))).flat()\n } else {\n const resolved = await this.resolve(input)\n return resolved ? [resolved.address] : []\n }\n }\n\n private processPreviousResults(payloads: Record<string, Payload[]>, inputs: string[]) {\n return inputs.flatMap((input) => payloads[input] ?? [])\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Payload } from '@xyo-network/payload-model'\nimport { PayloadWrapper } from '@xyo-network/payload-wrapper'\nimport {\n isSentinelIntervalAutomation,\n SentinelAutomationPayload,\n SentinelInstance,\n SentinelIntervalAutomationPayload,\n} from '@xyo-network/sentinel-model'\n\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 if (automations) for (const automation of automations) this.add(automation)\n }\n\n get automations() {\n return this._automations\n }\n\n private get next() {\n // eslint-disable-next-line unicorn/no-array-reduce\n return Object.values(this._automations).reduce<SentinelAutomationPayload | undefined>((previous, current) => {\n if (isSentinelIntervalAutomation(current) && isSentinelIntervalAutomation(previous)) {\n return current.start < (previous?.start ?? Number.POSITIVE_INFINITY) ? current : previous\n }\n return current\n // eslint-disable-next-line unicorn/no-useless-undefined\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 // NOTE: Keep async to match module start signature\n await Promise.resolve()\n assertEx(this.timeoutId === undefined, 'Already started')\n const automation = this.next\n if (isSentinelIntervalAutomation(automation)) {\n const now = Date.now()\n const start = Math.max(automation.start ?? now, now)\n const delay = Math.max(start - now, 0)\n if (delay < Number.POSITIVE_INFINITY) {\n this.timeoutId = setTimeout(async () => {\n try {\n // Run the automation\n await this.trigger(automation)\n this.stop()\n } finally {\n // No matter what start the next automation\n await this.start()\n }\n }, delay)\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.jsonPayload(), false)\n const triggerResult = await this.sentinel.report()\n this.onTriggerResult?.(triggerResult)\n // await this.start()\n }\n}\n","import { PayloadWrapper } from '@xyo-network/payload-wrapper'\nimport { SentinelIntervalAutomationPayload } from '@xyo-network/sentinel-model'\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.jsonPayload().frequency\n if (frequency === undefined) return Number.POSITIVE_INFINITY\n const frequencyUnits = this.jsonPayload().frequencyUnits\n switch (frequencyUnits ?? 'hour') {\n case 'second': {\n return frequency * 1000\n }\n case 'minute': {\n return frequency * 60 * 1000\n }\n case 'hour': {\n return frequency * 60 * 60 * 1000\n }\n case 'day': {\n return frequency * 24 * 60 * 60 * 1000\n }\n default: {\n return Number.POSITIVE_INFINITY\n }\n }\n }\n\n protected get remaining() {\n return this.jsonPayload().remaining ?? Number.POSITIVE_INFINITY\n }\n\n next() {\n const now = Date.now()\n const previousStart = this.jsonPayload()?.start ?? now\n const start = Math.max(previousStart, now)\n const nextStart = start + this.frequencyMillis\n this.setStart(nextStart)\n this.consumeRemaining()\n this.checkEnd()\n return this\n }\n\n protected checkEnd() {\n if (this.jsonPayload().start > (this.jsonPayload().end ?? Number.POSITIVE_INFINITY)) {\n this.setStart(Number.POSITIVE_INFINITY)\n }\n }\n\n protected consumeRemaining(count = 1) {\n const remaining = Math.max(this.remaining - count, 0)\n this.setRemaining(remaining)\n if (remaining <= 0) this.setStart(Number.POSITIVE_INFINITY)\n }\n\n /**\n * Sets the remaining of the wrapped automation\n * @param remaining The remaining time in milliseconds\n */\n protected setRemaining(remaining: number) {\n this.obj.remaining = remaining\n }\n\n /**\n * Sets the start of the wrapped automation\n * @param start The start time in milliseconds\n */\n protected setStart(start: number) {\n this.obj.start = start\n }\n}\n"],"mappings":"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","names":["fulfilled","rejected","asDivinerInstance","AbstractSentinel","asSentinelInstance","SentinelConfigSchema","asWitnessInstance","assertEx","PayloadWrapper","isSentinelIntervalAutomation","PayloadWrapper","SentinelIntervalAutomationWrapper","PayloadWrapper","constructor","payload","frequencyMillis","frequency","jsonPayload","undefined","Number","POSITIVE_INFINITY","frequencyUnits","remaining","next","now","Date","previousStart","start","Math","max","nextStart","setStart","consumeRemaining","checkEnd","end","count","setRemaining","obj","SentinelRunner","_automations","onTriggerResult","sentinel","timeoutId","constructor","automations","automation","add","next","Object","values","reduce","previous","current","isSentinelIntervalAutomation","start","Number","POSITIVE_INFINITY","undefined","restart","hash","PayloadWrapper","hashAsync","find","entries","key","remove","removeAll","stop","Promise","resolve","assertEx","now","Date","Math","max","delay","setTimeout","trigger","clearTimeout","update","wrapper","SentinelIntervalAutomationWrapper","jsonPayload","triggerResult","report","MemorySentinel","AbstractSentinel","configSchemas","SentinelConfigSchema","runner","reportHandler","inPayloads","started","logger","debug","JSON","stringify","job","jobPromise","index","previousResults","tasks","length","generatedPayloads","generateResults","result","Object","values","flat","start","timeout","config","automations","SentinelRunner","stop","undefined","results","Promise","allSettled","map","task","input","inPayloadsFound","processPreviousResults","inputAddresses","witness","asWitnessInstance","module","observed","observe","id","address","diviner","asDivinerInstance","divined","divine","sentinel","asSentinelInstance","reported","report","Error","finalResult","filter","fulfilled","payloads","value","push","throwErrors","errors","rejected","reason","Array","isArray","all","inputItem","resolved","resolve","inputs","flatMap"]}
|
|
1
|
+
{"version":3,"sources":["../../src/MemorySentinel.ts","../../src/SentinelRunner.ts","../../src/SentinelIntervalAutomationWrapper.ts"],"sourcesContent":["import { Address } from '@xylabs/hex'\nimport { fulfilled, rejected } from '@xylabs/promise'\nimport { asDivinerInstance } from '@xyo-network/diviner-model'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { Payload } from '@xyo-network/payload-model'\nimport { AbstractSentinel } from '@xyo-network/sentinel-abstract'\nimport {\n asSentinelInstance,\n ResolvedTask,\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 { SentinelRunner } from './SentinelRunner'\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 private runner?: SentinelRunner\n\n async reportHandler(inPayloads: Payload[] = []): Promise<Payload[]> {\n await this.started('throw')\n this.logger?.debug(`reportHandler:in: ${JSON.stringify(inPayloads)}`)\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 const result = Object.values(previousResults).flat()\n this.logger?.debug(`reportHandler:out: ${JSON.stringify(result)}`)\n return result\n }\n\n override async start(timeout?: number | undefined): Promise<boolean> {\n if (await super.start(timeout)) {\n if ((this.config.automations?.length ?? 0) > 0) {\n this.runner = new SentinelRunner(this, this.config.automations)\n await this.runner.start()\n }\n return true\n }\n return false\n }\n\n override async stop(timeout?: number | undefined): Promise<boolean> {\n if (this.runner) {\n this.runner.stop()\n this.runner = undefined\n }\n return await super.stop(timeout)\n }\n\n private async generateResults(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n this.logger?.debug(`generateResults:tasks: ${JSON.stringify(tasks.length)}`)\n this.logger?.debug(`generateResults:previous: ${JSON.stringify(previousResults)}`)\n this.logger?.debug(`generateResults:in: ${JSON.stringify(inPayloads)}`)\n const results: PromiseSettledResult<[Address, Payload[]]>[] = await Promise.allSettled(\n tasks?.map(async (task) => {\n const input = task.input ?? false\n const inPayloadsFound =\n input === true ? inPayloads : input === false ? [] : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n const witness = asWitnessInstance(task.module)\n if (witness) {\n const observed = await witness.observe(inPayloadsFound)\n this.logger?.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`)\n return [witness.address, observed]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n const divined = await diviner.divine(inPayloadsFound)\n this.logger?.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`)\n return [diviner.address, divined]\n }\n const sentinel = asSentinelInstance(task.module)\n if (sentinel) {\n const reported = await sentinel.report(inPayloadsFound)\n this.logger?.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`)\n return [sentinel.address, reported]\n }\n throw new Error('Unsupported module type')\n }),\n )\n const finalResult: Record<Address, Payload[]> = {}\n for (const result of results.filter(fulfilled)) {\n const [address, payloads] = result.value\n finalResult[address] = finalResult[address] ?? []\n finalResult[address].push(...payloads)\n }\n if (this.throwErrors) {\n const errors = results.filter(rejected).map((result) => result.reason)\n if (errors.length > 0) {\n throw new Error('At least one module failed')\n }\n }\n this.logger?.debug(`generateResults:out: ${JSON.stringify(finalResult)}`)\n return finalResult\n }\n\n private async inputAddresses(input: string | string[]): Promise<string[]> {\n if (Array.isArray(input)) {\n return (await Promise.all(input.map(async (inputItem) => await this.inputAddresses(inputItem)))).flat()\n } else {\n const resolved = await this.resolve(input)\n return resolved ? [resolved.address] : []\n }\n }\n\n private processPreviousResults(payloads: Record<string, Payload[]>, inputs: string[]) {\n return inputs.flatMap((input) => payloads[input] ?? [])\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { forget } from '@xylabs/forget'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport { Payload } from '@xyo-network/payload-model'\nimport {\n isSentinelIntervalAutomation,\n SentinelAutomationPayload,\n SentinelInstance,\n SentinelIntervalAutomationPayload,\n} from '@xyo-network/sentinel-model'\n\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 if (automations) for (const automation of automations) forget(this.add(automation))\n }\n\n get automations() {\n return this._automations\n }\n\n private get next() {\n // eslint-disable-next-line unicorn/no-array-reduce\n return Object.values(this._automations).reduce<SentinelAutomationPayload | undefined>((previous, current) => {\n if (isSentinelIntervalAutomation(current) && isSentinelIntervalAutomation(previous)) {\n return current.start < (previous?.start ?? Number.POSITIVE_INFINITY) ? current : previous\n }\n return current\n // eslint-disable-next-line unicorn/no-useless-undefined\n }, undefined)\n }\n\n async add(automation: SentinelAutomationPayload, restart = true) {\n const hash = await PayloadBuilder.dataHash(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 // NOTE: Keep async to match module start signature\n await Promise.resolve()\n assertEx(this.timeoutId === undefined, 'Already started')\n const automation = this.next\n if (isSentinelIntervalAutomation(automation)) {\n const now = Date.now()\n const start = Math.max(automation.start ?? now, now)\n const delay = Math.max(start - now, 0)\n if (delay < Number.POSITIVE_INFINITY) {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.timeoutId = setTimeout(async () => {\n try {\n // Run the automation\n await this.trigger(automation)\n this.stop()\n } finally {\n // No matter what start the next automation\n await this.start()\n }\n }, delay)\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.dataHash(), false)\n wrapper.next()\n await this.add(wrapper.jsonPayload(), false)\n const triggerResult = await this.sentinel.report()\n this.onTriggerResult?.(triggerResult)\n // await this.start()\n }\n}\n","import { PayloadWrapper } from '@xyo-network/payload-wrapper'\nimport { SentinelIntervalAutomationPayload } from '@xyo-network/sentinel-model'\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.jsonPayload().frequency\n if (frequency === undefined) return Number.POSITIVE_INFINITY\n const frequencyUnits = this.jsonPayload().frequencyUnits\n switch (frequencyUnits ?? 'hour') {\n case 'second': {\n return frequency * 1000\n }\n case 'minute': {\n return frequency * 60 * 1000\n }\n case 'hour': {\n return frequency * 60 * 60 * 1000\n }\n case 'day': {\n return frequency * 24 * 60 * 60 * 1000\n }\n default: {\n return Number.POSITIVE_INFINITY\n }\n }\n }\n\n protected get remaining() {\n return this.jsonPayload().remaining ?? Number.POSITIVE_INFINITY\n }\n\n next() {\n const now = Date.now()\n const previousStart = this.jsonPayload()?.start ?? now\n const start = Math.max(previousStart, now)\n const nextStart = start + this.frequencyMillis\n this.setStart(nextStart)\n this.consumeRemaining()\n this.checkEnd()\n return this\n }\n\n protected checkEnd() {\n if (this.jsonPayload().start > (this.jsonPayload().end ?? Number.POSITIVE_INFINITY)) {\n this.setStart(Number.POSITIVE_INFINITY)\n }\n }\n\n protected consumeRemaining(count = 1) {\n const remaining = Math.max(this.remaining - count, 0)\n this.setRemaining(remaining)\n if (remaining <= 0) this.setStart(Number.POSITIVE_INFINITY)\n }\n\n /**\n * Sets the remaining of the wrapped automation\n * @param remaining The remaining time in milliseconds\n */\n protected setRemaining(remaining: number) {\n this.obj.remaining = remaining\n }\n\n /**\n * Sets the start of the wrapped automation\n * @param start The start time in milliseconds\n */\n protected setStart(start: number) {\n this.obj.start = start\n }\n}\n"],"mappings":"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","names":["fulfilled","rejected","asDivinerInstance","AbstractSentinel","asSentinelInstance","SentinelConfigSchema","asWitnessInstance","assertEx","forget","PayloadBuilder","isSentinelIntervalAutomation","PayloadWrapper","SentinelIntervalAutomationWrapper","PayloadWrapper","constructor","payload","frequencyMillis","frequency","jsonPayload","undefined","Number","POSITIVE_INFINITY","frequencyUnits","remaining","next","now","Date","previousStart","start","Math","max","nextStart","setStart","consumeRemaining","checkEnd","end","count","setRemaining","obj","SentinelRunner","_automations","onTriggerResult","sentinel","timeoutId","constructor","automations","automation","forget","add","next","Object","values","reduce","previous","current","isSentinelIntervalAutomation","start","Number","POSITIVE_INFINITY","undefined","restart","hash","PayloadBuilder","dataHash","find","entries","key","remove","removeAll","stop","Promise","resolve","assertEx","now","Date","Math","max","delay","setTimeout","trigger","clearTimeout","update","wrapper","SentinelIntervalAutomationWrapper","jsonPayload","triggerResult","report","MemorySentinel","AbstractSentinel","configSchemas","SentinelConfigSchema","runner","reportHandler","inPayloads","started","logger","debug","JSON","stringify","job","jobPromise","index","previousResults","tasks","length","generatedPayloads","generateResults","result","Object","values","flat","start","timeout","config","automations","SentinelRunner","stop","undefined","results","Promise","allSettled","map","task","input","inPayloadsFound","processPreviousResults","inputAddresses","witness","asWitnessInstance","module","observed","observe","id","address","diviner","asDivinerInstance","divined","divine","sentinel","asSentinelInstance","reported","report","Error","finalResult","filter","fulfilled","payloads","value","push","throwErrors","errors","rejected","reason","Array","isArray","all","inputItem","resolved","resolve","inputs","flatMap"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SentinelRunner.d.ts","sourceRoot":"","sources":["../../src/SentinelRunner.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"SentinelRunner.d.ts","sourceRoot":"","sources":["../../src/SentinelRunner.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AACpD,OAAO,EAEL,yBAAyB,EACzB,gBAAgB,EAEjB,MAAM,6BAA6B,CAAA;AAIpC,MAAM,MAAM,6BAA6B,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;AAEvE,qBAAa,cAAc;IACzB,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAK;IACtE,SAAS,CAAC,eAAe,EAAE,6BAA6B,GAAG,SAAS,CAAA;IACpE,SAAS,CAAC,QAAQ,EAAE,gBAAgB,CAAA;IACpC,SAAS,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;gBAE1C,QAAQ,EAAE,gBAAgB,EAAE,WAAW,CAAC,EAAE,yBAAyB,EAAE,EAAE,eAAe,CAAC,EAAE,6BAA6B;IAMlI,IAAI,WAAW,8CAEd;IAED,OAAO,KAAK,IAAI,GASf;IAEK,GAAG,CAAC,UAAU,EAAE,yBAAyB,EAAE,OAAO,UAAO;IAO/D,IAAI,CAAC,IAAI,EAAE,MAAM;IAIX,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,UAAO;IAKzC,SAAS;IAKH,OAAO;IAKP,KAAK;IAyBX,IAAI;IAOE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,yBAAyB,EAAE,OAAO,UAAO;YAMlE,OAAO;CAStB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SentinelRunner.d.ts","sourceRoot":"","sources":["../../src/SentinelRunner.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"SentinelRunner.d.ts","sourceRoot":"","sources":["../../src/SentinelRunner.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AACpD,OAAO,EAEL,yBAAyB,EACzB,gBAAgB,EAEjB,MAAM,6BAA6B,CAAA;AAIpC,MAAM,MAAM,6BAA6B,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;AAEvE,qBAAa,cAAc;IACzB,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAK;IACtE,SAAS,CAAC,eAAe,EAAE,6BAA6B,GAAG,SAAS,CAAA;IACpE,SAAS,CAAC,QAAQ,EAAE,gBAAgB,CAAA;IACpC,SAAS,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;gBAE1C,QAAQ,EAAE,gBAAgB,EAAE,WAAW,CAAC,EAAE,yBAAyB,EAAE,EAAE,eAAe,CAAC,EAAE,6BAA6B;IAMlI,IAAI,WAAW,8CAEd;IAED,OAAO,KAAK,IAAI,GASf;IAEK,GAAG,CAAC,UAAU,EAAE,yBAAyB,EAAE,OAAO,UAAO;IAO/D,IAAI,CAAC,IAAI,EAAE,MAAM;IAIX,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,UAAO;IAKzC,SAAS;IAKH,OAAO;IAKP,KAAK;IAyBX,IAAI;IAOE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,yBAAyB,EAAE,OAAO,UAAO;YAMlE,OAAO;CAStB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SentinelRunner.d.ts","sourceRoot":"","sources":["../../src/SentinelRunner.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"SentinelRunner.d.ts","sourceRoot":"","sources":["../../src/SentinelRunner.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AACpD,OAAO,EAEL,yBAAyB,EACzB,gBAAgB,EAEjB,MAAM,6BAA6B,CAAA;AAIpC,MAAM,MAAM,6BAA6B,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;AAEvE,qBAAa,cAAc;IACzB,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAK;IACtE,SAAS,CAAC,eAAe,EAAE,6BAA6B,GAAG,SAAS,CAAA;IACpE,SAAS,CAAC,QAAQ,EAAE,gBAAgB,CAAA;IACpC,SAAS,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;gBAE1C,QAAQ,EAAE,gBAAgB,EAAE,WAAW,CAAC,EAAE,yBAAyB,EAAE,EAAE,eAAe,CAAC,EAAE,6BAA6B;IAMlI,IAAI,WAAW,8CAEd;IAED,OAAO,KAAK,IAAI,GASf;IAEK,GAAG,CAAC,UAAU,EAAE,yBAAyB,EAAE,OAAO,UAAO;IAO/D,IAAI,CAAC,IAAI,EAAE,MAAM;IAIX,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,UAAO;IAKzC,SAAS;IAKH,OAAO;IAKP,KAAK;IAyBX,IAAI;IAOE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,yBAAyB,EAAE,OAAO,UAAO;YAMlE,OAAO;CAStB"}
|
package/dist/node/index.cjs
CHANGED
|
@@ -41,7 +41,8 @@ var import_witness_model = require("@xyo-network/witness-model");
|
|
|
41
41
|
|
|
42
42
|
// src/SentinelRunner.ts
|
|
43
43
|
var import_assert = require("@xylabs/assert");
|
|
44
|
-
var
|
|
44
|
+
var import_forget = require("@xylabs/forget");
|
|
45
|
+
var import_payload_builder = require("@xyo-network/payload-builder");
|
|
45
46
|
var import_sentinel_model = require("@xyo-network/sentinel-model");
|
|
46
47
|
|
|
47
48
|
// src/SentinelIntervalAutomationWrapper.ts
|
|
@@ -127,7 +128,7 @@ var _SentinelRunner = class _SentinelRunner {
|
|
|
127
128
|
this.onTriggerResult = onTriggerResult;
|
|
128
129
|
if (automations)
|
|
129
130
|
for (const automation of automations)
|
|
130
|
-
this.add(automation);
|
|
131
|
+
(0, import_forget.forget)(this.add(automation));
|
|
131
132
|
}
|
|
132
133
|
get automations() {
|
|
133
134
|
return this._automations;
|
|
@@ -141,7 +142,7 @@ var _SentinelRunner = class _SentinelRunner {
|
|
|
141
142
|
}, void 0);
|
|
142
143
|
}
|
|
143
144
|
async add(automation, restart = true) {
|
|
144
|
-
const hash = await
|
|
145
|
+
const hash = await import_payload_builder.PayloadBuilder.dataHash(automation);
|
|
145
146
|
this._automations[hash] = automation;
|
|
146
147
|
if (restart)
|
|
147
148
|
await this.restart();
|
|
@@ -198,7 +199,7 @@ var _SentinelRunner = class _SentinelRunner {
|
|
|
198
199
|
async trigger(automation) {
|
|
199
200
|
var _a;
|
|
200
201
|
const wrapper = new SentinelIntervalAutomationWrapper(automation);
|
|
201
|
-
await this.remove(await wrapper.
|
|
202
|
+
await this.remove(await wrapper.dataHash(), false);
|
|
202
203
|
wrapper.next();
|
|
203
204
|
await this.add(wrapper.jsonPayload(), false);
|
|
204
205
|
const triggerResult = await this.sentinel.report();
|
package/dist/node/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts","../../src/MemorySentinel.ts","../../src/SentinelRunner.ts","../../src/SentinelIntervalAutomationWrapper.ts"],"sourcesContent":["export * from './MemorySentinel'\nexport * from './SentinelIntervalAutomationWrapper'\nexport * from './SentinelRunner'\n","import { Address } from '@xylabs/hex'\nimport { fulfilled, rejected } from '@xylabs/promise'\nimport { asDivinerInstance } from '@xyo-network/diviner-model'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { Payload } from '@xyo-network/payload-model'\nimport { AbstractSentinel } from '@xyo-network/sentinel-abstract'\nimport {\n asSentinelInstance,\n ResolvedTask,\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 { SentinelRunner } from './SentinelRunner'\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 private runner?: SentinelRunner\n\n async reportHandler(inPayloads: Payload[] = []): Promise<Payload[]> {\n await this.started('throw')\n this.logger?.debug(`reportHandler:in: ${JSON.stringify(inPayloads)}`)\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 const result = Object.values(previousResults).flat()\n this.logger?.debug(`reportHandler:out: ${JSON.stringify(result)}`)\n return result\n }\n\n override async start(timeout?: number | undefined): Promise<boolean> {\n if (await super.start(timeout)) {\n if ((this.config.automations?.length ?? 0) > 0) {\n this.runner = new SentinelRunner(this, this.config.automations)\n await this.runner.start()\n }\n return true\n }\n return false\n }\n\n override async stop(timeout?: number | undefined): Promise<boolean> {\n if (this.runner) {\n this.runner.stop()\n this.runner = undefined\n }\n return await super.stop(timeout)\n }\n\n private async generateResults(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n this.logger?.debug(`generateResults:tasks: ${JSON.stringify(tasks.length)}`)\n this.logger?.debug(`generateResults:previous: ${JSON.stringify(previousResults)}`)\n this.logger?.debug(`generateResults:in: ${JSON.stringify(inPayloads)}`)\n const results: PromiseSettledResult<[Address, Payload[]]>[] = await Promise.allSettled(\n tasks?.map(async (task) => {\n const input = task.input ?? false\n const inPayloadsFound =\n input === true ? inPayloads : input === false ? [] : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n const witness = asWitnessInstance(task.module)\n if (witness) {\n const observed = await witness.observe(inPayloadsFound)\n this.logger?.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`)\n return [witness.address, observed]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n const divined = await diviner.divine(inPayloadsFound)\n this.logger?.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`)\n return [diviner.address, divined]\n }\n const sentinel = asSentinelInstance(task.module)\n if (sentinel) {\n const reported = await sentinel.report(inPayloadsFound)\n this.logger?.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`)\n return [sentinel.address, reported]\n }\n throw new Error('Unsupported module type')\n }),\n )\n const finalResult: Record<Address, Payload[]> = {}\n for (const result of results.filter(fulfilled)) {\n const [address, payloads] = result.value\n finalResult[address] = finalResult[address] ?? []\n finalResult[address].push(...payloads)\n }\n if (this.throwErrors) {\n const errors = results.filter(rejected).map((result) => result.reason)\n if (errors.length > 0) {\n throw new Error('At least one module failed')\n }\n }\n this.logger?.debug(`generateResults:out: ${JSON.stringify(finalResult)}`)\n return finalResult\n }\n\n private async inputAddresses(input: string | string[]): Promise<string[]> {\n if (Array.isArray(input)) {\n return (await Promise.all(input.map(async (inputItem) => await this.inputAddresses(inputItem)))).flat()\n } else {\n const resolved = await this.resolve(input)\n return resolved ? [resolved.address] : []\n }\n }\n\n private processPreviousResults(payloads: Record<string, Payload[]>, inputs: string[]) {\n return inputs.flatMap((input) => payloads[input] ?? [])\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Payload } from '@xyo-network/payload-model'\nimport { PayloadWrapper } from '@xyo-network/payload-wrapper'\nimport {\n isSentinelIntervalAutomation,\n SentinelAutomationPayload,\n SentinelInstance,\n SentinelIntervalAutomationPayload,\n} from '@xyo-network/sentinel-model'\n\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 if (automations) for (const automation of automations) this.add(automation)\n }\n\n get automations() {\n return this._automations\n }\n\n private get next() {\n // eslint-disable-next-line unicorn/no-array-reduce\n return Object.values(this._automations).reduce<SentinelAutomationPayload | undefined>((previous, current) => {\n if (isSentinelIntervalAutomation(current) && isSentinelIntervalAutomation(previous)) {\n return current.start < (previous?.start ?? Number.POSITIVE_INFINITY) ? current : previous\n }\n return current\n // eslint-disable-next-line unicorn/no-useless-undefined\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 // NOTE: Keep async to match module start signature\n await Promise.resolve()\n assertEx(this.timeoutId === undefined, 'Already started')\n const automation = this.next\n if (isSentinelIntervalAutomation(automation)) {\n const now = Date.now()\n const start = Math.max(automation.start ?? now, now)\n const delay = Math.max(start - now, 0)\n if (delay < Number.POSITIVE_INFINITY) {\n this.timeoutId = setTimeout(async () => {\n try {\n // Run the automation\n await this.trigger(automation)\n this.stop()\n } finally {\n // No matter what start the next automation\n await this.start()\n }\n }, delay)\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.jsonPayload(), false)\n const triggerResult = await this.sentinel.report()\n this.onTriggerResult?.(triggerResult)\n // await this.start()\n }\n}\n","import { PayloadWrapper } from '@xyo-network/payload-wrapper'\nimport { SentinelIntervalAutomationPayload } from '@xyo-network/sentinel-model'\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.jsonPayload().frequency\n if (frequency === undefined) return Number.POSITIVE_INFINITY\n const frequencyUnits = this.jsonPayload().frequencyUnits\n switch (frequencyUnits ?? 'hour') {\n case 'second': {\n return frequency * 1000\n }\n case 'minute': {\n return frequency * 60 * 1000\n }\n case 'hour': {\n return frequency * 60 * 60 * 1000\n }\n case 'day': {\n return frequency * 24 * 60 * 60 * 1000\n }\n default: {\n return Number.POSITIVE_INFINITY\n }\n }\n }\n\n protected get remaining() {\n return this.jsonPayload().remaining ?? Number.POSITIVE_INFINITY\n }\n\n next() {\n const now = Date.now()\n const previousStart = this.jsonPayload()?.start ?? now\n const start = Math.max(previousStart, now)\n const nextStart = start + this.frequencyMillis\n this.setStart(nextStart)\n this.consumeRemaining()\n this.checkEnd()\n return this\n }\n\n protected checkEnd() {\n if (this.jsonPayload().start > (this.jsonPayload().end ?? Number.POSITIVE_INFINITY)) {\n this.setStart(Number.POSITIVE_INFINITY)\n }\n }\n\n protected consumeRemaining(count = 1) {\n const remaining = Math.max(this.remaining - count, 0)\n this.setRemaining(remaining)\n if (remaining <= 0) this.setStart(Number.POSITIVE_INFINITY)\n }\n\n /**\n * Sets the remaining of the wrapped automation\n * @param remaining The remaining time in milliseconds\n */\n protected setRemaining(remaining: number) {\n this.obj.remaining = remaining\n }\n\n /**\n * Sets the start of the wrapped automation\n * @param start The start time in milliseconds\n */\n protected setStart(start: number) {\n this.obj.start = start\n }\n}\n"],"mappings":"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","names":["import_sentinel_model","import_payload_wrapper","SentinelIntervalAutomationWrapper","PayloadWrapper","constructor","payload","frequencyMillis","frequency","jsonPayload","undefined","Number","POSITIVE_INFINITY","frequencyUnits","remaining","next","now","Date","previousStart","start","Math","max","nextStart","setStart","consumeRemaining","checkEnd","end","count","setRemaining","obj","SentinelRunner","_automations","onTriggerResult","sentinel","timeoutId","constructor","automations","automation","add","next","Object","values","reduce","previous","current","isSentinelIntervalAutomation","start","Number","POSITIVE_INFINITY","undefined","restart","hash","PayloadWrapper","hashAsync","find","entries","key","remove","removeAll","stop","Promise","resolve","assertEx","now","Date","Math","max","delay","setTimeout","trigger","clearTimeout","update","wrapper","SentinelIntervalAutomationWrapper","jsonPayload","triggerResult","report","MemorySentinel","AbstractSentinel","runner","reportHandler","inPayloads","started","logger","debug","JSON","stringify","job","jobPromise","index","previousResults","tasks","length","generatedPayloads","generateResults","result","Object","values","flat","start","timeout","config","automations","SentinelRunner","stop","undefined","results","Promise","allSettled","map","task","_a","_b","_c","input","inPayloadsFound","processPreviousResults","inputAddresses","witness","asWitnessInstance","module","observed","observe","id","address","diviner","asDivinerInstance","divined","divine","sentinel","asSentinelInstance","reported","report","Error","finalResult","filter","fulfilled","payloads","value","push","throwErrors","errors","rejected","reason","Array","isArray","all","inputItem","resolved","resolve","inputs","flatMap","configSchemas","SentinelConfigSchema"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/MemorySentinel.ts","../../src/SentinelRunner.ts","../../src/SentinelIntervalAutomationWrapper.ts"],"sourcesContent":["export * from './MemorySentinel'\nexport * from './SentinelIntervalAutomationWrapper'\nexport * from './SentinelRunner'\n","import { Address } from '@xylabs/hex'\nimport { fulfilled, rejected } from '@xylabs/promise'\nimport { asDivinerInstance } from '@xyo-network/diviner-model'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { Payload } from '@xyo-network/payload-model'\nimport { AbstractSentinel } from '@xyo-network/sentinel-abstract'\nimport {\n asSentinelInstance,\n ResolvedTask,\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 { SentinelRunner } from './SentinelRunner'\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 private runner?: SentinelRunner\n\n async reportHandler(inPayloads: Payload[] = []): Promise<Payload[]> {\n await this.started('throw')\n this.logger?.debug(`reportHandler:in: ${JSON.stringify(inPayloads)}`)\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 const result = Object.values(previousResults).flat()\n this.logger?.debug(`reportHandler:out: ${JSON.stringify(result)}`)\n return result\n }\n\n override async start(timeout?: number | undefined): Promise<boolean> {\n if (await super.start(timeout)) {\n if ((this.config.automations?.length ?? 0) > 0) {\n this.runner = new SentinelRunner(this, this.config.automations)\n await this.runner.start()\n }\n return true\n }\n return false\n }\n\n override async stop(timeout?: number | undefined): Promise<boolean> {\n if (this.runner) {\n this.runner.stop()\n this.runner = undefined\n }\n return await super.stop(timeout)\n }\n\n private async generateResults(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n this.logger?.debug(`generateResults:tasks: ${JSON.stringify(tasks.length)}`)\n this.logger?.debug(`generateResults:previous: ${JSON.stringify(previousResults)}`)\n this.logger?.debug(`generateResults:in: ${JSON.stringify(inPayloads)}`)\n const results: PromiseSettledResult<[Address, Payload[]]>[] = await Promise.allSettled(\n tasks?.map(async (task) => {\n const input = task.input ?? false\n const inPayloadsFound =\n input === true ? inPayloads : input === false ? [] : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n const witness = asWitnessInstance(task.module)\n if (witness) {\n const observed = await witness.observe(inPayloadsFound)\n this.logger?.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`)\n return [witness.address, observed]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n const divined = await diviner.divine(inPayloadsFound)\n this.logger?.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`)\n return [diviner.address, divined]\n }\n const sentinel = asSentinelInstance(task.module)\n if (sentinel) {\n const reported = await sentinel.report(inPayloadsFound)\n this.logger?.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`)\n return [sentinel.address, reported]\n }\n throw new Error('Unsupported module type')\n }),\n )\n const finalResult: Record<Address, Payload[]> = {}\n for (const result of results.filter(fulfilled)) {\n const [address, payloads] = result.value\n finalResult[address] = finalResult[address] ?? []\n finalResult[address].push(...payloads)\n }\n if (this.throwErrors) {\n const errors = results.filter(rejected).map((result) => result.reason)\n if (errors.length > 0) {\n throw new Error('At least one module failed')\n }\n }\n this.logger?.debug(`generateResults:out: ${JSON.stringify(finalResult)}`)\n return finalResult\n }\n\n private async inputAddresses(input: string | string[]): Promise<string[]> {\n if (Array.isArray(input)) {\n return (await Promise.all(input.map(async (inputItem) => await this.inputAddresses(inputItem)))).flat()\n } else {\n const resolved = await this.resolve(input)\n return resolved ? [resolved.address] : []\n }\n }\n\n private processPreviousResults(payloads: Record<string, Payload[]>, inputs: string[]) {\n return inputs.flatMap((input) => payloads[input] ?? [])\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { forget } from '@xylabs/forget'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport { Payload } from '@xyo-network/payload-model'\nimport {\n isSentinelIntervalAutomation,\n SentinelAutomationPayload,\n SentinelInstance,\n SentinelIntervalAutomationPayload,\n} from '@xyo-network/sentinel-model'\n\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 if (automations) for (const automation of automations) forget(this.add(automation))\n }\n\n get automations() {\n return this._automations\n }\n\n private get next() {\n // eslint-disable-next-line unicorn/no-array-reduce\n return Object.values(this._automations).reduce<SentinelAutomationPayload | undefined>((previous, current) => {\n if (isSentinelIntervalAutomation(current) && isSentinelIntervalAutomation(previous)) {\n return current.start < (previous?.start ?? Number.POSITIVE_INFINITY) ? current : previous\n }\n return current\n // eslint-disable-next-line unicorn/no-useless-undefined\n }, undefined)\n }\n\n async add(automation: SentinelAutomationPayload, restart = true) {\n const hash = await PayloadBuilder.dataHash(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 // NOTE: Keep async to match module start signature\n await Promise.resolve()\n assertEx(this.timeoutId === undefined, 'Already started')\n const automation = this.next\n if (isSentinelIntervalAutomation(automation)) {\n const now = Date.now()\n const start = Math.max(automation.start ?? now, now)\n const delay = Math.max(start - now, 0)\n if (delay < Number.POSITIVE_INFINITY) {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.timeoutId = setTimeout(async () => {\n try {\n // Run the automation\n await this.trigger(automation)\n this.stop()\n } finally {\n // No matter what start the next automation\n await this.start()\n }\n }, delay)\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.dataHash(), false)\n wrapper.next()\n await this.add(wrapper.jsonPayload(), false)\n const triggerResult = await this.sentinel.report()\n this.onTriggerResult?.(triggerResult)\n // await this.start()\n }\n}\n","import { PayloadWrapper } from '@xyo-network/payload-wrapper'\nimport { SentinelIntervalAutomationPayload } from '@xyo-network/sentinel-model'\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.jsonPayload().frequency\n if (frequency === undefined) return Number.POSITIVE_INFINITY\n const frequencyUnits = this.jsonPayload().frequencyUnits\n switch (frequencyUnits ?? 'hour') {\n case 'second': {\n return frequency * 1000\n }\n case 'minute': {\n return frequency * 60 * 1000\n }\n case 'hour': {\n return frequency * 60 * 60 * 1000\n }\n case 'day': {\n return frequency * 24 * 60 * 60 * 1000\n }\n default: {\n return Number.POSITIVE_INFINITY\n }\n }\n }\n\n protected get remaining() {\n return this.jsonPayload().remaining ?? Number.POSITIVE_INFINITY\n }\n\n next() {\n const now = Date.now()\n const previousStart = this.jsonPayload()?.start ?? now\n const start = Math.max(previousStart, now)\n const nextStart = start + this.frequencyMillis\n this.setStart(nextStart)\n this.consumeRemaining()\n this.checkEnd()\n return this\n }\n\n protected checkEnd() {\n if (this.jsonPayload().start > (this.jsonPayload().end ?? Number.POSITIVE_INFINITY)) {\n this.setStart(Number.POSITIVE_INFINITY)\n }\n }\n\n protected consumeRemaining(count = 1) {\n const remaining = Math.max(this.remaining - count, 0)\n this.setRemaining(remaining)\n if (remaining <= 0) this.setStart(Number.POSITIVE_INFINITY)\n }\n\n /**\n * Sets the remaining of the wrapped automation\n * @param remaining The remaining time in milliseconds\n */\n protected setRemaining(remaining: number) {\n this.obj.remaining = remaining\n }\n\n /**\n * Sets the start of the wrapped automation\n * @param start The start time in milliseconds\n */\n protected setStart(start: number) {\n this.obj.start = start\n }\n}\n"],"mappings":"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","names":["import_sentinel_model","SentinelIntervalAutomationWrapper","PayloadWrapper","constructor","payload","frequencyMillis","frequency","jsonPayload","undefined","Number","POSITIVE_INFINITY","frequencyUnits","remaining","next","now","Date","previousStart","start","Math","max","nextStart","setStart","consumeRemaining","checkEnd","end","count","setRemaining","obj","SentinelRunner","_automations","onTriggerResult","sentinel","timeoutId","constructor","automations","automation","forget","add","next","Object","values","reduce","previous","current","isSentinelIntervalAutomation","start","Number","POSITIVE_INFINITY","undefined","restart","hash","PayloadBuilder","dataHash","find","entries","key","remove","removeAll","stop","Promise","resolve","assertEx","now","Date","Math","max","delay","setTimeout","trigger","clearTimeout","update","wrapper","SentinelIntervalAutomationWrapper","jsonPayload","triggerResult","report","MemorySentinel","AbstractSentinel","runner","reportHandler","inPayloads","started","logger","debug","JSON","stringify","job","jobPromise","index","previousResults","tasks","length","generatedPayloads","generateResults","result","Object","values","flat","start","timeout","config","automations","SentinelRunner","stop","undefined","results","Promise","allSettled","map","task","_a","_b","_c","input","inPayloadsFound","processPreviousResults","inputAddresses","witness","asWitnessInstance","module","observed","observe","id","address","diviner","asDivinerInstance","divined","divine","sentinel","asSentinelInstance","reported","report","Error","finalResult","filter","fulfilled","payloads","value","push","throwErrors","errors","rejected","reason","Array","isArray","all","inputItem","resolved","resolve","inputs","flatMap","configSchemas","SentinelConfigSchema"]}
|
package/dist/node/index.js
CHANGED
|
@@ -15,7 +15,8 @@ import { asWitnessInstance } from "@xyo-network/witness-model";
|
|
|
15
15
|
|
|
16
16
|
// src/SentinelRunner.ts
|
|
17
17
|
import { assertEx } from "@xylabs/assert";
|
|
18
|
-
import {
|
|
18
|
+
import { forget } from "@xylabs/forget";
|
|
19
|
+
import { PayloadBuilder } from "@xyo-network/payload-builder";
|
|
19
20
|
import { isSentinelIntervalAutomation } from "@xyo-network/sentinel-model";
|
|
20
21
|
|
|
21
22
|
// src/SentinelIntervalAutomationWrapper.ts
|
|
@@ -101,7 +102,7 @@ var _SentinelRunner = class _SentinelRunner {
|
|
|
101
102
|
this.onTriggerResult = onTriggerResult;
|
|
102
103
|
if (automations)
|
|
103
104
|
for (const automation of automations)
|
|
104
|
-
this.add(automation);
|
|
105
|
+
forget(this.add(automation));
|
|
105
106
|
}
|
|
106
107
|
get automations() {
|
|
107
108
|
return this._automations;
|
|
@@ -115,7 +116,7 @@ var _SentinelRunner = class _SentinelRunner {
|
|
|
115
116
|
}, void 0);
|
|
116
117
|
}
|
|
117
118
|
async add(automation, restart = true) {
|
|
118
|
-
const hash = await
|
|
119
|
+
const hash = await PayloadBuilder.dataHash(automation);
|
|
119
120
|
this._automations[hash] = automation;
|
|
120
121
|
if (restart)
|
|
121
122
|
await this.restart();
|
|
@@ -172,7 +173,7 @@ var _SentinelRunner = class _SentinelRunner {
|
|
|
172
173
|
async trigger(automation) {
|
|
173
174
|
var _a;
|
|
174
175
|
const wrapper = new SentinelIntervalAutomationWrapper(automation);
|
|
175
|
-
await this.remove(await wrapper.
|
|
176
|
+
await this.remove(await wrapper.dataHash(), false);
|
|
176
177
|
wrapper.next();
|
|
177
178
|
await this.add(wrapper.jsonPayload(), false);
|
|
178
179
|
const triggerResult = await this.sentinel.report();
|
package/dist/node/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/MemorySentinel.ts","../../src/SentinelRunner.ts","../../src/SentinelIntervalAutomationWrapper.ts"],"sourcesContent":["import { Address } from '@xylabs/hex'\nimport { fulfilled, rejected } from '@xylabs/promise'\nimport { asDivinerInstance } from '@xyo-network/diviner-model'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { Payload } from '@xyo-network/payload-model'\nimport { AbstractSentinel } from '@xyo-network/sentinel-abstract'\nimport {\n asSentinelInstance,\n ResolvedTask,\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 { SentinelRunner } from './SentinelRunner'\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 private runner?: SentinelRunner\n\n async reportHandler(inPayloads: Payload[] = []): Promise<Payload[]> {\n await this.started('throw')\n this.logger?.debug(`reportHandler:in: ${JSON.stringify(inPayloads)}`)\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 const result = Object.values(previousResults).flat()\n this.logger?.debug(`reportHandler:out: ${JSON.stringify(result)}`)\n return result\n }\n\n override async start(timeout?: number | undefined): Promise<boolean> {\n if (await super.start(timeout)) {\n if ((this.config.automations?.length ?? 0) > 0) {\n this.runner = new SentinelRunner(this, this.config.automations)\n await this.runner.start()\n }\n return true\n }\n return false\n }\n\n override async stop(timeout?: number | undefined): Promise<boolean> {\n if (this.runner) {\n this.runner.stop()\n this.runner = undefined\n }\n return await super.stop(timeout)\n }\n\n private async generateResults(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n this.logger?.debug(`generateResults:tasks: ${JSON.stringify(tasks.length)}`)\n this.logger?.debug(`generateResults:previous: ${JSON.stringify(previousResults)}`)\n this.logger?.debug(`generateResults:in: ${JSON.stringify(inPayloads)}`)\n const results: PromiseSettledResult<[Address, Payload[]]>[] = await Promise.allSettled(\n tasks?.map(async (task) => {\n const input = task.input ?? false\n const inPayloadsFound =\n input === true ? inPayloads : input === false ? [] : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n const witness = asWitnessInstance(task.module)\n if (witness) {\n const observed = await witness.observe(inPayloadsFound)\n this.logger?.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`)\n return [witness.address, observed]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n const divined = await diviner.divine(inPayloadsFound)\n this.logger?.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`)\n return [diviner.address, divined]\n }\n const sentinel = asSentinelInstance(task.module)\n if (sentinel) {\n const reported = await sentinel.report(inPayloadsFound)\n this.logger?.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`)\n return [sentinel.address, reported]\n }\n throw new Error('Unsupported module type')\n }),\n )\n const finalResult: Record<Address, Payload[]> = {}\n for (const result of results.filter(fulfilled)) {\n const [address, payloads] = result.value\n finalResult[address] = finalResult[address] ?? []\n finalResult[address].push(...payloads)\n }\n if (this.throwErrors) {\n const errors = results.filter(rejected).map((result) => result.reason)\n if (errors.length > 0) {\n throw new Error('At least one module failed')\n }\n }\n this.logger?.debug(`generateResults:out: ${JSON.stringify(finalResult)}`)\n return finalResult\n }\n\n private async inputAddresses(input: string | string[]): Promise<string[]> {\n if (Array.isArray(input)) {\n return (await Promise.all(input.map(async (inputItem) => await this.inputAddresses(inputItem)))).flat()\n } else {\n const resolved = await this.resolve(input)\n return resolved ? [resolved.address] : []\n }\n }\n\n private processPreviousResults(payloads: Record<string, Payload[]>, inputs: string[]) {\n return inputs.flatMap((input) => payloads[input] ?? [])\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Payload } from '@xyo-network/payload-model'\nimport { PayloadWrapper } from '@xyo-network/payload-wrapper'\nimport {\n isSentinelIntervalAutomation,\n SentinelAutomationPayload,\n SentinelInstance,\n SentinelIntervalAutomationPayload,\n} from '@xyo-network/sentinel-model'\n\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 if (automations) for (const automation of automations) this.add(automation)\n }\n\n get automations() {\n return this._automations\n }\n\n private get next() {\n // eslint-disable-next-line unicorn/no-array-reduce\n return Object.values(this._automations).reduce<SentinelAutomationPayload | undefined>((previous, current) => {\n if (isSentinelIntervalAutomation(current) && isSentinelIntervalAutomation(previous)) {\n return current.start < (previous?.start ?? Number.POSITIVE_INFINITY) ? current : previous\n }\n return current\n // eslint-disable-next-line unicorn/no-useless-undefined\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 // NOTE: Keep async to match module start signature\n await Promise.resolve()\n assertEx(this.timeoutId === undefined, 'Already started')\n const automation = this.next\n if (isSentinelIntervalAutomation(automation)) {\n const now = Date.now()\n const start = Math.max(automation.start ?? now, now)\n const delay = Math.max(start - now, 0)\n if (delay < Number.POSITIVE_INFINITY) {\n this.timeoutId = setTimeout(async () => {\n try {\n // Run the automation\n await this.trigger(automation)\n this.stop()\n } finally {\n // No matter what start the next automation\n await this.start()\n }\n }, delay)\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.jsonPayload(), false)\n const triggerResult = await this.sentinel.report()\n this.onTriggerResult?.(triggerResult)\n // await this.start()\n }\n}\n","import { PayloadWrapper } from '@xyo-network/payload-wrapper'\nimport { SentinelIntervalAutomationPayload } from '@xyo-network/sentinel-model'\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.jsonPayload().frequency\n if (frequency === undefined) return Number.POSITIVE_INFINITY\n const frequencyUnits = this.jsonPayload().frequencyUnits\n switch (frequencyUnits ?? 'hour') {\n case 'second': {\n return frequency * 1000\n }\n case 'minute': {\n return frequency * 60 * 1000\n }\n case 'hour': {\n return frequency * 60 * 60 * 1000\n }\n case 'day': {\n return frequency * 24 * 60 * 60 * 1000\n }\n default: {\n return Number.POSITIVE_INFINITY\n }\n }\n }\n\n protected get remaining() {\n return this.jsonPayload().remaining ?? Number.POSITIVE_INFINITY\n }\n\n next() {\n const now = Date.now()\n const previousStart = this.jsonPayload()?.start ?? now\n const start = Math.max(previousStart, now)\n const nextStart = start + this.frequencyMillis\n this.setStart(nextStart)\n this.consumeRemaining()\n this.checkEnd()\n return this\n }\n\n protected checkEnd() {\n if (this.jsonPayload().start > (this.jsonPayload().end ?? Number.POSITIVE_INFINITY)) {\n this.setStart(Number.POSITIVE_INFINITY)\n }\n }\n\n protected consumeRemaining(count = 1) {\n const remaining = Math.max(this.remaining - count, 0)\n this.setRemaining(remaining)\n if (remaining <= 0) this.setStart(Number.POSITIVE_INFINITY)\n }\n\n /**\n * Sets the remaining of the wrapped automation\n * @param remaining The remaining time in milliseconds\n */\n protected setRemaining(remaining: number) {\n this.obj.remaining = remaining\n }\n\n /**\n * Sets the start of the wrapped automation\n * @param start The start time in milliseconds\n */\n protected setStart(start: number) {\n this.obj.start = start\n }\n}\n"],"mappings":"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","names":["fulfilled","rejected","asDivinerInstance","AbstractSentinel","asSentinelInstance","SentinelConfigSchema","asWitnessInstance","assertEx","PayloadWrapper","isSentinelIntervalAutomation","PayloadWrapper","SentinelIntervalAutomationWrapper","PayloadWrapper","constructor","payload","frequencyMillis","frequency","jsonPayload","undefined","Number","POSITIVE_INFINITY","frequencyUnits","remaining","next","now","Date","previousStart","start","Math","max","nextStart","setStart","consumeRemaining","checkEnd","end","count","setRemaining","obj","SentinelRunner","_automations","onTriggerResult","sentinel","timeoutId","constructor","automations","automation","add","next","Object","values","reduce","previous","current","isSentinelIntervalAutomation","start","Number","POSITIVE_INFINITY","undefined","restart","hash","PayloadWrapper","hashAsync","find","entries","key","remove","removeAll","stop","Promise","resolve","assertEx","now","Date","Math","max","delay","setTimeout","trigger","clearTimeout","update","wrapper","SentinelIntervalAutomationWrapper","jsonPayload","triggerResult","report","MemorySentinel","AbstractSentinel","runner","reportHandler","inPayloads","started","logger","debug","JSON","stringify","job","jobPromise","index","previousResults","tasks","length","generatedPayloads","generateResults","result","Object","values","flat","start","timeout","config","automations","SentinelRunner","stop","undefined","results","Promise","allSettled","map","task","_a","_b","_c","input","inPayloadsFound","processPreviousResults","inputAddresses","witness","asWitnessInstance","module","observed","observe","id","address","diviner","asDivinerInstance","divined","divine","sentinel","asSentinelInstance","reported","report","Error","finalResult","filter","fulfilled","payloads","value","push","throwErrors","errors","rejected","reason","Array","isArray","all","inputItem","resolved","resolve","inputs","flatMap","configSchemas","SentinelConfigSchema"]}
|
|
1
|
+
{"version":3,"sources":["../../src/MemorySentinel.ts","../../src/SentinelRunner.ts","../../src/SentinelIntervalAutomationWrapper.ts"],"sourcesContent":["import { Address } from '@xylabs/hex'\nimport { fulfilled, rejected } from '@xylabs/promise'\nimport { asDivinerInstance } from '@xyo-network/diviner-model'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { Payload } from '@xyo-network/payload-model'\nimport { AbstractSentinel } from '@xyo-network/sentinel-abstract'\nimport {\n asSentinelInstance,\n ResolvedTask,\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 { SentinelRunner } from './SentinelRunner'\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 private runner?: SentinelRunner\n\n async reportHandler(inPayloads: Payload[] = []): Promise<Payload[]> {\n await this.started('throw')\n this.logger?.debug(`reportHandler:in: ${JSON.stringify(inPayloads)}`)\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 const result = Object.values(previousResults).flat()\n this.logger?.debug(`reportHandler:out: ${JSON.stringify(result)}`)\n return result\n }\n\n override async start(timeout?: number | undefined): Promise<boolean> {\n if (await super.start(timeout)) {\n if ((this.config.automations?.length ?? 0) > 0) {\n this.runner = new SentinelRunner(this, this.config.automations)\n await this.runner.start()\n }\n return true\n }\n return false\n }\n\n override async stop(timeout?: number | undefined): Promise<boolean> {\n if (this.runner) {\n this.runner.stop()\n this.runner = undefined\n }\n return await super.stop(timeout)\n }\n\n private async generateResults(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n this.logger?.debug(`generateResults:tasks: ${JSON.stringify(tasks.length)}`)\n this.logger?.debug(`generateResults:previous: ${JSON.stringify(previousResults)}`)\n this.logger?.debug(`generateResults:in: ${JSON.stringify(inPayloads)}`)\n const results: PromiseSettledResult<[Address, Payload[]]>[] = await Promise.allSettled(\n tasks?.map(async (task) => {\n const input = task.input ?? false\n const inPayloadsFound =\n input === true ? inPayloads : input === false ? [] : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n const witness = asWitnessInstance(task.module)\n if (witness) {\n const observed = await witness.observe(inPayloadsFound)\n this.logger?.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`)\n return [witness.address, observed]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n const divined = await diviner.divine(inPayloadsFound)\n this.logger?.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`)\n return [diviner.address, divined]\n }\n const sentinel = asSentinelInstance(task.module)\n if (sentinel) {\n const reported = await sentinel.report(inPayloadsFound)\n this.logger?.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`)\n return [sentinel.address, reported]\n }\n throw new Error('Unsupported module type')\n }),\n )\n const finalResult: Record<Address, Payload[]> = {}\n for (const result of results.filter(fulfilled)) {\n const [address, payloads] = result.value\n finalResult[address] = finalResult[address] ?? []\n finalResult[address].push(...payloads)\n }\n if (this.throwErrors) {\n const errors = results.filter(rejected).map((result) => result.reason)\n if (errors.length > 0) {\n throw new Error('At least one module failed')\n }\n }\n this.logger?.debug(`generateResults:out: ${JSON.stringify(finalResult)}`)\n return finalResult\n }\n\n private async inputAddresses(input: string | string[]): Promise<string[]> {\n if (Array.isArray(input)) {\n return (await Promise.all(input.map(async (inputItem) => await this.inputAddresses(inputItem)))).flat()\n } else {\n const resolved = await this.resolve(input)\n return resolved ? [resolved.address] : []\n }\n }\n\n private processPreviousResults(payloads: Record<string, Payload[]>, inputs: string[]) {\n return inputs.flatMap((input) => payloads[input] ?? [])\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { forget } from '@xylabs/forget'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport { Payload } from '@xyo-network/payload-model'\nimport {\n isSentinelIntervalAutomation,\n SentinelAutomationPayload,\n SentinelInstance,\n SentinelIntervalAutomationPayload,\n} from '@xyo-network/sentinel-model'\n\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 if (automations) for (const automation of automations) forget(this.add(automation))\n }\n\n get automations() {\n return this._automations\n }\n\n private get next() {\n // eslint-disable-next-line unicorn/no-array-reduce\n return Object.values(this._automations).reduce<SentinelAutomationPayload | undefined>((previous, current) => {\n if (isSentinelIntervalAutomation(current) && isSentinelIntervalAutomation(previous)) {\n return current.start < (previous?.start ?? Number.POSITIVE_INFINITY) ? current : previous\n }\n return current\n // eslint-disable-next-line unicorn/no-useless-undefined\n }, undefined)\n }\n\n async add(automation: SentinelAutomationPayload, restart = true) {\n const hash = await PayloadBuilder.dataHash(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 // NOTE: Keep async to match module start signature\n await Promise.resolve()\n assertEx(this.timeoutId === undefined, 'Already started')\n const automation = this.next\n if (isSentinelIntervalAutomation(automation)) {\n const now = Date.now()\n const start = Math.max(automation.start ?? now, now)\n const delay = Math.max(start - now, 0)\n if (delay < Number.POSITIVE_INFINITY) {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.timeoutId = setTimeout(async () => {\n try {\n // Run the automation\n await this.trigger(automation)\n this.stop()\n } finally {\n // No matter what start the next automation\n await this.start()\n }\n }, delay)\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.dataHash(), false)\n wrapper.next()\n await this.add(wrapper.jsonPayload(), false)\n const triggerResult = await this.sentinel.report()\n this.onTriggerResult?.(triggerResult)\n // await this.start()\n }\n}\n","import { PayloadWrapper } from '@xyo-network/payload-wrapper'\nimport { SentinelIntervalAutomationPayload } from '@xyo-network/sentinel-model'\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.jsonPayload().frequency\n if (frequency === undefined) return Number.POSITIVE_INFINITY\n const frequencyUnits = this.jsonPayload().frequencyUnits\n switch (frequencyUnits ?? 'hour') {\n case 'second': {\n return frequency * 1000\n }\n case 'minute': {\n return frequency * 60 * 1000\n }\n case 'hour': {\n return frequency * 60 * 60 * 1000\n }\n case 'day': {\n return frequency * 24 * 60 * 60 * 1000\n }\n default: {\n return Number.POSITIVE_INFINITY\n }\n }\n }\n\n protected get remaining() {\n return this.jsonPayload().remaining ?? Number.POSITIVE_INFINITY\n }\n\n next() {\n const now = Date.now()\n const previousStart = this.jsonPayload()?.start ?? now\n const start = Math.max(previousStart, now)\n const nextStart = start + this.frequencyMillis\n this.setStart(nextStart)\n this.consumeRemaining()\n this.checkEnd()\n return this\n }\n\n protected checkEnd() {\n if (this.jsonPayload().start > (this.jsonPayload().end ?? Number.POSITIVE_INFINITY)) {\n this.setStart(Number.POSITIVE_INFINITY)\n }\n }\n\n protected consumeRemaining(count = 1) {\n const remaining = Math.max(this.remaining - count, 0)\n this.setRemaining(remaining)\n if (remaining <= 0) this.setStart(Number.POSITIVE_INFINITY)\n }\n\n /**\n * Sets the remaining of the wrapped automation\n * @param remaining The remaining time in milliseconds\n */\n protected setRemaining(remaining: number) {\n this.obj.remaining = remaining\n }\n\n /**\n * Sets the start of the wrapped automation\n * @param start The start time in milliseconds\n */\n protected setStart(start: number) {\n this.obj.start = start\n }\n}\n"],"mappings":"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","names":["fulfilled","rejected","asDivinerInstance","AbstractSentinel","asSentinelInstance","SentinelConfigSchema","asWitnessInstance","assertEx","forget","PayloadBuilder","isSentinelIntervalAutomation","PayloadWrapper","SentinelIntervalAutomationWrapper","PayloadWrapper","constructor","payload","frequencyMillis","frequency","jsonPayload","undefined","Number","POSITIVE_INFINITY","frequencyUnits","remaining","next","now","Date","previousStart","start","Math","max","nextStart","setStart","consumeRemaining","checkEnd","end","count","setRemaining","obj","SentinelRunner","_automations","onTriggerResult","sentinel","timeoutId","constructor","automations","automation","forget","add","next","Object","values","reduce","previous","current","isSentinelIntervalAutomation","start","Number","POSITIVE_INFINITY","undefined","restart","hash","PayloadBuilder","dataHash","find","entries","key","remove","removeAll","stop","Promise","resolve","assertEx","now","Date","Math","max","delay","setTimeout","trigger","clearTimeout","update","wrapper","SentinelIntervalAutomationWrapper","jsonPayload","triggerResult","report","MemorySentinel","AbstractSentinel","runner","reportHandler","inPayloads","started","logger","debug","JSON","stringify","job","jobPromise","index","previousResults","tasks","length","generatedPayloads","generateResults","result","Object","values","flat","start","timeout","config","automations","SentinelRunner","stop","undefined","results","Promise","allSettled","map","task","_a","_b","_c","input","inPayloadsFound","processPreviousResults","inputAddresses","witness","asWitnessInstance","module","observed","observe","id","address","diviner","asDivinerInstance","divined","divine","sentinel","asSentinelInstance","reported","report","Error","finalResult","filter","fulfilled","payloads","value","push","throwErrors","errors","rejected","reason","Array","isArray","all","inputItem","resolved","resolve","inputs","flatMap","configSchemas","SentinelConfigSchema"]}
|
package/package.json
CHANGED
|
@@ -10,28 +10,30 @@
|
|
|
10
10
|
"url": "https://github.com/XYOracleNetwork/sdk-xyo-client-js/issues"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@xylabs/assert": "^2.
|
|
14
|
-
"@xylabs/
|
|
15
|
-
"@xylabs/
|
|
16
|
-
"@
|
|
17
|
-
"@xyo-network/
|
|
18
|
-
"@xyo-network/
|
|
19
|
-
"@xyo-network/payload-
|
|
20
|
-
"@xyo-network/
|
|
21
|
-
"@xyo-network/
|
|
22
|
-
"@xyo-network/
|
|
13
|
+
"@xylabs/assert": "^2.14.0",
|
|
14
|
+
"@xylabs/forget": "^2.14.0",
|
|
15
|
+
"@xylabs/hex": "^2.14.0",
|
|
16
|
+
"@xylabs/promise": "^2.14.0",
|
|
17
|
+
"@xyo-network/diviner-model": "~2.89.0-rc.10",
|
|
18
|
+
"@xyo-network/module-model": "~2.89.0-rc.10",
|
|
19
|
+
"@xyo-network/payload-builder": "~2.89.0-rc.10",
|
|
20
|
+
"@xyo-network/payload-model": "~2.89.0-rc.10",
|
|
21
|
+
"@xyo-network/payload-wrapper": "~2.89.0-rc.10",
|
|
22
|
+
"@xyo-network/sentinel-abstract": "~2.89.0-rc.10",
|
|
23
|
+
"@xyo-network/sentinel-model": "~2.89.0-rc.10",
|
|
24
|
+
"@xyo-network/witness-model": "~2.89.0-rc.10"
|
|
23
25
|
},
|
|
24
26
|
"description": "Primary SDK for using XYO Protocol 2.0",
|
|
25
27
|
"devDependencies": {
|
|
26
|
-
"@xylabs/delay": "^2.
|
|
28
|
+
"@xylabs/delay": "^2.14.0",
|
|
27
29
|
"@xylabs/ts-scripts-yarn3": "^3.2.42",
|
|
28
30
|
"@xylabs/tsconfig": "^3.2.42",
|
|
29
|
-
"@xyo-network/abstract-witness": "~2.89.0-rc.
|
|
30
|
-
"@xyo-network/account": "~2.89.0-rc.
|
|
31
|
-
"@xyo-network/archivist-memory": "~2.89.0-rc.
|
|
32
|
-
"@xyo-network/id-payload-plugin": "~2.89.0-rc.
|
|
33
|
-
"@xyo-network/node-memory": "~2.89.0-rc.
|
|
34
|
-
"@xyo-network/witness-adhoc": "~2.89.0-rc.
|
|
31
|
+
"@xyo-network/abstract-witness": "~2.89.0-rc.10",
|
|
32
|
+
"@xyo-network/account": "~2.89.0-rc.10",
|
|
33
|
+
"@xyo-network/archivist-memory": "~2.89.0-rc.10",
|
|
34
|
+
"@xyo-network/id-payload-plugin": "~2.89.0-rc.10",
|
|
35
|
+
"@xyo-network/node-memory": "~2.89.0-rc.10",
|
|
36
|
+
"@xyo-network/witness-adhoc": "~2.89.0-rc.10",
|
|
35
37
|
"typescript": "^5.3.3"
|
|
36
38
|
},
|
|
37
39
|
"types": "dist/node/index.d.ts",
|
|
@@ -72,7 +74,7 @@
|
|
|
72
74
|
"url": "https://github.com/XYOracleNetwork/sdk-xyo-client-js.git"
|
|
73
75
|
},
|
|
74
76
|
"sideEffects": false,
|
|
75
|
-
"version": "2.89.0-rc.
|
|
77
|
+
"version": "2.89.0-rc.10",
|
|
76
78
|
"type": "module",
|
|
77
79
|
"stableVersion": "2.88.3"
|
|
78
80
|
}
|
package/src/SentinelRunner.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { assertEx } from '@xylabs/assert'
|
|
2
|
+
import { forget } from '@xylabs/forget'
|
|
3
|
+
import { PayloadBuilder } from '@xyo-network/payload-builder'
|
|
2
4
|
import { Payload } from '@xyo-network/payload-model'
|
|
3
|
-
import { PayloadWrapper } from '@xyo-network/payload-wrapper'
|
|
4
5
|
import {
|
|
5
6
|
isSentinelIntervalAutomation,
|
|
6
7
|
SentinelAutomationPayload,
|
|
@@ -21,7 +22,7 @@ export class SentinelRunner {
|
|
|
21
22
|
constructor(sentinel: SentinelInstance, automations?: SentinelAutomationPayload[], onTriggerResult?: OnSentinelRunnerTriggerResult) {
|
|
22
23
|
this.sentinel = sentinel
|
|
23
24
|
this.onTriggerResult = onTriggerResult
|
|
24
|
-
if (automations) for (const automation of automations) this.add(automation)
|
|
25
|
+
if (automations) for (const automation of automations) forget(this.add(automation))
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
get automations() {
|
|
@@ -40,7 +41,7 @@ export class SentinelRunner {
|
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
async add(automation: SentinelAutomationPayload, restart = true) {
|
|
43
|
-
const hash = await
|
|
44
|
+
const hash = await PayloadBuilder.dataHash(automation)
|
|
44
45
|
this._automations[hash] = automation
|
|
45
46
|
if (restart) await this.restart()
|
|
46
47
|
return hash
|
|
@@ -75,6 +76,7 @@ export class SentinelRunner {
|
|
|
75
76
|
const start = Math.max(automation.start ?? now, now)
|
|
76
77
|
const delay = Math.max(start - now, 0)
|
|
77
78
|
if (delay < Number.POSITIVE_INFINITY) {
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
78
80
|
this.timeoutId = setTimeout(async () => {
|
|
79
81
|
try {
|
|
80
82
|
// Run the automation
|
|
@@ -104,7 +106,7 @@ export class SentinelRunner {
|
|
|
104
106
|
|
|
105
107
|
private async trigger(automation: SentinelIntervalAutomationPayload) {
|
|
106
108
|
const wrapper = new SentinelIntervalAutomationWrapper(automation)
|
|
107
|
-
await this.remove(await wrapper.
|
|
109
|
+
await this.remove(await wrapper.dataHash(), false)
|
|
108
110
|
wrapper.next()
|
|
109
111
|
await this.add(wrapper.jsonPayload(), false)
|
|
110
112
|
const triggerResult = await this.sentinel.report()
|