@xyo-network/sentinel-memory 2.89.0-rc.9 → 2.89.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.
Files changed (35) hide show
  1. package/dist/browser/MemorySentinel.d.cts +1 -1
  2. package/dist/browser/MemorySentinel.d.cts.map +1 -1
  3. package/dist/browser/MemorySentinel.d.mts +1 -1
  4. package/dist/browser/MemorySentinel.d.mts.map +1 -1
  5. package/dist/browser/MemorySentinel.d.ts +1 -1
  6. package/dist/browser/MemorySentinel.d.ts.map +1 -1
  7. package/dist/browser/SentinelRunner.d.cts +2 -2
  8. package/dist/browser/SentinelRunner.d.cts.map +1 -1
  9. package/dist/browser/SentinelRunner.d.mts +2 -2
  10. package/dist/browser/SentinelRunner.d.mts.map +1 -1
  11. package/dist/browser/SentinelRunner.d.ts +2 -2
  12. package/dist/browser/SentinelRunner.d.ts.map +1 -1
  13. package/dist/browser/index.cjs +65 -24
  14. package/dist/browser/index.cjs.map +1 -1
  15. package/dist/browser/index.js +65 -24
  16. package/dist/browser/index.js.map +1 -1
  17. package/dist/node/MemorySentinel.d.cts +1 -1
  18. package/dist/node/MemorySentinel.d.cts.map +1 -1
  19. package/dist/node/MemorySentinel.d.mts +1 -1
  20. package/dist/node/MemorySentinel.d.mts.map +1 -1
  21. package/dist/node/MemorySentinel.d.ts +1 -1
  22. package/dist/node/MemorySentinel.d.ts.map +1 -1
  23. package/dist/node/SentinelRunner.d.cts +2 -2
  24. package/dist/node/SentinelRunner.d.cts.map +1 -1
  25. package/dist/node/SentinelRunner.d.mts +2 -2
  26. package/dist/node/SentinelRunner.d.mts.map +1 -1
  27. package/dist/node/SentinelRunner.d.ts +2 -2
  28. package/dist/node/SentinelRunner.d.ts.map +1 -1
  29. package/dist/node/index.cjs +65 -24
  30. package/dist/node/index.cjs.map +1 -1
  31. package/dist/node/index.js +65 -24
  32. package/dist/node/index.js.map +1 -1
  33. package/package.json +16 -17
  34. package/src/MemorySentinel.ts +27 -19
  35. package/src/SentinelRunner.ts +4 -6
@@ -134,12 +134,11 @@ var _SentinelRunner = class _SentinelRunner {
134
134
  this.stop();
135
135
  this._automations = {};
136
136
  }
