@xyo-network/sentinel 2.82.0 → 2.83.0

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 (43) hide show
  1. package/dist/browser/Automation.d.cts +41 -13
  2. package/dist/browser/Automation.d.cts.map +1 -1
  3. package/dist/browser/Automation.d.mts +41 -13
  4. package/dist/browser/Automation.d.mts.map +1 -1
  5. package/dist/browser/Automation.d.ts +41 -13
  6. package/dist/browser/Automation.d.ts.map +1 -1
  7. package/dist/browser/SentinelRunner.d.cts.map +1 -1
  8. package/dist/browser/SentinelRunner.d.mts.map +1 -1
  9. package/dist/browser/SentinelRunner.d.ts.map +1 -1
  10. package/dist/browser/Wrapper.d.cts +1 -1
  11. package/dist/browser/Wrapper.d.cts.map +1 -1
  12. package/dist/browser/Wrapper.d.mts +1 -1
  13. package/dist/browser/Wrapper.d.mts.map +1 -1
  14. package/dist/browser/Wrapper.d.ts +1 -1
  15. package/dist/browser/Wrapper.d.ts.map +1 -1
  16. package/dist/browser/index.cjs +22 -12
  17. package/dist/browser/index.cjs.map +1 -1
  18. package/dist/browser/index.js +22 -12
  19. package/dist/browser/index.js.map +1 -1
  20. package/dist/node/Automation.d.cts +41 -13
  21. package/dist/node/Automation.d.cts.map +1 -1
  22. package/dist/node/Automation.d.mts +41 -13
  23. package/dist/node/Automation.d.mts.map +1 -1
  24. package/dist/node/Automation.d.ts +41 -13
  25. package/dist/node/Automation.d.ts.map +1 -1
  26. package/dist/node/SentinelRunner.d.cts.map +1 -1
  27. package/dist/node/SentinelRunner.d.mts.map +1 -1
  28. package/dist/node/SentinelRunner.d.ts.map +1 -1
  29. package/dist/node/Wrapper.d.cts +1 -1
  30. package/dist/node/Wrapper.d.cts.map +1 -1
  31. package/dist/node/Wrapper.d.mts +1 -1
  32. package/dist/node/Wrapper.d.mts.map +1 -1
  33. package/dist/node/Wrapper.d.ts +1 -1
  34. package/dist/node/Wrapper.d.ts.map +1 -1
  35. package/dist/node/index.js +25 -12
  36. package/dist/node/index.js.map +1 -1
  37. package/dist/node/index.mjs +22 -12
  38. package/dist/node/index.mjs.map +1 -1
  39. package/package.json +19 -19
  40. package/src/Automation.ts +31 -15
  41. package/src/SentinelIntervalAutomationWrapper.ts +7 -7
  42. package/src/SentinelRunner.ts +9 -6
  43. package/typedoc.json +1 -1
@@ -1,5 +1,9 @@
1
1
  // src/Automation.ts
2
+ import { isPayloadOfSchemaType } from "@xyo-network/payload-model";
2
3
  var SentinelAutomationSchema = "network.xyo.automation";
4
+ var SentinelIntervalAutomationSchema = "network.xyo.automation.interval";
5
+ var SentinelEventAutomationSchema = "network.xyo.automation.event";
6
+ var isSentinelIntervalAutomation = isPayloadOfSchemaType(SentinelIntervalAutomationSchema);
3
7
 
4
8
  // src/MemorySentinel.ts
5
9
  import { fulfilled } from "@xylabs/promise";
@@ -67,10 +71,10 @@ var SentinelIntervalAutomationWrapper = class extends PayloadWrapper {
67
71
  super(payload);
68
72
  }
