@xyo-network/sentinel 2.84.5 → 2.84.7

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.
@@ -1 +1 @@
1
- {"version":3,"file":"SentinelIntervalAutomationWrapper.d.ts","sourceRoot":"","sources":["../../src/SentinelIntervalAutomationWrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAE7D,OAAO,EAAE,iCAAiC,EAAE,MAAM,cAAc,CAAA;AAEhE,qBAAa,iCAAiC,CAC5C,CAAC,SAAS,iCAAiC,GAAG,iCAAiC,CAC/E,SAAQ,cAAc,CAAC,CAAC,CAAC;gBACb,OAAO,EAAE,CAAC;IAItB,SAAS,KAAK,eAAe,WAa5B;IAED,SAAS,KAAK,SAAS,WAGtB;IAED,IAAI;IAOJ,SAAS,CAAC,QAAQ;IAMlB,SAAS,CAAC,gBAAgB,CAAC,KAAK,SAAI;CAQrC"}
1
+ {"version":3,"file":"SentinelIntervalAutomationWrapper.d.ts","sourceRoot":"","sources":["../../src/SentinelIntervalAutomationWrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAE7D,OAAO,EAAE,iCAAiC,EAAE,MAAM,cAAc,CAAA;AAEhE,qBAAa,iCAAiC,CAC5C,CAAC,SAAS,iCAAiC,GAAG,iCAAiC,CAC/E,SAAQ,cAAc,CAAC,CAAC,CAAC;gBACb,OAAO,EAAE,CAAC;IAItB,SAAS,KAAK,eAAe,WAiB5B;IAED,SAAS,KAAK,SAAS,WAGtB;IAED,IAAI;IAOJ,SAAS,CAAC,QAAQ;IAMlB,SAAS,CAAC,gBAAgB,CAAC,KAAK,SAAI;CAQrC"}
@@ -1 +1 @@
1
- {"version":3,"file":"SentinelIntervalAutomationWrapper.d.ts","sourceRoot":"","sources":["../../src/SentinelIntervalAutomationWrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAE7D,OAAO,EAAE,iCAAiC,EAAE,MAAM,cAAc,CAAA;AAEhE,qBAAa,iCAAiC,CAC5C,CAAC,SAAS,iCAAiC,GAAG,iCAAiC,CAC/E,SAAQ,cAAc,CAAC,CAAC,CAAC;gBACb,OAAO,EAAE,CAAC;IAItB,SAAS,KAAK,eAAe,WAa5B;IAED,SAAS,KAAK,SAAS,WAGtB;IAED,IAAI;IAOJ,SAAS,CAAC,QAAQ;IAMlB,SAAS,CAAC,gBAAgB,CAAC,KAAK,SAAI;CAQrC"}
1
+ {"version":3,"file":"SentinelIntervalAutomationWrapper.d.ts","sourceRoot":"","sources":["../../src/SentinelIntervalAutomationWrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAE7D,OAAO,EAAE,iCAAiC,EAAE,MAAM,cAAc,CAAA;AAEhE,qBAAa,iCAAiC,CAC5C,CAAC,SAAS,iCAAiC,GAAG,iCAAiC,CAC/E,SAAQ,cAAc,CAAC,CAAC,CAAC;gBACb,OAAO,EAAE,CAAC;IAItB,SAAS,KAAK,eAAe,WAiB5B;IAED,SAAS,KAAK,SAAS,WAGtB;IAED,IAAI;IAOJ,SAAS,CAAC,QAAQ;IAMlB,SAAS,CAAC,gBAAgB,CAAC,KAAK,SAAI;CAQrC"}
@@ -1 +1 @@
1
- {"version":3,"file":"SentinelIntervalAutomationWrapper.d.ts","sourceRoot":"","sources":["../../src/SentinelIntervalAutomationWrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAE7D,OAAO,EAAE,iCAAiC,EAAE,MAAM,cAAc,CAAA;AAEhE,qBAAa,iCAAiC,CAC5C,CAAC,SAAS,iCAAiC,GAAG,iCAAiC,CAC/E,SAAQ,cAAc,CAAC,CAAC,CAAC;gBACb,OAAO,EAAE,CAAC;IAItB,SAAS,KAAK,eAAe,WAa5B;IAED,SAAS,KAAK,SAAS,WAGtB;IAED,IAAI;IAOJ,SAAS,CAAC,QAAQ;IAMlB,SAAS,CAAC,gBAAgB,CAAC,KAAK,SAAI;CAQrC"}
1
+ {"version":3,"file":"SentinelIntervalAutomationWrapper.d.ts","sourceRoot":"","sources":["../../src/SentinelIntervalAutomationWrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAE7D,OAAO,EAAE,iCAAiC,EAAE,MAAM,cAAc,CAAA;AAEhE,qBAAa,iCAAiC,CAC5C,CAAC,SAAS,iCAAiC,GAAG,iCAAiC,CAC/E,SAAQ,cAAc,CAAC,CAAC,CAAC;gBACb,OAAO,EAAE,CAAC;IAItB,SAAS,KAAK,eAAe,WAiB5B;IAED,SAAS,KAAK,SAAS,WAGtB;IAED,IAAI;IAOJ,SAAS,CAAC,QAAQ;IAMlB,SAAS,CAAC,gBAAgB,CAAC,KAAK,SAAI;CAQrC"}
@@ -72,19 +72,19 @@ var MemorySentinel = class extends import_sentinel_abstract.AbstractSentinel {
72
72
  if (diviner) {
73
73
  return [diviner.address, await diviner.divine(inPayloadsFound)];
74
74
  }
75
- throw Error("Unsupported module type");
75
+ throw new Error("Unsupported module type");
76
76
  })
77
77
  );
78
78
  const finalResult = {};
79
- results.filter(import_promise.fulfilled).forEach((result) => {
79
+ for (const result of results.filter(import_promise.fulfilled)) {
80
80
  const [address, payloads] = result.value;
81
81
  finalResult[address] = finalResult[address] ?? [];
82
82
  finalResult[address].push(...payloads);
83
- });
83
+ }
84
84
  if (this.throwErrors) {
85
85
  const errors = results.filter(import_promise.rejected).map((result) => result.reason);
86
86
  if (errors.length > 0) {
87
- throw Error("At least one module failed");
87
+ throw new Error("At least one module failed");
88
88
  }
89
89
  }
90
90
  return finalResult;
@@ -98,7 +98,7 @@ var MemorySentinel = class extends import_sentinel_abstract.AbstractSentinel {
98
98
  }
99
99
  }
100
100
  processPreviousResults(payloads, inputs) {
101
- return inputs.map((input) => payloads[input] ?? []).flat();
101
+ return inputs.flatMap((input) => payloads[input] ?? []);
102
102
  }
103
103
  };
104
104
 
@@ -111,20 +111,24 @@ var SentinelIntervalAutomationWrapper = class extends import_payload_wrapper.Pay
111
111
  get frequencyMillis() {
112
112
  const frequency = this.jsonPayload().frequency;
113
113
  if (frequency === void 0)
114
- return Infinity;
114
+ return Number.POSITIVE_INFINITY;
115
115
  switch (this.jsonPayload().frequencyUnits ?? "hour") {
116
- case "second":
116
+ case "second": {
117
117
  return frequency * 1e3;
118
- case "minute":
118
+ }
119
+ case "minute": {
119
120
  return frequency * 60 * 1e3;
120
- case "hour":
121
+ }
122
+ case "hour": {
121
123
  return frequency * 60 * 60 * 1e3;
122
- case "day":
124
+ }
125
+ case "day": {
123
126
  return frequency * 24 * 60 * 60 * 1e3;
127
+ }
124
128
  }
125
129
  }
126
130
  get remaining() {
127
- return this.payload().remaining ?? Infinity;
131
+ return this.payload().remaining ?? Number.POSITIVE_INFINITY;
128
132
  }
129
133
  next() {
130
134
  this.jsonPayload().start = this.jsonPayload().start + this.frequencyMillis;
@@ -133,15 +137,15 @@ var SentinelIntervalAutomationWrapper = class extends import_payload_wrapper.Pay
133
137
  return this;
134
138
  }
135
139
  checkEnd() {
136
- if (this.jsonPayload().start > (this.jsonPayload().end ?? Infinity)) {
137
- this.jsonPayload().start = Infinity;
140
+ if (this.jsonPayload().start > (this.jsonPayload().end ?? Number.POSITIVE_INFINITY)) {
141
+ this.jsonPayload().start = Number.POSITIVE_INFINITY;
138
142
  }
139
143
  }
140
144
  consumeRemaining(count = 1) {
141
145
  const remaining = this.remaining - count;
142
146
  this.jsonPayload().remaining = remaining;
143
147
  if (remaining <= 0) {
144
- this.jsonPayload().start = Infinity;
148
+ this.jsonPayload().start = Number.POSITIVE_INFINITY;
145
149
  }
146
150
  }
147
151
  };
@@ -157,17 +161,17 @@ var SentinelRunner = class {
157
161
  constructor(sentinel, automations, onTriggerResult) {
158
162
  this.sentinel = sentinel;
159
163
  this.onTriggerResult = onTriggerResult;
160
- automations?.forEach((automation) => this.add(automation));
164
+ if (automations)
165
+ for (const automation of automations)
166
+ this.add(automation);
161
167
  }
162
168
  get automations() {
163
169
  return this._automations;
164
170
  }
165
171
  get next() {
166
172
  return Object.values(this._automations).reduce((previous, current) => {
167
- if (isSentinelIntervalAutomation(current)) {
168
- if (isSentinelIntervalAutomation(previous)) {
169
- return current.start < (previous?.start ?? Infinity) ? current : previous;
170
- }
173
+ if (isSentinelIntervalAutomation(current) && isSentinelIntervalAutomation(previous)) {
174
+ return current.start < (previous?.start ?? Number.POSITIVE_INFINITY) ? current : previous;
171
175
  }
172
176
  return current;
173
177
  }, void 0);
@@ -245,7 +249,7 @@ var SentinelWrapper = class extends import_module_wrapper.ModuleWrapper {
245
249
  static moduleIdentityCheck = import_sentinel_model2.isSentinelModule;
246
250
  static requiredQueries = [import_sentinel_model2.SentinelReportQuerySchema, ...super.requiredQueries];
247
251
  archivists() {
248
- throw Error("Not supported");
252
+ throw new Error("Not supported");
249
253
  }
250
254
  async report(payloads) {
251
255
  const queryPayload = { schema: import_sentinel_model2.SentinelReportQuerySchema };
@@ -253,7 +257,7 @@ var SentinelWrapper = class extends import_module_wrapper.ModuleWrapper {
253
257
  return result;
254
258
  }
255
259
  witnesses() {
256
- throw Error("Not supported");
260
+ throw new Error("Not supported");
257
261
  }
258
262
  };
259
263
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts","../../src/Automation.ts","../../src/MemorySentinel.ts","../../src/SentinelIntervalAutomationWrapper.ts","../../src/SentinelRunner.ts","../../src/Wrapper.ts"],"sourcesContent":["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","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, 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 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 if (this.throwErrors) {\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 }\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"],"mappings":"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","names":["import_payload_wrapper","import_sentinel_model"]}
1
+ {"version":3,"sources":["../../src/index.ts","../../src/Automation.ts","../../src/MemorySentinel.ts","../../src/SentinelIntervalAutomationWrapper.ts","../../src/SentinelRunner.ts","../../src/Wrapper.ts"],"sourcesContent":["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","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, 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 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 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 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 { 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 Number.POSITIVE_INFINITY\n switch (this.jsonPayload().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 }\n }\n\n protected get remaining() {\n //if remaining is not defined, we assume Infinity\n return this.payload().remaining ?? Number.POSITIVE_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 ?? Number.POSITIVE_INFINITY)) {\n this.jsonPayload().start = Number.POSITIVE_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 = Number.POSITIVE_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 if (automations) for (const automation of automations) this.add(automation)\n }\n\n get automations() {\n return this._automations\n }\n\n private get next() {\n // eslint-disable-next-line unicorn/no-array-reduce\n return Object.values(this._automations).reduce<SentinelAutomationPayload | undefined>((previous, current) => {\n if (isSentinelIntervalAutomation(current) && isSentinelIntervalAutomation(previous)) {\n return current.start < (previous?.start ?? Number.POSITIVE_INFINITY) ? current : previous\n }\n return current\n // eslint-disable-next-line unicorn/no-useless-undefined\n }, undefined)\n }\n\n async add(automation: SentinelAutomationPayload, restart = true) {\n const hash = await PayloadWrapper.hashAsync(automation)\n this._automations[hash] = automation\n if (restart) await this.restart()\n return hash\n }\n\n find(hash: string) {\n Object.entries(this._automations).find(([key]) => key === hash)\n }\n\n async remove(hash: string, restart = true) {\n delete this._automations[hash]\n if (restart) await this.restart()\n }\n\n removeAll() {\n this.stop()\n this._automations = {}\n }\n\n async restart() {\n this.stop()\n await this.start()\n }\n\n async start() {\n 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 new 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 new Error('Not supported')\n }\n}\n"],"mappings":"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","names":["import_payload_wrapper","import_sentinel_model"]}
@@ -40,19 +40,19 @@ var MemorySentinel = class extends AbstractSentinel {
40
40
  if (diviner) {
41
41
  return [diviner.address, await diviner.divine(inPayloadsFound)];
42
42
  }
43
- throw Error("Unsupported module type");
43
+ throw new Error("Unsupported module type");
44
44
  })
45
45
  );
46
46
  const finalResult = {};
47
- results.filter(fulfilled).forEach((result) => {
47
+ for (const result of results.filter(fulfilled)) {
48
48
  const [address, payloads] = result.value;
49
49
  finalResult[address] = finalResult[address] ?? [];
50
50
  finalResult[address].push(...payloads);
51
- });
51
+ }
52
52
  if (this.throwErrors) {
53
53
  const errors = results.filter(rejected).map((result) => result.reason);
54
54
  if (errors.length > 0) {
55
- throw Error("At least one module failed");
55
+ throw new Error("At least one module failed");
56
56
  }
57
57
  }
58
58
  return finalResult;
@@ -66,7 +66,7 @@ var MemorySentinel = class extends AbstractSentinel {
66
66
  }
67
67
  }
68
68
  processPreviousResults(payloads, inputs) {
69
- return inputs.map((input) => payloads[input] ?? []).flat();
69
+ return inputs.flatMap((input) => payloads[input] ?? []);
70
70
  }
71
71
  };
72
72
 
@@ -79,20 +79,24 @@ var SentinelIntervalAutomationWrapper = class extends PayloadWrapper {
79
79
  get frequencyMillis() {
80
80
  const frequency = this.jsonPayload().frequency;
81
81
  if (frequency === void 0)
82
- return Infinity;
82
+ return Number.POSITIVE_INFINITY;
83
83
  switch (this.jsonPayload().frequencyUnits ?? "hour") {
84
- case "second":
84
+ case "second": {
85
85
  return frequency * 1e3;
86
- case "minute":
86
+ }
87
+ case "minute": {
87
88
  return frequency * 60 * 1e3;
88
- case "hour":
89
+ }
90
+ case "hour": {
89
91
  return frequency * 60 * 60 * 1e3;
90
- case "day":
92
+ }
93
+ case "day": {
91
94
  return frequency * 24 * 60 * 60 * 1e3;
95
+ }
92
96
  }
93
97
  }
94
98
  get remaining() {
95
- return this.payload().remaining ?? Infinity;
99
+ return this.payload().remaining ?? Number.POSITIVE_INFINITY;
96
100
  }
97
101
  next() {
98
102
  this.jsonPayload().start = this.jsonPayload().start + this.frequencyMillis;
@@ -101,15 +105,15 @@ var SentinelIntervalAutomationWrapper = class extends PayloadWrapper {
101
105
  return this;
102
106
  }
103
107
  checkEnd() {
104
- if (this.jsonPayload().start > (this.jsonPayload().end ?? Infinity)) {
105
- this.jsonPayload().start = Infinity;
108
+ if (this.jsonPayload().start > (this.jsonPayload().end ?? Number.POSITIVE_INFINITY)) {
109
+ this.jsonPayload().start = Number.POSITIVE_INFINITY;
106
110
  }
107
111
  }
108
112
  consumeRemaining(count = 1) {
109
113
  const remaining = this.remaining - count;
110
114
  this.jsonPayload().remaining = remaining;
111
115
  if (remaining <= 0) {
112
- this.jsonPayload().start = Infinity;
116
+ this.jsonPayload().start = Number.POSITIVE_INFINITY;
113
117
  }
114
118
  }
115
119
  };
@@ -125,17 +129,17 @@ var SentinelRunner = class {
125
129
  constructor(sentinel, automations, onTriggerResult) {
126
130
  this.sentinel = sentinel;
127
131
  this.onTriggerResult = onTriggerResult;
128
- automations?.forEach((automation) => this.add(automation));
132
+ if (automations)
133
+ for (const automation of automations)
134
+ this.add(automation);
129
135
  }
130
136
  get automations() {
131
137
  return this._automations;
132
138
  }
133
139
  get next() {
134
140
  return Object.values(this._automations).reduce((previous, current) => {
135
- if (isSentinelIntervalAutomation(current)) {
136
- if (isSentinelIntervalAutomation(previous)) {
137
- return current.start < (previous?.start ?? Infinity) ? current : previous;
138
- }
141
+ if (isSentinelIntervalAutomation(current) && isSentinelIntervalAutomation(previous)) {
142
+ return current.start < (previous?.start ?? Number.POSITIVE_INFINITY) ? current : previous;
139
143
  }
140
144
  return current;
141
145
  }, void 0);
@@ -217,7 +221,7 @@ var SentinelWrapper = class extends ModuleWrapper {
217
221
  static moduleIdentityCheck = isSentinelModule;
218
222
  static requiredQueries = [SentinelReportQuerySchema, ...super.requiredQueries];
219
223
  archivists() {
220
- throw Error("Not supported");
224
+ throw new Error("Not supported");
221
225
  }
222
226
  async report(payloads) {
223
227
  const queryPayload = { schema: SentinelReportQuerySchema };
@@ -225,7 +229,7 @@ var SentinelWrapper = class extends ModuleWrapper {
225
229
  return result;
226
230
  }
227
231
  witnesses() {
228
- throw Error("Not supported");
232
+ throw new Error("Not supported");
229
233
  }
230
234
  };
231
235
 
@@ -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 { 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, 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 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 if (this.throwErrors) {\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 }\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"]}
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, 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 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 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 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 { 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 Number.POSITIVE_INFINITY\n switch (this.jsonPayload().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 }\n }\n\n protected get remaining() {\n //if remaining is not defined, we assume Infinity\n return this.payload().remaining ?? Number.POSITIVE_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 ?? Number.POSITIVE_INFINITY)) {\n this.jsonPayload().start = Number.POSITIVE_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 = Number.POSITIVE_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 if (automations) for (const automation of automations) this.add(automation)\n }\n\n get automations() {\n return this._automations\n }\n\n private get next() {\n // eslint-disable-next-line unicorn/no-array-reduce\n return Object.values(this._automations).reduce<SentinelAutomationPayload | undefined>((previous, current) => {\n if (isSentinelIntervalAutomation(current) && isSentinelIntervalAutomation(previous)) {\n return current.start < (previous?.start ?? Number.POSITIVE_INFINITY) ? current : previous\n }\n return current\n // eslint-disable-next-line unicorn/no-useless-undefined\n }, undefined)\n }\n\n async add(automation: SentinelAutomationPayload, restart = true) {\n const hash = await PayloadWrapper.hashAsync(automation)\n this._automations[hash] = automation\n if (restart) await this.restart()\n return hash\n }\n\n find(hash: string) {\n Object.entries(this._automations).find(([key]) => key === hash)\n }\n\n async remove(hash: string, restart = true) {\n delete this._automations[hash]\n if (restart) await this.restart()\n }\n\n removeAll() {\n this.stop()\n this._automations = {}\n }\n\n async restart() {\n this.stop()\n await this.start()\n }\n\n async start() {\n 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 new 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 new 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":";AAAA,SAAS,6BAAsC;AAIxC,IAAM,2BAAqD;AAG3D,IAAM,mCAAqE;AAG3E,IAAM,gCAA+D;AAgCrE,IAAM,+BAA+B,sBAAyD,gCAAgC;;;ACzCrI,SAAS,WAAW,gBAAgB;AACpC,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,OAAO,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,IAAI,MAAM,yBAAyB;AAAA,MAC3C,CAAC;AAAA,IACH;AACA,UAAM,cAA0C,CAAC;AACjD,eAAW,UAAU,QAAQ,OAAO,SAAS,GAAG;AAC9C,YAAM,CAAC,SAAS,QAAQ,IAAI,OAAO;AACnC,kBAAY,OAAO,IAAI,YAAY,OAAO,KAAK,CAAC;AAChD,kBAAY,OAAO,EAAE,KAAK,GAAG,QAAQ;AAAA,IACvC;AACA,QAAI,KAAK,aAAa;AACpB,YAAM,SAAS,QAAQ,OAAO,QAAQ,EAAE,IAAI,CAAC,WAAW,OAAO,MAAM;AACrE,UAAI,OAAO,SAAS,GAAG;AACrB,cAAM,IAAI,MAAM,4BAA4B;AAAA,MAC9C;AAAA,IACF;AACA,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,QAAQ,CAAC,UAAU,SAAS,KAAK,KAAK,CAAC,CAAC;AAAA,EACxD;AACF;;;ACtFA,SAAS,sBAAsB;AAIxB,IAAM,oCAAN,cAEG,eAAkB;AAAA,EAC1B,YAAY,SAAY;AACtB,UAAM,OAAO;AAAA,EACf;AAAA,EAEA,IAAc,kBAAkB;AAC9B,UAAM,YAAY,KAAK,YAAY,EAAE;AACrC,QAAI,cAAc;AAAW,aAAO,OAAO;AAC3C,YAAQ,KAAK,YAAY,EAAE,kBAAkB,QAAQ;AAAA,MACnD,KAAK,UAAU;AACb,eAAO,YAAY;AAAA,MACrB;AAAA,MACA,KAAK,UAAU;AACb,eAAO,YAAY,KAAK;AAAA,MAC1B;AAAA,MACA,KAAK,QAAQ;AACX,eAAO,YAAY,KAAK,KAAK;AAAA,MAC/B;AAAA,MACA,KAAK,OAAO;AACV,eAAO,YAAY,KAAK,KAAK,KAAK;AAAA,MACpC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,IAAc,YAAY;AAExB,WAAO,KAAK,QAAQ,EAAE,aAAa,OAAO;AAAA,EAC5C;AAAA,EAEA,OAAO;AACL,SAAK,YAAY,EAAE,QAAQ,KAAK,YAAY,EAAE,QAAQ,KAAK;AAC3D,SAAK,iBAAiB;AACtB,SAAK,SAAS;AACd,WAAO;AAAA,EACT;AAAA,EAEU,WAAW;AACnB,QAAI,KAAK,YAAY,EAAE,SAAS,KAAK,YAAY,EAAE,OAAO,OAAO,oBAAoB;AACnF,WAAK,YAAY,EAAE,QAAQ,OAAO;AAAA,IACpC;AAAA,EACF;AAAA,EAEU,iBAAiB,QAAQ,GAAG;AACpC,UAAM,YAAY,KAAK,YAAY;AACnC,SAAK,YAAY,EAAE,YAAY;AAE/B,QAAI,aAAa,GAAG;AAClB,WAAK,YAAY,EAAE,QAAQ,OAAO;AAAA,IACpC;AAAA,EACF;AACF;;;ACxDA,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,QAAI;AAAa,iBAAW,cAAc;AAAa,aAAK,IAAI,UAAU;AAAA,EAC5E;AAAA,EAEA,IAAI,cAAc;AAChB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAY,OAAO;AAEjB,WAAO,OAAO,OAAO,KAAK,YAAY,EAAE,OAA8C,CAAC,UAAU,YAAY;AAC3G,UAAI,6BAA6B,OAAO,KAAK,6BAA6B,QAAQ,GAAG;AACnF,eAAO,QAAQ,SAAS,UAAU,SAAS,OAAO,qBAAqB,UAAU;AAAA,MACnF;AACA,aAAO;AAAA,IAET,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,6BAA6B,UAAU,GAAG;AAC5C,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;AACnE,UAAM,UAAU,IAAI,kCAAkC,UAAU;AAChE,UAAM,KAAK,OAAO,MAAM,QAAQ,UAAU,GAAG,KAAK;AAClD,YAAQ,KAAK;AACb,UAAM,KAAK,IAAI,QAAQ,YAAY,GAAG,KAAK;AAC3C,UAAM,gBAAgB,MAAM,KAAK,SAAS,OAAO;AACjD,SAAK,kBAAkB,aAAa;AACpC,UAAM,KAAK,MAAM;AAAA,EACnB;AACF;;;ACxGA,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,IAAI,MAAM,eAAe;AAAA,EACjC;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,IAAI,MAAM,eAAe;AAAA,EACjC;AACF;;;AC9BA,cAAc;AACd,cAAc;","names":["PayloadWrapper","PayloadWrapper"]}
@@ -1 +1 @@
1
- {"version":3,"file":"SentinelIntervalAutomationWrapper.d.ts","sourceRoot":"","sources":["../../src/SentinelIntervalAutomationWrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAE7D,OAAO,EAAE,iCAAiC,EAAE,MAAM,cAAc,CAAA;AAEhE,qBAAa,iCAAiC,CAC5C,CAAC,SAAS,iCAAiC,GAAG,iCAAiC,CAC/E,SAAQ,cAAc,CAAC,CAAC,CAAC;gBACb,OAAO,EAAE,CAAC;IAItB,SAAS,KAAK,eAAe,WAa5B;IAED,SAAS,KAAK,SAAS,WAGtB;IAED,IAAI;IAOJ,SAAS,CAAC,QAAQ;IAMlB,SAAS,CAAC,gBAAgB,CAAC,KAAK,SAAI;CAQrC"}
1
+ {"version":3,"file":"SentinelIntervalAutomationWrapper.d.ts","sourceRoot":"","sources":["../../src/SentinelIntervalAutomationWrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAE7D,OAAO,EAAE,iCAAiC,EAAE,MAAM,cAAc,CAAA;AAEhE,qBAAa,iCAAiC,CAC5C,CAAC,SAAS,iCAAiC,GAAG,iCAAiC,CAC/E,SAAQ,cAAc,CAAC,CAAC,CAAC;gBACb,OAAO,EAAE,CAAC;IAItB,SAAS,KAAK,eAAe,WAiB5B;IAED,SAAS,KAAK,SAAS,WAGtB;IAED,IAAI;IAOJ,SAAS,CAAC,QAAQ;IAMlB,SAAS,CAAC,gBAAgB,CAAC,KAAK,SAAI;CAQrC"}
@@ -1 +1 @@
1
- {"version":3,"file":"SentinelIntervalAutomationWrapper.d.ts","sourceRoot":"","sources":["../../src/SentinelIntervalAutomationWrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAE7D,OAAO,EAAE,iCAAiC,EAAE,MAAM,cAAc,CAAA;AAEhE,qBAAa,iCAAiC,CAC5C,CAAC,SAAS,iCAAiC,GAAG,iCAAiC,CAC/E,SAAQ,cAAc,CAAC,CAAC,CAAC;gBACb,OAAO,EAAE,CAAC;IAItB,SAAS,KAAK,eAAe,WAa5B;IAED,SAAS,KAAK,SAAS,WAGtB;IAED,IAAI;IAOJ,SAAS,CAAC,QAAQ;IAMlB,SAAS,CAAC,gBAAgB,CAAC,KAAK,SAAI;CAQrC"}
1
+ {"version":3,"file":"SentinelIntervalAutomationWrapper.d.ts","sourceRoot":"","sources":["../../src/SentinelIntervalAutomationWrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAE7D,OAAO,EAAE,iCAAiC,EAAE,MAAM,cAAc,CAAA;AAEhE,qBAAa,iCAAiC,CAC5C,CAAC,SAAS,iCAAiC,GAAG,iCAAiC,CAC/E,SAAQ,cAAc,CAAC,CAAC,CAAC;gBACb,OAAO,EAAE,CAAC;IAItB,SAAS,KAAK,eAAe,WAiB5B;IAED,SAAS,KAAK,SAAS,WAGtB;IAED,IAAI;IAOJ,SAAS,CAAC,QAAQ;IAMlB,SAAS,CAAC,gBAAgB,CAAC,KAAK,SAAI;CAQrC"}
@@ -1 +1 @@
1
- {"version":3,"file":"SentinelIntervalAutomationWrapper.d.ts","sourceRoot":"","sources":["../../src/SentinelIntervalAutomationWrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAE7D,OAAO,EAAE,iCAAiC,EAAE,MAAM,cAAc,CAAA;AAEhE,qBAAa,iCAAiC,CAC5C,CAAC,SAAS,iCAAiC,GAAG,iCAAiC,CAC/E,SAAQ,cAAc,CAAC,CAAC,CAAC;gBACb,OAAO,EAAE,CAAC;IAItB,SAAS,KAAK,eAAe,WAa5B;IAED,SAAS,KAAK,SAAS,WAGtB;IAED,IAAI;IAOJ,SAAS,CAAC,QAAQ;IAMlB,SAAS,CAAC,gBAAgB,CAAC,KAAK,SAAI;CAQrC"}
1
+ {"version":3,"file":"SentinelIntervalAutomationWrapper.d.ts","sourceRoot":"","sources":["../../src/SentinelIntervalAutomationWrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAE7D,OAAO,EAAE,iCAAiC,EAAE,MAAM,cAAc,CAAA;AAEhE,qBAAa,iCAAiC,CAC5C,CAAC,SAAS,iCAAiC,GAAG,iCAAiC,CAC/E,SAAQ,cAAc,CAAC,CAAC,CAAC;gBACb,OAAO,EAAE,CAAC;IAItB,SAAS,KAAK,eAAe,WAiB5B;IAED,SAAS,KAAK,SAAS,WAGtB;IAED,IAAI;IAOJ,SAAS,CAAC,QAAQ;IAMlB,SAAS,CAAC,gBAAgB,CAAC,KAAK,SAAI;CAQrC"}
@@ -72,19 +72,19 @@ var MemorySentinel = class extends import_sentinel_abstract.AbstractSentinel {
72
72
  if (diviner) {
73
73
  return [diviner.address, await diviner.divine(inPayloadsFound)];
74
74
  }
75
- throw Error("Unsupported module type");
75
+ throw new Error("Unsupported module type");
76
76
  })
77
77
  );
78
78
  const finalResult = {};
79
- results.filter(import_promise.fulfilled).forEach((result) => {
79
+ for (const result of results.filter(import_promise.fulfilled)) {
80
80
  const [address, payloads] = result.value;
81
81
  finalResult[address] = finalResult[address] ?? [];
82
82
  finalResult[address].push(...payloads);
83
- });
83
+ }
84
84
  if (this.throwErrors) {
85
85
  const errors = results.filter(import_promise.rejected).map((result) => result.reason);
86
86
  if (errors.length > 0) {
87
- throw Error("At least one module failed");
87
+ throw new Error("At least one module failed");
88
88
  }
89
89
  }
90
90
  return finalResult;
@@ -98,7 +98,7 @@ var MemorySentinel = class extends import_sentinel_abstract.AbstractSentinel {
98
98
  }
99
99
  }
100
100
  processPreviousResults(payloads, inputs) {
101
- return inputs.map((input) => payloads[input] ?? []).flat();
101
+ return inputs.flatMap((input) => payloads[input] ?? []);
102
102
  }
103
103
  };
104
104
 
@@ -111,20 +111,24 @@ var SentinelIntervalAutomationWrapper = class extends import_payload_wrapper.Pay
111
111
  get frequencyMillis() {
112
112
  const frequency = this.jsonPayload().frequency;
113
113
  if (frequency === void 0)
114
- return Infinity;
114
+ return Number.POSITIVE_INFINITY;
115
115
  switch (this.jsonPayload().frequencyUnits ?? "hour") {
116
- case "second":
116
+ case "second": {
117
117
  return frequency * 1e3;
118
- case "minute":
118
+ }
119
+ case "minute": {
119
120
  return frequency * 60 * 1e3;
120
- case "hour":
121
+ }
122
+ case "hour": {
121
123
  return frequency * 60 * 60 * 1e3;
122
- case "day":
124
+ }
125
+ case "day": {
123
126
  return frequency * 24 * 60 * 60 * 1e3;
127
+ }
124
128
  }
125
129
  }
126
130
  get remaining() {
127
- return this.payload().remaining ?? Infinity;
131
+ return this.payload().remaining ?? Number.POSITIVE_INFINITY;
128
132
  }
129
133
  next() {
130
134
  this.jsonPayload().start = this.jsonPayload().start + this.frequencyMillis;
@@ -133,15 +137,15 @@ var SentinelIntervalAutomationWrapper = class extends import_payload_wrapper.Pay
133
137
  return this;
134
138
  }
135
139
  checkEnd() {
136
- if (this.jsonPayload().start > (this.jsonPayload().end ?? Infinity)) {
137
- this.jsonPayload().start = Infinity;
140
+ if (this.jsonPayload().start > (this.jsonPayload().end ?? Number.POSITIVE_INFINITY)) {
141
+ this.jsonPayload().start = Number.POSITIVE_INFINITY;
138
142
  }
139
143
  }
140
144
  consumeRemaining(count = 1) {
141
145
  const remaining = this.remaining - count;
142
146
  this.jsonPayload().remaining = remaining;
143
147
  if (remaining <= 0) {
144
- this.jsonPayload().start = Infinity;
148
+ this.jsonPayload().start = Number.POSITIVE_INFINITY;
145
149
  }
146
150
  }
147
151
  };
@@ -157,17 +161,17 @@ var SentinelRunner = class {
157
161
  constructor(sentinel, automations, onTriggerResult) {
158
162
  this.sentinel = sentinel;
159
163
  this.onTriggerResult = onTriggerResult;
160
- automations == null ? void 0 : automations.forEach((automation) => this.add(automation));
164
+ if (automations)
165
+ for (const automation of automations)
166
+ this.add(automation);
161
167
  }
162
168
  get automations() {
163
169
  return this._automations;
164
170
  }
165
171
  get next() {
166
172
  return Object.values(this._automations).reduce((previous, current) => {
167
- if (isSentinelIntervalAutomation(current)) {
168
- if (isSentinelIntervalAutomation(previous)) {
169
- return current.start < ((previous == null ? void 0 : previous.start) ?? Infinity) ? current : previous;
170
- }
173
+ if (isSentinelIntervalAutomation(current) && isSentinelIntervalAutomation(previous)) {
174
+ return current.start < ((previous == null ? void 0 : previous.start) ?? Number.POSITIVE_INFINITY) ? current : previous;
171
175
  }
172
176
  return current;
173
177
  }, void 0);
@@ -246,7 +250,7 @@ var SentinelWrapper = class extends import_module_wrapper.ModuleWrapper {
246
250
  static moduleIdentityCheck = import_sentinel_model2.isSentinelModule;
247
251
  static requiredQueries = [import_sentinel_model2.SentinelReportQuerySchema, ...super.requiredQueries];
248
252
  archivists() {
249
- throw Error("Not supported");
253
+ throw new Error("Not supported");
250
254
  }
251
255
  async report(payloads) {
252
256
  const queryPayload = { schema: import_sentinel_model2.SentinelReportQuerySchema };
@@ -254,7 +258,7 @@ var SentinelWrapper = class extends import_module_wrapper.ModuleWrapper {
254
258
  return result;
255
259
  }
256
260
  witnesses() {
257
- throw Error("Not supported");
261
+ throw new Error("Not supported");
258
262
  }
259
263
  };
260
264
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts","../../src/Automation.ts","../../src/MemorySentinel.ts","../../src/SentinelIntervalAutomationWrapper.ts","../../src/SentinelRunner.ts","../../src/Wrapper.ts"],"sourcesContent":["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","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, 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 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 if (this.throwErrors) {\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 }\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"],"mappings":"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","names":["import_payload_wrapper","import_sentinel_model"]}
1
+ {"version":3,"sources":["../../src/index.ts","../../src/Automation.ts","../../src/MemorySentinel.ts","../../src/SentinelIntervalAutomationWrapper.ts","../../src/SentinelRunner.ts","../../src/Wrapper.ts"],"sourcesContent":["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","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, 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 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 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 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 { 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 Number.POSITIVE_INFINITY\n switch (this.jsonPayload().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 }\n }\n\n protected get remaining() {\n //if remaining is not defined, we assume Infinity\n return this.payload().remaining ?? Number.POSITIVE_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 ?? Number.POSITIVE_INFINITY)) {\n this.jsonPayload().start = Number.POSITIVE_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 = Number.POSITIVE_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 if (automations) for (const automation of automations) this.add(automation)\n }\n\n get automations() {\n return this._automations\n }\n\n private get next() {\n // eslint-disable-next-line unicorn/no-array-reduce\n return Object.values(this._automations).reduce<SentinelAutomationPayload | undefined>((previous, current) => {\n if (isSentinelIntervalAutomation(current) && isSentinelIntervalAutomation(previous)) {\n return current.start < (previous?.start ?? Number.POSITIVE_INFINITY) ? current : previous\n }\n return current\n // eslint-disable-next-line unicorn/no-useless-undefined\n }, undefined)\n }\n\n async add(automation: SentinelAutomationPayload, restart = true) {\n const hash = await PayloadWrapper.hashAsync(automation)\n this._automations[hash] = automation\n if (restart) await this.restart()\n return hash\n }\n\n find(hash: string) {\n Object.entries(this._automations).find(([key]) => key === hash)\n }\n\n async remove(hash: string, restart = true) {\n delete this._automations[hash]\n if (restart) await this.restart()\n }\n\n removeAll() {\n this.stop()\n this._automations = {}\n }\n\n async restart() {\n this.stop()\n await this.start()\n }\n\n async start() {\n 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 new 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 new Error('Not supported')\n }\n}\n"],"mappings":"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","names":["import_payload_wrapper","import_sentinel_model"]}
@@ -40,19 +40,19 @@ var MemorySentinel = class extends AbstractSentinel {
40
40
  if (diviner) {
41
41
  return [diviner.address, await diviner.divine(inPayloadsFound)];
42
42
  }
43
- throw Error("Unsupported module type");
43
+ throw new Error("Unsupported module type");
44
44
  })
45
45
  );
46
46
  const finalResult = {};
47
- results.filter(fulfilled).forEach((result) => {
47
+ for (const result of results.filter(fulfilled)) {
48
48
  const [address, payloads] = result.value;
49
49
  finalResult[address] = finalResult[address] ?? [];
50
50
  finalResult[address].push(...payloads);
51
- });
51
+ }
52
52
  if (this.throwErrors) {
53
53
  const errors = results.filter(rejected).map((result) => result.reason);
54
54
  if (errors.length > 0) {
55
- throw Error("At least one module failed");
55
+ throw new Error("At least one module failed");
56
56
  }
57
57
  }
58
58
  return finalResult;
@@ -66,7 +66,7 @@ var MemorySentinel = class extends AbstractSentinel {
66
66
  }
67
67
  }
68
68
  processPreviousResults(payloads, inputs) {
69
- return inputs.map((input) => payloads[input] ?? []).flat();
69
+ return inputs.flatMap((input) => payloads[input] ?? []);
70
70
  }
71
71
  };
72
72
 
@@ -79,20 +79,24 @@ var SentinelIntervalAutomationWrapper = class extends PayloadWrapper {
79
79
  get frequencyMillis() {
80
80
  const frequency = this.jsonPayload().frequency;
81
81
  if (frequency === void 0)
82
- return Infinity;
82
+ return Number.POSITIVE_INFINITY;
83
83
  switch (this.jsonPayload().frequencyUnits ?? "hour") {
84
- case "second":
84
+ case "second": {
85
85
  return frequency * 1e3;
86
- case "minute":
86
+ }
87
+ case "minute": {
87
88
  return frequency * 60 * 1e3;
88
- case "hour":
89
+ }
90
+ case "hour": {
89
91
  return frequency * 60 * 60 * 1e3;
90
- case "day":
92
+ }
93
+ case "day": {
91
94
  return frequency * 24 * 60 * 60 * 1e3;
95
+ }
92
96
  }
93
97
  }
94
98
  get remaining() {
95
- return this.payload().remaining ?? Infinity;
99
+ return this.payload().remaining ?? Number.POSITIVE_INFINITY;
96
100
  }
97
101
  next() {
98
102
  this.jsonPayload().start = this.jsonPayload().start + this.frequencyMillis;
@@ -101,15 +105,15 @@ var SentinelIntervalAutomationWrapper = class extends PayloadWrapper {
101
105
  return this;
102
106
  }
103
107
  checkEnd() {
104
- if (this.jsonPayload().start > (this.jsonPayload().end ?? Infinity)) {
105
- this.jsonPayload().start = Infinity;
108
+ if (this.jsonPayload().start > (this.jsonPayload().end ?? Number.POSITIVE_INFINITY)) {
109
+ this.jsonPayload().start = Number.POSITIVE_INFINITY;
106
110
  }
107
111
  }
108
112
  consumeRemaining(count = 1) {
109
113
  const remaining = this.remaining - count;
110
114
  this.jsonPayload().remaining = remaining;
111
115
  if (remaining <= 0) {
112
- this.jsonPayload().start = Infinity;
116
+ this.jsonPayload().start = Number.POSITIVE_INFINITY;
113
117
  }
114
118
  }
115
119
  };
@@ -125,17 +129,17 @@ var SentinelRunner = class {
125
129
  constructor(sentinel, automations, onTriggerResult) {
126
130
  this.sentinel = sentinel;
127
131
  this.onTriggerResult = onTriggerResult;
128
- automations == null ? void 0 : automations.forEach((automation) => this.add(automation));
132
+ if (automations)
133
+ for (const automation of automations)
134
+ this.add(automation);
129
135
  }
130
136
  get automations() {
131
137
  return this._automations;
132
138
  }
133
139
  get next() {
134
140
  return Object.values(this._automations).reduce((previous, current) => {
135
- if (isSentinelIntervalAutomation(current)) {
136
- if (isSentinelIntervalAutomation(previous)) {
137
- return current.start < ((previous == null ? void 0 : previous.start) ?? Infinity) ? current : previous;
138
- }
141
+ if (isSentinelIntervalAutomation(current) && isSentinelIntervalAutomation(previous)) {
142
+ return current.start < ((previous == null ? void 0 : previous.start) ?? Number.POSITIVE_INFINITY) ? current : previous;
139
143
  }
140
144
  return current;
141
145
  }, void 0);
@@ -218,7 +222,7 @@ var SentinelWrapper = class extends ModuleWrapper {
218
222
  static moduleIdentityCheck = isSentinelModule;
219
223
  static requiredQueries = [SentinelReportQuerySchema, ...super.requiredQueries];
220
224
  archivists() {
221
- throw Error("Not supported");
225
+ throw new Error("Not supported");
222
226
  }
223
227
  async report(payloads) {
224
228
  const queryPayload = { schema: SentinelReportQuerySchema };
@@ -226,7 +230,7 @@ var SentinelWrapper = class extends ModuleWrapper {
226
230
  return result;
227
231
  }
228
232
  witnesses() {
229
- throw Error("Not supported");
233
+ throw new Error("Not supported");
230
234
  }
231
235
  };
232
236
 
@@ -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 { 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, 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 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 if (this.throwErrors) {\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 }\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"]}
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, 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 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 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 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 { 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 Number.POSITIVE_INFINITY\n switch (this.jsonPayload().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 }\n }\n\n protected get remaining() {\n //if remaining is not defined, we assume Infinity\n return this.payload().remaining ?? Number.POSITIVE_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 ?? Number.POSITIVE_INFINITY)) {\n this.jsonPayload().start = Number.POSITIVE_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 = Number.POSITIVE_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 if (automations) for (const automation of automations) this.add(automation)\n }\n\n get automations() {\n return this._automations\n }\n\n private get next() {\n // eslint-disable-next-line unicorn/no-array-reduce\n return Object.values(this._automations).reduce<SentinelAutomationPayload | undefined>((previous, current) => {\n if (isSentinelIntervalAutomation(current) && isSentinelIntervalAutomation(previous)) {\n return current.start < (previous?.start ?? Number.POSITIVE_INFINITY) ? current : previous\n }\n return current\n // eslint-disable-next-line unicorn/no-useless-undefined\n }, undefined)\n }\n\n async add(automation: SentinelAutomationPayload, restart = true) {\n const hash = await PayloadWrapper.hashAsync(automation)\n this._automations[hash] = automation\n if (restart) await this.restart()\n return hash\n }\n\n find(hash: string) {\n Object.entries(this._automations).find(([key]) => key === hash)\n }\n\n async remove(hash: string, restart = true) {\n delete this._automations[hash]\n if (restart) await this.restart()\n }\n\n removeAll() {\n this.stop()\n this._automations = {}\n }\n\n async restart() {\n this.stop()\n await this.start()\n }\n\n async start() {\n 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 new 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 new 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,28 +13,28 @@
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.84.5",
17
- "@xyo-network/diviner-model": "~2.84.5",
18
- "@xyo-network/module-model": "~2.84.5",
19
- "@xyo-network/module-wrapper": "~2.84.5",
20
- "@xyo-network/payload-model": "~2.84.5",
21
- "@xyo-network/payload-wrapper": "~2.84.5",
22
- "@xyo-network/sentinel-abstract": "~2.84.5",
23
- "@xyo-network/sentinel-model": "~2.84.5",
24
- "@xyo-network/witness-model": "~2.84.5"
16
+ "@xyo-network/archivist": "~2.84.7",
17
+ "@xyo-network/diviner-model": "~2.84.7",
18
+ "@xyo-network/module-model": "~2.84.7",
19
+ "@xyo-network/module-wrapper": "~2.84.7",
20
+ "@xyo-network/payload-model": "~2.84.7",
21
+ "@xyo-network/payload-wrapper": "~2.84.7",
22
+ "@xyo-network/sentinel-abstract": "~2.84.7",
23
+ "@xyo-network/sentinel-model": "~2.84.7",
24
+ "@xyo-network/witness-model": "~2.84.7"
25
25
  },
26
26
  "description": "Primary SDK for using XYO Protocol 2.0",
27
27
  "devDependencies": {
28
28
  "@xylabs/delay": "^2.13.20",
29
- "@xylabs/ts-scripts-yarn3": "^3.2.19",
30
- "@xylabs/tsconfig": "^3.2.19",
31
- "@xyo-network/abstract-witness": "~2.84.5",
32
- "@xyo-network/account": "~2.84.5",
33
- "@xyo-network/boundwitness-model": "~2.84.5",
34
- "@xyo-network/hash": "~2.84.5",
35
- "@xyo-network/id-payload-plugin": "^2.84.1",
36
- "@xyo-network/node-memory": "~2.84.5",
37
- "@xyo-network/witnesses": "~2.84.5",
29
+ "@xylabs/ts-scripts-yarn3": "^3.2.24",
30
+ "@xylabs/tsconfig": "^3.2.24",
31
+ "@xyo-network/abstract-witness": "~2.84.7",
32
+ "@xyo-network/account": "~2.84.7",
33
+ "@xyo-network/boundwitness-model": "~2.84.7",
34
+ "@xyo-network/hash": "~2.84.7",
35
+ "@xyo-network/id-payload-plugin": "^2.84.2",
36
+ "@xyo-network/node-memory": "~2.84.7",
37
+ "@xyo-network/witness-adhoc": "~2.84.6",
38
38
  "typescript": "^5.3.3"
39
39
  },
40
40
  "types": "dist/node/index.d.ts",
@@ -75,6 +75,6 @@
75
75
  "url": "https://github.com/XYOracleNetwork/sdk-xyo-client-js.git"
76
76
  },
77
77
  "sideEffects": false,
78
- "version": "2.84.5",
78
+ "version": "2.84.7",
79
79
  "type": "module"
80
80
  }
@@ -54,19 +54,19 @@ export class MemorySentinel<
54
54
  if (diviner) {
55
55
  return [diviner.address, await diviner.divine(inPayloadsFound)]
56
56
  }
57
- throw Error('Unsupported module type')
57
+ throw new Error('Unsupported module type')
58
58
  }),
59
59
  )
60
60
  const finalResult: Record<Address, Payload[]> = {}
61
- results.filter(fulfilled).forEach((result) => {
61
+ for (const result of results.filter(fulfilled)) {
62
62
  const [address, payloads] = result.value
63
63
  finalResult[address] = finalResult[address] ?? []
64
64
  finalResult[address].push(...payloads)
65
- })
65
+ }
66
66
  if (this.throwErrors) {
67
67
  const errors = results.filter(rejected).map((result) => result.reason)
68
68
  if (errors.length > 0) {
69
- throw Error('At least one module failed')
69
+ throw new Error('At least one module failed')
70
70
  }
71
71
  }
72
72
  return finalResult
@@ -82,6 +82,6 @@ export class MemorySentinel<
82
82
  }
83
83
 
84
84
  private processPreviousResults(payloads: Record<string, Payload[]>, inputs: string[]) {
85
- return inputs.map((input) => payloads[input] ?? []).flat()
85
+ return inputs.flatMap((input) => payloads[input] ?? [])
86
86
  }
87
87
  }
@@ -11,22 +11,26 @@ export class SentinelIntervalAutomationWrapper<
11
11
 
12
12
  protected get frequencyMillis() {
13
13
  const frequency = this.jsonPayload().frequency
14
- if (frequency === undefined) return Infinity
14
+ if (frequency === undefined) return Number.POSITIVE_INFINITY
15
15
  switch (this.jsonPayload().frequencyUnits ?? 'hour') {
16
- case 'second':
16
+ case 'second': {
17
17
  return frequency * 1000
18
- case 'minute':
18
+ }
19
+ case 'minute': {
19
20
  return frequency * 60 * 1000
20
- case 'hour':
21
+ }
22
+ case 'hour': {
21
23
  return frequency * 60 * 60 * 1000
22
- case 'day':
24
+ }
25
+ case 'day': {
23
26
  return frequency * 24 * 60 * 60 * 1000
27
+ }
24
28
  }
25
29
  }
26
30
 
27
31
  protected get remaining() {
28
32
  //if remaining is not defined, we assume Infinity
29
- return this.payload().remaining ?? Infinity
33
+ return this.payload().remaining ?? Number.POSITIVE_INFINITY
30
34
  }
31
35
 
32
36
  next() {
@@ -37,8 +41,8 @@ export class SentinelIntervalAutomationWrapper<
37
41
  }
38
42
 
39
43
  protected checkEnd() {
40
- if (this.jsonPayload().start > (this.jsonPayload().end ?? Infinity)) {
41
- this.jsonPayload().start = Infinity
44
+ if (this.jsonPayload().start > (this.jsonPayload().end ?? Number.POSITIVE_INFINITY)) {
45
+ this.jsonPayload().start = Number.POSITIVE_INFINITY
42
46
  }
43
47
  }
44
48
 
@@ -47,7 +51,7 @@ export class SentinelIntervalAutomationWrapper<
47
51
  this.jsonPayload().remaining = remaining
48
52
 
49
53
  if (remaining <= 0) {
50
- this.jsonPayload().start = Infinity
54
+ this.jsonPayload().start = Number.POSITIVE_INFINITY
51
55
  }
52
56
  }
53
57
  }
@@ -17,7 +17,7 @@ export class SentinelRunner {
17
17
  constructor(sentinel: SentinelInstance, automations?: SentinelAutomationPayload[], onTriggerResult?: OnSentinelRunnerTriggerResult) {
18
18
  this.sentinel = sentinel
19
19
  this.onTriggerResult = onTriggerResult
20
- automations?.forEach((automation) => this.add(automation))
20
+ if (automations) for (const automation of automations) this.add(automation)
21
21
  }
22
22
 
23
23
  get automations() {
@@ -25,13 +25,13 @@ export class SentinelRunner {
25
25
  }
26
26
 
27
27
  private get next() {
28
+ // eslint-disable-next-line unicorn/no-array-reduce
28
29
  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
- }
30
+ if (isSentinelIntervalAutomation(current) && isSentinelIntervalAutomation(previous)) {
31
+ return current.start < (previous?.start ?? Number.POSITIVE_INFINITY) ? current : previous
33
32
  }
34
33
  return current
34
+ // eslint-disable-next-line unicorn/no-useless-undefined
35
35
  }, undefined)
36
36
  }
37
37
 
package/src/Wrapper.ts CHANGED
@@ -21,7 +21,7 @@ export class SentinelWrapper<TModule extends SentinelModule = SentinelModule>
21
21
  static override requiredQueries = [SentinelReportQuerySchema, ...super.requiredQueries]
22
22
 
23
23
  archivists(): Promise<ArchivistInstance[]> {
24
- throw Error('Not supported')
24
+ throw new Error('Not supported')
25
25
  }
26
26
 
27
27
  async report(payloads?: Payload[]): Promise<Payload[]> {
@@ -31,6 +31,6 @@ export class SentinelWrapper<TModule extends SentinelModule = SentinelModule>
31
31
  }
32
32
 
33
33
  witnesses(): Promise<WitnessInstance[]> {
34
- throw Error('Not supported')
34
+ throw new Error('Not supported')
35
35
  }
36
36
  }