@xyo-network/sentinel 2.82.0-rc.1 → 2.83.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/Automation.d.cts +41 -13
- package/dist/browser/Automation.d.cts.map +1 -1
- package/dist/browser/Automation.d.mts +41 -13
- package/dist/browser/Automation.d.mts.map +1 -1
- package/dist/browser/Automation.d.ts +41 -13
- package/dist/browser/Automation.d.ts.map +1 -1
- package/dist/browser/SentinelRunner.d.cts.map +1 -1
- package/dist/browser/SentinelRunner.d.mts.map +1 -1
- package/dist/browser/SentinelRunner.d.ts.map +1 -1
- package/dist/browser/Wrapper.d.cts +1 -1
- package/dist/browser/Wrapper.d.cts.map +1 -1
- package/dist/browser/Wrapper.d.mts +1 -1
- package/dist/browser/Wrapper.d.mts.map +1 -1
- package/dist/browser/Wrapper.d.ts +1 -1
- package/dist/browser/Wrapper.d.ts.map +1 -1
- package/dist/browser/index.cjs +22 -12
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.js +22 -12
- package/dist/browser/index.js.map +1 -1
- package/dist/node/Automation.d.cts +41 -13
- package/dist/node/Automation.d.cts.map +1 -1
- package/dist/node/Automation.d.mts +41 -13
- package/dist/node/Automation.d.mts.map +1 -1
- package/dist/node/Automation.d.ts +41 -13
- package/dist/node/Automation.d.ts.map +1 -1
- package/dist/node/SentinelRunner.d.cts.map +1 -1
- package/dist/node/SentinelRunner.d.mts.map +1 -1
- package/dist/node/SentinelRunner.d.ts.map +1 -1
- package/dist/node/Wrapper.d.cts +1 -1
- package/dist/node/Wrapper.d.cts.map +1 -1
- package/dist/node/Wrapper.d.mts +1 -1
- package/dist/node/Wrapper.d.mts.map +1 -1
- package/dist/node/Wrapper.d.ts +1 -1
- package/dist/node/Wrapper.d.ts.map +1 -1
- package/dist/node/index.js +25 -12
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +22 -12
- package/dist/node/index.mjs.map +1 -1
- package/package.json +23 -24
- package/src/Automation.ts +31 -15
- package/src/SentinelIntervalAutomationWrapper.ts +7 -7
- package/src/SentinelRunner.ts +9 -6
- package/typedoc.json +1 -1
package/dist/node/index.mjs
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
// src/Automation.ts
|
|
2
|
+
import { isPayloadOfSchemaType } from "@xyo-network/payload-model";
|
|
2
3
|
var SentinelAutomationSchema = "network.xyo.automation";
|
|
4
|
+
var SentinelIntervalAutomationSchema = "network.xyo.automation.interval";
|
|
5
|
+
var SentinelEventAutomationSchema = "network.xyo.automation.event";
|
|
6
|
+
var isSentinelIntervalAutomation = isPayloadOfSchemaType(SentinelIntervalAutomationSchema);
|
|
3
7
|
|
|
4
8
|
// src/MemorySentinel.ts
|
|
5
9
|
import { fulfilled } from "@xylabs/promise";
|
|
@@ -67,10 +71,10 @@ var SentinelIntervalAutomationWrapper = class extends PayloadWrapper {
|
|
|
67
71
|
super(payload);
|
|
68
72
|
}
|
|
69
73
|
get frequencyMillis() {
|
|
70
|
-
const frequency = this.
|
|
74
|
+
const frequency = this.jsonPayload().frequency;
|
|
71
75
|
if (frequency === void 0)
|
|
72
76
|
return Infinity;
|
|
73
|
-
switch (this.
|
|
77
|
+
switch (this.jsonPayload().frequencyUnits ?? "hour") {
|
|
74
78
|
case "second":
|
|
75
79
|
return frequency * 1e3;
|
|
76
80
|
case "minute":
|
|
@@ -85,21 +89,21 @@ var SentinelIntervalAutomationWrapper = class extends PayloadWrapper {
|
|
|
85
89
|
return this.payload().remaining ?? Infinity;
|
|
86
90
|
}
|
|
87
91
|
next() {
|
|
88
|
-
this.
|
|
92
|
+
this.jsonPayload().start = this.jsonPayload().start + this.frequencyMillis;
|
|
89
93
|
this.consumeRemaining();
|
|
90
94
|
this.checkEnd();
|
|
91
95
|
return this;
|
|
92
96
|
}
|
|
93
97
|
checkEnd() {
|
|
94
|
-
if (this.
|
|
95
|
-
this.
|
|
98
|
+
if (this.jsonPayload().start > (this.jsonPayload().end ?? Infinity)) {
|
|
99
|
+
this.jsonPayload().start = Infinity;
|
|
96
100
|
}
|
|
97
101
|
}
|
|
98
102
|
consumeRemaining(count = 1) {
|
|
99
103
|
const remaining = this.remaining - count;
|
|
100
|
-
this.
|
|
104
|
+
this.jsonPayload().remaining = remaining;
|
|
101
105
|
if (remaining <= 0) {
|
|
102
|
-
this.
|
|
106
|
+
this.jsonPayload().start = Infinity;
|
|
103
107
|
}
|
|
104
108
|
}
|
|
105
109
|
};
|
|
@@ -122,9 +126,12 @@ var SentinelRunner = class {
|
|
|
122
126
|
}
|
|
123
127
|
get next() {
|
|
124
128
|
return Object.values(this._automations).reduce((previous, current) => {
|
|
125
|
-
if (current
|
|
126
|
-
|
|
129
|
+
if (isSentinelIntervalAutomation(current)) {
|
|
130
|
+
if (isSentinelIntervalAutomation(previous)) {
|
|
131
|
+
return current.start < ((previous == null ? void 0 : previous.start) ?? Infinity) ? current : previous;
|
|
132
|
+
}
|
|
127
133
|
}
|
|
134
|
+
return current;
|
|
128
135
|
}, void 0);
|
|
129
136
|
}
|
|
130
137
|
async add(automation, restart = true) {
|
|
@@ -153,7 +160,7 @@ var SentinelRunner = class {
|
|
|
153
160
|
async start() {
|
|
154
161
|
assertEx(this.timeoutId === void 0, "Already started");
|
|
155
162
|
const automation = this.next;
|
|
156
|
-
if (automation) {
|
|
163
|
+
if (isSentinelIntervalAutomation(automation)) {
|
|
157
164
|
const delay = automation.start - Date.now();
|
|
158
165
|
if (delay < 0) {
|
|
159
166
|
await this.trigger(automation);
|
|
@@ -185,7 +192,7 @@ var SentinelRunner = class {
|
|
|
185
192
|
const wrapper = new SentinelIntervalAutomationWrapper(automation);
|
|
186
193
|
await this.remove(await wrapper.hashAsync(), false);
|
|
187
194
|
wrapper.next();
|
|
188
|
-
await this.add(wrapper.
|
|
195
|
+
await this.add(wrapper.jsonPayload(), false);
|
|
189
196
|
const triggerResult = await this.sentinel.report();
|
|
190
197
|
(_a = this.onTriggerResult) == null ? void 0 : _a.call(this, triggerResult);
|
|
191
198
|
await this.start();
|
|
@@ -223,8 +230,11 @@ export * from "@xyo-network/sentinel-model";
|
|
|
223
230
|
export {
|
|
224
231
|
MemorySentinel,
|
|
225
232
|
SentinelAutomationSchema,
|
|
233
|
+
SentinelEventAutomationSchema,
|
|
234
|
+
SentinelIntervalAutomationSchema,
|
|
226
235
|
SentinelIntervalAutomationWrapper,
|
|
227
236
|
SentinelRunner,
|
|
228
|
-
SentinelWrapper
|
|
237
|
+
SentinelWrapper,
|
|
238
|
+
isSentinelIntervalAutomation
|
|
229
239
|
};
|
|
230
240
|
//# sourceMappingURL=index.mjs.map
|
package/dist/node/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/Automation.ts","../../src/MemorySentinel.ts","../../src/SentinelIntervalAutomationWrapper.ts","../../src/SentinelRunner.ts","../../src/Wrapper.ts","../../src/index.ts"],"sourcesContent":["import { AnyObject } from '@xyo-network/core'\nimport { Payload } from '@xyo-network/payload-model'\nimport { Task } from '@xyo-network/sentinel-model'\n\nexport type SentinelAutomationSchema = 'network.xyo.automation'\nexport const SentinelAutomationSchema: SentinelAutomationSchema = 'network.xyo.automation'\n\nexport type SentinelBaseAutomationPayload<T extends AnyObject = AnyObject> = Payload<\n T & {\n schema: SentinelAutomationSchema\n tasks?: Task[]\n type?: 'interval' | 'change'\n }\n>\n\nexport type SentinelIntervalAutomationPayload = SentinelBaseAutomationPayload<{\n /** @field epoch after which any reoccurrence stops */\n end?: number\n\n /** @field time between triggers [non-repeating if undefined] */\n frequency?: number\n\n /** @field units for frequency field [hour if undefined] */\n frequencyUnits?: 'second' | 'minute' | 'hour' | 'day'\n\n /** @field remaining triggers [infinite if undefined] */\n remaining?: number\n\n /** @field epoch of the next trigger */\n start: number\n\n type: 'interval'\n}>\n\nexport type SentinelChangeAutomationPayload = SentinelBaseAutomationPayload<{\n type: 'change'\n}>\n\nexport type SentinelAutomationPayload = SentinelIntervalAutomationPayload | SentinelChangeAutomationPayload\n","import { Address } from '@xylabs/hex'\nimport { fulfilled } from '@xylabs/promise'\nimport { asDivinerInstance } from '@xyo-network/diviner-model'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { Payload } from '@xyo-network/payload-model'\nimport { AbstractSentinel } from '@xyo-network/sentinel-abstract'\nimport {\n ResolvedTask,\n SentinelConfig,\n SentinelConfigSchema,\n SentinelInstance,\n SentinelModuleEventData,\n SentinelParams,\n} from '@xyo-network/sentinel-model'\nimport { asWitnessInstance } from '@xyo-network/witness-model'\n\nexport type MemorySentinelParams<TConfig extends AnyConfigSchema<SentinelConfig> = AnyConfigSchema<SentinelConfig>> = SentinelParams<TConfig>\n\nexport class MemorySentinel<\n TParams extends MemorySentinelParams = MemorySentinelParams,\n TEventData extends SentinelModuleEventData<SentinelInstance<TParams>> = SentinelModuleEventData<SentinelInstance<TParams>>,\n> extends AbstractSentinel<TParams, TEventData> {\n static override configSchemas = [SentinelConfigSchema]\n\n async reportHandler(inPayloads: Payload[] = []): Promise<Payload[]> {\n await this.started('throw')\n const job = await this.jobPromise\n\n let index = 0\n let previousResults: Record<Address, Payload[]> = {}\n while (index < job.tasks.length) {\n const generatedPayloads = await this.generateResults(job.tasks[index], previousResults, inPayloads)\n previousResults = generatedPayloads\n index++\n }\n return Object.values(previousResults).flat()\n }\n\n private async generateResults(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n const results: PromiseSettledResult<[Address, Payload[]]>[] = await Promise.allSettled(\n tasks?.map(async (task) => {\n const witness = asWitnessInstance(task.module)\n const input = task.input ?? false\n const inPayloadsFound =\n input === true ? inPayloads : input === false ? [] : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n if (witness) {\n return [witness.address, await witness.observe(inPayloadsFound)]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n return [diviner.address, await diviner.divine(inPayloadsFound)]\n }\n throw Error('Unsupported module type')\n }),\n )\n const finalResult: Record<Address, Payload[]> = {}\n results.filter(fulfilled).forEach((result) => {\n const [address, payloads] = result.value\n finalResult[address] = finalResult[address] ?? []\n finalResult[address].push(...payloads)\n })\n /*const errors = results.filter(rejected).map((result) => result.reason)\n if (errors.length > 0) {\n throw Error('At least one module failed')\n }*/\n return finalResult\n }\n\n private async inputAddresses(input: string | string[]): Promise<string[]> {\n if (Array.isArray(input)) {\n return (await Promise.all(input.map(async (inputItem) => await this.inputAddresses(inputItem)))).flat()\n } else {\n const resolved = await this.resolve(input)\n return resolved ? [resolved.address] : []\n }\n }\n\n private processPreviousResults(payloads: Record<string, Payload[]>, inputs: string[]) {\n return inputs.map((input) => payloads[input] ?? []).flat()\n }\n}\n","import { PayloadWrapper } from '@xyo-network/payload-wrapper'\n\nimport { SentinelIntervalAutomationPayload } from './Automation'\n\nexport class SentinelIntervalAutomationWrapper<\n T extends SentinelIntervalAutomationPayload = SentinelIntervalAutomationPayload,\n> extends PayloadWrapper<T> {\n constructor(payload: T) {\n super(payload)\n }\n\n protected get frequencyMillis() {\n const frequency = this.payload().frequency\n if (frequency === undefined) return Infinity\n switch (this.payload().frequencyUnits ?? 'hour') {\n case 'second':\n return frequency * 1000\n case 'minute':\n return frequency * 60 * 1000\n case 'hour':\n return frequency * 60 * 60 * 1000\n case 'day':\n return frequency * 24 * 60 * 60 * 1000\n }\n }\n\n protected get remaining() {\n //if remaining is not defined, we assume Infinity\n return this.payload().remaining ?? Infinity\n }\n\n next() {\n this.payload().start = this.payload().start + this.frequencyMillis\n this.consumeRemaining()\n this.checkEnd()\n return this\n }\n\n protected checkEnd() {\n if (this.payload().start > (this.payload().end ?? Infinity)) {\n this.payload().start = Infinity\n }\n }\n\n protected consumeRemaining(count = 1) {\n const remaining = this.remaining - count\n this.payload().remaining = remaining\n\n if (remaining <= 0) {\n this.payload().start = Infinity\n }\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Payload } from '@xyo-network/payload-model'\nimport { PayloadWrapper } from '@xyo-network/payload-wrapper'\nimport { SentinelInstance } from '@xyo-network/sentinel-model'\n\nimport { SentinelAutomationPayload, SentinelIntervalAutomationPayload } from './Automation'\nimport { SentinelIntervalAutomationWrapper } from './SentinelIntervalAutomationWrapper'\n\nexport type OnSentinelRunnerTriggerResult = (result: Payload[]) => void\n\nexport class SentinelRunner {\n protected _automations: Record<string, SentinelAutomationPayload> = {}\n protected onTriggerResult: OnSentinelRunnerTriggerResult | undefined\n protected sentinel: SentinelInstance\n protected timeoutId?: NodeJS.Timeout | string | number\n\n constructor(sentinel: SentinelInstance, automations?: SentinelAutomationPayload[], onTriggerResult?: OnSentinelRunnerTriggerResult) {\n this.sentinel = sentinel\n this.onTriggerResult = onTriggerResult\n automations?.forEach((automation) => this.add(automation))\n }\n\n get automations() {\n return this._automations\n }\n\n private get next() {\n return Object.values(this._automations).reduce<SentinelIntervalAutomationPayload | undefined>((previous, current) => {\n if (current.type === 'interval') {\n return current.start < (previous?.start ?? Infinity) ? current : previous\n }\n }, undefined)\n }\n\n async add(automation: SentinelAutomationPayload, restart = true) {\n const hash = await PayloadWrapper.hashAsync(automation)\n this._automations[hash] = automation\n if (restart) await this.restart()\n return hash\n }\n\n find(hash: string) {\n Object.entries(this._automations).find(([key]) => key === hash)\n }\n\n async remove(hash: string, restart = true) {\n delete this._automations[hash]\n if (restart) await this.restart()\n }\n\n removeAll() {\n this.stop()\n this._automations = {}\n }\n\n async restart() {\n this.stop()\n await this.start()\n }\n\n async start() {\n assertEx(this.timeoutId === undefined, 'Already started')\n const automation = this.next\n if (automation) {\n const delay = automation.start - Date.now()\n if (delay < 0) {\n //automation is due, just do it\n await this.trigger(automation)\n } else {\n this.timeoutId = setTimeout(\n async () => {\n this.timeoutId = undefined\n await this.start()\n },\n delay > 0 ? delay : 0,\n )\n }\n }\n }\n\n stop() {\n if (this.timeoutId) {\n clearTimeout(this.timeoutId)\n this.timeoutId = undefined\n }\n }\n\n async update(hash: string, automation: SentinelAutomationPayload, restart = true) {\n await this.remove(hash, false)\n await this.add(automation, false)\n if (restart) await this.restart()\n }\n\n private async trigger(automation: SentinelIntervalAutomationPayload) {\n const wrapper = new SentinelIntervalAutomationWrapper(automation)\n await this.remove(await wrapper.hashAsync(), false)\n wrapper.next()\n await this.add(wrapper.payload(), false)\n const triggerResult = await this.sentinel.report()\n this.onTriggerResult?.(triggerResult)\n await this.start()\n }\n}\n","import { ArchivistInstance } from '@xyo-network/archivist'\nimport { constructableModuleWrapper, ModuleWrapper } from '@xyo-network/module-wrapper'\nimport { Payload } from '@xyo-network/payload-model'\nimport {\n isSentinelInstance,\n isSentinelModule,\n SentinelInstance,\n SentinelModule,\n SentinelReportQuery,\n SentinelReportQuerySchema,\n} from '@xyo-network/sentinel-model'\nimport { WitnessInstance } from '@xyo-network/witness-model'\n\nconstructableModuleWrapper()\nexport class SentinelWrapper<TModule extends SentinelModule = SentinelModule>\n extends ModuleWrapper<TModule>\n implements SentinelInstance<TModule['params']>\n{\n static override instanceIdentityCheck = isSentinelInstance\n static override moduleIdentityCheck = isSentinelModule\n static override requiredQueries = [SentinelReportQuerySchema, ...super.requiredQueries]\n\n archivists(): Promise<ArchivistInstance[]> {\n throw Error('Not supported')\n }\n\n async report(payloads?: Payload[]): Promise<Payload[]> {\n const queryPayload: SentinelReportQuery = { schema: SentinelReportQuerySchema }\n const result = await this.sendQuery(queryPayload, payloads)\n return result\n }\n\n witnesses(): Promise<WitnessInstance[]> {\n throw Error('Not supported')\n }\n}\n","export * from './Automation'\nexport * from './MemorySentinel'\nexport * from './SentinelIntervalAutomationWrapper'\nexport * from './SentinelRunner'\nexport * from './Wrapper'\nexport * from '@xyo-network/sentinel-abstract'\nexport * from '@xyo-network/sentinel-model'\n"],"mappings":"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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 } from '@xylabs/promise'\nimport { asDivinerInstance } from '@xyo-network/diviner-model'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { Payload } from '@xyo-network/payload-model'\nimport { AbstractSentinel } from '@xyo-network/sentinel-abstract'\nimport {\n ResolvedTask,\n SentinelConfig,\n SentinelConfigSchema,\n SentinelInstance,\n SentinelModuleEventData,\n SentinelParams,\n} from '@xyo-network/sentinel-model'\nimport { asWitnessInstance } from '@xyo-network/witness-model'\n\nexport type MemorySentinelParams<TConfig extends AnyConfigSchema<SentinelConfig> = AnyConfigSchema<SentinelConfig>> = SentinelParams<TConfig>\n\nexport class MemorySentinel<\n TParams extends MemorySentinelParams = MemorySentinelParams,\n TEventData extends SentinelModuleEventData<SentinelInstance<TParams>> = SentinelModuleEventData<SentinelInstance<TParams>>,\n> extends AbstractSentinel<TParams, TEventData> {\n static override configSchemas = [SentinelConfigSchema]\n\n async reportHandler(inPayloads: Payload[] = []): Promise<Payload[]> {\n await this.started('throw')\n const job = await this.jobPromise\n\n let index = 0\n let previousResults: Record<Address, Payload[]> = {}\n while (index < job.tasks.length) {\n const generatedPayloads = await this.generateResults(job.tasks[index], previousResults, inPayloads)\n previousResults = generatedPayloads\n index++\n }\n return Object.values(previousResults).flat()\n }\n\n private async generateResults(\n tasks: ResolvedTask[],\n previousResults: Record<Address, Payload[]>,\n inPayloads?: Payload[],\n ): Promise<Record<Address, Payload[]>> {\n const results: PromiseSettledResult<[Address, Payload[]]>[] = await Promise.allSettled(\n tasks?.map(async (task) => {\n const witness = asWitnessInstance(task.module)\n const input = task.input ?? false\n const inPayloadsFound =\n input === true ? inPayloads : input === false ? [] : this.processPreviousResults(previousResults, await this.inputAddresses(input))\n if (witness) {\n return [witness.address, await witness.observe(inPayloadsFound)]\n }\n const diviner = asDivinerInstance(task.module)\n if (diviner) {\n return [diviner.address, await diviner.divine(inPayloadsFound)]\n }\n throw Error('Unsupported module type')\n }),\n )\n const finalResult: Record<Address, Payload[]> = {}\n results.filter(fulfilled).forEach((result) => {\n const [address, payloads] = result.value\n finalResult[address] = finalResult[address] ?? []\n finalResult[address].push(...payloads)\n })\n /*const errors = results.filter(rejected).map((result) => result.reason)\n if (errors.length > 0) {\n throw Error('At least one module failed')\n }*/\n return finalResult\n }\n\n private async inputAddresses(input: string | string[]): Promise<string[]> {\n if (Array.isArray(input)) {\n return (await Promise.all(input.map(async (inputItem) => await this.inputAddresses(inputItem)))).flat()\n } else {\n const resolved = await this.resolve(input)\n return resolved ? [resolved.address] : []\n }\n }\n\n private processPreviousResults(payloads: Record<string, Payload[]>, inputs: string[]) {\n return inputs.map((input) => payloads[input] ?? []).flat()\n }\n}\n","import { PayloadWrapper } from '@xyo-network/payload-wrapper'\n\nimport { SentinelIntervalAutomationPayload } from './Automation'\n\nexport class SentinelIntervalAutomationWrapper<\n T extends SentinelIntervalAutomationPayload = SentinelIntervalAutomationPayload,\n> extends PayloadWrapper<T> {\n constructor(payload: T) {\n super(payload)\n }\n\n protected get frequencyMillis() {\n const frequency = this.jsonPayload().frequency\n if (frequency === undefined) return Infinity\n switch (this.jsonPayload().frequencyUnits ?? 'hour') {\n case 'second':\n return frequency * 1000\n case 'minute':\n return frequency * 60 * 1000\n case 'hour':\n return frequency * 60 * 60 * 1000\n case 'day':\n return frequency * 24 * 60 * 60 * 1000\n }\n }\n\n protected get remaining() {\n //if remaining is not defined, we assume Infinity\n return this.payload().remaining ?? Infinity\n }\n\n next() {\n this.jsonPayload().start = this.jsonPayload().start + this.frequencyMillis\n this.consumeRemaining()\n this.checkEnd()\n return this\n }\n\n protected checkEnd() {\n if (this.jsonPayload().start > (this.jsonPayload().end ?? Infinity)) {\n this.jsonPayload().start = Infinity\n }\n }\n\n protected consumeRemaining(count = 1) {\n const remaining = this.remaining - count\n this.jsonPayload().remaining = remaining\n\n if (remaining <= 0) {\n this.jsonPayload().start = Infinity\n }\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Payload } from '@xyo-network/payload-model'\nimport { PayloadWrapper } from '@xyo-network/payload-wrapper'\nimport { SentinelInstance } from '@xyo-network/sentinel-model'\n\nimport { isSentinelIntervalAutomation, SentinelAutomationPayload, SentinelIntervalAutomationPayload } from './Automation'\nimport { SentinelIntervalAutomationWrapper } from './SentinelIntervalAutomationWrapper'\n\nexport type OnSentinelRunnerTriggerResult = (result: Payload[]) => void\n\nexport class SentinelRunner {\n protected _automations: Record<string, SentinelAutomationPayload> = {}\n protected onTriggerResult: OnSentinelRunnerTriggerResult | undefined\n protected sentinel: SentinelInstance\n protected timeoutId?: NodeJS.Timeout | string | number\n\n constructor(sentinel: SentinelInstance, automations?: SentinelAutomationPayload[], onTriggerResult?: OnSentinelRunnerTriggerResult) {\n this.sentinel = sentinel\n this.onTriggerResult = onTriggerResult\n automations?.forEach((automation) => this.add(automation))\n }\n\n get automations() {\n return this._automations\n }\n\n private get next() {\n return Object.values(this._automations).reduce<SentinelAutomationPayload | undefined>((previous, current) => {\n if (isSentinelIntervalAutomation(current)) {\n if (isSentinelIntervalAutomation(previous)) {\n return current.start < (previous?.start ?? Infinity) ? current : previous\n }\n }\n return current\n }, undefined)\n }\n\n async add(automation: SentinelAutomationPayload, restart = true) {\n const hash = await PayloadWrapper.hashAsync(automation)\n this._automations[hash] = automation\n if (restart) await this.restart()\n return hash\n }\n\n find(hash: string) {\n Object.entries(this._automations).find(([key]) => key === hash)\n }\n\n async remove(hash: string, restart = true) {\n delete this._automations[hash]\n if (restart) await this.restart()\n }\n\n removeAll() {\n this.stop()\n this._automations = {}\n }\n\n async restart() {\n this.stop()\n await this.start()\n }\n\n async start() {\n assertEx(this.timeoutId === undefined, 'Already started')\n const automation = this.next\n if (isSentinelIntervalAutomation(automation)) {\n const delay = automation.start - Date.now()\n if (delay < 0) {\n //automation is due, just do it\n await this.trigger(automation)\n } else {\n this.timeoutId = setTimeout(\n async () => {\n this.timeoutId = undefined\n await this.start()\n },\n delay > 0 ? delay : 0,\n )\n }\n }\n }\n\n stop() {\n if (this.timeoutId) {\n clearTimeout(this.timeoutId)\n this.timeoutId = undefined\n }\n }\n\n async update(hash: string, automation: SentinelAutomationPayload, restart = true) {\n await this.remove(hash, false)\n await this.add(automation, false)\n if (restart) await this.restart()\n }\n\n private async trigger(automation: SentinelIntervalAutomationPayload) {\n const wrapper = new SentinelIntervalAutomationWrapper(automation)\n await this.remove(await wrapper.hashAsync(), false)\n wrapper.next()\n await this.add(wrapper.jsonPayload(), false)\n const triggerResult = await this.sentinel.report()\n this.onTriggerResult?.(triggerResult)\n await this.start()\n }\n}\n","import { ArchivistInstance } from '@xyo-network/archivist'\nimport { constructableModuleWrapper, ModuleWrapper } from '@xyo-network/module-wrapper'\nimport { Payload } from '@xyo-network/payload-model'\nimport {\n isSentinelInstance,\n isSentinelModule,\n SentinelInstance,\n SentinelModule,\n SentinelReportQuery,\n SentinelReportQuerySchema,\n} from '@xyo-network/sentinel-model'\nimport { WitnessInstance } from '@xyo-network/witness-model'\n\nconstructableModuleWrapper()\nexport class SentinelWrapper<TModule extends SentinelModule = SentinelModule>\n extends ModuleWrapper<TModule>\n implements SentinelInstance<TModule['params']>\n{\n static override instanceIdentityCheck = isSentinelInstance\n static override moduleIdentityCheck = isSentinelModule\n static override requiredQueries = [SentinelReportQuerySchema, ...super.requiredQueries]\n\n archivists(): Promise<ArchivistInstance[]> {\n throw Error('Not supported')\n }\n\n async report(payloads?: Payload[]): Promise<Payload[]> {\n const queryPayload: SentinelReportQuery = { schema: SentinelReportQuerySchema }\n const result = await this.sendQuery(queryPayload, payloads)\n return result\n }\n\n witnesses(): Promise<WitnessInstance[]> {\n throw Error('Not supported')\n }\n}\n","export * from './Automation'\nexport * from './MemorySentinel'\nexport * from './SentinelIntervalAutomationWrapper'\nexport * from './SentinelRunner'\nexport * from './Wrapper'\nexport * from '@xyo-network/sentinel-abstract'\nexport * from '@xyo-network/sentinel-model'\n"],"mappings":"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","names":["PayloadWrapper","PayloadWrapper"]}
|
package/package.json
CHANGED
|
@@ -10,33 +10,33 @@
|
|
|
10
10
|
"url": "https://github.com/XYOracleNetwork/sdk-xyo-client-js/issues"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@xylabs/assert": "^2.13.
|
|
14
|
-
"@xylabs/hex": "^2.13.
|
|
15
|
-
"@xylabs/promise": "^2.13.
|
|
16
|
-
"@xyo-network/archivist": "~2.
|
|
17
|
-
"@xyo-network/
|
|
18
|
-
"@xyo-network/
|
|
19
|
-
"@xyo-network/module-
|
|
20
|
-
"@xyo-network/
|
|
21
|
-
"@xyo-network/payload-
|
|
22
|
-
"@xyo-network/
|
|
23
|
-
"@xyo-network/sentinel-
|
|
24
|
-
"@xyo-network/
|
|
25
|
-
"@xyo-network/witness-model": "~2.82.0-rc.1"
|
|
13
|
+
"@xylabs/assert": "^2.13.20",
|
|
14
|
+
"@xylabs/hex": "^2.13.20",
|
|
15
|
+
"@xylabs/promise": "^2.13.20",
|
|
16
|
+
"@xyo-network/archivist": "~2.83.0",
|
|
17
|
+
"@xyo-network/diviner-model": "~2.83.0",
|
|
18
|
+
"@xyo-network/module-model": "~2.83.0",
|
|
19
|
+
"@xyo-network/module-wrapper": "~2.83.0",
|
|
20
|
+
"@xyo-network/payload-model": "~2.83.0",
|
|
21
|
+
"@xyo-network/payload-wrapper": "~2.83.0",
|
|
22
|
+
"@xyo-network/sentinel-abstract": "~2.83.0",
|
|
23
|
+
"@xyo-network/sentinel-model": "~2.83.0",
|
|
24
|
+
"@xyo-network/witness-model": "~2.83.0"
|
|
26
25
|
},
|
|
27
26
|
"description": "Primary SDK for using XYO Protocol 2.0",
|
|
28
27
|
"devDependencies": {
|
|
29
|
-
"@xylabs/delay": "^2.13.
|
|
28
|
+
"@xylabs/delay": "^2.13.20",
|
|
30
29
|
"@xylabs/ts-scripts-yarn3": "^3.2.10",
|
|
31
30
|
"@xylabs/tsconfig": "^3.2.10",
|
|
32
|
-
"@xyo-network/abstract-witness": "~2.
|
|
33
|
-
"@xyo-network/account": "~2.
|
|
34
|
-
"@xyo-network/boundwitness-model": "~2.
|
|
35
|
-
"@xyo-network/
|
|
36
|
-
"@xyo-network/id-plugin": "^2.
|
|
37
|
-
"@xyo-network/
|
|
38
|
-
"@xyo-network/node-
|
|
39
|
-
"@xyo-network/
|
|
31
|
+
"@xyo-network/abstract-witness": "~2.83.0",
|
|
32
|
+
"@xyo-network/account": "~2.83.0",
|
|
33
|
+
"@xyo-network/boundwitness-model": "~2.83.0",
|
|
34
|
+
"@xyo-network/hash": "~2.83.0",
|
|
35
|
+
"@xyo-network/id-payload-plugin": "^2.82.2",
|
|
36
|
+
"@xyo-network/id-plugin": "^2.82.2",
|
|
37
|
+
"@xyo-network/node-memory": "~2.83.0",
|
|
38
|
+
"@xyo-network/node-system-info-plugin": "^2.82.2",
|
|
39
|
+
"@xyo-network/witnesses": "~2.83.0",
|
|
40
40
|
"typescript": "^5.3.2"
|
|
41
41
|
},
|
|
42
42
|
"docs": "dist/docs.json",
|
|
@@ -78,6 +78,5 @@
|
|
|
78
78
|
"url": "https://github.com/XYOracleNetwork/sdk-xyo-client-js.git"
|
|
79
79
|
},
|
|
80
80
|
"sideEffects": false,
|
|
81
|
-
"version": "2.
|
|
82
|
-
"stableVersion": "2.81.7"
|
|
81
|
+
"version": "2.83.0"
|
|
83
82
|
}
|
package/src/Automation.ts
CHANGED
|
@@ -1,39 +1,55 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Payload } from '@xyo-network/payload-model'
|
|
1
|
+
import { isPayloadOfSchemaType, Payload } from '@xyo-network/payload-model'
|
|
3
2
|
import { Task } from '@xyo-network/sentinel-model'
|
|
4
3
|
|
|
5
4
|
export type SentinelAutomationSchema = 'network.xyo.automation'
|
|
6
5
|
export const SentinelAutomationSchema: SentinelAutomationSchema = 'network.xyo.automation'
|
|
7
6
|
|
|
8
|
-
export type
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
export type SentinelIntervalAutomationSchema = 'network.xyo.automation.interval'
|
|
8
|
+
export const SentinelIntervalAutomationSchema: SentinelIntervalAutomationSchema = 'network.xyo.automation.interval'
|
|
9
|
+
|
|
10
|
+
export type SentinelEventAutomationSchema = 'network.xyo.automation.event'
|
|
11
|
+
export const SentinelEventAutomationSchema: SentinelEventAutomationSchema = 'network.xyo.automation.event'
|
|
12
|
+
|
|
13
|
+
export type SentinelBaseAutomationPayload<T extends Payload> = Payload<
|
|
14
|
+
{
|
|
11
15
|
tasks?: Task[]
|
|
12
|
-
type?: 'interval' | '
|
|
13
|
-
}
|
|
16
|
+
type?: 'interval' | 'event'
|
|
17
|
+
} & T
|
|
14
18
|
>
|
|
15
19
|
|
|
20
|
+
/** Settings for an Interval Automation */
|
|
16
21
|
export type SentinelIntervalAutomationPayload = SentinelBaseAutomationPayload<{
|
|
17
|
-
/**
|
|
22
|
+
/** Epoch after which any reoccurrence stops */
|
|
18
23
|
end?: number
|
|
19
24
|
|
|
20
|
-
/**
|
|
25
|
+
/** Time between triggers [non-repeating if undefined] */
|
|
21
26
|
frequency?: number
|
|
22
27
|
|
|
23
|
-
/**
|
|
28
|
+
/** Units for frequency field [hour if undefined] */
|
|
24
29
|
frequencyUnits?: 'second' | 'minute' | 'hour' | 'day'
|
|
25
30
|
|
|
26
|
-
/**
|
|
31
|
+
/** Remaining triggers [infinite if undefined] */
|
|
27
32
|
remaining?: number
|
|
28
33
|
|
|
29
|
-
|
|
34
|
+
schema: SentinelIntervalAutomationSchema
|
|
35
|
+
|
|
36
|
+
/** Epoch of the next trigger */
|
|
30
37
|
start: number
|
|
31
38
|
|
|
39
|
+
/** The type of automation */
|
|
32
40
|
type: 'interval'
|
|
33
41
|
}>
|
|
34
42
|
|
|
35
|
-
export
|
|
36
|
-
|
|
43
|
+
export const isSentinelIntervalAutomation = isPayloadOfSchemaType<SentinelIntervalAutomationPayload>(SentinelIntervalAutomationSchema)
|
|
44
|
+
|
|
45
|
+
/** Settings for an Event Automation */
|
|
46
|
+
export type SentinelEventAutomationPayload = SentinelBaseAutomationPayload<{
|
|
47
|
+
schema: SentinelEventAutomationSchema
|
|
48
|
+
type: 'event'
|
|
37
49
|
}>
|
|
38
50
|
|
|
39
|
-
|
|
51
|
+
/** Settings for an Automation */
|
|
52
|
+
export type SentinelAutomationPayload = Payload<
|
|
53
|
+
SentinelIntervalAutomationPayload | SentinelEventAutomationPayload,
|
|
54
|
+
SentinelAutomationSchema | SentinelIntervalAutomationSchema | SentinelEventAutomationSchema
|
|
55
|
+
>
|
|
@@ -10,9 +10,9 @@ export class SentinelIntervalAutomationWrapper<
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
protected get frequencyMillis() {
|
|
13
|
-
const frequency = this.
|
|
13
|
+
const frequency = this.jsonPayload().frequency
|
|
14
14
|
if (frequency === undefined) return Infinity
|
|
15
|
-
switch (this.
|
|
15
|
+
switch (this.jsonPayload().frequencyUnits ?? 'hour') {
|
|
16
16
|
case 'second':
|
|
17
17
|
return frequency * 1000
|
|
18
18
|
case 'minute':
|
|
@@ -30,24 +30,24 @@ export class SentinelIntervalAutomationWrapper<
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
next() {
|
|
33
|
-
this.
|
|
33
|
+
this.jsonPayload().start = this.jsonPayload().start + this.frequencyMillis
|
|
34
34
|
this.consumeRemaining()
|
|
35
35
|
this.checkEnd()
|
|
36
36
|
return this
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
protected checkEnd() {
|
|
40
|
-
if (this.
|
|
41
|
-
this.
|
|
40
|
+
if (this.jsonPayload().start > (this.jsonPayload().end ?? Infinity)) {
|
|
41
|
+
this.jsonPayload().start = Infinity
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
protected consumeRemaining(count = 1) {
|
|
46
46
|
const remaining = this.remaining - count
|
|
47
|
-
this.
|
|
47
|
+
this.jsonPayload().remaining = remaining
|
|
48
48
|
|
|
49
49
|
if (remaining <= 0) {
|
|
50
|
-
this.
|
|
50
|
+
this.jsonPayload().start = Infinity
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
}
|
package/src/SentinelRunner.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Payload } from '@xyo-network/payload-model'
|
|
|
3
3
|
import { PayloadWrapper } from '@xyo-network/payload-wrapper'
|
|
4
4
|
import { SentinelInstance } from '@xyo-network/sentinel-model'
|
|
5
5
|
|
|
6
|
-
import { SentinelAutomationPayload, SentinelIntervalAutomationPayload } from './Automation'
|
|
6
|
+
import { isSentinelIntervalAutomation, SentinelAutomationPayload, SentinelIntervalAutomationPayload } from './Automation'
|
|
7
7
|
import { SentinelIntervalAutomationWrapper } from './SentinelIntervalAutomationWrapper'
|
|
8
8
|
|
|
9
9
|
export type OnSentinelRunnerTriggerResult = (result: Payload[]) => void
|
|
@@ -25,10 +25,13 @@ export class SentinelRunner {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
private get next() {
|
|
28
|
-
return Object.values(this._automations).reduce<
|
|
29
|
-
if (current
|
|
30
|
-
|
|
28
|
+
return Object.values(this._automations).reduce<SentinelAutomationPayload | undefined>((previous, current) => {
|
|
29
|
+
if (isSentinelIntervalAutomation(current)) {
|
|
30
|
+
if (isSentinelIntervalAutomation(previous)) {
|
|
31
|
+
return current.start < (previous?.start ?? Infinity) ? current : previous
|
|
32
|
+
}
|
|
31
33
|
}
|
|
34
|
+
return current
|
|
32
35
|
}, undefined)
|
|
33
36
|
}
|
|
34
37
|
|
|
@@ -61,7 +64,7 @@ export class SentinelRunner {
|
|
|
61
64
|
async start() {
|
|
62
65
|
assertEx(this.timeoutId === undefined, 'Already started')
|
|
63
66
|
const automation = this.next
|
|
64
|
-
if (automation) {
|
|
67
|
+
if (isSentinelIntervalAutomation(automation)) {
|
|
65
68
|
const delay = automation.start - Date.now()
|
|
66
69
|
if (delay < 0) {
|
|
67
70
|
//automation is due, just do it
|
|
@@ -95,7 +98,7 @@ export class SentinelRunner {
|
|
|
95
98
|
const wrapper = new SentinelIntervalAutomationWrapper(automation)
|
|
96
99
|
await this.remove(await wrapper.hashAsync(), false)
|
|
97
100
|
wrapper.next()
|
|
98
|
-
await this.add(wrapper.
|
|
101
|
+
await this.add(wrapper.jsonPayload(), false)
|
|
99
102
|
const triggerResult = await this.sentinel.report()
|
|
100
103
|
this.onTriggerResult?.(triggerResult)
|
|
101
104
|
await this.start()
|
package/typedoc.json
CHANGED