69
73
  get frequencyMillis() {
70
- const frequency = this.payload().frequency;
74
+ const frequency = this.jsonPayload().frequency;
71
75
  if (frequency === void 0)
72
76
  return Infinity;
73
- switch (this.payload().frequencyUnits ?? "hour") {
77
+ switch (this.jsonPayload().frequencyUnits ?? "hour") {
74
78
  case "second":
75
79
  return frequency * 1e3;
76
80
  case "minute":
@@ -85,21 +89,21 @@ var SentinelIntervalAutomationWrapper = class extends PayloadWrapper {
85
89
  return this.payload().remaining ?? Infinity;
86
90
  }
87
91
  next() {
88
- this.payload().start = this.payload().start + this.frequencyMillis;
92
+ this.jsonPayload().start = this.jsonPayload().start + this.frequencyMillis;
89
93
  this.consumeRemaining();
90
94
  this.checkEnd();
91
95
  return this;
92
96
  }
93
97
  checkEnd() {
94
- if (this.payload().start > (this.payload().end ?? Infinity)) {
95
- this.payload().start = Infinity;
98
+ if (this.jsonPayload().start > (this.jsonPayload().end ?? Infinity)) {
99
+ this.jsonPayload().start = Infinity;
96
100
  }
97
101
  }
98
102
  consumeRemaining(count = 1) {
99
103
  const remaining = this.remaining - count;
100
- this.payload().remaining = remaining;
104
+ this.jsonPayload().remaining = remaining;
101
105
  if (remaining <= 0) {
102
- this.payload().start = Infinity;
106
+ this.jsonPayload().start = Infinity;
103
107
  }
104
108
  }
105
109
  };
@@ -122,9 +126,12 @@ var SentinelRunner = class {
122
126
  }
123
127
  get next() {
124
128
  return Object.values(this._automations).reduce((previous, current) => {
125
- if (current.type === "interval") {
126
- return current.start < ((previous == null ? void 0 : previous.start) ?? Infinity) ? current : previous;
129
+ if (isSentinelIntervalAutomation(current)) {
130
+ if (isSentinelIntervalAutomation(previous)) {
131
+ return current.start < ((previous == null ? void 0 : previous.start) ?? Infinity) ? current : previous;
132
+ }
127
133
  }
134
+ return current;
128
135
  }, void 0);
129
136
  }
130
137
  async add(automation, restart = true) {
@@ -153,7 +160,7 @@ var SentinelRunner = class {
153
160
  async start() {
154
161
  assertEx(this.timeoutId === void 0, "Already started");
155
162
  const automation = this.next;
156
- if (automation) {
163
+ if (isSentinelIntervalAutomation(automation)) {
157
164
  const delay = automation.start - Date.now();
158
165
  if (delay < 0) {
159
166
  await this.trigger(automation);
@@ -185,7 +192,7 @@ var SentinelRunner = class {
185
192
  const wrapper = new SentinelIntervalAutomationWrapper(automation);
186
193
  await this.remove(await wrapper.hashAsync(), false);
187
194
  wrapper.next();
188
- await this.add(wrapper.payload(), false);
195
+ await this.add(wrapper.jsonPayload(), false);
189
196
  const triggerResult = await this.sentinel.report();
190
197
  (_a = this.onTriggerResult) == null ? void 0 : _a.call(this, triggerResult);
191
198
  await this.start();
@@ -223,8 +230,11 @@ export * from "@xyo-network/sentinel-model";
223
230
  export {
224
231
  MemorySentinel,
225
232
  SentinelAutomationSchema,
233
+ SentinelEventAutomationSchema,
234
+ SentinelIntervalAutomationSchema,
226
235
  SentinelIntervalAutomationWrapper,
227
236
  SentinelRunner,
228
- SentinelWrapper
237
+ SentinelWrapper,
238
+ isSentinelIntervalAutomation
229
239
  };
230
240
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/Automation.ts","../../src/MemorySentinel.ts","../../src/SentinelIntervalAutomationWrapper.ts","../../src/SentinelRunner.ts","../../src/Wrapper.ts","../../src/index.ts"],"sourcesContent":["import { AnyObject } from '@xyo-network/core'\nimport { Payload } from '@xyo-network/payload-model'\nimport { Task } from '@xyo-network/sentinel-model'\n\nexport type SentinelAutomationSchema = 'network.xyo.automation'\nexport const SentinelAutomationSchema: SentinelAutomationSchema = 'network.xyo.automation'\n\nexport type SentinelBaseAutomationPayload<T extends AnyObject = AnyObject> = Payload<\n T & {\n schema: SentinelAutomationSchema\n tasks?: Task[]\n type?: 'interval' | 'change'\n }\n>\n\nexport type SentinelIntervalAutomationPayload = SentinelBaseAutomationPayload<{\n /** @field epoch after which any reoccurrence stops */\n end?: number\n\n /** @field time between triggers [non-repeating if undefined] */\n frequency?: number\n\n /** @field units for frequency field [hour if undefined] */\n frequencyUnits?: 'second' | 'minute' | 'hour' | 'day'\n\n /** @field remaining triggers [infinite if undefined] */\n remaining?: number\n\n /** @field epoch of the next trigger */\n start: number\n\n type: 'interval'\n}>\n\nexport type SentinelChangeAutomationPayload = SentinelBaseAutomationPayload<{\n type: 'change'\n}>\n\nexport type SentinelAutomationPayload = SentinelIntervalAutomationPayload | SentinelChangeAutomationPayload\n","import { Address } from '@xylabs/hex'\nimport { fulfilled } 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 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\nexport type MemorySentinelParams<TConfig extends AnyConfigSchema<SentinelConfig> = AnyConfigSchema<SentinelConfig>> = SentinelParams<TConfig>\n\nexport class MemorySentinel<\n TParams extends MemorySentinelParams = MemorySentinelParams,\n TEventData extends SentinelModuleEventData<SentinelInstance<TParams>> = SentinelModuleEventData<SentinelInstance<TParams>>,\n> extends AbstractSentinel<TParams, TEventData> {\n static override configSchemas = [SentinelConfigSchema]\n\n async reportHandler(inPayloads: Payload[] = []): Promise<Payload[]> {\n await this.started('throw')\n const job = await this.jobPromise\n\n let index = 0\n let previousResults: Record<Address, Payload[]> = {}\n while (index < job.tasks.length) {\n const generatedPayloads = await this.generateResults(job.tasks[index], previousResults, inPayloads)\n previousResults = generatedPayloads\n index++\n }\n return Object.values(previousResults).flat()\n }\n\n private async generateResults(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n const results: PromiseSettledResult<[Address, Payload[]]>[] = await Promise.allSettled(\n tasks?.map(async (task) => {\n const witness = asWitnessInstance(task.module)\n const input = task.input ?? false\n const inPayloadsFound =\n input === true ? inPayloads : input === false ? [] : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n if (witness) {\n return [witness.address, await witness.observe(inPayloadsFound)]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n return [diviner.address, await diviner.divine(inPayloadsFound)]\n }\n throw Error('Unsupported module type')\n }),\n )\n const finalResult: Record<Address, Payload[]> = {}\n results.filter(fulfilled).forEach((result) => {\n const [address, payloads] = result.value\n finalResult[address] = finalResult[address] ?? []\n finalResult[address].push(...payloads)\n })\n /*const errors = results.filter(rejected).map((result) => result.reason)\n if (errors.length > 0) {\n throw Error('At least one module failed')\n }*/\n return finalResult\n }\n\n 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.map((input) => payloads[input] ?? []).flat()\n }\n}\n","import { PayloadWrapper } from '@xyo-network/payload-wrapper'\n\nimport { SentinelIntervalAutomationPayload } from './Automation'\n\nexport class SentinelIntervalAutomationWrapper<\n T extends SentinelIntervalAutomationPayload = SentinelIntervalAutomationPayload,\n> extends PayloadWrapper<T> {\n constructor(payload: T) {\n super(payload)\n }\n\n protected get frequencyMillis() {\n const frequency = this.payload().frequency\n if (frequency === undefined) return Infinity\n switch (this.payload().frequencyUnits ?? 'hour') {\n case 'second':\n return frequency * 1000\n case 'minute':\n return frequency * 60 * 1000\n case 'hour':\n return frequency * 60 * 60 * 1000\n case 'day':\n return frequency * 24 * 60 * 60 * 1000\n }\n }\n\n protected get remaining() {\n //if remaining is not defined, we assume Infinity\n return this.payload().remaining ?? Infinity\n }\n\n next() {\n this.payload().start = this.payload().start + this.frequencyMillis\n this.consumeRemaining()\n this.checkEnd()\n return this\n }\n\n protected checkEnd() {\n if (this.payload().start > (this.payload().end ?? Infinity)) {\n this.payload().start = Infinity\n }\n }\n\n protected consumeRemaining(count = 1) {\n const remaining = this.remaining - count\n this.payload().remaining = remaining\n\n if (remaining <= 0) {\n this.payload().start = Infinity\n }\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Payload } from '@xyo-network/payload-model'\nimport { PayloadWrapper } from '@xyo-network/payload-wrapper'\nimport { SentinelInstance } from '@xyo-network/sentinel-model'\n\nimport { SentinelAutomationPayload, SentinelIntervalAutomationPayload } from './Automation'\nimport { SentinelIntervalAutomationWrapper } from './SentinelIntervalAutomationWrapper'\n\nexport type OnSentinelRunnerTriggerResult = (result: Payload[]) => void\n\nexport class SentinelRunner {\n protected _automations: Record<string, SentinelAutomationPayload> = {}\n protected onTriggerResult: OnSentinelRunnerTriggerResult | undefined\n protected sentinel: SentinelInstance\n protected timeoutId?: NodeJS.Timeout | string | number\n\n constructor(sentinel: SentinelInstance, automations?: SentinelAutomationPayload[], onTriggerResult?: OnSentinelRunnerTriggerResult) {\n this.sentinel = sentinel\n this.onTriggerResult = onTriggerResult\n automations?.forEach((automation) => this.add(automation))\n }\n\n get automations() {\n return this._automations\n }\n\n private get next() {\n return Object.values(this._automations).reduce<SentinelIntervalAutomationPayload | undefined>((previous, current) => {\n if (current.type === 'interval') {\n return current.start < (previous?.start ?? Infinity) ? current : previous\n }\n }, undefined)\n }\n\n async add(automation: SentinelAutomationPayload, restart = true) {\n const hash = await PayloadWrapper.hashAsync(automation)\n this._automations[hash] = automation\n if (restart) await this.restart()\n return hash\n }\n\n find(hash: string) {\n Object.entries(this._automations).find(([key]) => key === hash)\n }\n\n async remove(hash: string, restart = true) {\n delete this._automations[hash]\n if (restart) await this.restart()\n }\n\n removeAll() {\n this.stop()\n this._automations = {}\n }\n\n async restart() {\n this.stop()\n await this.start()\n }\n\n async start() {\n assertEx(this.timeoutId === undefined, 'Already started')\n const automation = this.next\n if (automation) {\n const delay = automation.start - Date.now()\n if (delay < 0) {\n //automation is due, just do it\n await this.trigger(automation)\n } else {\n this.timeoutId = setTimeout(\n async () => {\n this.timeoutId = undefined\n await this.start()\n },\n delay > 0 ? delay : 0,\n )\n }\n }\n }\n\n stop() {\n if (this.timeoutId) {\n clearTimeout(this.timeoutId)\n this.timeoutId = undefined\n }\n }\n\n async update(hash: string, automation: SentinelAutomationPayload, restart = true) {\n await this.remove(hash, false)\n await this.add(automation, false)\n if (restart) await this.restart()\n }\n\n private async trigger(automation: SentinelIntervalAutomationPayload) {\n const wrapper = new SentinelIntervalAutomationWrapper(automation)\n await this.remove(await wrapper.hashAsync(), false)\n wrapper.next()\n await this.add(wrapper.payload(), false)\n const triggerResult = await this.sentinel.report()\n this.onTriggerResult?.(triggerResult)\n await this.start()\n }\n}\n","import { ArchivistInstance } from '@xyo-network/archivist'\nimport { constructableModuleWrapper, ModuleWrapper } from '@xyo-network/module-wrapper'\nimport { Payload } from '@xyo-network/payload-model'\nimport {\n isSentinelInstance,\n isSentinelModule,\n SentinelInstance,\n SentinelModule,\n SentinelReportQuery,\n SentinelReportQuerySchema,\n} from '@xyo-network/sentinel-model'\nimport { WitnessInstance } from '@xyo-network/witness-model'\n\nconstructableModuleWrapper()\nexport class SentinelWrapper<TModule extends SentinelModule = SentinelModule>\n extends ModuleWrapper<TModule>\n implements SentinelInstance<TModule['params']>\n{\n static override instanceIdentityCheck = isSentinelInstance\n static override moduleIdentityCheck = isSentinelModule\n static override requiredQueries = [SentinelReportQuerySchema, ...super.requiredQueries]\n\n archivists(): Promise<ArchivistInstance[]> {\n throw Error('Not supported')\n }\n\n async report(payloads?: Payload[]): Promise<Payload[]> {\n const queryPayload: SentinelReportQuery = { schema: SentinelReportQuerySchema }\n const result = await this.sendQuery(queryPayload, payloads)\n return result\n }\n\n witnesses(): Promise<WitnessInstance[]> {\n throw Error('Not supported')\n }\n}\n","export * from './Automation'\nexport * from './MemorySentinel'\nexport * from './SentinelIntervalAutomationWrapper'\nexport * from './SentinelRunner'\nexport * from './Wrapper'\nexport * from '@xyo-network/sentinel-abstract'\nexport * from '@xyo-network/sentinel-model'\n"],"mappings":";AAKO,IAAM,2BAAqD;;;ACJlE,SAAS,iBAAiB;AAC1B,SAAS,yBAAyB;AAGlC,SAAS,wBAAwB;AACjC;AAAA,EAGE;AAAA,OAIK;AACP,SAAS,yBAAyB;AAI3B,IAAM,iBAAN,cAGG,iBAAsC;AAAA,EAC9C,OAAgB,gBAAgB,CAAC,oBAAoB;AAAA,EAErD,MAAM,cAAc,aAAwB,CAAC,GAAuB;AAClE,UAAM,KAAK,QAAQ,OAAO;AAC1B,UAAM,MAAM,MAAM,KAAK;AAEvB,QAAI,QAAQ;AACZ,QAAI,kBAA8C,CAAC;AACnD,WAAO,QAAQ,IAAI,MAAM,QAAQ;AAC/B,YAAM,oBAAoB,MAAM,KAAK,gBAAgB,IAAI,MAAM,KAAK,GAAG,iBAAiB,UAAU;AAClG,wBAAkB;AAClB;AAAA,IACF;AACA,WAAO,OAAO,OAAO,eAAe,EAAE,KAAK;AAAA,EAC7C;AAAA,EAEA,MAAc,gBACZ,OACA,iBACA,YACqC;AACrC,UAAM,UAAwD,MAAM,QAAQ;AAAA,MAC1E,+BAAO,IAAI,OAAO,SAAS;AACzB,cAAM,UAAU,kBAAkB,KAAK,MAAM;AAC7C,cAAM,QAAQ,KAAK,SAAS;AAC5B,cAAM,kBACJ,UAAU,OAAO,aAAa,UAAU,QAAQ,CAAC,IAAI,KAAK,uBAAuB,iBAAiB,MAAM,KAAK,eAAe,KAAK,CAAC;AACpI,YAAI,SAAS;AACX,iBAAO,CAAC,QAAQ,SAAS,MAAM,QAAQ,QAAQ,eAAe,CAAC;AAAA,QACjE;AACA,cAAM,UAAU,kBAAkB,KAAK,MAAM;AAC7C,YAAI,SAAS;AACX,iBAAO,CAAC,QAAQ,SAAS,MAAM,QAAQ,OAAO,eAAe,CAAC;AAAA,QAChE;AACA,cAAM,MAAM,yBAAyB;AAAA,MACvC;AAAA,IACF;AACA,UAAM,cAA0C,CAAC;AACjD,YAAQ,OAAO,SAAS,EAAE,QAAQ,CAAC,WAAW;AAC5C,YAAM,CAAC,SAAS,QAAQ,IAAI,OAAO;AACnC,kBAAY,OAAO,IAAI,YAAY,OAAO,KAAK,CAAC;AAChD,kBAAY,OAAO,EAAE,KAAK,GAAG,QAAQ;AAAA,IACvC,CAAC;AAKD,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,eAAe,OAA6C;AACxE,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,cAAQ,MAAM,QAAQ,IAAI,MAAM,IAAI,OAAO,cAAc,MAAM,KAAK,eAAe,SAAS,CAAC,CAAC,GAAG,KAAK;AAAA,IACxG,OAAO;AACL,YAAM,WAAW,MAAM,KAAK,QAAQ,KAAK;AACzC,aAAO,WAAW,CAAC,SAAS,OAAO,IAAI,CAAC;AAAA,IAC1C;AAAA,EACF;AAAA,EAEQ,uBAAuB,UAAqC,QAAkB;AACpF,WAAO,OAAO,IAAI,CAAC,UAAU,SAAS,KAAK,KAAK,CAAC,CAAC,EAAE,KAAK;AAAA,EAC3D;AACF;;;ACpFA,SAAS,sBAAsB;AAIxB,IAAM,oCAAN,cAEG,eAAkB;AAAA,EAC1B,YAAY,SAAY;AACtB,UAAM,OAAO;AAAA,EACf;AAAA,EAEA,IAAc,kBAAkB;AAC9B,UAAM,YAAY,KAAK,QAAQ,EAAE;AACjC,QAAI,cAAc;AAAW,aAAO;AACpC,YAAQ,KAAK,QAAQ,EAAE,kBAAkB,QAAQ;AAAA,MAC/C,KAAK;AACH,eAAO,YAAY;AAAA,MACrB,KAAK;AACH,eAAO,YAAY,KAAK;AAAA,MAC1B,KAAK;AACH,eAAO,YAAY,KAAK,KAAK;AAAA,MAC/B,KAAK;AACH,eAAO,YAAY,KAAK,KAAK,KAAK;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,IAAc,YAAY;AAExB,WAAO,KAAK,QAAQ,EAAE,aAAa;AAAA,EACrC;AAAA,EAEA,OAAO;AACL,SAAK,QAAQ,EAAE,QAAQ,KAAK,QAAQ,EAAE,QAAQ,KAAK;AACnD,SAAK,iBAAiB;AACtB,SAAK,SAAS;AACd,WAAO;AAAA,EACT;AAAA,EAEU,WAAW;AACnB,QAAI,KAAK,QAAQ,EAAE,SAAS,KAAK,QAAQ,EAAE,OAAO,WAAW;AAC3D,WAAK,QAAQ,EAAE,QAAQ;AAAA,IACzB;AAAA,EACF;AAAA,EAEU,iBAAiB,QAAQ,GAAG;AACpC,UAAM,YAAY,KAAK,YAAY;AACnC,SAAK,QAAQ,EAAE,YAAY;AAE3B,QAAI,aAAa,GAAG;AAClB,WAAK,QAAQ,EAAE,QAAQ;AAAA,IACzB;AAAA,EACF;AACF;;;ACpDA,SAAS,gBAAgB;AAEzB,SAAS,kBAAAA,uBAAsB;AAQxB,IAAM,iBAAN,MAAqB;AAAA,EAChB,eAA0D,CAAC;AAAA,EAC3D;AAAA,EACA;AAAA,EACA;AAAA,EAEV,YAAY,UAA4B,aAA2C,iBAAiD;AAClI,SAAK,WAAW;AAChB,SAAK,kBAAkB;AACvB,+CAAa,QAAQ,CAAC,eAAe,KAAK,IAAI,UAAU;AAAA,EAC1D;AAAA,EAEA,IAAI,cAAc;AAChB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAY,OAAO;AACjB,WAAO,OAAO,OAAO,KAAK,YAAY,EAAE,OAAsD,CAAC,UAAU,YAAY;AACnH,UAAI,QAAQ,SAAS,YAAY;AAC/B,eAAO,QAAQ,UAAS,qCAAU,UAAS,YAAY,UAAU;AAAA,MACnE;AAAA,IACF,GAAG,MAAS;AAAA,EACd;AAAA,EAEA,MAAM,IAAI,YAAuC,UAAU,MAAM;AAC/D,UAAM,OAAO,MAAMC,gBAAe,UAAU,UAAU;AACtD,SAAK,aAAa,IAAI,IAAI;AAC1B,QAAI;AAAS,YAAM,KAAK,QAAQ;AAChC,WAAO;AAAA,EACT;AAAA,EAEA,KAAK,MAAc;AACjB,WAAO,QAAQ,KAAK,YAAY,EAAE,KAAK,CAAC,CAAC,GAAG,MAAM,QAAQ,IAAI;AAAA,EAChE;AAAA,EAEA,MAAM,OAAO,MAAc,UAAU,MAAM;AACzC,WAAO,KAAK,aAAa,IAAI;AAC7B,QAAI;AAAS,YAAM,KAAK,QAAQ;AAAA,EAClC;AAAA,EAEA,YAAY;AACV,SAAK,KAAK;AACV,SAAK,eAAe,CAAC;AAAA,EACvB;AAAA,EAEA,MAAM,UAAU;AACd,SAAK,KAAK;AACV,UAAM,KAAK,MAAM;AAAA,EACnB;AAAA,EAEA,MAAM,QAAQ;AACZ,aAAS,KAAK,cAAc,QAAW,iBAAiB;AACxD,UAAM,aAAa,KAAK;AACxB,QAAI,YAAY;AACd,YAAM,QAAQ,WAAW,QAAQ,KAAK,IAAI;AAC1C,UAAI,QAAQ,GAAG;AAEb,cAAM,KAAK,QAAQ,UAAU;AAAA,MAC/B,OAAO;AACL,aAAK,YAAY;AAAA,UACf,YAAY;AACV,iBAAK,YAAY;AACjB,kBAAM,KAAK,MAAM;AAAA,UACnB;AAAA,UACA,QAAQ,IAAI,QAAQ;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO;AACL,QAAI,KAAK,WAAW;AAClB,mBAAa,KAAK,SAAS;AAC3B,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,MAAc,YAAuC,UAAU,MAAM;AAChF,UAAM,KAAK,OAAO,MAAM,KAAK;AAC7B,UAAM,KAAK,IAAI,YAAY,KAAK;AAChC,QAAI;AAAS,YAAM,KAAK,QAAQ;AAAA,EAClC;AAAA,EAEA,MAAc,QAAQ,YAA+C;AA7FvE;AA8FI,UAAM,UAAU,IAAI,kCAAkC,UAAU;AAChE,UAAM,KAAK,OAAO,MAAM,QAAQ,UAAU,GAAG,KAAK;AAClD,YAAQ,KAAK;AACb,UAAM,KAAK,IAAI,QAAQ,QAAQ,GAAG,KAAK;AACvC,UAAM,gBAAgB,MAAM,KAAK,SAAS,OAAO;AACjD,eAAK,oBAAL,8BAAuB;AACvB,UAAM,KAAK,MAAM;AAAA,EACnB;AACF;;;ACrGA,SAAS,4BAA4B,qBAAqB;AAE1D;AAAA,EACE;AAAA,EACA;AAAA,EAIA;AAAA,OACK;AAGP,2BAA2B;AACpB,IAAM,kBAAN,cACG,cAEV;AAAA,EACE,OAAgB,wBAAwB;AAAA,EACxC,OAAgB,sBAAsB;AAAA,EACtC,OAAgB,kBAAkB,CAAC,2BAA2B,GAAG,MAAM,eAAe;AAAA,EAEtF,aAA2C;AACzC,UAAM,MAAM,eAAe;AAAA,EAC7B;AAAA,EAEA,MAAM,OAAO,UAA0C;AACrD,UAAM,eAAoC,EAAE,QAAQ,0BAA0B;AAC9E,UAAM,SAAS,MAAM,KAAK,UAAU,cAAc,QAAQ;AAC1D,WAAO;AAAA,EACT;AAAA,EAEA,YAAwC;AACtC,UAAM,MAAM,eAAe;AAAA,EAC7B;AACF;;;AC9BA,cAAc;AACd,cAAc;","names":["PayloadWrapper","PayloadWrapper"]}
1
+ {"version":3,"sources":["../../src/Automation.ts","../../src/MemorySentinel.ts","../../src/SentinelIntervalAutomationWrapper.ts","../../src/SentinelRunner.ts","../../src/Wrapper.ts","../../src/index.ts"],"sourcesContent":["import { isPayloadOfSchemaType, Payload } from '@xyo-network/payload-model'\nimport { Task } from '@xyo-network/sentinel-model'\n\nexport type SentinelAutomationSchema = 'network.xyo.automation'\nexport const SentinelAutomationSchema: SentinelAutomationSchema = 'network.xyo.automation'\n\nexport type SentinelIntervalAutomationSchema = 'network.xyo.automation.interval'\nexport const SentinelIntervalAutomationSchema: SentinelIntervalAutomationSchema = 'network.xyo.automation.interval'\n\nexport type SentinelEventAutomationSchema = 'network.xyo.automation.event'\nexport const SentinelEventAutomationSchema: SentinelEventAutomationSchema = 'network.xyo.automation.event'\n\nexport type SentinelBaseAutomationPayload<T extends Payload> = Payload<\n {\n tasks?: Task[]\n type?: 'interval' | 'event'\n } & T\n>\n\n/** Settings for an Interval Automation */\nexport type SentinelIntervalAutomationPayload = SentinelBaseAutomationPayload<{\n /** Epoch after which any reoccurrence stops */\n end?: number\n\n /** Time between triggers [non-repeating if undefined] */\n frequency?: number\n\n /** Units for frequency field [hour if undefined] */\n frequencyUnits?: 'second' | 'minute' | 'hour' | 'day'\n\n /** Remaining triggers [infinite if undefined] */\n remaining?: number\n\n schema: SentinelIntervalAutomationSchema\n\n /** Epoch of the next trigger */\n start: number\n\n /** The type of automation */\n type: 'interval'\n}>\n\nexport const isSentinelIntervalAutomation = isPayloadOfSchemaType<SentinelIntervalAutomationPayload>(SentinelIntervalAutomationSchema)\n\n/** Settings for an Event Automation */\nexport type SentinelEventAutomationPayload = SentinelBaseAutomationPayload<{\n schema: SentinelEventAutomationSchema\n type: 'event'\n}>\n\n/** Settings for an Automation */\nexport type SentinelAutomationPayload = Payload<\n SentinelIntervalAutomationPayload | SentinelEventAutomationPayload,\n SentinelAutomationSchema | SentinelIntervalAutomationSchema | SentinelEventAutomationSchema\n>\n","import { Address } from '@xylabs/hex'\nimport { fulfilled } 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 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\nexport type MemorySentinelParams<TConfig extends AnyConfigSchema<SentinelConfig> = AnyConfigSchema<SentinelConfig>> = SentinelParams<TConfig>\n\nexport class MemorySentinel<\n TParams extends MemorySentinelParams = MemorySentinelParams,\n TEventData extends SentinelModuleEventData<SentinelInstance<TParams>> = SentinelModuleEventData<SentinelInstance<TParams>>,\n> extends AbstractSentinel<TParams, TEventData> {\n static override configSchemas = [SentinelConfigSchema]\n\n async reportHandler(inPayloads: Payload[] = []): Promise<Payload[]> {\n await this.started('throw')\n const job = await this.jobPromise\n\n let index = 0\n let previousResults: Record<Address, Payload[]> = {}\n while (index < job.tasks.length) {\n const generatedPayloads = await this.generateResults(job.tasks[index], previousResults, inPayloads)\n previousResults = generatedPayloads\n index++\n }\n return Object.values(previousResults).flat()\n }\n\n private async generateResults(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n const results: PromiseSettledResult<[Address, Payload[]]>[] = await Promise.allSettled(\n tasks?.map(async (task) => {\n const witness = asWitnessInstance(task.module)\n const input = task.input ?? false\n const inPayloadsFound =\n input === true ? inPayloads : input === false ? [] : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n if (witness) {\n return [witness.address, await witness.observe(inPayloadsFound)]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n return [diviner.address, await diviner.divine(inPayloadsFound)]\n }\n throw Error('Unsupported module type')\n }),\n )\n const finalResult: Record<Address, Payload[]> = {}\n results.filter(fulfilled).forEach((result) => {\n const [address, payloads] = result.value\n finalResult[address] = finalResult[address] ?? []\n finalResult[address].push(...payloads)\n })\n /*const errors = results.filter(rejected).map((result) => result.reason)\n if (errors.length > 0) {\n throw Error('At least one module failed')\n }*/\n return finalResult\n }\n\n 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.map((input) => payloads[input] ?? []).flat()\n }\n}\n","import { PayloadWrapper } from '@xyo-network/payload-wrapper'\n\nimport { SentinelIntervalAutomationPayload } from './Automation'\n\nexport class SentinelIntervalAutomationWrapper<\n T extends SentinelIntervalAutomationPayload = SentinelIntervalAutomationPayload,\n> extends PayloadWrapper<T> {\n constructor(payload: T) {\n super(payload)\n }\n\n protected get frequencyMillis() {\n const frequency = this.jsonPayload().frequency\n if (frequency === undefined) return Infinity\n switch (this.jsonPayload().frequencyUnits ?? 'hour') {\n case 'second':\n return frequency * 1000\n case 'minute':\n return frequency * 60 * 1000\n case 'hour':\n return frequency * 60 * 60 * 1000\n case 'day':\n return frequency * 24 * 60 * 60 * 1000\n }\n }\n\n protected get remaining() {\n //if remaining is not defined, we assume Infinity\n return this.payload().remaining ?? Infinity\n }\n\n next() {\n this.jsonPayload().start = this.jsonPayload().start + this.frequencyMillis\n this.consumeRemaining()\n this.checkEnd()\n return this\n }\n\n protected checkEnd() {\n if (this.jsonPayload().start > (this.jsonPayload().end ?? Infinity)) {\n this.jsonPayload().start = Infinity\n }\n }\n\n protected consumeRemaining(count = 1) {\n const remaining = this.remaining - count\n this.jsonPayload().remaining = remaining\n\n if (remaining <= 0) {\n this.jsonPayload().start = Infinity\n }\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Payload } from '@xyo-network/payload-model'\nimport { PayloadWrapper } from '@xyo-network/payload-wrapper'\nimport { SentinelInstance } from '@xyo-network/sentinel-model'\n\nimport { isSentinelIntervalAutomation, SentinelAutomationPayload, SentinelIntervalAutomationPayload } from './Automation'\nimport { SentinelIntervalAutomationWrapper } from './SentinelIntervalAutomationWrapper'\n\nexport type OnSentinelRunnerTriggerResult = (result: Payload[]) => void\n\nexport class SentinelRunner {\n protected _automations: Record<string, SentinelAutomationPayload> = {}\n protected onTriggerResult: OnSentinelRunnerTriggerResult | undefined\n protected sentinel: SentinelInstance\n protected timeoutId?: NodeJS.Timeout | string | number\n\n constructor(sentinel: SentinelInstance, automations?: SentinelAutomationPayload[], onTriggerResult?: OnSentinelRunnerTriggerResult) {\n this.sentinel = sentinel\n this.onTriggerResult = onTriggerResult\n automations?.forEach((automation) => this.add(automation))\n }\n\n get automations() {\n return this._automations\n }\n\n private get next() {\n return Object.values(this._automations).reduce<SentinelAutomationPayload | undefined>((previous, current) => {\n if (isSentinelIntervalAutomation(current)) {\n if (isSentinelIntervalAutomation(previous)) {\n return current.start < (previous?.start ?? Infinity) ? current : previous\n }\n }\n return current\n }, undefined)\n }\n\n async add(automation: SentinelAutomationPayload, restart = true) {\n const hash = await PayloadWrapper.hashAsync(automation)\n this._automations[hash] = automation\n if (restart) await this.restart()\n return hash\n }\n\n find(hash: string) {\n Object.entries(this._automations).find(([key]) => key === hash)\n }\n\n async remove(hash: string, restart = true) {\n delete this._automations[hash]\n if (restart) await this.restart()\n }\n\n removeAll() {\n this.stop()\n this._automations = {}\n }\n\n async restart() {\n this.stop()\n await this.start()\n }\n\n async start() {\n assertEx(this.timeoutId === undefined, 'Already started')\n const automation = this.next\n if (isSentinelIntervalAutomation(automation)) {\n const delay = automation.start - Date.now()\n if (delay < 0) {\n //automation is due, just do it\n await this.trigger(automation)\n } else {\n this.timeoutId = setTimeout(\n async () => {\n this.timeoutId = undefined\n await this.start()\n },\n delay > 0 ? delay : 0,\n )\n }\n }\n }\n\n stop() {\n if (this.timeoutId) {\n clearTimeout(this.timeoutId)\n this.timeoutId = undefined\n }\n }\n\n async update(hash: string, automation: SentinelAutomationPayload, restart = true) {\n await this.remove(hash, false)\n await this.add(automation, false)\n if (restart) await this.restart()\n }\n\n private async trigger(automation: SentinelIntervalAutomationPayload) {\n const wrapper = new SentinelIntervalAutomationWrapper(automation)\n await this.remove(await wrapper.hashAsync(), false)\n wrapper.next()\n await this.add(wrapper.jsonPayload(), false)\n const triggerResult = await this.sentinel.report()\n this.onTriggerResult?.(triggerResult)\n await this.start()\n }\n}\n","import { ArchivistInstance } from '@xyo-network/archivist'\nimport { constructableModuleWrapper, ModuleWrapper } from '@xyo-network/module-wrapper'\nimport { Payload } from '@xyo-network/payload-model'\nimport {\n isSentinelInstance,\n isSentinelModule,\n SentinelInstance,\n SentinelModule,\n SentinelReportQuery,\n SentinelReportQuerySchema,\n} from '@xyo-network/sentinel-model'\nimport { WitnessInstance } from '@xyo-network/witness-model'\n\nconstructableModuleWrapper()\nexport class SentinelWrapper<TModule extends SentinelModule = SentinelModule>\n extends ModuleWrapper<TModule>\n implements SentinelInstance<TModule['params']>\n{\n static override instanceIdentityCheck = isSentinelInstance\n static override moduleIdentityCheck = isSentinelModule\n static override requiredQueries = [SentinelReportQuerySchema, ...super.requiredQueries]\n\n archivists(): Promise<ArchivistInstance[]> {\n throw Error('Not supported')\n }\n\n async report(payloads?: Payload[]): Promise<Payload[]> {\n const queryPayload: SentinelReportQuery = { schema: SentinelReportQuerySchema }\n const result = await this.sendQuery(queryPayload, payloads)\n return result\n }\n\n witnesses(): Promise<WitnessInstance[]> {\n throw Error('Not supported')\n }\n}\n","export * from './Automation'\nexport * from './MemorySentinel'\nexport * from './SentinelIntervalAutomationWrapper'\nexport * from './SentinelRunner'\nexport * from './Wrapper'\nexport * from '@xyo-network/sentinel-abstract'\nexport * from '@xyo-network/sentinel-model'\n"],"mappings":"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","names":["PayloadWrapper","PayloadWrapper"]}
package/package.json CHANGED
@@ -13,30 +13,30 @@
13
13
  "@xylabs/assert": "^2.13.20",
14
14
  "@xylabs/hex": "^2.13.20",
15
15
  "@xylabs/promise": "^2.13.20",
16
- "@xyo-network/archivist": "~2.82.0",
17
- "@xyo-network/core": "~2.82.0",
18
- "@xyo-network/diviner-model": "~2.82.0",
19
- "@xyo-network/module-model": "~2.82.0",
20
- "@xyo-network/module-wrapper": "~2.82.0",
21
- "@xyo-network/payload-model": "~2.82.0",
22
- "@xyo-network/payload-wrapper": "~2.82.0",
23
- "@xyo-network/sentinel-abstract": "~2.82.0",
24
- "@xyo-network/sentinel-model": "~2.82.0",
25
- "@xyo-network/witness-model": "~2.82.0"
16
+ "@xyo-network/archivist": "~2.83.0",
17
+ "@xyo-network/diviner-model": "~2.83.0",
18
+ "@xyo-network/module-model": "~2.83.0",
19
+ "@xyo-network/module-wrapper": "~2.83.0",
20
+ "@xyo-network/payload-model": "~2.83.0",
21
+ "@xyo-network/payload-wrapper": "~2.83.0",
22
+ "@xyo-network/sentinel-abstract": "~2.83.0",
23
+ "@xyo-network/sentinel-model": "~2.83.0",
24
+ "@xyo-network/witness-model": "~2.83.0"
26
25
  },
27
26
  "description": "Primary SDK for using XYO Protocol 2.0",
28
27
  "devDependencies": {
29
28
  "@xylabs/delay": "^2.13.20",
30
29
  "@xylabs/ts-scripts-yarn3": "^3.2.10",
31
30
  "@xylabs/tsconfig": "^3.2.10",
32
- "@xyo-network/abstract-witness": "~2.82.0",
33
- "@xyo-network/account": "~2.82.0",
34
- "@xyo-network/boundwitness-model": "~2.82.0",
35
- "@xyo-network/id-payload-plugin": "^2.82.0",
36
- "@xyo-network/id-plugin": "^2.82.0",
37
- "@xyo-network/node-memory": "~2.82.0",
38
- "@xyo-network/node-system-info-plugin": "^2.82.0",
39
- "@xyo-network/witnesses": "~2.82.0",
31
+ "@xyo-network/abstract-witness": "~2.83.0",
32
+ "@xyo-network/account": "~2.83.0",
33
+ "@xyo-network/boundwitness-model": "~2.83.0",
34
+ "@xyo-network/hash": "~2.83.0",
35
+ "@xyo-network/id-payload-plugin": "^2.82.2",
36
+ "@xyo-network/id-plugin": "^2.82.2",
37
+ "@xyo-network/node-memory": "~2.83.0",
38
+ "@xyo-network/node-system-info-plugin": "^2.82.2",
39
+ "@xyo-network/witnesses": "~2.83.0",
40
40
  "typescript": "^5.3.2"
41
41
  },
42
42
  "docs": "dist/docs.json",
@@ -78,5 +78,5 @@
78
78
  "url": "https://github.com/XYOracleNetwork/sdk-xyo-client-js.git"
79
79
  },
80
80
  "sideEffects": false,
81
- "version": "2.82.0"
81
+ "version": "2.83.0"
82
82
  }
package/src/Automation.ts CHANGED
@@ -1,39 +1,55 @@
1
- import { AnyObject } from '@xyo-network/core'
2
- import { Payload } from '@xyo-network/payload-model'
1
+ import { isPayloadOfSchemaType, Payload } from '@xyo-network/payload-model'
3
2
  import { Task } from '@xyo-network/sentinel-model'
4
3
 
5
4
  export type SentinelAutomationSchema = 'network.xyo.automation'
6
5
  export const SentinelAutomationSchema: SentinelAutomationSchema = 'network.xyo.automation'
7
6
 
8
- export type SentinelBaseAutomationPayload<T extends AnyObject = AnyObject> = Payload<
9
- T & {
10
- schema: SentinelAutomationSchema
7
+ export type SentinelIntervalAutomationSchema = 'network.xyo.automation.interval'
8
+ export const SentinelIntervalAutomationSchema: SentinelIntervalAutomationSchema = 'network.xyo.automation.interval'
9
+
10
+ export type SentinelEventAutomationSchema = 'network.xyo.automation.event'
11
+ export const SentinelEventAutomationSchema: SentinelEventAutomationSchema = 'network.xyo.automation.event'
12
+
13
+ export type SentinelBaseAutomationPayload<T extends Payload> = Payload<
14
+ {
11
15
  tasks?: Task[]
12
- type?: 'interval' | 'change'
13
- }
16
+ type?: 'interval' | 'event'
17
+ } & T
14
18
  >
15
19
 
20
+ /** Settings for an Interval Automation */
16
21
  export type SentinelIntervalAutomationPayload = SentinelBaseAutomationPayload<{
17
- /** @field epoch after which any reoccurrence stops */
22
+ /** Epoch after which any reoccurrence stops */
18
23
  end?: number
19
24
 
20
- /** @field time between triggers [non-repeating if undefined] */
25
+ /** Time between triggers [non-repeating if undefined] */
21
26
  frequency?: number
22
27
 
23
- /** @field units for frequency field [hour if undefined] */
28
+ /** Units for frequency field [hour if undefined] */
24
29
  frequencyUnits?: 'second' | 'minute' | 'hour' | 'day'
25
30
 
26
- /** @field remaining triggers [infinite if undefined] */
31
+ /** Remaining triggers [infinite if undefined] */
27
32
  remaining?: number
28
33
 
29
- /** @field epoch of the next trigger */
34
+ schema: SentinelIntervalAutomationSchema
35
+
36
+ /** Epoch of the next trigger */
30
37
  start: number
31
38
 
39
+ /** The type of automation */
32
40
  type: 'interval'
33
41
  }>
34
42
 
35
- export type SentinelChangeAutomationPayload = SentinelBaseAutomationPayload<{
36
- type: 'change'
43
+ export const isSentinelIntervalAutomation = isPayloadOfSchemaType<SentinelIntervalAutomationPayload>(SentinelIntervalAutomationSchema)
44
+
45
+ /** Settings for an Event Automation */
46
+ export type SentinelEventAutomationPayload = SentinelBaseAutomationPayload<{
47
+ schema: SentinelEventAutomationSchema
48
+ type: 'event'
37
49
  }>
38
50
 
39
- export type SentinelAutomationPayload = SentinelIntervalAutomationPayload | SentinelChangeAutomationPayload
51
+ /** Settings for an Automation */
52
+ export type SentinelAutomationPayload = Payload<
53
+ SentinelIntervalAutomationPayload | SentinelEventAutomationPayload,
54
+ SentinelAutomationSchema | SentinelIntervalAutomationSchema | SentinelEventAutomationSchema
55
+ >
@@ -10,9 +10,9 @@ export class SentinelIntervalAutomationWrapper<
10
10
  }
11
11
 
12
12
  protected get frequencyMillis() {
13
- const frequency = this.payload().frequency
13
+ const frequency = this.jsonPayload().frequency
14
14
  if (frequency === undefined) return Infinity
15
- switch (this.payload().frequencyUnits ?? 'hour') {
15
+ switch (this.jsonPayload().frequencyUnits ?? 'hour') {
16
16
  case 'second':
17
17
  return frequency * 1000
18
18
  case 'minute':
@@ -30,24 +30,24 @@ export class SentinelIntervalAutomationWrapper<
30
30
  }
31
31
 
32
32
  next() {
33
- this.payload().start = this.payload().start + this.frequencyMillis
33
+ this.jsonPayload().start = this.jsonPayload().start + this.frequencyMillis
34
34
  this.consumeRemaining()
35
35
  this.checkEnd()
36
36
  return this
37
37
  }
38
38
 
39
39
  protected checkEnd() {
40
- if (this.payload().start > (this.payload().end ?? Infinity)) {
41
- this.payload().start = Infinity
40
+ if (this.jsonPayload().start > (this.jsonPayload().end ?? Infinity)) {
41
+ this.jsonPayload().start = Infinity
42
42
  }
43
43
  }
44
44
 
45
45
  protected consumeRemaining(count = 1) {
46
46
  const remaining = this.remaining - count
47
- this.payload().remaining = remaining
47
+ this.jsonPayload().remaining = remaining
48
48
 
49
49
  if (remaining <= 0) {
50
- this.payload().start = Infinity
50
+ this.jsonPayload().start = Infinity
51
51
  }
52
52
  }
53
53
  }
@@ -3,7 +3,7 @@ import { Payload } from '@xyo-network/payload-model'
3
3
  import { PayloadWrapper } from '@xyo-network/payload-wrapper'
4
4
  import { SentinelInstance } from '@xyo-network/sentinel-model'
5
5
 
6
- import { SentinelAutomationPayload, SentinelIntervalAutomationPayload } from './Automation'
6
+ import { isSentinelIntervalAutomation, SentinelAutomationPayload, SentinelIntervalAutomationPayload } from './Automation'
7
7
  import { SentinelIntervalAutomationWrapper } from './SentinelIntervalAutomationWrapper'
8
8
 
9
9
  export type OnSentinelRunnerTriggerResult = (result: Payload[]) => void
@@ -25,10 +25,13 @@ export class SentinelRunner {
25
25
  }
26
26
 
27
27
  private get next() {
28
- return Object.values(this._automations).reduce<SentinelIntervalAutomationPayload | undefined>((previous, current) => {
29
- if (current.type === 'interval') {
30
- return current.start < (previous?.start ?? Infinity) ? current : previous
28
+ return Object.values(this._automations).reduce<SentinelAutomationPayload | undefined>((previous, current) => {
29
+ if (isSentinelIntervalAutomation(current)) {
30
+ if (isSentinelIntervalAutomation(previous)) {
31
+ return current.start < (previous?.start ?? Infinity) ? current : previous
32
+ }
31
33
  }
34
+ return current
32
35
  }, undefined)
33
36
  }
34
37
 
@@ -61,7 +64,7 @@ export class SentinelRunner {
61
64
  async start() {
62
65
  assertEx(this.timeoutId === undefined, 'Already started')
63
66
  const automation = this.next
64
- if (automation) {
67
+ if (isSentinelIntervalAutomation(automation)) {
65
68
  const delay = automation.start - Date.now()
66
69
  if (delay < 0) {
67
70
  //automation is due, just do it
@@ -95,7 +98,7 @@ export class SentinelRunner {
95
98
  const wrapper = new SentinelIntervalAutomationWrapper(automation)
96
99
  await this.remove(await wrapper.hashAsync(), false)
97
100
  wrapper.next()
98
- await this.add(wrapper.payload(), false)
101
+ await this.add(wrapper.jsonPayload(), false)
99
102
  const triggerResult = await this.sentinel.report()
100
103
  this.onTriggerResult?.(triggerResult)
101
104
  await this.start()
package/typedoc.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "$schema": "https://typedoc.org/schema.json",
3
- "entryPoints": ["src/index.ts"],
3
+ "entryPoints": ["./src/index.ts"],
4
4
  "tsconfig": "./tsconfig.typedoc.json"
5
5
  }