@xyo-network/sentinel-memory 2.104.0 → 2.105.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -51,8 +51,7 @@ var SentinelIntervalAutomationWrapper = class extends import_payload_wrapper.Pay
51
51
  }
52
52
  get frequencyMillis() {
53
53
  const frequency = this.payload.frequency;
54
- if (frequency === void 0)
55
- return Number.POSITIVE_INFINITY;
54
+ if (frequency === void 0) return Number.POSITIVE_INFINITY;
56
55
  const frequencyUnits = this.payload.frequencyUnits;
57
56
  switch (frequencyUnits ?? "hour") {
58
57
  case "second": {
@@ -93,8 +92,7 @@ var SentinelIntervalAutomationWrapper = class extends import_payload_wrapper.Pay
93
92
  consumeRemaining(count = 1) {
94
93
  const remaining = Math.max(this.remaining - count, 0);
95
94
  this.setRemaining(remaining);
96
- if (remaining <= 0)
97
- this.setStart(Number.POSITIVE_INFINITY);
95
+ if (remaining <= 0) this.setStart(Number.POSITIVE_INFINITY);
98
96
  }
99
97
  /**
100
98
  * Sets the remaining of the wrapped automation
@@ -124,9 +122,7 @@ var SentinelRunner = class {
124
122
  constructor(sentinel, automations, onTriggerResult) {
125
123
  this.sentinel = sentinel;
126
124
  this.onTriggerResult = onTriggerResult;
127
- if (automations)
128
- for (const automation of automations)
129
- (0, import_forget.forget)(this.add(automation));
125
+ if (automations) for (const automation of automations) (0, import_forget.forget)(this.add(automation));
130
126
  }
131
127
  get automations() {
132
128
  return this._automations;
@@ -142,8 +138,7 @@ var SentinelRunner = class {
142
138
  async add(automation, restart = true) {
143
139
  const hash = await import_payload_builder.PayloadBuilder.dataHash(automation);
144
140
  this._automations[hash] = automation;
145
- if (restart)
146
- await this.restart();
141
+ if (restart) await this.restart();
147
142
  return hash;
148
143
  }
149
144
  find(hash) {
@@ -151,8 +146,7 @@ var SentinelRunner = class {
151
146
  }
152
147
  async remove(hash, restart = true) {
153
148
  delete this._automations[hash];
154
- if (restart)
155
- await this.restart();
149
+ if (restart) await this.restart();
156
150
  }
157
151
  removeAll() {
158
152
  this.stop();
@@ -190,8 +184,7 @@ var SentinelRunner = class {
190
184
  async update(hash, automation, restart = true) {
191
185
  await this.remove(hash, false);
192
186
  await this.add(automation, false);
193
- if (restart)
194
- await this.restart();
187
+ if (restart) await this.restart();
195
188
  }
196
189
  async trigger(automation) {
197
190
  const wrapper = new SentinelIntervalAutomationWrapper(automation);
@@ -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, ModuleIdentifier } from '@xyo-network/module-model'\nimport { Payload, Schema } 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 readonly configSchemas: Schema[] = [...super.configSchemas, SentinelConfigSchema]\n static override readonly defaultConfigSchema: Schema = 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.runJob(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 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 inputAddresses(input: ModuleIdentifier | ModuleIdentifier[]): Promise<Address[]> {\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 private async runJob(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n await this.emit('jobStart', { inPayloads, module: this })\n this.logger?.debug(`runJob:tasks: ${JSON.stringify(tasks.length)}`)\n this.logger?.debug(`runJob:previous: ${JSON.stringify(previousResults)}`)\n this.logger?.debug(`runJob: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\n : input === false ? []\n : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n const witness = asWitnessInstance(task.module)\n if (witness) {\n await this.emit('taskStart', { address: witness.address, inPayloads: inPayloadsFound, module: this })\n const observed = await witness.observe(inPayloadsFound)\n this.logger?.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`)\n await this.emit('taskEnd', { address: witness.address, inPayloads: inPayloadsFound, module: this, outPayloads: observed })\n return [witness.address, observed]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n await this.emit('taskStart', { address: diviner.address, inPayloads: inPayloadsFound, module: this })\n const divined = await diviner.divine(inPayloadsFound)\n this.logger?.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`)\n await this.emit('taskEnd', { address: diviner.address, inPayloads: inPayloadsFound, module: this, outPayloads: divined })\n return [diviner.address, divined]\n }\n const sentinel = asSentinelInstance(task.module)\n if (sentinel) {\n await this.emit('taskStart', { address: sentinel.address, inPayloads: inPayloadsFound, module: this })\n const reported = await sentinel.report(inPayloadsFound)\n this.logger?.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`)\n await this.emit('taskEnd', { address: sentinel.address, inPayloads: inPayloadsFound, module: this, outPayloads: 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 await this.emit('jobEnd', { finalResult, inPayloads, module: this })\n return finalResult\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 restart() {\n this.stop()\n this.start()\n }\n\n start() {\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 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.payload, 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.payload.frequency\n if (frequency === undefined) return Number.POSITIVE_INFINITY\n const frequencyUnits = this.payload.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.payload.remaining ?? Number.POSITIVE_INFINITY\n }\n\n next() {\n const now = Date.now()\n const previousStart = this.payload?.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.payload.start > (this.payload.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.payload.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.payload.start = start\n }\n}\n"],"mappings":"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","names":["import_sentinel_model","SentinelIntervalAutomationWrapper","PayloadWrapper","constructor","payload","frequencyMillis","frequency","undefined","Number","POSITIVE_INFINITY","frequencyUnits","remaining","next","now","Date","previousStart","start","Math","max","nextStart","setStart","consumeRemaining","checkEnd","end","count","setRemaining","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","assertEx","now","Date","Math","max","delay","setTimeout","trigger","clearTimeout","update","wrapper","SentinelIntervalAutomationWrapper","payload","triggerResult","report","MemorySentinel","AbstractSentinel","configSchemas","SentinelConfigSchema","defaultConfigSchema","runner","reportHandler","inPayloads","started","logger","debug","JSON","stringify","job","jobPromise","index","previousResults","tasks","length","generatedPayloads","runJob","result","Object","values","flat","start","timeout","config","automations","SentinelRunner","stop","undefined","inputAddresses","input","Array","isArray","Promise","all","map","inputItem","resolved","resolve","address","processPreviousResults","payloads","inputs","flatMap","emit","module","results","allSettled","task","inPayloadsFound","witness","asWitnessInstance","observed","observe","id","outPayloads","diviner","asDivinerInstance","divined","divine","sentinel","asSentinelInstance","reported","report","Error","finalResult","filter","fulfilled","value","push","throwErrors","errors","rejected","reason"]}
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, ModuleIdentifier } from '@xyo-network/module-model'\nimport { Payload, Schema } 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 readonly configSchemas: Schema[] = [...super.configSchemas, SentinelConfigSchema]\n static override readonly defaultConfigSchema: Schema = 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.runJob(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 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 inputAddresses(input: ModuleIdentifier | ModuleIdentifier[]): Promise<Address[]> {\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 private async runJob(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n await this.emit('jobStart', { inPayloads, module: this })\n this.logger?.debug(`runJob:tasks: ${JSON.stringify(tasks.length)}`)\n this.logger?.debug(`runJob:previous: ${JSON.stringify(previousResults)}`)\n this.logger?.debug(`runJob: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\n : input === false ? []\n : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n const witness = asWitnessInstance(task.module)\n if (witness) {\n await this.emit('taskStart', { address: witness.address, inPayloads: inPayloadsFound, module: this })\n const observed = await witness.observe(inPayloadsFound)\n this.logger?.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`)\n await this.emit('taskEnd', { address: witness.address, inPayloads: inPayloadsFound, module: this, outPayloads: observed })\n return [witness.address, observed]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n await this.emit('taskStart', { address: diviner.address, inPayloads: inPayloadsFound, module: this })\n const divined = await diviner.divine(inPayloadsFound)\n this.logger?.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`)\n await this.emit('taskEnd', { address: diviner.address, inPayloads: inPayloadsFound, module: this, outPayloads: divined })\n return [diviner.address, divined]\n }\n const sentinel = asSentinelInstance(task.module)\n if (sentinel) {\n await this.emit('taskStart', { address: sentinel.address, inPayloads: inPayloadsFound, module: this })\n const reported = await sentinel.report(inPayloadsFound)\n this.logger?.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`)\n await this.emit('taskEnd', { address: sentinel.address, inPayloads: inPayloadsFound, module: this, outPayloads: 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 await this.emit('jobEnd', { finalResult, inPayloads, module: this })\n return finalResult\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 restart() {\n this.stop()\n this.start()\n }\n\n start() {\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 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.payload, 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.payload.frequency\n if (frequency === undefined) return Number.POSITIVE_INFINITY\n const frequencyUnits = this.payload.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.payload.remaining ?? Number.POSITIVE_INFINITY\n }\n\n next() {\n const now = Date.now()\n const previousStart = this.payload?.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.payload.start > (this.payload.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.payload.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.payload.start = start\n }\n}\n"],"mappings":"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","names":["import_sentinel_model","SentinelIntervalAutomationWrapper","PayloadWrapper","constructor","payload","frequencyMillis","frequency","undefined","Number","POSITIVE_INFINITY","frequencyUnits","remaining","next","now","Date","previousStart","start","Math","max","nextStart","setStart","consumeRemaining","checkEnd","end","count","setRemaining","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","assertEx","now","Date","Math","max","delay","setTimeout","trigger","clearTimeout","update","wrapper","SentinelIntervalAutomationWrapper","payload","triggerResult","report","MemorySentinel","AbstractSentinel","configSchemas","SentinelConfigSchema","defaultConfigSchema","runner","reportHandler","inPayloads","started","logger","debug","JSON","stringify","job","jobPromise","index","previousResults","tasks","length","generatedPayloads","runJob","result","Object","values","flat","start","timeout","config","automations","SentinelRunner","stop","undefined","inputAddresses","input","Array","isArray","Promise","all","map","inputItem","resolved","resolve","address","processPreviousResults","payloads","inputs","flatMap","emit","module","results","allSettled","task","inPayloadsFound","witness","asWitnessInstance","observed","observe","id","outPayloads","diviner","asDivinerInstance","divined","divine","sentinel","asSentinelInstance","reported","report","Error","finalResult","filter","fulfilled","value","push","throwErrors","errors","rejected","reason"]}
@@ -25,8 +25,7 @@ var SentinelIntervalAutomationWrapper = class extends PayloadWrapper {
25
25
  }
26
26
  get frequencyMillis() {
27
27
  const frequency = this.payload.frequency;
28
- if (frequency === void 0)
29
- return Number.POSITIVE_INFINITY;
28
+ if (frequency === void 0) return Number.POSITIVE_INFINITY;
30
29
  const frequencyUnits = this.payload.frequencyUnits;
31
30
  switch (frequencyUnits ?? "hour") {
32
31
  case "second": {
@@ -67,8 +66,7 @@ var SentinelIntervalAutomationWrapper = class extends PayloadWrapper {
67
66
  consumeRemaining(count = 1) {
68
67
  const remaining = Math.max(this.remaining - count, 0);
69
68
  this.setRemaining(remaining);
70
- if (remaining <= 0)
71
- this.setStart(Number.POSITIVE_INFINITY);
69
+ if (remaining <= 0) this.setStart(Number.POSITIVE_INFINITY);
72
70
  }
73
71
  /**
74
72
  * Sets the remaining of the wrapped automation
@@ -98,9 +96,7 @@ var SentinelRunner = class {
98
96
  constructor(sentinel, automations, onTriggerResult) {
99
97
  this.sentinel = sentinel;
100
98
  this.onTriggerResult = onTriggerResult;
101
- if (automations)
102
- for (const automation of automations)
103
- forget(this.add(automation));
99
+ if (automations) for (const automation of automations) forget(this.add(automation));
104
100
  }
105
101
  get automations() {
106
102
  return this._automations;
@@ -116,8 +112,7 @@ var SentinelRunner = class {
116
112
  async add(automation, restart = true) {
117
113
  const hash = await PayloadBuilder.dataHash(automation);
118
114
  this._automations[hash] = automation;
119
- if (restart)
120
- await this.restart();
115
+ if (restart) await this.restart();
121
116
  return hash;
122
117
  }
123
118
  find(hash) {
@@ -125,8 +120,7 @@ var SentinelRunner = class {
125
120
  }
126
121
  async remove(hash, restart = true) {
127
122
  delete this._automations[hash];
128
- if (restart)
129
- await this.restart();
123
+ if (restart) await this.restart();
130
124
  }
131
125
  removeAll() {
132
126
  this.stop();
@@ -164,8 +158,7 @@ var SentinelRunner = class {
164
158
  async update(hash, automation, restart = true) {
165
159
  await this.remove(hash, false);
166
160
  await this.add(automation, false);
167
- if (restart)
168
- await this.restart();
161
+ if (restart) await this.restart();
169
162
  }
170
163
  async trigger(automation) {
171
164
  const wrapper = new SentinelIntervalAutomationWrapper(automation);
@@ -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, ModuleIdentifier } from '@xyo-network/module-model'\nimport { Payload, Schema } 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 readonly configSchemas: Schema[] = [...super.configSchemas, SentinelConfigSchema]\n static override readonly defaultConfigSchema: Schema = 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.runJob(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 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 inputAddresses(input: ModuleIdentifier | ModuleIdentifier[]): Promise<Address[]> {\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 private async runJob(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n await this.emit('jobStart', { inPayloads, module: this })\n this.logger?.debug(`runJob:tasks: ${JSON.stringify(tasks.length)}`)\n this.logger?.debug(`runJob:previous: ${JSON.stringify(previousResults)}`)\n this.logger?.debug(`runJob: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\n : input === false ? []\n : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n const witness = asWitnessInstance(task.module)\n if (witness) {\n await this.emit('taskStart', { address: witness.address, inPayloads: inPayloadsFound, module: this })\n const observed = await witness.observe(inPayloadsFound)\n this.logger?.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`)\n await this.emit('taskEnd', { address: witness.address, inPayloads: inPayloadsFound, module: this, outPayloads: observed })\n return [witness.address, observed]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n await this.emit('taskStart', { address: diviner.address, inPayloads: inPayloadsFound, module: this })\n const divined = await diviner.divine(inPayloadsFound)\n this.logger?.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`)\n await this.emit('taskEnd', { address: diviner.address, inPayloads: inPayloadsFound, module: this, outPayloads: divined })\n return [diviner.address, divined]\n }\n const sentinel = asSentinelInstance(task.module)\n if (sentinel) {\n await this.emit('taskStart', { address: sentinel.address, inPayloads: inPayloadsFound, module: this })\n const reported = await sentinel.report(inPayloadsFound)\n this.logger?.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`)\n await this.emit('taskEnd', { address: sentinel.address, inPayloads: inPayloadsFound, module: this, outPayloads: 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 await this.emit('jobEnd', { finalResult, inPayloads, module: this })\n return finalResult\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 restart() {\n this.stop()\n this.start()\n }\n\n start() {\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 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.payload, 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.payload.frequency\n if (frequency === undefined) return Number.POSITIVE_INFINITY\n const frequencyUnits = this.payload.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.payload.remaining ?? Number.POSITIVE_INFINITY\n }\n\n next() {\n const now = Date.now()\n const previousStart = this.payload?.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.payload.start > (this.payload.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.payload.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.payload.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","undefined","Number","POSITIVE_INFINITY","frequencyUnits","remaining","next","now","Date","previousStart","start","Math","max","nextStart","setStart","consumeRemaining","checkEnd","end","count","setRemaining","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","assertEx","now","Date","Math","max","delay","setTimeout","trigger","clearTimeout","update","wrapper","SentinelIntervalAutomationWrapper","payload","triggerResult","report","MemorySentinel","AbstractSentinel","configSchemas","SentinelConfigSchema","defaultConfigSchema","runner","reportHandler","inPayloads","started","logger","debug","JSON","stringify","job","jobPromise","index","previousResults","tasks","length","generatedPayloads","runJob","result","Object","values","flat","start","timeout","config","automations","SentinelRunner","stop","undefined","inputAddresses","input","Array","isArray","Promise","all","map","inputItem","resolved","resolve","address","processPreviousResults","payloads","inputs","flatMap","emit","module","results","allSettled","task","inPayloadsFound","witness","asWitnessInstance","observed","observe","id","outPayloads","diviner","asDivinerInstance","divined","divine","sentinel","asSentinelInstance","reported","report","Error","finalResult","filter","fulfilled","value","push","throwErrors","errors","rejected","reason"]}
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, ModuleIdentifier } from '@xyo-network/module-model'\nimport { Payload, Schema } 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 readonly configSchemas: Schema[] = [...super.configSchemas, SentinelConfigSchema]\n static override readonly defaultConfigSchema: Schema = 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.runJob(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 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 inputAddresses(input: ModuleIdentifier | ModuleIdentifier[]): Promise<Address[]> {\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 private async runJob(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n await this.emit('jobStart', { inPayloads, module: this })\n this.logger?.debug(`runJob:tasks: ${JSON.stringify(tasks.length)}`)\n this.logger?.debug(`runJob:previous: ${JSON.stringify(previousResults)}`)\n this.logger?.debug(`runJob: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\n : input === false ? []\n : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n const witness = asWitnessInstance(task.module)\n if (witness) {\n await this.emit('taskStart', { address: witness.address, inPayloads: inPayloadsFound, module: this })\n const observed = await witness.observe(inPayloadsFound)\n this.logger?.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`)\n await this.emit('taskEnd', { address: witness.address, inPayloads: inPayloadsFound, module: this, outPayloads: observed })\n return [witness.address, observed]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n await this.emit('taskStart', { address: diviner.address, inPayloads: inPayloadsFound, module: this })\n const divined = await diviner.divine(inPayloadsFound)\n this.logger?.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`)\n await this.emit('taskEnd', { address: diviner.address, inPayloads: inPayloadsFound, module: this, outPayloads: divined })\n return [diviner.address, divined]\n }\n const sentinel = asSentinelInstance(task.module)\n if (sentinel) {\n await this.emit('taskStart', { address: sentinel.address, inPayloads: inPayloadsFound, module: this })\n const reported = await sentinel.report(inPayloadsFound)\n this.logger?.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`)\n await this.emit('taskEnd', { address: sentinel.address, inPayloads: inPayloadsFound, module: this, outPayloads: 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 await this.emit('jobEnd', { finalResult, inPayloads, module: this })\n return finalResult\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 restart() {\n this.stop()\n this.start()\n }\n\n start() {\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 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.payload, 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.payload.frequency\n if (frequency === undefined) return Number.POSITIVE_INFINITY\n const frequencyUnits = this.payload.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.payload.remaining ?? Number.POSITIVE_INFINITY\n }\n\n next() {\n const now = Date.now()\n const previousStart = this.payload?.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.payload.start > (this.payload.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.payload.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.payload.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","undefined","Number","POSITIVE_INFINITY","frequencyUnits","remaining","next","now","Date","previousStart","start","Math","max","nextStart","setStart","consumeRemaining","checkEnd","end","count","setRemaining","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","assertEx","now","Date","Math","max","delay","setTimeout","trigger","clearTimeout","update","wrapper","SentinelIntervalAutomationWrapper","payload","triggerResult","report","MemorySentinel","AbstractSentinel","configSchemas","SentinelConfigSchema","defaultConfigSchema","runner","reportHandler","inPayloads","started","logger","debug","JSON","stringify","job","jobPromise","index","previousResults","tasks","length","generatedPayloads","runJob","result","Object","values","flat","start","timeout","config","automations","SentinelRunner","stop","undefined","inputAddresses","input","Array","isArray","Promise","all","map","inputItem","resolved","resolve","address","processPreviousResults","payloads","inputs","flatMap","emit","module","results","allSettled","task","inPayloadsFound","witness","asWitnessInstance","observed","observe","id","outPayloads","diviner","asDivinerInstance","divined","divine","sentinel","asSentinelInstance","reported","report","Error","finalResult","filter","fulfilled","value","push","throwErrors","errors","rejected","reason"]}
@@ -51,8 +51,7 @@ var SentinelIntervalAutomationWrapper = class extends import_payload_wrapper.Pay
51
51
  }
52
52
  get frequencyMillis() {
53
53
  const frequency = this.payload.frequency;
54
- if (frequency === void 0)
55
- return Number.POSITIVE_INFINITY;
54
+ if (frequency === void 0) return Number.POSITIVE_INFINITY;
56
55
  const frequencyUnits = this.payload.frequencyUnits;
57
56
  switch (frequencyUnits ?? "hour") {
58
57
  case "second": {
@@ -93,8 +92,7 @@ var SentinelIntervalAutomationWrapper = class extends import_payload_wrapper.Pay
93
92
  consumeRemaining(count = 1) {
94
93
  const remaining = Math.max(this.remaining - count, 0);
95
94
  this.setRemaining(remaining);
96
- if (remaining <= 0)
97
- this.setStart(Number.POSITIVE_INFINITY);
95
+ if (remaining <= 0) this.setStart(Number.POSITIVE_INFINITY);
98
96
  }
99
97
  /**
100
98
  * Sets the remaining of the wrapped automation
@@ -124,9 +122,7 @@ var SentinelRunner = class {
124
122
  constructor(sentinel, automations, onTriggerResult) {
125
123
  this.sentinel = sentinel;
126
124
  this.onTriggerResult = onTriggerResult;
127
- if (automations)
128
- for (const automation of automations)
129
- (0, import_forget.forget)(this.add(automation));
125
+ if (automations) for (const automation of automations) (0, import_forget.forget)(this.add(automation));
130
126
  }
131
127
  get automations() {
132
128
  return this._automations;
@@ -142,8 +138,7 @@ var SentinelRunner = class {
142
138
  async add(automation, restart = true) {
143
139
  const hash = await import_payload_builder.PayloadBuilder.dataHash(automation);
144
140
  this._automations[hash] = automation;
145
- if (restart)
146
- await this.restart();
141
+ if (restart) await this.restart();
147
142
  return hash;
148
143
  }
149
144
  find(hash) {
@@ -151,8 +146,7 @@ var SentinelRunner = class {
151
146
  }
152
147
  async remove(hash, restart = true) {
153
148
  delete this._automations[hash];
154
- if (restart)
155
- await this.restart();
149
+ if (restart) await this.restart();
156
150
  }
157
151
  removeAll() {
158
152
  this.stop();
@@ -190,8 +184,7 @@ var SentinelRunner = class {
190
184
  async update(hash, automation, restart = true) {
191
185
  await this.remove(hash, false);
192
186
  await this.add(automation, false);
193
- if (restart)
194
- await this.restart();
187
+ if (restart) await this.restart();
195
188
  }
196
189
  async trigger(automation) {
197
190
  const wrapper = new SentinelIntervalAutomationWrapper(automation);
@@ -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, ModuleIdentifier } from '@xyo-network/module-model'\nimport { Payload, Schema } 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 readonly configSchemas: Schema[] = [...super.configSchemas, SentinelConfigSchema]\n static override readonly defaultConfigSchema: Schema = 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.runJob(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 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 inputAddresses(input: ModuleIdentifier | ModuleIdentifier[]): Promise<Address[]> {\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 private async runJob(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n await this.emit('jobStart', { inPayloads, module: this })\n this.logger?.debug(`runJob:tasks: ${JSON.stringify(tasks.length)}`)\n this.logger?.debug(`runJob:previous: ${JSON.stringify(previousResults)}`)\n this.logger?.debug(`runJob: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\n : input === false ? []\n : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n const witness = asWitnessInstance(task.module)\n if (witness) {\n await this.emit('taskStart', { address: witness.address, inPayloads: inPayloadsFound, module: this })\n const observed = await witness.observe(inPayloadsFound)\n this.logger?.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`)\n await this.emit('taskEnd', { address: witness.address, inPayloads: inPayloadsFound, module: this, outPayloads: observed })\n return [witness.address, observed]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n await this.emit('taskStart', { address: diviner.address, inPayloads: inPayloadsFound, module: this })\n const divined = await diviner.divine(inPayloadsFound)\n this.logger?.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`)\n await this.emit('taskEnd', { address: diviner.address, inPayloads: inPayloadsFound, module: this, outPayloads: divined })\n return [diviner.address, divined]\n }\n const sentinel = asSentinelInstance(task.module)\n if (sentinel) {\n await this.emit('taskStart', { address: sentinel.address, inPayloads: inPayloadsFound, module: this })\n const reported = await sentinel.report(inPayloadsFound)\n this.logger?.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`)\n await this.emit('taskEnd', { address: sentinel.address, inPayloads: inPayloadsFound, module: this, outPayloads: 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 await this.emit('jobEnd', { finalResult, inPayloads, module: this })\n return finalResult\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 restart() {\n this.stop()\n this.start()\n }\n\n start() {\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 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.payload, 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.payload.frequency\n if (frequency === undefined) return Number.POSITIVE_INFINITY\n const frequencyUnits = this.payload.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.payload.remaining ?? Number.POSITIVE_INFINITY\n }\n\n next() {\n const now = Date.now()\n const previousStart = this.payload?.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.payload.start > (this.payload.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.payload.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.payload.start = start\n }\n}\n"],"mappings":"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","names":["import_sentinel_model","SentinelIntervalAutomationWrapper","PayloadWrapper","constructor","payload","frequencyMillis","frequency","undefined","Number","POSITIVE_INFINITY","frequencyUnits","remaining","next","now","Date","previousStart","start","Math","max","nextStart","setStart","consumeRemaining","checkEnd","end","count","setRemaining","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","assertEx","now","Date","Math","max","delay","setTimeout","trigger","clearTimeout","update","wrapper","SentinelIntervalAutomationWrapper","payload","triggerResult","report","MemorySentinel","AbstractSentinel","configSchemas","SentinelConfigSchema","defaultConfigSchema","runner","reportHandler","inPayloads","started","logger","debug","JSON","stringify","job","jobPromise","index","previousResults","tasks","length","generatedPayloads","runJob","result","Object","values","flat","start","timeout","config","automations","SentinelRunner","stop","undefined","inputAddresses","input","Array","isArray","Promise","all","map","inputItem","resolved","resolve","address","processPreviousResults","payloads","inputs","flatMap","emit","module","results","allSettled","task","inPayloadsFound","witness","asWitnessInstance","observed","observe","id","outPayloads","diviner","asDivinerInstance","divined","divine","sentinel","asSentinelInstance","reported","report","Error","finalResult","filter","fulfilled","value","push","throwErrors","errors","rejected","reason"]}
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, ModuleIdentifier } from '@xyo-network/module-model'\nimport { Payload, Schema } 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 readonly configSchemas: Schema[] = [...super.configSchemas, SentinelConfigSchema]\n static override readonly defaultConfigSchema: Schema = 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.runJob(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 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 inputAddresses(input: ModuleIdentifier | ModuleIdentifier[]): Promise<Address[]> {\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 private async runJob(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n await this.emit('jobStart', { inPayloads, module: this })\n this.logger?.debug(`runJob:tasks: ${JSON.stringify(tasks.length)}`)\n this.logger?.debug(`runJob:previous: ${JSON.stringify(previousResults)}`)\n this.logger?.debug(`runJob: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\n : input === false ? []\n : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n const witness = asWitnessInstance(task.module)\n if (witness) {\n await this.emit('taskStart', { address: witness.address, inPayloads: inPayloadsFound, module: this })\n const observed = await witness.observe(inPayloadsFound)\n this.logger?.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`)\n await this.emit('taskEnd', { address: witness.address, inPayloads: inPayloadsFound, module: this, outPayloads: observed })\n return [witness.address, observed]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n await this.emit('taskStart', { address: diviner.address, inPayloads: inPayloadsFound, module: this })\n const divined = await diviner.divine(inPayloadsFound)\n this.logger?.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`)\n await this.emit('taskEnd', { address: diviner.address, inPayloads: inPayloadsFound, module: this, outPayloads: divined })\n return [diviner.address, divined]\n }\n const sentinel = asSentinelInstance(task.module)\n if (sentinel) {\n await this.emit('taskStart', { address: sentinel.address, inPayloads: inPayloadsFound, module: this })\n const reported = await sentinel.report(inPayloadsFound)\n this.logger?.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`)\n await this.emit('taskEnd', { address: sentinel.address, inPayloads: inPayloadsFound, module: this, outPayloads: 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 await this.emit('jobEnd', { finalResult, inPayloads, module: this })\n return finalResult\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 restart() {\n this.stop()\n this.start()\n }\n\n start() {\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 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.payload, 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.payload.frequency\n if (frequency === undefined) return Number.POSITIVE_INFINITY\n const frequencyUnits = this.payload.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.payload.remaining ?? Number.POSITIVE_INFINITY\n }\n\n next() {\n const now = Date.now()\n const previousStart = this.payload?.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.payload.start > (this.payload.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.payload.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.payload.start = start\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;ACCA,qBAAoC;AACpC,2BAAkC;AAGlC,+BAAiC;AACjC,IAAAA,yBAQO;AACP,2BAAkC;;;ACflC,oBAAyB;AACzB,oBAAuB;AACvB,6BAA+B;AAE/B,4BAKO;;;ACTP,6BAA+B;AAGxB,IAAMC,oCAAN,cAEGC,sCAAAA;EALV,OAKUA;;;EACRC,YAAYC,SAAY;AACtB,UAAMA,OAAAA;EACR;EAEA,IAAcC,kBAAkB;AAC9B,UAAMC,YAAY,KAAKF,QAAQE;AAC/B,QAAIA,cAAcC,OAAW,QAAOC,OAAOC;AAC3C,UAAMC,iBAAiB,KAAKN,QAAQM;AACpC,YAAQA,kBAAkB,QAAA;MACxB,KAAK,UAAU;AACb,eAAOJ,YAAY;MACrB;MACA,KAAK,UAAU;AACb,eAAOA,YAAY,KAAK;MAC1B;MACA,KAAK,QAAQ;AACX,eAAOA,YAAY,KAAK,KAAK;MAC/B;MACA,KAAK,OAAO;AACV,eAAOA,YAAY,KAAK,KAAK,KAAK;MACpC;MACA,SAAS;AACP,eAAOE,OAAOC;MAChB;IACF;EACF;EAEA,IAAcE,YAAY;AACxB,WAAO,KAAKP,QAAQO,aAAaH,OAAOC;EAC1C;EAEAG,OAAO;AACL,UAAMC,MAAMC,KAAKD,IAAG;AACpB,UAAME,gBAAgB,KAAKX,SAASY,SAASH;AAC7C,UAAMG,QAAQC,KAAKC,IAAIH,eAAeF,GAAAA;AACtC,UAAMM,YAAYH,QAAQ,KAAKX;AAC/B,SAAKe,SAASD,SAAAA;AACd,SAAKE,iBAAgB;AACrB,SAAKC,SAAQ;AACb,WAAO;EACT;EAEUA,WAAW;AACnB,QAAI,KAAKlB,QAAQY,SAAS,KAAKZ,QAAQmB,OAAOf,OAAOC,oBAAoB;AACvE,WAAKW,SAASZ,OAAOC,iBAAiB;IACxC;EACF;EAEUY,iBAAiBG,QAAQ,GAAG;AACpC,UAAMb,YAAYM,KAAKC,IAAI,KAAKP,YAAYa,OAAO,CAAA;AACnD,SAAKC,aAAad,SAAAA;AAClB,QAAIA,aAAa,EAAG,MAAKS,SAASZ,OAAOC,iBAAiB;EAC5D;;;;;EAMUgB,aAAad,WAAmB;AACxC,SAAKP,QAAQO,YAAYA;EAC3B;;;;;EAMUS,SAASJ,OAAe;AAChC,SAAKZ,QAAQY,QAAQA;EACvB;AACF;;;AD5DO,IAAMU,iBAAN,MAAMA;EAfb,OAeaA;;;EACDC,eAA0D,CAAC;EAC3DC;EACAC;EACAC;EAEVC,YAAYF,UAA4BG,aAA2CJ,iBAAiD;AAClI,SAAKC,WAAWA;AAChB,SAAKD,kBAAkBA;AACvB,QAAII,YAAa,YAAWC,cAAcD,YAAaE,2BAAO,KAAKC,IAAIF,UAAAA,CAAAA;EACzE;EAEA,IAAID,cAAc;AAChB,WAAO,KAAKL;EACd;EAEA,IAAYS,OAAO;AAEjB,WAAOC,OAAOC,OAAO,KAAKX,YAAY,EAAEY,OAA8C,CAACC,UAAUC,YAAAA;AAC/F,cAAIC,oDAA6BD,OAAAA,SAAYC,oDAA6BF,QAAAA,GAAW;AACnF,eAAOC,QAAQE,SAASH,UAAUG,SAASC,OAAOC,qBAAqBJ,UAAUD;MACnF;AACA,aAAOC;IAET,GAAGK,MAAAA;EACL;EAEA,MAAMX,IAAIF,YAAuCc,UAAU,MAAM;AAC/D,UAAMC,OAAO,MAAMC,sCAAeC,SAASjB,UAAAA;AAC3C,SAAKN,aAAaqB,IAAAA,IAAQf;AAC1B,QAAIc,QAAS,OAAM,KAAKA,QAAO;AAC/B,WAAOC;EACT;EAEAG,KAAKH,MAAc;AACjBX,WAAOe,QAAQ,KAAKzB,YAAY,EAAEwB,KAAK,CAAC,CAACE,GAAAA,MAASA,QAAQL,IAAAA;EAC5D;EAEA,MAAMM,OAAON,MAAcD,UAAU,MAAM;AACzC,WAAO,KAAKpB,aAAaqB,IAAAA;AACzB,QAAID,QAAS,OAAM,KAAKA,QAAO;EACjC;EAEAQ,YAAY;AACV,SAAKC,KAAI;AACT,SAAK7B,eAAe,CAAC;EACvB;EAEAoB,UAAU;AACR,SAAKS,KAAI;AACT,SAAKb,MAAK;EACZ;EAEAA,QAAQ;AACNc,gCAAS,KAAK3B,cAAcgB,QAAW,MAAM,iBAAA;AAC7C,UAAMb,aAAa,KAAKG;AACxB,YAAIM,oDAA6BT,UAAAA,GAAa;AAC5C,YAAMyB,MAAMC,KAAKD,IAAG;AACpB,YAAMf,QAAQiB,KAAKC,IAAI5B,WAAWU,SAASe,KAAKA,GAAAA;AAChD,YAAMI,QAAQF,KAAKC,IAAIlB,QAAQe,KAAK,CAAA;AACpC,UAAII,QAAQlB,OAAOC,mBAAmB;AAEpC,aAAKf,YAAYiC,WAAW,YAAA;AAC1B,cAAI;AAEF,kBAAM,KAAKC,QAAQ/B,UAAAA;AACnB,iBAAKuB,KAAI;UACX,UAAA;AAEE,iBAAKb,MAAK;UACZ;QACF,GAAGmB,KAAAA;MACL;IACF;EACF;EAEAN,OAAO;AACL,QAAI,KAAK1B,WAAW;AAClBmC,mBAAa,KAAKnC,SAAS;AAC3B,WAAKA,YAAYgB;IACnB;EACF;EAEA,MAAMoB,OAAOlB,MAAcf,YAAuCc,UAAU,MAAM;AAChF,UAAM,KAAKO,OAAON,MAAM,KAAA;AACxB,UAAM,KAAKb,IAAIF,YAAY,KAAA;AAC3B,QAAIc,QAAS,OAAM,KAAKA,QAAO;EACjC;EAEA,MAAciB,QAAQ/B,YAA+C;AACnE,UAAMkC,UAAU,IAAIC,kCAAkCnC,UAAAA;AACtD,UAAM,KAAKqB,OAAO,MAAMa,QAAQjB,SAAQ,GAAI,KAAA;AAC5CiB,YAAQ/B,KAAI;AACZ,UAAM,KAAKD,IAAIgC,QAAQE,SAAS,KAAA;AAChC,UAAMC,gBAAgB,MAAM,KAAKzC,SAAS0C,OAAM;AAChD,SAAK3C,kBAAkB0C,aAAAA;EAEzB;AACF;;;AD5FO,IAAME,iBAAN,cAGGC,0CAAAA;EAvBV,OAuBUA;;;EACR,OAAyBC,gBAA0B;OAAI,MAAMA;IAAeC;;EAC5E,OAAyBC,sBAA8BD;EAE/CE;EAER,MAAMC,cAAcC,aAAwB,CAAA,GAAwB;AAClE,UAAM,KAAKC,QAAQ,OAAA;AACnB,SAAKC,QAAQC,MAAM,qBAAqBC,KAAKC,UAAUL,UAAAA,CAAAA,EAAa;AACpE,UAAMM,MAAM,MAAM,KAAKC;AAEvB,QAAIC,QAAQ;AACZ,QAAIC,kBAA8C,CAAC;AACnD,WAAOD,QAAQF,IAAII,MAAMC,QAAQ;AAC/B,YAAMC,oBAAoB,MAAM,KAAKC,OAAOP,IAAII,MAAMF,KAAAA,GAAQC,iBAAiBT,UAAAA;AAC/ES,wBAAkBG;AAClBJ;IACF;AACA,UAAMM,SAASC,OAAOC,OAAOP,eAAAA,EAAiBQ,KAAI;AAClD,SAAKf,QAAQC,MAAM,sBAAsBC,KAAKC,UAAUS,MAAAA,CAAAA,EAAS;AACjE,WAAOA;EACT;EAEA,MAAeI,MAAMC,SAAgD;AACnE,QAAI,MAAM,MAAMD,MAAMC,OAAAA,GAAU;AAC9B,WAAK,KAAKC,OAAOC,aAAaV,UAAU,KAAK,GAAG;AAC9C,aAAKb,SAAS,IAAIwB,eAAe,MAAM,KAAKF,OAAOC,WAAW;AAC9D,aAAKvB,OAAOoB,MAAK;MACnB;AACA,aAAO;IACT;AACA,WAAO;EACT;EAEA,MAAeK,KAAKJ,SAAgD;AAClE,QAAI,KAAKrB,QAAQ;AACf,WAAKA,OAAOyB,KAAI;AAChB,WAAKzB,SAAS0B;IAChB;AACA,WAAO,MAAM,MAAMD,KAAKJ,OAAAA;EAC1B;EAEA,MAAcM,eAAeC,OAAkE;AAC7F,QAAIC,MAAMC,QAAQF,KAAAA,GAAQ;AACxB,cAAQ,MAAMG,QAAQC,IAAIJ,MAAMK,IAAI,OAAOC,cAAc,MAAM,KAAKP,eAAeO,SAAAA,CAAAA,CAAAA,GAAcf,KAAI;IACvG,OAAO;AACL,YAAMgB,WAAW,MAAM,KAAKC,QAAQR,KAAAA;AACpC,aAAOO,WAAW;QAACA,SAASE;UAAW,CAAA;IACzC;EACF;EAEQC,uBAAuBC,UAAqCC,QAAkB;AACpF,WAAOA,OAAOC,QAAQ,CAACb,UAAUW,SAASX,KAAAA,KAAU,CAAA,CAAE;EACxD;EAEA,MAAcb,OACZH,OACAD,iBACAT,YACqC;AACrC,UAAM,KAAKwC,KAAK,YAAY;MAAExC;MAAYyC,QAAQ;IAAK,CAAA;AACvD,SAAKvC,QAAQC,MAAM,iBAAiBC,KAAKC,UAAUK,MAAMC,MAAM,CAAA,EAAG;AAClE,SAAKT,QAAQC,MAAM,oBAAoBC,KAAKC,UAAUI,eAAAA,CAAAA,EAAkB;AACxE,SAAKP,QAAQC,MAAM,cAAcC,KAAKC,UAAUL,UAAAA,CAAAA,EAAa;AAC7D,UAAM0C,UAAwD,MAAMb,QAAQc,WAC1EjC,OAAOqB,IAAI,OAAOa,SAAAA;AAChB,YAAMlB,QAAQkB,KAAKlB,SAAS;AAC5B,YAAMmB,kBACJnB,UAAU,OAAO1B,aACf0B,UAAU,QAAQ,CAAA,IAClB,KAAKU,uBAAuB3B,iBAAiB,MAAM,KAAKgB,eAAeC,KAAAA,CAAAA;AAC3E,YAAMoB,cAAUC,wCAAkBH,KAAKH,MAAM;AAC7C,UAAIK,SAAS;AACX,cAAM,KAAKN,KAAK,aAAa;UAAEL,SAASW,QAAQX;UAASnC,YAAY6C;UAAiBJ,QAAQ;QAAK,CAAA;AACnG,cAAMO,WAAW,MAAMF,QAAQG,QAAQJ,eAAAA;AACvC,aAAK3C,QAAQC,MAAM,aAAa2C,QAAQI,EAAE,MAAM9C,KAAKC,UAAU2C,QAAAA,CAAAA,EAAW;AAC1E,cAAM,KAAKR,KAAK,WAAW;UAAEL,SAASW,QAAQX;UAASnC,YAAY6C;UAAiBJ,QAAQ;UAAMU,aAAaH;QAAS,CAAA;AACxH,eAAO;UAACF,QAAQX;UAASa;;MAC3B;AACA,YAAMI,cAAUC,wCAAkBT,KAAKH,MAAM;AAC7C,UAAIW,SAAS;AACX,cAAM,KAAKZ,KAAK,aAAa;UAAEL,SAASiB,QAAQjB;UAASnC,YAAY6C;UAAiBJ,QAAQ;QAAK,CAAA;AACnG,cAAMa,UAAU,MAAMF,QAAQG,OAAOV,eAAAA;AACrC,aAAK3C,QAAQC,MAAM,YAAYiD,QAAQF,EAAE,MAAM9C,KAAKC,UAAUiD,OAAAA,CAAAA,EAAU;AACxE,cAAM,KAAKd,KAAK,WAAW;UAAEL,SAASiB,QAAQjB;UAASnC,YAAY6C;UAAiBJ,QAAQ;UAAMU,aAAaG;QAAQ,CAAA;AACvH,eAAO;UAACF,QAAQjB;UAASmB;;MAC3B;AACA,YAAME,eAAWC,2CAAmBb,KAAKH,MAAM;AAC/C,UAAIe,UAAU;AACZ,cAAM,KAAKhB,KAAK,aAAa;UAAEL,SAASqB,SAASrB;UAASnC,YAAY6C;UAAiBJ,QAAQ;QAAK,CAAA;AACpG,cAAMiB,WAAW,MAAMF,SAASG,OAAOd,eAAAA;AACvC,aAAK3C,QAAQC,MAAM,aAAaqD,SAASN,EAAE,MAAM9C,KAAKC,UAAUqD,QAAAA,CAAAA,EAAW;AAC3E,cAAM,KAAKlB,KAAK,WAAW;UAAEL,SAASqB,SAASrB;UAASnC,YAAY6C;UAAiBJ,QAAQ;UAAMU,aAAaO;QAAS,CAAA;AACzH,eAAO;UAACF,SAASrB;UAASuB;;MAC5B;AACA,YAAM,IAAIE,MAAM,yBAAA;IAClB,CAAA,CAAA;AAEF,UAAMC,cAA0C,CAAC;AACjD,eAAW/C,UAAU4B,QAAQoB,OAAOC,wBAAAA,GAAY;AAC9C,YAAM,CAAC5B,SAASE,QAAAA,IAAYvB,OAAOkD;AACnCH,kBAAY1B,OAAAA,IAAW0B,YAAY1B,OAAAA,KAAY,CAAA;AAC/C0B,kBAAY1B,OAAAA,EAAS8B,KAAI,GAAI5B,QAAAA;IAC/B;AACA,QAAI,KAAK6B,aAAa;AACpB,YAAMC,SAASzB,QAAQoB,OAAOM,uBAAAA,EAAUrC,IAAI,CAACjB,WAAWA,OAAOuD,MAAM;AACrE,UAAIF,OAAOxD,SAAS,GAAG;AACrB,cAAM,IAAIiD,MAAM,4BAAA;MAClB;IACF;AACA,SAAK1D,QAAQC,MAAM,wBAAwBC,KAAKC,UAAUwD,WAAAA,CAAAA,EAAc;AACxE,UAAM,KAAKrB,KAAK,UAAU;MAAEqB;MAAa7D;MAAYyC,QAAQ;IAAK,CAAA;AAClE,WAAOoB;EACT;AACF;","names":["import_sentinel_model","SentinelIntervalAutomationWrapper","PayloadWrapper","constructor","payload","frequencyMillis","frequency","undefined","Number","POSITIVE_INFINITY","frequencyUnits","remaining","next","now","Date","previousStart","start","Math","max","nextStart","setStart","consumeRemaining","checkEnd","end","count","setRemaining","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","assertEx","now","Date","Math","max","delay","setTimeout","trigger","clearTimeout","update","wrapper","SentinelIntervalAutomationWrapper","payload","triggerResult","report","MemorySentinel","AbstractSentinel","configSchemas","SentinelConfigSchema","defaultConfigSchema","runner","reportHandler","inPayloads","started","logger","debug","JSON","stringify","job","jobPromise","index","previousResults","tasks","length","generatedPayloads","runJob","result","Object","values","flat","start","timeout","config","automations","SentinelRunner","stop","undefined","inputAddresses","input","Array","isArray","Promise","all","map","inputItem","resolved","resolve","address","processPreviousResults","payloads","inputs","flatMap","emit","module","results","allSettled","task","inPayloadsFound","witness","asWitnessInstance","observed","observe","id","outPayloads","diviner","asDivinerInstance","divined","divine","sentinel","asSentinelInstance","reported","report","Error","finalResult","filter","fulfilled","value","push","throwErrors","errors","rejected","reason"]}
@@ -25,8 +25,7 @@ var SentinelIntervalAutomationWrapper = class extends PayloadWrapper {
25
25
  }
26
26
  get frequencyMillis() {
27
27
  const frequency = this.payload.frequency;
28
- if (frequency === void 0)
29
- return Number.POSITIVE_INFINITY;
28
+ if (frequency === void 0) return Number.POSITIVE_INFINITY;
30
29
  const frequencyUnits = this.payload.frequencyUnits;
31
30
  switch (frequencyUnits ?? "hour") {
32
31
  case "second": {
@@ -67,8 +66,7 @@ var SentinelIntervalAutomationWrapper = class extends PayloadWrapper {
67
66
  consumeRemaining(count = 1) {
68
67
  const remaining = Math.max(this.remaining - count, 0);
69
68
  this.setRemaining(remaining);
70
- if (remaining <= 0)
71
- this.setStart(Number.POSITIVE_INFINITY);
69
+ if (remaining <= 0) this.setStart(Number.POSITIVE_INFINITY);
72
70
  }
73
71
  /**
74
72
  * Sets the remaining of the wrapped automation
@@ -98,9 +96,7 @@ var SentinelRunner = class {
98
96
  constructor(sentinel, automations, onTriggerResult) {
99
97
  this.sentinel = sentinel;
100
98
  this.onTriggerResult = onTriggerResult;
101
- if (automations)
102
- for (const automation of automations)
103
- forget(this.add(automation));
99
+ if (automations) for (const automation of automations) forget(this.add(automation));
104
100
  }
105
101
  get automations() {
106
102
  return this._automations;
@@ -116,8 +112,7 @@ var SentinelRunner = class {
116
112
  async add(automation, restart = true) {
117
113
  const hash = await PayloadBuilder.dataHash(automation);
118
114
  this._automations[hash] = automation;
119
- if (restart)
120
- await this.restart();
115
+ if (restart) await this.restart();
121
116
  return hash;
122
117
  }
123
118
  find(hash) {
@@ -125,8 +120,7 @@ var SentinelRunner = class {
125
120
  }
126
121
  async remove(hash, restart = true) {
127
122
  delete this._automations[hash];
128
- if (restart)
129
- await this.restart();
123
+ if (restart) await this.restart();
130
124
  }
131
125
  removeAll() {
132
126
  this.stop();
@@ -164,8 +158,7 @@ var SentinelRunner = class {
164
158
  async update(hash, automation, restart = true) {
165
159
  await this.remove(hash, false);
166
160
  await this.add(automation, false);
167
- if (restart)
168
- await this.restart();
161
+ if (restart) await this.restart();
169
162
  }
170
163
  async trigger(automation) {
171
164
  const wrapper = new SentinelIntervalAutomationWrapper(automation);
@@ -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, ModuleIdentifier } from '@xyo-network/module-model'\nimport { Payload, Schema } 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 readonly configSchemas: Schema[] = [...super.configSchemas, SentinelConfigSchema]\n static override readonly defaultConfigSchema: Schema = 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.runJob(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 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 inputAddresses(input: ModuleIdentifier | ModuleIdentifier[]): Promise<Address[]> {\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 private async runJob(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n await this.emit('jobStart', { inPayloads, module: this })\n this.logger?.debug(`runJob:tasks: ${JSON.stringify(tasks.length)}`)\n this.logger?.debug(`runJob:previous: ${JSON.stringify(previousResults)}`)\n this.logger?.debug(`runJob: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\n : input === false ? []\n : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n const witness = asWitnessInstance(task.module)\n if (witness) {\n await this.emit('taskStart', { address: witness.address, inPayloads: inPayloadsFound, module: this })\n const observed = await witness.observe(inPayloadsFound)\n this.logger?.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`)\n await this.emit('taskEnd', { address: witness.address, inPayloads: inPayloadsFound, module: this, outPayloads: observed })\n return [witness.address, observed]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n await this.emit('taskStart', { address: diviner.address, inPayloads: inPayloadsFound, module: this })\n const divined = await diviner.divine(inPayloadsFound)\n this.logger?.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`)\n await this.emit('taskEnd', { address: diviner.address, inPayloads: inPayloadsFound, module: this, outPayloads: divined })\n return [diviner.address, divined]\n }\n const sentinel = asSentinelInstance(task.module)\n if (sentinel) {\n await this.emit('taskStart', { address: sentinel.address, inPayloads: inPayloadsFound, module: this })\n const reported = await sentinel.report(inPayloadsFound)\n this.logger?.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`)\n await this.emit('taskEnd', { address: sentinel.address, inPayloads: inPayloadsFound, module: this, outPayloads: 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 await this.emit('jobEnd', { finalResult, inPayloads, module: this })\n return finalResult\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 restart() {\n this.stop()\n this.start()\n }\n\n start() {\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 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.payload, 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.payload.frequency\n if (frequency === undefined) return Number.POSITIVE_INFINITY\n const frequencyUnits = this.payload.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.payload.remaining ?? Number.POSITIVE_INFINITY\n }\n\n next() {\n const now = Date.now()\n const previousStart = this.payload?.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.payload.start > (this.payload.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.payload.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.payload.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","undefined","Number","POSITIVE_INFINITY","frequencyUnits","remaining","next","now","Date","previousStart","start","Math","max","nextStart","setStart","consumeRemaining","checkEnd","end","count","setRemaining","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","assertEx","now","Date","Math","max","delay","setTimeout","trigger","clearTimeout","update","wrapper","SentinelIntervalAutomationWrapper","payload","triggerResult","report","MemorySentinel","AbstractSentinel","configSchemas","SentinelConfigSchema","defaultConfigSchema","runner","reportHandler","inPayloads","started","logger","debug","JSON","stringify","job","jobPromise","index","previousResults","tasks","length","generatedPayloads","runJob","result","Object","values","flat","start","timeout","config","automations","SentinelRunner","stop","undefined","inputAddresses","input","Array","isArray","Promise","all","map","inputItem","resolved","resolve","address","processPreviousResults","payloads","inputs","flatMap","emit","module","results","allSettled","task","inPayloadsFound","witness","asWitnessInstance","observed","observe","id","outPayloads","diviner","asDivinerInstance","divined","divine","sentinel","asSentinelInstance","reported","report","Error","finalResult","filter","fulfilled","value","push","throwErrors","errors","rejected","reason"]}
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, ModuleIdentifier } from '@xyo-network/module-model'\nimport { Payload, Schema } 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 readonly configSchemas: Schema[] = [...super.configSchemas, SentinelConfigSchema]\n static override readonly defaultConfigSchema: Schema = 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.runJob(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 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 inputAddresses(input: ModuleIdentifier | ModuleIdentifier[]): Promise<Address[]> {\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 private async runJob(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n await this.emit('jobStart', { inPayloads, module: this })\n this.logger?.debug(`runJob:tasks: ${JSON.stringify(tasks.length)}`)\n this.logger?.debug(`runJob:previous: ${JSON.stringify(previousResults)}`)\n this.logger?.debug(`runJob: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\n : input === false ? []\n : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n const witness = asWitnessInstance(task.module)\n if (witness) {\n await this.emit('taskStart', { address: witness.address, inPayloads: inPayloadsFound, module: this })\n const observed = await witness.observe(inPayloadsFound)\n this.logger?.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`)\n await this.emit('taskEnd', { address: witness.address, inPayloads: inPayloadsFound, module: this, outPayloads: observed })\n return [witness.address, observed]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n await this.emit('taskStart', { address: diviner.address, inPayloads: inPayloadsFound, module: this })\n const divined = await diviner.divine(inPayloadsFound)\n this.logger?.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`)\n await this.emit('taskEnd', { address: diviner.address, inPayloads: inPayloadsFound, module: this, outPayloads: divined })\n return [diviner.address, divined]\n }\n const sentinel = asSentinelInstance(task.module)\n if (sentinel) {\n await this.emit('taskStart', { address: sentinel.address, inPayloads: inPayloadsFound, module: this })\n const reported = await sentinel.report(inPayloadsFound)\n this.logger?.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`)\n await this.emit('taskEnd', { address: sentinel.address, inPayloads: inPayloadsFound, module: this, outPayloads: 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 await this.emit('jobEnd', { finalResult, inPayloads, module: this })\n return finalResult\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 restart() {\n this.stop()\n this.start()\n }\n\n start() {\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 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.payload, 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.payload.frequency\n if (frequency === undefined) return Number.POSITIVE_INFINITY\n const frequencyUnits = this.payload.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.payload.remaining ?? Number.POSITIVE_INFINITY\n }\n\n next() {\n const now = Date.now()\n const previousStart = this.payload?.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.payload.start > (this.payload.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.payload.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.payload.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","undefined","Number","POSITIVE_INFINITY","frequencyUnits","remaining","next","now","Date","previousStart","start","Math","max","nextStart","setStart","consumeRemaining","checkEnd","end","count","setRemaining","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","assertEx","now","Date","Math","max","delay","setTimeout","trigger","clearTimeout","update","wrapper","SentinelIntervalAutomationWrapper","payload","triggerResult","report","MemorySentinel","AbstractSentinel","configSchemas","SentinelConfigSchema","defaultConfigSchema","runner","reportHandler","inPayloads","started","logger","debug","JSON","stringify","job","jobPromise","index","previousResults","tasks","length","generatedPayloads","runJob","result","Object","values","flat","start","timeout","config","automations","SentinelRunner","stop","undefined","inputAddresses","input","Array","isArray","Promise","all","map","inputItem","resolved","resolve","address","processPreviousResults","payloads","inputs","flatMap","emit","module","results","allSettled","task","inPayloadsFound","witness","asWitnessInstance","observed","observe","id","outPayloads","diviner","asDivinerInstance","divined","divine","sentinel","asSentinelInstance","reported","report","Error","finalResult","filter","fulfilled","value","push","throwErrors","errors","rejected","reason"]}
@@ -20,10 +20,7 @@ var __copyProps = (to, from, except, desc) => {
20
20
  return to;
21
21
  };
22
22
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
23
- var __publicField = (obj, key, value) => {
24
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
25
- return value;
26
- };
23
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
27
24
  var __superGet = (cls, obj, key) => __reflectGet(__getProtoOf(cls), key, obj);
28
25
 
29
26
  // src/index.ts
@@ -56,8 +53,7 @@ var _SentinelIntervalAutomationWrapper = class _SentinelIntervalAutomationWrappe
56
53
  }
57
54
  get frequencyMillis() {
58
55
  const frequency = this.payload.frequency;
59
- if (frequency === void 0)
60
- return Number.POSITIVE_INFINITY;
56
+ if (frequency === void 0) return Number.POSITIVE_INFINITY;
61
57
  const frequencyUnits = this.payload.frequencyUnits;
62
58
  switch (frequencyUnits ?? "hour") {
63
59
  case "second": {
@@ -99,8 +95,7 @@ var _SentinelIntervalAutomationWrapper = class _SentinelIntervalAutomationWrappe
99
95
  consumeRemaining(count = 1) {
100
96
  const remaining = Math.max(this.remaining - count, 0);
101
97
  this.setRemaining(remaining);
102
- if (remaining <= 0)
103
- this.setStart(Number.POSITIVE_INFINITY);
98
+ if (remaining <= 0) this.setStart(Number.POSITIVE_INFINITY);
104
99
  }
105
100
  /**
106
101
  * Sets the remaining of the wrapped automation
@@ -129,9 +124,7 @@ var _SentinelRunner = class _SentinelRunner {
129
124
  constructor(sentinel, automations, onTriggerResult) {
130
125
  this.sentinel = sentinel;
131
126
  this.onTriggerResult = onTriggerResult;
132
- if (automations)
133
- for (const automation of automations)
134
- (0, import_forget.forget)(this.add(automation));
127
+ if (automations) for (const automation of automations) (0, import_forget.forget)(this.add(automation));
135
128
  }
136
129
  get automations() {
137
130
  return this._automations;
@@ -147,8 +140,7 @@ var _SentinelRunner = class _SentinelRunner {
147
140
  async add(automation, restart = true) {
148
141
  const hash = await import_payload_builder.PayloadBuilder.dataHash(automation);
149
142
  this._automations[hash] = automation;
150
- if (restart)
151
- await this.restart();
143
+ if (restart) await this.restart();
152
144
  return hash;
153
145
  }
154
146
  find(hash) {
@@ -156,8 +148,7 @@ var _SentinelRunner = class _SentinelRunner {
156
148
  }
157
149
  async remove(hash, restart = true) {
158
150
  delete this._automations[hash];
159
- if (restart)
160
- await this.restart();
151
+ if (restart) await this.restart();
161
152
  }
162
153
  removeAll() {
163
154
  this.stop();
@@ -195,8 +186,7 @@ var _SentinelRunner = class _SentinelRunner {
195
186
  async update(hash, automation, restart = true) {
196
187
  await this.remove(hash, false);
197
188
  await this.add(automation, false);
198
- if (restart)
199
- await this.restart();
189
+ if (restart) await this.restart();
200
190
  }
201
191
  async trigger(automation) {
202
192
  var _a;
@@ -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, ModuleIdentifier } from '@xyo-network/module-model'\nimport { Payload, Schema } 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 readonly configSchemas: Schema[] = [...super.configSchemas, SentinelConfigSchema]\n static override readonly defaultConfigSchema: Schema = 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.runJob(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 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 inputAddresses(input: ModuleIdentifier | ModuleIdentifier[]): Promise<Address[]> {\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 private async runJob(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n await this.emit('jobStart', { inPayloads, module: this })\n this.logger?.debug(`runJob:tasks: ${JSON.stringify(tasks.length)}`)\n this.logger?.debug(`runJob:previous: ${JSON.stringify(previousResults)}`)\n this.logger?.debug(`runJob: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\n : input === false ? []\n : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n const witness = asWitnessInstance(task.module)\n if (witness) {\n await this.emit('taskStart', { address: witness.address, inPayloads: inPayloadsFound, module: this })\n const observed = await witness.observe(inPayloadsFound)\n this.logger?.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`)\n await this.emit('taskEnd', { address: witness.address, inPayloads: inPayloadsFound, module: this, outPayloads: observed })\n return [witness.address, observed]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n await this.emit('taskStart', { address: diviner.address, inPayloads: inPayloadsFound, module: this })\n const divined = await diviner.divine(inPayloadsFound)\n this.logger?.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`)\n await this.emit('taskEnd', { address: diviner.address, inPayloads: inPayloadsFound, module: this, outPayloads: divined })\n return [diviner.address, divined]\n }\n const sentinel = asSentinelInstance(task.module)\n if (sentinel) {\n await this.emit('taskStart', { address: sentinel.address, inPayloads: inPayloadsFound, module: this })\n const reported = await sentinel.report(inPayloadsFound)\n this.logger?.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`)\n await this.emit('taskEnd', { address: sentinel.address, inPayloads: inPayloadsFound, module: this, outPayloads: 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 await this.emit('jobEnd', { finalResult, inPayloads, module: this })\n return finalResult\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 restart() {\n this.stop()\n this.start()\n }\n\n start() {\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 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.payload, 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.payload.frequency\n if (frequency === undefined) return Number.POSITIVE_INFINITY\n const frequencyUnits = this.payload.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.payload.remaining ?? Number.POSITIVE_INFINITY\n }\n\n next() {\n const now = Date.now()\n const previousStart = this.payload?.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.payload.start > (this.payload.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.payload.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.payload.start = start\n }\n}\n"],"mappings":"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","names":["import_sentinel_model","SentinelIntervalAutomationWrapper","PayloadWrapper","constructor","payload","frequencyMillis","frequency","undefined","Number","POSITIVE_INFINITY","frequencyUnits","remaining","next","now","Date","previousStart","start","Math","max","nextStart","setStart","consumeRemaining","checkEnd","end","count","setRemaining","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","assertEx","now","Date","Math","max","delay","setTimeout","trigger","clearTimeout","update","wrapper","SentinelIntervalAutomationWrapper","payload","triggerResult","report","MemorySentinel","AbstractSentinel","runner","reportHandler","inPayloads","started","logger","debug","JSON","stringify","job","jobPromise","index","previousResults","tasks","length","generatedPayloads","runJob","result","Object","values","flat","start","timeout","config","automations","SentinelRunner","stop","undefined","inputAddresses","input","Array","isArray","Promise","all","map","inputItem","resolved","resolve","address","processPreviousResults","payloads","inputs","flatMap","emit","module","results","allSettled","task","_a","_b","_c","inPayloadsFound","witness","asWitnessInstance","observed","observe","id","outPayloads","diviner","asDivinerInstance","divined","divine","sentinel","asSentinelInstance","reported","report","Error","finalResult","filter","fulfilled","value","push","throwErrors","errors","rejected","reason","configSchemas","SentinelConfigSchema","defaultConfigSchema"]}
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, ModuleIdentifier } from '@xyo-network/module-model'\nimport { Payload, Schema } 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 readonly configSchemas: Schema[] = [...super.configSchemas, SentinelConfigSchema]\n static override readonly defaultConfigSchema: Schema = 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.runJob(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 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 inputAddresses(input: ModuleIdentifier | ModuleIdentifier[]): Promise<Address[]> {\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 private async runJob(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n await this.emit('jobStart', { inPayloads, module: this })\n this.logger?.debug(`runJob:tasks: ${JSON.stringify(tasks.length)}`)\n this.logger?.debug(`runJob:previous: ${JSON.stringify(previousResults)}`)\n this.logger?.debug(`runJob: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\n : input === false ? []\n : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n const witness = asWitnessInstance(task.module)\n if (witness) {\n await this.emit('taskStart', { address: witness.address, inPayloads: inPayloadsFound, module: this })\n const observed = await witness.observe(inPayloadsFound)\n this.logger?.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`)\n await this.emit('taskEnd', { address: witness.address, inPayloads: inPayloadsFound, module: this, outPayloads: observed })\n return [witness.address, observed]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n await this.emit('taskStart', { address: diviner.address, inPayloads: inPayloadsFound, module: this })\n const divined = await diviner.divine(inPayloadsFound)\n this.logger?.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`)\n await this.emit('taskEnd', { address: diviner.address, inPayloads: inPayloadsFound, module: this, outPayloads: divined })\n return [diviner.address, divined]\n }\n const sentinel = asSentinelInstance(task.module)\n if (sentinel) {\n await this.emit('taskStart', { address: sentinel.address, inPayloads: inPayloadsFound, module: this })\n const reported = await sentinel.report(inPayloadsFound)\n this.logger?.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`)\n await this.emit('taskEnd', { address: sentinel.address, inPayloads: inPayloadsFound, module: this, outPayloads: 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 await this.emit('jobEnd', { finalResult, inPayloads, module: this })\n return finalResult\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 restart() {\n this.stop()\n this.start()\n }\n\n start() {\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 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.payload, 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.payload.frequency\n if (frequency === undefined) return Number.POSITIVE_INFINITY\n const frequencyUnits = this.payload.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.payload.remaining ?? Number.POSITIVE_INFINITY\n }\n\n next() {\n const now = Date.now()\n const previousStart = this.payload?.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.payload.start > (this.payload.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.payload.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.payload.start = start\n }\n}\n"],"mappings":"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","names":["import_sentinel_model","SentinelIntervalAutomationWrapper","PayloadWrapper","constructor","payload","frequencyMillis","frequency","undefined","Number","POSITIVE_INFINITY","frequencyUnits","remaining","next","now","Date","previousStart","start","Math","max","nextStart","setStart","consumeRemaining","checkEnd","end","count","setRemaining","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","assertEx","now","Date","Math","max","delay","setTimeout","trigger","clearTimeout","update","wrapper","SentinelIntervalAutomationWrapper","payload","triggerResult","report","MemorySentinel","AbstractSentinel","runner","reportHandler","inPayloads","started","logger","debug","JSON","stringify","job","jobPromise","index","previousResults","tasks","length","generatedPayloads","runJob","result","Object","values","flat","start","timeout","config","automations","SentinelRunner","stop","undefined","inputAddresses","input","Array","isArray","Promise","all","map","inputItem","resolved","resolve","address","processPreviousResults","payloads","inputs","flatMap","emit","module","results","allSettled","task","_a","_b","_c","inPayloadsFound","witness","asWitnessInstance","observed","observe","id","outPayloads","diviner","asDivinerInstance","divined","divine","sentinel","asSentinelInstance","reported","report","Error","finalResult","filter","fulfilled","value","push","throwErrors","errors","rejected","reason","configSchemas","SentinelConfigSchema","defaultConfigSchema"]}
@@ -3,10 +3,7 @@ var __getProtoOf = Object.getPrototypeOf;
3
3
  var __reflectGet = Reflect.get;
4
4
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
5
5
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
6
- var __publicField = (obj, key, value) => {
7
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
8
- return value;
9
- };
6
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
10
7
  var __superGet = (cls, obj, key) => __reflectGet(__getProtoOf(cls), key, obj);
11
8
 
12
9
  // src/MemorySentinel.ts
@@ -30,8 +27,7 @@ var _SentinelIntervalAutomationWrapper = class _SentinelIntervalAutomationWrappe
30
27
  }
31
28
  get frequencyMillis() {
32
29
  const frequency = this.payload.frequency;
33
- if (frequency === void 0)
34
- return Number.POSITIVE_INFINITY;
30
+ if (frequency === void 0) return Number.POSITIVE_INFINITY;
35
31
  const frequencyUnits = this.payload.frequencyUnits;
36
32
  switch (frequencyUnits ?? "hour") {
37
33
  case "second": {
@@ -73,8 +69,7 @@ var _SentinelIntervalAutomationWrapper = class _SentinelIntervalAutomationWrappe
73
69
  consumeRemaining(count = 1) {
74
70
  const remaining = Math.max(this.remaining - count, 0);
75
71
  this.setRemaining(remaining);
76
- if (remaining <= 0)
77
- this.setStart(Number.POSITIVE_INFINITY);
72
+ if (remaining <= 0) this.setStart(Number.POSITIVE_INFINITY);
78
73
  }
79
74
  /**
80
75
  * Sets the remaining of the wrapped automation
@@ -103,9 +98,7 @@ var _SentinelRunner = class _SentinelRunner {
103
98
  constructor(sentinel, automations, onTriggerResult) {
104
99
  this.sentinel = sentinel;
105
100
  this.onTriggerResult = onTriggerResult;
106
- if (automations)
107
- for (const automation of automations)
108
- forget(this.add(automation));
101
+ if (automations) for (const automation of automations) forget(this.add(automation));
109
102
  }
110
103
  get automations() {
111
104
  return this._automations;
@@ -121,8 +114,7 @@ var _SentinelRunner = class _SentinelRunner {
121
114
  async add(automation, restart = true) {
122
115
  const hash = await PayloadBuilder.dataHash(automation);
123
116
  this._automations[hash] = automation;
124
- if (restart)
125
- await this.restart();
117
+ if (restart) await this.restart();
126
118
  return hash;
127
119
  }
128
120
  find(hash) {
@@ -130,8 +122,7 @@ var _SentinelRunner = class _SentinelRunner {
130
122
  }
131
123
  async remove(hash, restart = true) {
132
124
  delete this._automations[hash];
133
- if (restart)
134
- await this.restart();
125
+ if (restart) await this.restart();
135
126
  }
136
127
  removeAll() {
137
128
  this.stop();
@@ -169,8 +160,7 @@ var _SentinelRunner = class _SentinelRunner {
169
160
  async update(hash, automation, restart = true) {
170
161
  await this.remove(hash, false);
171
162
  await this.add(automation, false);
172
- if (restart)
173
- await this.restart();
163
+ if (restart) await this.restart();
174
164
  }
175
165
  async trigger(automation) {
176
166
  var _a;
@@ -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, ModuleIdentifier } from '@xyo-network/module-model'\nimport { Payload, Schema } 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 readonly configSchemas: Schema[] = [...super.configSchemas, SentinelConfigSchema]\n static override readonly defaultConfigSchema: Schema = 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.runJob(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 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 inputAddresses(input: ModuleIdentifier | ModuleIdentifier[]): Promise<Address[]> {\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 private async runJob(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n await this.emit('jobStart', { inPayloads, module: this })\n this.logger?.debug(`runJob:tasks: ${JSON.stringify(tasks.length)}`)\n this.logger?.debug(`runJob:previous: ${JSON.stringify(previousResults)}`)\n this.logger?.debug(`runJob: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\n : input === false ? []\n : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n const witness = asWitnessInstance(task.module)\n if (witness) {\n await this.emit('taskStart', { address: witness.address, inPayloads: inPayloadsFound, module: this })\n const observed = await witness.observe(inPayloadsFound)\n this.logger?.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`)\n await this.emit('taskEnd', { address: witness.address, inPayloads: inPayloadsFound, module: this, outPayloads: observed })\n return [witness.address, observed]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n await this.emit('taskStart', { address: diviner.address, inPayloads: inPayloadsFound, module: this })\n const divined = await diviner.divine(inPayloadsFound)\n this.logger?.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`)\n await this.emit('taskEnd', { address: diviner.address, inPayloads: inPayloadsFound, module: this, outPayloads: divined })\n return [diviner.address, divined]\n }\n const sentinel = asSentinelInstance(task.module)\n if (sentinel) {\n await this.emit('taskStart', { address: sentinel.address, inPayloads: inPayloadsFound, module: this })\n const reported = await sentinel.report(inPayloadsFound)\n this.logger?.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`)\n await this.emit('taskEnd', { address: sentinel.address, inPayloads: inPayloadsFound, module: this, outPayloads: 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 await this.emit('jobEnd', { finalResult, inPayloads, module: this })\n return finalResult\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 restart() {\n this.stop()\n this.start()\n }\n\n start() {\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 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.payload, 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.payload.frequency\n if (frequency === undefined) return Number.POSITIVE_INFINITY\n const frequencyUnits = this.payload.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.payload.remaining ?? Number.POSITIVE_INFINITY\n }\n\n next() {\n const now = Date.now()\n const previousStart = this.payload?.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.payload.start > (this.payload.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.payload.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.payload.start = start\n }\n}\n"],"mappings":";;;;;;;;;;;;AACA,SAASA,WAAWC,gBAAgB;AACpC,SAASC,yBAAyB;AAGlC,SAASC,wBAAwB;AACjC,SACEC,oBAGAC,4BAIK;AACP,SAASC,yBAAyB;;;ACflC,SAASC,gBAAgB;AACzB,SAASC,cAAc;AACvB,SAASC,sBAAsB;AAE/B,SACEC,oCAIK;;;ACTP,SAASC,sBAAsB;AAGxB,IAAMC,qCAAN,MAAMA,2CAEHC,eAAAA;EACRC,YAAYC,SAAY;AACtB,UAAMA,OAAAA;EACR;EAEA,IAAcC,kBAAkB;AAC9B,UAAMC,YAAY,KAAKF,QAAQE;AAC/B,QAAIA,cAAcC;AAAW,aAAOC,OAAOC;AAC3C,UAAMC,iBAAiB,KAAKN,QAAQM;AACpC,YAAQA,kBAAkB,QAAA;MACxB,KAAK,UAAU;AACb,eAAOJ,YAAY;MACrB;MACA,KAAK,UAAU;AACb,eAAOA,YAAY,KAAK;MAC1B;MACA,KAAK,QAAQ;AACX,eAAOA,YAAY,KAAK,KAAK;MAC/B;MACA,KAAK,OAAO;AACV,eAAOA,YAAY,KAAK,KAAK,KAAK;MACpC;MACA,SAAS;AACP,eAAOE,OAAOC;MAChB;IACF;EACF;EAEA,IAAcE,YAAY;AACxB,WAAO,KAAKP,QAAQO,aAAaH,OAAOC;EAC1C;EAEAG,OAAO;AArCT;AAsCI,UAAMC,MAAMC,KAAKD,IAAG;AACpB,UAAME,kBAAgB,UAAKX,YAAL,mBAAcY,UAASH;AAC7C,UAAMG,QAAQC,KAAKC,IAAIH,eAAeF,GAAAA;AACtC,UAAMM,YAAYH,QAAQ,KAAKX;AAC/B,SAAKe,SAASD,SAAAA;AACd,SAAKE,iBAAgB;AACrB,SAAKC,SAAQ;AACb,WAAO;EACT;EAEUA,WAAW;AACnB,QAAI,KAAKlB,QAAQY,SAAS,KAAKZ,QAAQmB,OAAOf,OAAOC,oBAAoB;AACvE,WAAKW,SAASZ,OAAOC,iBAAiB;IACxC;EACF;EAEUY,iBAAiBG,QAAQ,GAAG;AACpC,UAAMb,YAAYM,KAAKC,IAAI,KAAKP,YAAYa,OAAO,CAAA;AACnD,SAAKC,aAAad,SAAAA;AAClB,QAAIA,aAAa;AAAG,WAAKS,SAASZ,OAAOC,iBAAiB;EAC5D;;;;;EAMUgB,aAAad,WAAmB;AACxC,SAAKP,QAAQO,YAAYA;EAC3B;;;;;EAMUS,SAASJ,OAAe;AAChC,SAAKZ,QAAQY,QAAQA;EACvB;AACF;AAtEUd;AAFH,IAAMD,oCAAN;;;ADYA,IAAMyB,kBAAN,MAAMA,gBAAAA;EACDC,eAA0D,CAAC;EAC3DC;EACAC;EACAC;EAEVC,YAAYF,UAA4BG,aAA2CJ,iBAAiD;AAClI,SAAKC,WAAWA;AAChB,SAAKD,kBAAkBA;AACvB,QAAII;AAAa,iBAAWC,cAAcD;AAAaE,eAAO,KAAKC,IAAIF,UAAAA,CAAAA;EACzE;EAEA,IAAID,cAAc;AAChB,WAAO,KAAKL;EACd;EAEA,IAAYS,OAAO;AAEjB,WAAOC,OAAOC,OAAO,KAAKX,YAAY,EAAEY,OAA8C,CAACC,UAAUC,YAAAA;AAC/F,UAAIC,6BAA6BD,OAAAA,KAAYC,6BAA6BF,QAAAA,GAAW;AACnF,eAAOC,QAAQE,UAASH,qCAAUG,UAASC,OAAOC,qBAAqBJ,UAAUD;MACnF;AACA,aAAOC;IAET,GAAGK,MAAAA;EACL;EAEA,MAAMX,IAAIF,YAAuCc,UAAU,MAAM;AAC/D,UAAMC,OAAO,MAAMC,eAAeC,SAASjB,UAAAA;AAC3C,SAAKN,aAAaqB,IAAAA,IAAQf;AAC1B,QAAIc;AAAS,YAAM,KAAKA,QAAO;AAC/B,WAAOC;EACT;EAEAG,KAAKH,MAAc;AACjBX,WAAOe,QAAQ,KAAKzB,YAAY,EAAEwB,KAAK,CAAC,CAACE,GAAAA,MAASA,QAAQL,IAAAA;EAC5D;EAEA,MAAMM,OAAON,MAAcD,UAAU,MAAM;AACzC,WAAO,KAAKpB,aAAaqB,IAAAA;AACzB,QAAID;AAAS,YAAM,KAAKA,QAAO;EACjC;EAEAQ,YAAY;AACV,SAAKC,KAAI;AACT,SAAK7B,eAAe,CAAC;EACvB;EAEAoB,UAAU;AACR,SAAKS,KAAI;AACT,SAAKb,MAAK;EACZ;EAEAA,QAAQ;AACNc,aAAS,KAAK3B,cAAcgB,QAAW,MAAM,iBAAA;AAC7C,UAAMb,aAAa,KAAKG;AACxB,QAAIM,6BAA6BT,UAAAA,GAAa;AAC5C,YAAMyB,MAAMC,KAAKD,IAAG;AACpB,YAAMf,QAAQiB,KAAKC,IAAI5B,WAAWU,SAASe,KAAKA,GAAAA;AAChD,YAAMI,QAAQF,KAAKC,IAAIlB,QAAQe,KAAK,CAAA;AACpC,UAAII,QAAQlB,OAAOC,mBAAmB;AAEpC,aAAKf,YAAYiC,WAAW,YAAA;AAC1B,cAAI;AAEF,kBAAM,KAAKC,QAAQ/B,UAAAA;AACnB,iBAAKuB,KAAI;UACX,UAAA;AAEE,iBAAKb,MAAK;UACZ;QACF,GAAGmB,KAAAA;MACL;IACF;EACF;EAEAN,OAAO;AACL,QAAI,KAAK1B,WAAW;AAClBmC,mBAAa,KAAKnC,SAAS;AAC3B,WAAKA,YAAYgB;IACnB;EACF;EAEA,MAAMoB,OAAOlB,MAAcf,YAAuCc,UAAU,MAAM;AAChF,UAAM,KAAKO,OAAON,MAAM,KAAA;AACxB,UAAM,KAAKb,IAAIF,YAAY,KAAA;AAC3B,QAAIc;AAAS,YAAM,KAAKA,QAAO;EACjC;EAEA,MAAciB,QAAQ/B,YAA+C;AAxGvE;AAyGI,UAAMkC,UAAU,IAAIC,kCAAkCnC,UAAAA;AACtD,UAAM,KAAKqB,OAAO,MAAMa,QAAQjB,SAAQ,GAAI,KAAA;AAC5CiB,YAAQ/B,KAAI;AACZ,UAAM,KAAKD,IAAIgC,QAAQE,SAAS,KAAA;AAChC,UAAMC,gBAAgB,MAAM,KAAKzC,SAAS0C,OAAM;AAChD,eAAK3C,oBAAL,8BAAuB0C;EAEzB;AACF;AAlGa5C;AAAN,IAAMA,iBAAN;;;ADMA,IAAM8C,kBAAN,MAAMA,wBAGHC,iBAAAA;EAIAC;EAER,MAAMC,cAAcC,aAAwB,CAAA,GAAwB;AA7BtE;AA8BI,UAAM,KAAKC,QAAQ,OAAA;AACnB,eAAKC,WAAL,mBAAaC,MAAM,qBAAqBC,KAAKC,UAAUL,UAAAA,CAAAA;AACvD,UAAMM,MAAM,MAAM,KAAKC;AAEvB,QAAIC,QAAQ;AACZ,QAAIC,kBAA8C,CAAC;AACnD,WAAOD,QAAQF,IAAII,MAAMC,QAAQ;AAC/B,YAAMC,oBAAoB,MAAM,KAAKC,OAAOP,IAAII,MAAMF,KAAAA,GAAQC,iBAAiBT,UAAAA;AAC/ES,wBAAkBG;AAClBJ;IACF;AACA,UAAMM,SAASC,OAAOC,OAAOP,eAAAA,EAAiBQ,KAAI;AAClD,eAAKf,WAAL,mBAAaC,MAAM,sBAAsBC,KAAKC,UAAUS,MAAAA,CAAAA;AACxD,WAAOA;EACT;EAEA,MAAeI,MAAMC,SAAgD;AA9CvE;AA+CI,QAAI,MAAM,MAAMD,MAAMC,OAAAA,GAAU;AAC9B,aAAK,UAAKC,OAAOC,gBAAZ,mBAAyBV,WAAU,KAAK,GAAG;AAC9C,aAAKb,SAAS,IAAIwB,eAAe,MAAM,KAAKF,OAAOC,WAAW;AAC9D,aAAKvB,OAAOoB,MAAK;MACnB;AACA,aAAO;IACT;AACA,WAAO;EACT;EAEA,MAAeK,KAAKJ,SAAgD;AAClE,QAAI,KAAKrB,QAAQ;AACf,WAAKA,OAAOyB,KAAI;AAChB,WAAKzB,SAAS0B;IAChB;AACA,WAAO,MAAM,MAAMD,KAAKJ,OAAAA;EAC1B;EAEA,MAAcM,eAAeC,OAAkE;AAC7F,QAAIC,MAAMC,QAAQF,KAAAA,GAAQ;AACxB,cAAQ,MAAMG,QAAQC,IAAIJ,MAAMK,IAAI,OAAOC,cAAc,MAAM,KAAKP,eAAeO,SAAAA,CAAAA,CAAAA,GAAcf,KAAI;IACvG,OAAO;AACL,YAAMgB,WAAW,MAAM,KAAKC,QAAQR,KAAAA;AACpC,aAAOO,WAAW;QAACA,SAASE;UAAW,CAAA;IACzC;EACF;EAEQC,uBAAuBC,UAAqCC,QAAkB;AACpF,WAAOA,OAAOC,QAAQ,CAACb,UAAUW,SAASX,KAAAA,KAAU,CAAA,CAAE;EACxD;EAEA,MAAcb,OACZH,OACAD,iBACAT,YACqC;AAlFzC;AAmFI,UAAM,KAAKwC,KAAK,YAAY;MAAExC;MAAYyC,QAAQ;IAAK,CAAA;AACvD,eAAKvC,WAAL,mBAAaC,MAAM,iBAAiBC,KAAKC,UAAUK,MAAMC,MAAM,CAAA;AAC/D,eAAKT,WAAL,mBAAaC,MAAM,oBAAoBC,KAAKC,UAAUI,eAAAA,CAAAA;AACtD,eAAKP,WAAL,mBAAaC,MAAM,cAAcC,KAAKC,UAAUL,UAAAA,CAAAA;AAChD,UAAM0C,UAAwD,MAAMb,QAAQc,WAC1EjC,+BAAOqB,IAAI,OAAOa,SAAAA;AAxFxB,UAAAC,KAAAC,KAAAC;AAyFQ,YAAMrB,QAAQkB,KAAKlB,SAAS;AAC5B,YAAMsB,kBACJtB,UAAU,OAAO1B,aACf0B,UAAU,QAAQ,CAAA,IAClB,KAAKU,uBAAuB3B,iBAAiB,MAAM,KAAKgB,eAAeC,KAAAA,CAAAA;AAC3E,YAAMuB,UAAUC,kBAAkBN,KAAKH,MAAM;AAC7C,UAAIQ,SAAS;AACX,cAAM,KAAKT,KAAK,aAAa;UAAEL,SAASc,QAAQd;UAASnC,YAAYgD;UAAiBP,QAAQ;QAAK,CAAA;AACnG,cAAMU,WAAW,MAAMF,QAAQG,QAAQJ,eAAAA;AACvC,SAAAH,MAAA,KAAK3C,WAAL,gBAAA2C,IAAa1C,MAAM,aAAa8C,QAAQI,EAAE,MAAMjD,KAAKC,UAAU8C,QAAAA,CAAAA;AAC/D,cAAM,KAAKX,KAAK,WAAW;UAAEL,SAASc,QAAQd;UAASnC,YAAYgD;UAAiBP,QAAQ;UAAMa,aAAaH;QAAS,CAAA;AACxH,eAAO;UAACF,QAAQd;UAASgB;;MAC3B;AACA,YAAMI,UAAUC,kBAAkBZ,KAAKH,MAAM;AAC7C,UAAIc,SAAS;AACX,cAAM,KAAKf,KAAK,aAAa;UAAEL,SAASoB,QAAQpB;UAASnC,YAAYgD;UAAiBP,QAAQ;QAAK,CAAA;AACnG,cAAMgB,UAAU,MAAMF,QAAQG,OAAOV,eAAAA;AACrC,SAAAF,MAAA,KAAK5C,WAAL,gBAAA4C,IAAa3C,MAAM,YAAYoD,QAAQF,EAAE,MAAMjD,KAAKC,UAAUoD,OAAAA,CAAAA;AAC9D,cAAM,KAAKjB,KAAK,WAAW;UAAEL,SAASoB,QAAQpB;UAASnC,YAAYgD;UAAiBP,QAAQ;UAAMa,aAAaG;QAAQ,CAAA;AACvH,eAAO;UAACF,QAAQpB;UAASsB;;MAC3B;AACA,YAAME,WAAWC,mBAAmBhB,KAAKH,MAAM;AAC/C,UAAIkB,UAAU;AACZ,cAAM,KAAKnB,KAAK,aAAa;UAAEL,SAASwB,SAASxB;UAASnC,YAAYgD;UAAiBP,QAAQ;QAAK,CAAA;AACpG,cAAMoB,WAAW,MAAMF,SAASG,OAAOd,eAAAA;AACvC,SAAAD,MAAA,KAAK7C,WAAL,gBAAA6C,IAAa5C,MAAM,aAAawD,SAASN,EAAE,MAAMjD,KAAKC,UAAUwD,QAAAA,CAAAA;AAChE,cAAM,KAAKrB,KAAK,WAAW;UAAEL,SAASwB,SAASxB;UAASnC,YAAYgD;UAAiBP,QAAQ;UAAMa,aAAaO;QAAS,CAAA;AACzH,eAAO;UAACF,SAASxB;UAAS0B;;MAC5B;AACA,YAAM,IAAIE,MAAM,yBAAA;IAClB,EAAA;AAEF,UAAMC,cAA0C,CAAC;AACjD,eAAWlD,UAAU4B,QAAQuB,OAAOC,SAAAA,GAAY;AAC9C,YAAM,CAAC/B,SAASE,QAAAA,IAAYvB,OAAOqD;AACnCH,kBAAY7B,OAAAA,IAAW6B,YAAY7B,OAAAA,KAAY,CAAA;AAC/C6B,kBAAY7B,OAAAA,EAASiC,KAAI,GAAI/B,QAAAA;IAC/B;AACA,QAAI,KAAKgC,aAAa;AACpB,YAAMC,SAAS5B,QAAQuB,OAAOM,QAAAA,EAAUxC,IAAI,CAACjB,WAAWA,OAAO0D,MAAM;AACrE,UAAIF,OAAO3D,SAAS,GAAG;AACrB,cAAM,IAAIoD,MAAM,4BAAA;MAClB;IACF;AACA,eAAK7D,WAAL,mBAAaC,MAAM,wBAAwBC,KAAKC,UAAU2D,WAAAA,CAAAA;AAC1D,UAAM,KAAKxB,KAAK,UAAU;MAAEwB;MAAahE;MAAYyC,QAAQ;IAAK,CAAA;AAClE,WAAOuB;EACT;AACF;AAlHUnE;AACR,cAJWD,iBAIc6E,iBAA0B;KAAI,6CAAMA;EAAeC;;AAC5E,cALW9E,iBAKc+E,uBAA8BD;AALlD,IAAM9E,iBAAN;","names":["fulfilled","rejected","asDivinerInstance","AbstractSentinel","asSentinelInstance","SentinelConfigSchema","asWitnessInstance","assertEx","forget","PayloadBuilder","isSentinelIntervalAutomation","PayloadWrapper","SentinelIntervalAutomationWrapper","PayloadWrapper","constructor","payload","frequencyMillis","frequency","undefined","Number","POSITIVE_INFINITY","frequencyUnits","remaining","next","now","Date","previousStart","start","Math","max","nextStart","setStart","consumeRemaining","checkEnd","end","count","setRemaining","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","assertEx","now","Date","Math","max","delay","setTimeout","trigger","clearTimeout","update","wrapper","SentinelIntervalAutomationWrapper","payload","triggerResult","report","MemorySentinel","AbstractSentinel","runner","reportHandler","inPayloads","started","logger","debug","JSON","stringify","job","jobPromise","index","previousResults","tasks","length","generatedPayloads","runJob","result","Object","values","flat","start","timeout","config","automations","SentinelRunner","stop","undefined","inputAddresses","input","Array","isArray","Promise","all","map","inputItem","resolved","resolve","address","processPreviousResults","payloads","inputs","flatMap","emit","module","results","allSettled","task","_a","_b","_c","inPayloadsFound","witness","asWitnessInstance","observed","observe","id","outPayloads","diviner","asDivinerInstance","divined","divine","sentinel","asSentinelInstance","reported","report","Error","finalResult","filter","fulfilled","value","push","throwErrors","errors","rejected","reason","configSchemas","SentinelConfigSchema","defaultConfigSchema"]}
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, ModuleIdentifier } from '@xyo-network/module-model'\nimport { Payload, Schema } 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 readonly configSchemas: Schema[] = [...super.configSchemas, SentinelConfigSchema]\n static override readonly defaultConfigSchema: Schema = 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.runJob(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 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 inputAddresses(input: ModuleIdentifier | ModuleIdentifier[]): Promise<Address[]> {\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 private async runJob(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n await this.emit('jobStart', { inPayloads, module: this })\n this.logger?.debug(`runJob:tasks: ${JSON.stringify(tasks.length)}`)\n this.logger?.debug(`runJob:previous: ${JSON.stringify(previousResults)}`)\n this.logger?.debug(`runJob: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\n : input === false ? []\n : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n const witness = asWitnessInstance(task.module)\n if (witness) {\n await this.emit('taskStart', { address: witness.address, inPayloads: inPayloadsFound, module: this })\n const observed = await witness.observe(inPayloadsFound)\n this.logger?.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`)\n await this.emit('taskEnd', { address: witness.address, inPayloads: inPayloadsFound, module: this, outPayloads: observed })\n return [witness.address, observed]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n await this.emit('taskStart', { address: diviner.address, inPayloads: inPayloadsFound, module: this })\n const divined = await diviner.divine(inPayloadsFound)\n this.logger?.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`)\n await this.emit('taskEnd', { address: diviner.address, inPayloads: inPayloadsFound, module: this, outPayloads: divined })\n return [diviner.address, divined]\n }\n const sentinel = asSentinelInstance(task.module)\n if (sentinel) {\n await this.emit('taskStart', { address: sentinel.address, inPayloads: inPayloadsFound, module: this })\n const reported = await sentinel.report(inPayloadsFound)\n this.logger?.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`)\n await this.emit('taskEnd', { address: sentinel.address, inPayloads: inPayloadsFound, module: this, outPayloads: 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 await this.emit('jobEnd', { finalResult, inPayloads, module: this })\n return finalResult\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 restart() {\n this.stop()\n this.start()\n }\n\n start() {\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 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.payload, 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.payload.frequency\n if (frequency === undefined) return Number.POSITIVE_INFINITY\n const frequencyUnits = this.payload.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.payload.remaining ?? Number.POSITIVE_INFINITY\n }\n\n next() {\n const now = Date.now()\n const previousStart = this.payload?.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.payload.start > (this.payload.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.payload.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.payload.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","undefined","Number","POSITIVE_INFINITY","frequencyUnits","remaining","next","now","Date","previousStart","start","Math","max","nextStart","setStart","consumeRemaining","checkEnd","end","count","setRemaining","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","assertEx","now","Date","Math","max","delay","setTimeout","trigger","clearTimeout","update","wrapper","SentinelIntervalAutomationWrapper","payload","triggerResult","report","MemorySentinel","AbstractSentinel","runner","reportHandler","inPayloads","started","logger","debug","JSON","stringify","job","jobPromise","index","previousResults","tasks","length","generatedPayloads","runJob","result","Object","values","flat","start","timeout","config","automations","SentinelRunner","stop","undefined","inputAddresses","input","Array","isArray","Promise","all","map","inputItem","resolved","resolve","address","processPreviousResults","payloads","inputs","flatMap","emit","module","results","allSettled","task","_a","_b","_c","inPayloadsFound","witness","asWitnessInstance","observed","observe","id","outPayloads","diviner","asDivinerInstance","divined","divine","sentinel","asSentinelInstance","reported","report","Error","finalResult","filter","fulfilled","value","push","throwErrors","errors","rejected","reason","configSchemas","SentinelConfigSchema","defaultConfigSchema"]}
package/package.json CHANGED
@@ -14,26 +14,26 @@
14
14
  "@xylabs/forget": "^3.5.1",
15
15
  "@xylabs/hex": "^3.5.1",
16
16
  "@xylabs/promise": "^3.5.1",
17
- "@xyo-network/diviner-model": "~2.104.0",
18
- "@xyo-network/module-model": "~2.104.0",
19
- "@xyo-network/payload-builder": "~2.104.0",
20
- "@xyo-network/payload-model": "~2.104.0",
21
- "@xyo-network/payload-wrapper": "~2.104.0",
22
- "@xyo-network/sentinel-abstract": "~2.104.0",
23
- "@xyo-network/sentinel-model": "~2.104.0",
24
- "@xyo-network/witness-model": "~2.104.0"
17
+ "@xyo-network/diviner-model": "~2.105.0-rc.1",
18
+ "@xyo-network/module-model": "~2.105.0-rc.1",
19
+ "@xyo-network/payload-builder": "~2.105.0-rc.1",
20
+ "@xyo-network/payload-model": "~2.105.0-rc.1",
21
+ "@xyo-network/payload-wrapper": "~2.105.0-rc.1",
22
+ "@xyo-network/sentinel-abstract": "~2.105.0-rc.1",
23
+ "@xyo-network/sentinel-model": "~2.105.0-rc.1",
24
+ "@xyo-network/witness-model": "~2.105.0-rc.1"
25
25
  },
26
26
  "description": "Primary SDK for using XYO Protocol 2.0",
27
27
  "devDependencies": {
28
28
  "@xylabs/delay": "^3.5.1",
29
- "@xylabs/ts-scripts-yarn3": "^3.10.4",
30
- "@xylabs/tsconfig": "^3.10.4",
31
- "@xyo-network/abstract-witness": "~2.104.0",
32
- "@xyo-network/account": "~2.104.0",
33
- "@xyo-network/archivist-memory": "~2.104.0",
34
- "@xyo-network/id-payload-plugin": "~2.104.0",
35
- "@xyo-network/node-memory": "~2.104.0",
36
- "@xyo-network/witness-adhoc": "~2.104.0",
29
+ "@xylabs/ts-scripts-yarn3": "^3.11.2",
30
+ "@xylabs/tsconfig": "^3.11.2",
31
+ "@xyo-network/abstract-witness": "~2.105.0-rc.1",
32
+ "@xyo-network/account": "~2.105.0-rc.1",
33
+ "@xyo-network/archivist-memory": "~2.105.0-rc.1",
34
+ "@xyo-network/id-payload-plugin": "~2.105.0-rc.1",
35
+ "@xyo-network/node-memory": "~2.105.0-rc.1",
36
+ "@xyo-network/witness-adhoc": "~2.105.0-rc.1",
37
37
  "typescript": "^5.4.5"
38
38
  },
39
39
  "types": "dist/node/index.d.ts",
@@ -74,6 +74,7 @@
74
74
  "url": "https://github.com/XYOracleNetwork/sdk-xyo-client-js.git"
75
75
  },
76
76
  "sideEffects": false,
77
- "version": "2.104.0",
78
- "type": "module"
77
+ "version": "2.105.0-rc.1",
78
+ "type": "module",
79
+ "stableVersion": "2.104.1"
79
80
  }