137
- async restart() {
137
+ restart() {
138
138
  this.stop();
139
- await this.start();
139
+ this.start();
140
140
  }
141
- async start() {
142
- await Promise.resolve();
141
+ start() {
143
142
  assertEx(this.timeoutId === void 0, "Already started");
144
143
  const automation = this.next;
145
144
  if (isSentinelIntervalAutomation(automation)) {
@@ -152,7 +151,7 @@ var _SentinelRunner = class _SentinelRunner {
152
151
  await this.trigger(automation);
153
152
  this.stop();
154
153
  } finally {
155
- await this.start();
154
+ this.start();
156
155
  }
157
156
  }, delay);
158
157
  }
@@ -194,7 +193,7 @@ var _MemorySentinel = class _MemorySentinel extends AbstractSentinel {
194
193
  let index = 0;
195
194
  let previousResults = {};
196
195
  while (index < job.tasks.length) {
197
- const generatedPayloads = await this.generateResults(job.tasks[index], previousResults, inPayloads);
196
+ const generatedPayloads = await this.runJob(job.tasks[index], previousResults, inPayloads);
198
197
  previousResults = generatedPayloads;
199
198
  index++;
200
199
  }
@@ -207,7 +206,7 @@ var _MemorySentinel = class _MemorySentinel extends AbstractSentinel {
207
206
  if (await super.start(timeout)) {
208
207
  if ((((_a = this.config.automations) == null ? void 0 : _a.length) ?? 0) > 0) {
209
208
  this.runner = new SentinelRunner(this, this.config.automations);
210
- await this.runner.start();
209
+ this.runner.start();
211
210
  }
212
211
  return true;
213
212
  }
@@ -220,19 +219,47 @@ var _MemorySentinel = class _MemorySentinel extends AbstractSentinel {
220
219
  }
221
220
  return await super.stop(timeout);
222
221
  }
223
- async generateResults(tasks, previousResults, inPayloads) {
222
+ async inputAddresses(input) {
223
+ if (Array.isArray(input)) {
224
+ return (await Promise.all(input.map(async (inputItem) => await this.inputAddresses(inputItem)))).flat();
225
+ } else {
226
+ const resolved = await this.resolve(input);
227
+ return resolved ? [
228
+ resolved.address
229
+ ] : [];
230
+ }
231
+ }
232
+ processPreviousResults(payloads, inputs) {
233
+ return inputs.flatMap((input) => payloads[input] ?? []);
234
+ }
235
+ async runJob(tasks, previousResults, inPayloads) {
224
236
  var _a, _b, _c, _d;
225
- (_a = this.logger) == null ? void 0 : _a.debug(`generateResults:tasks: ${JSON.stringify(tasks.length)}`);
226
- (_b = this.logger) == null ? void 0 : _b.debug(`generateResults:previous: ${JSON.stringify(previousResults)}`);
227
- (_c = this.logger) == null ? void 0 : _c.debug(`generateResults:in: ${JSON.stringify(inPayloads)}`);
237
+ await this.emit("jobStart", {
238
+ inPayloads,
239
+ module: this
240
+ });
241
+ (_a = this.logger) == null ? void 0 : _a.debug(`runJob:tasks: ${JSON.stringify(tasks.length)}`);
242
+ (_b = this.logger) == null ? void 0 : _b.debug(`runJob:previous: ${JSON.stringify(previousResults)}`);
243
+ (_c = this.logger) == null ? void 0 : _c.debug(`runJob:in: ${JSON.stringify(inPayloads)}`);
228
244
  const results = await Promise.allSettled(tasks == null ? void 0 : tasks.map(async (task) => {
229
245
  var _a2, _b2, _c2;
230
246
  const input = task.input ?? false;
231
247
  const inPayloadsFound = input === true ? inPayloads : input === false ? [] : this.processPreviousResults(previousResults, await this.inputAddresses(input));
232
248
  const witness = asWitnessInstance(task.module);
233
249
  if (witness) {
250
+ await this.emit("taskStart", {
251
+ address: witness.address,
252
+ inPayloads: inPayloadsFound,
253
+ module: this
254
+ });
234
255
  const observed = await witness.observe(inPayloadsFound);
235
256
  (_a2 = this.logger) == null ? void 0 : _a2.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`);
257
+ await this.emit("taskEnd", {
258
+ address: witness.address,
259
+ inPayloads: inPayloadsFound,
260
+ module: this,
261
+ outPayloads: observed
262
+ });
236
263
  return [
237
264
  witness.address,
238
265
  observed
@@ -240,8 +267,19 @@ var _MemorySentinel = class _MemorySentinel extends AbstractSentinel {
240
267
  }
241
268
  const diviner = asDivinerInstance(task.module);
242
269
  if (diviner) {
270
+ await this.emit("taskStart", {
271
+ address: diviner.address,
272
+ inPayloads: inPayloadsFound,
273
+ module: this
274
+ });
243
275
  const divined = await diviner.divine(inPayloadsFound);
244
276
  (_b2 = this.logger) == null ? void 0 : _b2.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`);
277
+ await this.emit("taskEnd", {
278
+ address: diviner.address,
279
+ inPayloads: inPayloadsFound,
280
+ module: this,
281
+ outPayloads: divined
282
+ });
245
283
  return [
246
284
  diviner.address,
247
285
  divined
@@ -249,8 +287,19 @@ var _MemorySentinel = class _MemorySentinel extends AbstractSentinel {
249
287
  }
250
288
  const sentinel = asSentinelInstance(task.module);
251
289
  if (sentinel) {
290
+ await this.emit("taskStart", {
291
+ address: sentinel.address,
292
+ inPayloads: inPayloadsFound,
293
+ module: this
294
+ });
252
295
  const reported = await sentinel.report(inPayloadsFound);
253
296
  (_c2 = this.logger) == null ? void 0 : _c2.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`);
297
+ await this.emit("taskEnd", {
298
+ address: sentinel.address,
299
+ inPayloads: inPayloadsFound,
300
+ module: this,
301
+ outPayloads: reported
302
+ });
254
303
  return [
255
304
  sentinel.address,
256
305
  reported
@@ -271,21 +320,13 @@ var _MemorySentinel = class _MemorySentinel extends AbstractSentinel {
271
320
  }
272
321
  }
273
322
  (_d = this.logger) == null ? void 0 : _d.debug(`generateResults:out: ${JSON.stringify(finalResult)}`);
323
+ await this.emit("jobEnd", {
324
+ finalResult,
325
+ inPayloads,
326
+ module: this
327
+ });
274
328
  return finalResult;
275
329
  }
276
- async inputAddresses(input) {
277
- if (Array.isArray(input)) {
278
- return (await Promise.all(input.map(async (inputItem) => await this.inputAddresses(inputItem)))).flat();
279
- } else {
280
- const resolved = await this.resolve(input);
281
- return resolved ? [
282
- resolved.address
283
- ] : [];
284
- }
285
- }
286
- processPreviousResults(payloads, inputs) {
287
- return inputs.flatMap((input) => payloads[input] ?? []);
288
- }
289
330
  };
290
331
  __name(_MemorySentinel, "MemorySentinel");
291
332
  __publicField(_MemorySentinel, "configSchemas", [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/MemorySentinel.ts","../../src/SentinelRunner.ts","../../src/SentinelIntervalAutomationWrapper.ts"],"sourcesContent":["import { Address } from '@xylabs/hex'\nimport { fulfilled, rejected } from '@xylabs/promise'\nimport { asDivinerInstance } from '@xyo-network/diviner-model'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { Payload } from '@xyo-network/payload-model'\nimport { AbstractSentinel } from '@xyo-network/sentinel-abstract'\nimport {\n asSentinelInstance,\n ResolvedTask,\n SentinelConfig,\n SentinelConfigSchema,\n SentinelInstance,\n SentinelModuleEventData,\n SentinelParams,\n} from '@xyo-network/sentinel-model'\nimport { asWitnessInstance } from '@xyo-network/witness-model'\n\nimport { SentinelRunner } from './SentinelRunner'\n\nexport type MemorySentinelParams<TConfig extends AnyConfigSchema<SentinelConfig> = AnyConfigSchema<SentinelConfig>> = SentinelParams<TConfig>\n\nexport class MemorySentinel<\n TParams extends MemorySentinelParams = MemorySentinelParams,\n TEventData extends SentinelModuleEventData<SentinelInstance<TParams>> = SentinelModuleEventData<SentinelInstance<TParams>>,\n> extends AbstractSentinel<TParams, TEventData> {\n static override configSchemas = [SentinelConfigSchema]\n\n private runner?: SentinelRunner\n\n async reportHandler(inPayloads: Payload[] = []): Promise<Payload[]> {\n await this.started('throw')\n this.logger?.debug(`reportHandler:in: ${JSON.stringify(inPayloads)}`)\n const job = await this.jobPromise\n\n let index = 0\n let previousResults: Record<Address, Payload[]> = {}\n while (index < job.tasks.length) {\n const generatedPayloads = await this.generateResults(job.tasks[index], previousResults, inPayloads)\n previousResults = generatedPayloads\n index++\n }\n const result = Object.values(previousResults).flat()\n this.logger?.debug(`reportHandler:out: ${JSON.stringify(result)}`)\n return result\n }\n\n override async start(timeout?: number | undefined): Promise<boolean> {\n if (await super.start(timeout)) {\n if ((this.config.automations?.length ?? 0) > 0) {\n this.runner = new SentinelRunner(this, this.config.automations)\n await this.runner.start()\n }\n return true\n }\n return false\n }\n\n override async stop(timeout?: number | undefined): Promise<boolean> {\n if (this.runner) {\n this.runner.stop()\n this.runner = undefined\n }\n return await super.stop(timeout)\n }\n\n private async generateResults(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n this.logger?.debug(`generateResults:tasks: ${JSON.stringify(tasks.length)}`)\n this.logger?.debug(`generateResults:previous: ${JSON.stringify(previousResults)}`)\n this.logger?.debug(`generateResults:in: ${JSON.stringify(inPayloads)}`)\n const results: PromiseSettledResult<[Address, Payload[]]>[] = await Promise.allSettled(\n tasks?.map(async (task) => {\n const input = task.input ?? false\n const inPayloadsFound =\n input === true ? inPayloads : input === false ? [] : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n const witness = asWitnessInstance(task.module)\n if (witness) {\n const observed = await witness.observe(inPayloadsFound)\n this.logger?.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`)\n return [witness.address, observed]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n const divined = await diviner.divine(inPayloadsFound)\n this.logger?.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`)\n return [diviner.address, divined]\n }\n const sentinel = asSentinelInstance(task.module)\n if (sentinel) {\n const reported = await sentinel.report(inPayloadsFound)\n this.logger?.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`)\n return [sentinel.address, reported]\n }\n throw new Error('Unsupported module type')\n }),\n )\n const finalResult: Record<Address, Payload[]> = {}\n for (const result of results.filter(fulfilled)) {\n const [address, payloads] = result.value\n finalResult[address] = finalResult[address] ?? []\n finalResult[address].push(...payloads)\n }\n if (this.throwErrors) {\n const errors = results.filter(rejected).map((result) => result.reason)\n if (errors.length > 0) {\n throw new Error('At least one module failed')\n }\n }\n this.logger?.debug(`generateResults:out: ${JSON.stringify(finalResult)}`)\n return finalResult\n }\n\n private async inputAddresses(input: string | string[]): Promise<string[]> {\n if (Array.isArray(input)) {\n return (await Promise.all(input.map(async (inputItem) => await this.inputAddresses(inputItem)))).flat()\n } else {\n const resolved = await this.resolve(input)\n return resolved ? [resolved.address] : []\n }\n }\n\n private processPreviousResults(payloads: Record<string, Payload[]>, inputs: string[]) {\n return inputs.flatMap((input) => payloads[input] ?? [])\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { forget } from '@xylabs/forget'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport { Payload } from '@xyo-network/payload-model'\nimport {\n isSentinelIntervalAutomation,\n SentinelAutomationPayload,\n SentinelInstance,\n SentinelIntervalAutomationPayload,\n} from '@xyo-network/sentinel-model'\n\nimport { SentinelIntervalAutomationWrapper } from './SentinelIntervalAutomationWrapper'\n\nexport type OnSentinelRunnerTriggerResult = (result: Payload[]) => void\n\nexport class SentinelRunner {\n protected _automations: Record<string, SentinelAutomationPayload> = {}\n protected onTriggerResult: OnSentinelRunnerTriggerResult | undefined\n protected sentinel: SentinelInstance\n protected timeoutId?: NodeJS.Timeout | string | number\n\n constructor(sentinel: SentinelInstance, automations?: SentinelAutomationPayload[], onTriggerResult?: OnSentinelRunnerTriggerResult) {\n this.sentinel = sentinel\n this.onTriggerResult = onTriggerResult\n if (automations) for (const automation of automations) forget(this.add(automation))\n }\n\n get automations() {\n return this._automations\n }\n\n private get next() {\n // eslint-disable-next-line unicorn/no-array-reduce\n return Object.values(this._automations).reduce<SentinelAutomationPayload | undefined>((previous, current) => {\n if (isSentinelIntervalAutomation(current) && isSentinelIntervalAutomation(previous)) {\n return current.start < (previous?.start ?? Number.POSITIVE_INFINITY) ? current : previous\n }\n return current\n // eslint-disable-next-line unicorn/no-useless-undefined\n }, undefined)\n }\n\n async add(automation: SentinelAutomationPayload, restart = true) {\n const hash = await PayloadBuilder.dataHash(automation)\n this._automations[hash] = automation\n if (restart) await this.restart()\n return hash\n }\n\n find(hash: string) {\n Object.entries(this._automations).find(([key]) => key === hash)\n }\n\n async remove(hash: string, restart = true) {\n delete this._automations[hash]\n if (restart) await this.restart()\n }\n\n removeAll() {\n this.stop()\n this._automations = {}\n }\n\n async restart() {\n this.stop()\n await this.start()\n }\n\n async start() {\n // NOTE: Keep async to match module start signature\n await Promise.resolve()\n assertEx(this.timeoutId === undefined, 'Already started')\n const automation = this.next\n if (isSentinelIntervalAutomation(automation)) {\n const now = Date.now()\n const start = Math.max(automation.start ?? now, now)\n const delay = Math.max(start - now, 0)\n if (delay < Number.POSITIVE_INFINITY) {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.timeoutId = setTimeout(async () => {\n try {\n // Run the automation\n await this.trigger(automation)\n this.stop()\n } finally {\n // No matter what start the next automation\n await this.start()\n }\n }, delay)\n }\n }\n }\n\n stop() {\n if (this.timeoutId) {\n clearTimeout(this.timeoutId)\n this.timeoutId = undefined\n }\n }\n\n async update(hash: string, automation: SentinelAutomationPayload, restart = true) {\n await this.remove(hash, false)\n await this.add(automation, false)\n if (restart) await this.restart()\n }\n\n private async trigger(automation: SentinelIntervalAutomationPayload) {\n const wrapper = new SentinelIntervalAutomationWrapper(automation)\n await this.remove(await wrapper.dataHash(), false)\n wrapper.next()\n await this.add(wrapper.jsonPayload(), false)\n const triggerResult = await this.sentinel.report()\n this.onTriggerResult?.(triggerResult)\n // await this.start()\n }\n}\n","import { PayloadWrapper } from '@xyo-network/payload-wrapper'\nimport { SentinelIntervalAutomationPayload } from '@xyo-network/sentinel-model'\n\nexport class SentinelIntervalAutomationWrapper<\n T extends SentinelIntervalAutomationPayload = SentinelIntervalAutomationPayload,\n> extends PayloadWrapper<T> {\n constructor(payload: T) {\n super(payload)\n }\n\n protected get frequencyMillis() {\n const frequency = this.jsonPayload().frequency\n if (frequency === undefined) return Number.POSITIVE_INFINITY\n const frequencyUnits = this.jsonPayload().frequencyUnits\n switch (frequencyUnits ?? 'hour') {\n case 'second': {\n return frequency * 1000\n }\n case 'minute': {\n return frequency * 60 * 1000\n }\n case 'hour': {\n return frequency * 60 * 60 * 1000\n }\n case 'day': {\n return frequency * 24 * 60 * 60 * 1000\n }\n default: {\n return Number.POSITIVE_INFINITY\n }\n }\n }\n\n protected get remaining() {\n return this.jsonPayload().remaining ?? Number.POSITIVE_INFINITY\n }\n\n next() {\n const now = Date.now()\n const previousStart = this.jsonPayload()?.start ?? now\n const start = Math.max(previousStart, now)\n const nextStart = start + this.frequencyMillis\n this.setStart(nextStart)\n this.consumeRemaining()\n this.checkEnd()\n return this\n }\n\n protected checkEnd() {\n if (this.jsonPayload().start > (this.jsonPayload().end ?? Number.POSITIVE_INFINITY)) {\n this.setStart(Number.POSITIVE_INFINITY)\n }\n }\n\n protected consumeRemaining(count = 1) {\n const remaining = Math.max(this.remaining - count, 0)\n this.setRemaining(remaining)\n if (remaining <= 0) this.setStart(Number.POSITIVE_INFINITY)\n }\n\n /**\n * Sets the remaining of the wrapped automation\n * @param remaining The remaining time in milliseconds\n */\n protected setRemaining(remaining: number) {\n this.obj.remaining = remaining\n }\n\n /**\n * Sets the start of the wrapped automation\n * @param start The start time in milliseconds\n */\n protected setStart(start: number) {\n this.obj.start = start\n }\n}\n"],"mappings":"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","names":["fulfilled","rejected","asDivinerInstance","AbstractSentinel","asSentinelInstance","SentinelConfigSchema","asWitnessInstance","assertEx","forget","PayloadBuilder","isSentinelIntervalAutomation","PayloadWrapper","SentinelIntervalAutomationWrapper","PayloadWrapper","constructor","payload","frequencyMillis","frequency","jsonPayload","undefined","Number","POSITIVE_INFINITY","frequencyUnits","remaining","next","now","Date","previousStart","start","Math","max","nextStart","setStart","consumeRemaining","checkEnd","end","count","setRemaining","obj","SentinelRunner","_automations","onTriggerResult","sentinel","timeoutId","constructor","automations","automation","forget","add","next","Object","values","reduce","previous","current","isSentinelIntervalAutomation","start","Number","POSITIVE_INFINITY","undefined","restart","hash","PayloadBuilder","dataHash","find","entries","key","remove","removeAll","stop","Promise","resolve","assertEx","now","Date","Math","max","delay","setTimeout","trigger","clearTimeout","update","wrapper","SentinelIntervalAutomationWrapper","jsonPayload","triggerResult","report","MemorySentinel","AbstractSentinel","runner","reportHandler","inPayloads","started","logger","debug","JSON","stringify","job","jobPromise","index","previousResults","tasks","length","generatedPayloads","generateResults","result","Object","values","flat","start","timeout","config","automations","SentinelRunner","stop","undefined","results","Promise","allSettled","map","task","_a","_b","_c","input","inPayloadsFound","processPreviousResults","inputAddresses","witness","asWitnessInstance","module","observed","observe","id","address","diviner","asDivinerInstance","divined","divine","sentinel","asSentinelInstance","reported","report","Error","finalResult","filter","fulfilled","payloads","value","push","throwErrors","errors","rejected","reason","Array","isArray","all","inputItem","resolved","resolve","inputs","flatMap","configSchemas","SentinelConfigSchema"]}
1
+ {"version":3,"sources":["../../src/MemorySentinel.ts","../../src/SentinelRunner.ts","../../src/SentinelIntervalAutomationWrapper.ts"],"sourcesContent":["import { Address } from '@xylabs/hex'\nimport { fulfilled, rejected } from '@xylabs/promise'\nimport { asDivinerInstance } from '@xyo-network/diviner-model'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { Payload } from '@xyo-network/payload-model'\nimport { AbstractSentinel } from '@xyo-network/sentinel-abstract'\nimport {\n asSentinelInstance,\n ResolvedTask,\n SentinelConfig,\n SentinelConfigSchema,\n SentinelInstance,\n SentinelModuleEventData,\n SentinelParams,\n} from '@xyo-network/sentinel-model'\nimport { asWitnessInstance } from '@xyo-network/witness-model'\n\nimport { SentinelRunner } from './SentinelRunner'\n\nexport type MemorySentinelParams<TConfig extends AnyConfigSchema<SentinelConfig> = AnyConfigSchema<SentinelConfig>> = SentinelParams<TConfig>\n\nexport class MemorySentinel<\n TParams extends MemorySentinelParams = MemorySentinelParams,\n TEventData extends SentinelModuleEventData<SentinelInstance<TParams>> = SentinelModuleEventData<SentinelInstance<TParams>>,\n> extends AbstractSentinel<TParams, TEventData> {\n static override configSchemas = [SentinelConfigSchema]\n\n private runner?: SentinelRunner\n\n async reportHandler(inPayloads: Payload[] = []): Promise<Payload[]> {\n await this.started('throw')\n this.logger?.debug(`reportHandler:in: ${JSON.stringify(inPayloads)}`)\n const job = await this.jobPromise\n\n let index = 0\n let previousResults: Record<Address, Payload[]> = {}\n while (index < job.tasks.length) {\n const generatedPayloads = await this.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: string | string[]): Promise<string[]> {\n if (Array.isArray(input)) {\n return (await Promise.all(input.map(async (inputItem) => await this.inputAddresses(inputItem)))).flat()\n } else {\n const resolved = await this.resolve(input)\n return resolved ? [resolved.address] : []\n }\n }\n\n private processPreviousResults(payloads: Record<string, Payload[]>, inputs: string[]) {\n return inputs.flatMap((input) => payloads[input] ?? [])\n }\n\n 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 : input === false ? [] : 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.jsonPayload(), false)\n const triggerResult = await this.sentinel.report()\n this.onTriggerResult?.(triggerResult)\n // await this.start()\n }\n}\n","import { PayloadWrapper } from '@xyo-network/payload-wrapper'\nimport { SentinelIntervalAutomationPayload } from '@xyo-network/sentinel-model'\n\nexport class SentinelIntervalAutomationWrapper<\n T extends SentinelIntervalAutomationPayload = SentinelIntervalAutomationPayload,\n> extends PayloadWrapper<T> {\n constructor(payload: T) {\n super(payload)\n }\n\n protected get frequencyMillis() {\n const frequency = this.jsonPayload().frequency\n if (frequency === undefined) return Number.POSITIVE_INFINITY\n const frequencyUnits = this.jsonPayload().frequencyUnits\n switch (frequencyUnits ?? 'hour') {\n case 'second': {\n return frequency * 1000\n }\n case 'minute': {\n return frequency * 60 * 1000\n }\n case 'hour': {\n return frequency * 60 * 60 * 1000\n }\n case 'day': {\n return frequency * 24 * 60 * 60 * 1000\n }\n default: {\n return Number.POSITIVE_INFINITY\n }\n }\n }\n\n protected get remaining() {\n return this.jsonPayload().remaining ?? Number.POSITIVE_INFINITY\n }\n\n next() {\n const now = Date.now()\n const previousStart = this.jsonPayload()?.start ?? now\n const start = Math.max(previousStart, now)\n const nextStart = start + this.frequencyMillis\n this.setStart(nextStart)\n this.consumeRemaining()\n this.checkEnd()\n return this\n }\n\n protected checkEnd() {\n if (this.jsonPayload().start > (this.jsonPayload().end ?? Number.POSITIVE_INFINITY)) {\n this.setStart(Number.POSITIVE_INFINITY)\n }\n }\n\n protected consumeRemaining(count = 1) {\n const remaining = Math.max(this.remaining - count, 0)\n this.setRemaining(remaining)\n if (remaining <= 0) this.setStart(Number.POSITIVE_INFINITY)\n }\n\n /**\n * Sets the remaining of the wrapped automation\n * @param remaining The remaining time in milliseconds\n */\n protected setRemaining(remaining: number) {\n this.obj.remaining = remaining\n }\n\n /**\n * Sets the start of the wrapped automation\n * @param start The start time in milliseconds\n */\n protected setStart(start: number) {\n this.obj.start = start\n }\n}\n"],"mappings":"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","names":["fulfilled","rejected","asDivinerInstance","AbstractSentinel","asSentinelInstance","SentinelConfigSchema","asWitnessInstance","assertEx","forget","PayloadBuilder","isSentinelIntervalAutomation","PayloadWrapper","SentinelIntervalAutomationWrapper","PayloadWrapper","constructor","payload","frequencyMillis","frequency","jsonPayload","undefined","Number","POSITIVE_INFINITY","frequencyUnits","remaining","next","now","Date","previousStart","start","Math","max","nextStart","setStart","consumeRemaining","checkEnd","end","count","setRemaining","obj","SentinelRunner","_automations","onTriggerResult","sentinel","timeoutId","constructor","automations","automation","forget","add","next","Object","values","reduce","previous","current","isSentinelIntervalAutomation","start","Number","POSITIVE_INFINITY","undefined","restart","hash","PayloadBuilder","dataHash","find","entries","key","remove","removeAll","stop","assertEx","now","Date","Math","max","delay","setTimeout","trigger","clearTimeout","update","wrapper","SentinelIntervalAutomationWrapper","jsonPayload","triggerResult","report","MemorySentinel","AbstractSentinel","runner","reportHandler","inPayloads","started","logger","debug","JSON","stringify","job","jobPromise","index","previousResults","tasks","length","generatedPayloads","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"]}
package/package.json CHANGED
@@ -14,26 +14,26 @@
14
14
  "@xylabs/forget": "^2.14.0",
15
15
  "@xylabs/hex": "^2.14.0",
16
16
  "@xylabs/promise": "^2.14.0",
17
- "@xyo-network/diviner-model": "~2.89.0-rc.9",
18
- "@xyo-network/module-model": "~2.89.0-rc.9",
19
- "@xyo-network/payload-builder": "~2.89.0-rc.9",
20
- "@xyo-network/payload-model": "~2.89.0-rc.9",
21
- "@xyo-network/payload-wrapper": "~2.89.0-rc.9",
22
- "@xyo-network/sentinel-abstract": "~2.89.0-rc.9",
23
- "@xyo-network/sentinel-model": "~2.89.0-rc.9",
24
- "@xyo-network/witness-model": "~2.89.0-rc.9"
17
+ "@xyo-network/diviner-model": "~2.89.1",
18
+ "@xyo-network/module-model": "~2.89.1",
19
+ "@xyo-network/payload-builder": "~2.89.1",
20
+ "@xyo-network/payload-model": "~2.89.1",
21
+ "@xyo-network/payload-wrapper": "~2.89.1",
22
+ "@xyo-network/sentinel-abstract": "~2.89.1",
23
+ "@xyo-network/sentinel-model": "~2.89.1",
24
+ "@xyo-network/witness-model": "~2.89.1"
25
25
  },
26
26
  "description": "Primary SDK for using XYO Protocol 2.0",
27
27
  "devDependencies": {
28
28
  "@xylabs/delay": "^2.14.0",
29
29
  "@xylabs/ts-scripts-yarn3": "^3.2.42",
30
30
  "@xylabs/tsconfig": "^3.2.42",
31
- "@xyo-network/abstract-witness": "~2.89.0-rc.9",
32
- "@xyo-network/account": "~2.89.0-rc.9",
33
- "@xyo-network/archivist-memory": "~2.89.0-rc.9",
34
- "@xyo-network/id-payload-plugin": "~2.89.0-rc.9",
35
- "@xyo-network/node-memory": "~2.89.0-rc.9",
36
- "@xyo-network/witness-adhoc": "~2.89.0-rc.9",
31
+ "@xyo-network/abstract-witness": "~2.89.1",
32
+ "@xyo-network/account": "~2.89.1",
33
+ "@xyo-network/archivist-memory": "~2.89.1",
34
+ "@xyo-network/id-payload-plugin": "~2.89.1",
35
+ "@xyo-network/node-memory": "~2.89.1",
36
+ "@xyo-network/witness-adhoc": "~2.89.1",
37
37
  "typescript": "^5.3.3"
38
38
  },
39
39
  "types": "dist/node/index.d.ts",
@@ -74,7 +74,6 @@
74
74
  "url": "https://github.com/XYOracleNetwork/sdk-xyo-client-js.git"
75
75
  },
76
76
  "sideEffects": false,
77
- "version": "2.89.0-rc.9",
78
- "type": "module",
79
- "stableVersion": "2.88.3"
77
+ "version": "2.89.1",
78
+ "type": "module"
80
79
  }
@@ -35,7 +35,7 @@ export class MemorySentinel<
35
35
  let index = 0
36
36
  let previousResults: Record<Address, Payload[]> = {}
37
37
  while (index < job.tasks.length) {
38
- const generatedPayloads = await this.generateResults(job.tasks[index], previousResults, inPayloads)
38
+ const generatedPayloads = await this.runJob(job.tasks[index], previousResults, inPayloads)
39
39
  previousResults = generatedPayloads
40
40
  index++
41
41
  }
@@ -48,7 +48,7 @@ export class MemorySentinel<
48
48
  if (await super.start(timeout)) {
49
49
  if ((this.config.automations?.length ?? 0) > 0) {
50
50
  this.runner = new SentinelRunner(this, this.config.automations)
51
- await this.runner.start()
51
+ this.runner.start()
52
52
  }
53
53
  return true
54
54
  }
@@ -63,14 +63,28 @@ export class MemorySentinel<
63
63
  return await super.stop(timeout)
64
64
  }
65
65
 
66
- private async generateResults(
66
+ private async inputAddresses(input: string | string[]): Promise<string[]> {
67
+ if (Array.isArray(input)) {
68
+ return (await Promise.all(input.map(async (inputItem) => await this.inputAddresses(inputItem)))).flat()
69
+ } else {
70
+ const resolved = await this.resolve(input)
71
+ return resolved ? [resolved.address] : []
72
+ }
73
+ }
74
+
75
+ private processPreviousResults(payloads: Record<string, Payload[]>, inputs: string[]) {
76
+ return inputs.flatMap((input) => payloads[input] ?? [])
77
+ }
78
+
79
+ private async runJob(
67
80
  tasks: ResolvedTask[],
68
81
  previousResults: Record<Address, Payload[]>,
69
82
  inPayloads?: Payload[],
70
83
  ): Promise<Record<Address, Payload[]>> {
71
- this.logger?.debug(`generateResults:tasks: ${JSON.stringify(tasks.length)}`)
72
- this.logger?.debug(`generateResults:previous: ${JSON.stringify(previousResults)}`)
73
- this.logger?.debug(`generateResults:in: ${JSON.stringify(inPayloads)}`)
84
+ await this.emit('jobStart', { inPayloads, module: this })
85
+ this.logger?.debug(`runJob:tasks: ${JSON.stringify(tasks.length)}`)
86
+ this.logger?.debug(`runJob:previous: ${JSON.stringify(previousResults)}`)
87
+ this.logger?.debug(`runJob:in: ${JSON.stringify(inPayloads)}`)
74
88
  const results: PromiseSettledResult<[Address, Payload[]]>[] = await Promise.allSettled(
75
89
  tasks?.map(async (task) => {
76
90
  const input = task.input ?? false
@@ -78,20 +92,26 @@ export class MemorySentinel<
78
92
  input === true ? inPayloads : input === false ? [] : this.processPreviousResults(previousResults, await this.inputAddresses(input))
79
93
  const witness = asWitnessInstance(task.module)
80
94
  if (witness) {
95
+ await this.emit('taskStart', { address: witness.address, inPayloads: inPayloadsFound, module: this })
81
96
  const observed = await witness.observe(inPayloadsFound)
82
97
  this.logger?.debug(`observed [${witness.id}]: ${JSON.stringify(observed)}`)
98
+ await this.emit('taskEnd', { address: witness.address, inPayloads: inPayloadsFound, module: this, outPayloads: observed })
83
99
  return [witness.address, observed]
84
100
  }
85
101
  const diviner = asDivinerInstance(task.module)
86
102
  if (diviner) {
103
+ await this.emit('taskStart', { address: diviner.address, inPayloads: inPayloadsFound, module: this })
87
104
  const divined = await diviner.divine(inPayloadsFound)
88
105
  this.logger?.debug(`divined [${diviner.id}]: ${JSON.stringify(divined)}`)
106
+ await this.emit('taskEnd', { address: diviner.address, inPayloads: inPayloadsFound, module: this, outPayloads: divined })
89
107
  return [diviner.address, divined]
90
108
  }
91
109
  const sentinel = asSentinelInstance(task.module)
92
110
  if (sentinel) {
111
+ await this.emit('taskStart', { address: sentinel.address, inPayloads: inPayloadsFound, module: this })
93
112
  const reported = await sentinel.report(inPayloadsFound)
94
113
  this.logger?.debug(`reported [${sentinel.id}]: ${JSON.stringify(reported)}`)
114
+ await this.emit('taskEnd', { address: sentinel.address, inPayloads: inPayloadsFound, module: this, outPayloads: reported })
95
115
  return [sentinel.address, reported]
96
116
  }
97
117
  throw new Error('Unsupported module type')
@@ -110,19 +130,7 @@ export class MemorySentinel<
110
130
  }
111
131
  }
112
132
  this.logger?.debug(`generateResults:out: ${JSON.stringify(finalResult)}`)
133
+ await this.emit('jobEnd', { finalResult, inPayloads, module: this })
113
134
  return finalResult
114
135
  }
115
-
116
- private async inputAddresses(input: string | string[]): Promise<string[]> {
117
- if (Array.isArray(input)) {
118
- return (await Promise.all(input.map(async (inputItem) => await this.inputAddresses(inputItem)))).flat()
119
- } else {
120
- const resolved = await this.resolve(input)
121
- return resolved ? [resolved.address] : []
122
- }
123
- }
124
-
125
- private processPreviousResults(payloads: Record<string, Payload[]>, inputs: string[]) {
126
- return inputs.flatMap((input) => payloads[input] ?? [])
127
- }
128
136
  }
@@ -61,14 +61,12 @@ export class SentinelRunner {
61
61
  this._automations = {}
62
62
  }
63
63
 
64
- async restart() {
64
+ restart() {
65
65
  this.stop()
66
- await this.start()
66
+ this.start()
67
67
  }
68
68
 
69
- async start() {
70
- // NOTE: Keep async to match module start signature
71
- await Promise.resolve()
69
+ start() {
72
70
  assertEx(this.timeoutId === undefined, 'Already started')
73
71
  const automation = this.next
74
72
  if (isSentinelIntervalAutomation(automation)) {
@@ -84,7 +82,7 @@ export class SentinelRunner {
84
82
  this.stop()
85
83
  } finally {
86
84
  // No matter what start the next automation
87
- await this.start()
85
+ this.start()
88
86
  }
89
87
  }, delay)
90
88
  }