UNPKG

@comunica/core

Version:

Lightweight, semantic and modular actor framework

1 lines 8.16 kB
{"version":3,"file":"Mediator.js","sourceRoot":"","sources":["Mediator.ts"],"names":[],"mappings":";;;AAIA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAsB,QAAQ;IAU5B;;;;;;;;;OASG;IACH,YAAsB,IAAmC;QACvD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED;;;;;;;;;OASG;IACI,OAAO,CAAC,MAAS;QACtB,6BAA6B;QAC7B,MAAM,MAAM,GAAkC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACvE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,uDAAuD,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1F,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;;OAQG;IACI,KAAK,CAAC,YAAY,CAAC,MAAS;QACjC,2CAA2C;QAC3C,OAAO,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED;;;;;;;;;OASG;IACI,KAAK,CAAC,eAAe,CAAC,MAAS;QACpC,gDAAgD;QAChD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QACpD,OAAO,WAAW,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC1F,CAAC;IAED;;;;;;;;;OASG;IACI,KAAK,CAAC,OAAO,CAAC,MAAS;QAC5B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QACpD,OAAO,QAAQ,CAAC,UAAU,EAAE,CAAC;IAC/B,CAAC;IAeD;;;;;OAKG;IACO,uBAAuB,CAAC,MAAS,EAAE,aAAuB;QAClE,MAAM,MAAM,GAAG,YAAY,CAAC;QAC5B,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW;aACrC,UAAU,CAAC,eAAe,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,QAAQ;aAClD,cAAc,CAAC,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC;QAC1D,OAAO,GAAG,WAAW,0CAA0C,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;IACvG,CAAC;IAES,MAAM,CAAC,cAAc,CAAC,GAAQ,EAAE,IAAc;QACtD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,GAAG,CAAC;QACb,CAAC;QACD,IAAI,GAAG,EAAE,CAAC;YACR,OAAO,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;CACF;AA5HD,4BA4HC","sourcesContent":["import type { Actor, IAction, IActorOutput, IActorTest } from './Actor';\nimport type { Bus, IActorReply } from './Bus';\nimport type { TestResult } from './TestResult';\n\n/**\n * A mediator can mediate an action over a bus of actors.\n *\n * It does the following:\n * 1. Accepts an action in {@link Mediator#mediate}.\n * 2. Sends the action to the bus to test its applicability on all actors.\n * 3. It _mediates_ over these test results.\n * 4. It selects the _best_ actor.\n * 5. The action is run by the _best_ actor, and the result if returned.\n *\n * The _mediates_ and _best_ parts are filled in by subclasses of this abstract Mediator class.\n *\n * @template A The type of actor to mediator over.\n * @template I The input type of an actor.\n * @template T The test type of an actor.\n * @template O The output type of an actor.\n */\nexport abstract class Mediator<\n A extends Actor<I, T, O, TS>,\nI extends IAction,\nT extends IActorTest,\nO extends IActorOutput,\nTS = undefined,\n> implements IMediatorArgs<A, I, T, O, TS> {\n public readonly name: string;\n public readonly bus: Bus<A, I, T, O, TS>;\n\n /**\n * All enumerable properties from the `args` object are inherited to this mediator.\n *\n * @param {IMediatorArgs<A extends Actor<I, T, O>, I extends IAction, T extends IActorTest,\n * O extends IActorOutput>} args Arguments object\n * @param {string} args.name The name for this mediator.\n * @param {Bus<A extends Actor<I, T, O>, I extends IAction, T extends IActorTest, O extends IActorOutput>} args.bus\n * The bus this mediator will mediate over.\n * @throws When required arguments are missing.\n */\n protected constructor(args: IMediatorArgs<A, I, T, O, TS>) {\n Object.assign(this, args);\n }\n\n /**\n * Publish the given action in the bus.\n *\n * This will send the test action on all actors in the bus.\n * All actor replies will be returned.\n *\n * @param {I} action The action to mediate for.\n * @return {IActorReply<A extends Actor<I, T, O>, I extends IAction, T extends IActorTest, O extends IActorOutput>[]}\n * The list of actor replies.\n */\n public publish(action: I): IActorReply<A, I, T, O, TS>[] {\n // Test all actors in the bus\n const actors: IActorReply<A, I, T, O, TS>[] = this.bus.publish(action);\n if (actors.length === 0) {\n throw new Error(`No actors are able to reply to a message in the bus ${this.bus.name}`);\n }\n return actors;\n }\n\n /**\n * Mediate for the given action to get an actor.\n *\n * This will send the test action on all actors in the bus.\n * The actor that tests _best_ will be returned.\n *\n * @param {I} action The action to mediate for.\n * @return {Promise<O extends IActorOutput>} A promise that resolves to the _best_ actor.\n */\n public async mediateActor(action: I): Promise<TestResult<A, TS>> {\n // Mediate to one actor and run that actor.\n return await this.mediateWith(action, this.publish(action));\n }\n\n /**\n * Mediate for the given action.\n *\n * This will send the test action on all actors in the bus.\n * The action will be run on the actor that tests _best_,\n * of which the result will be returned.\n *\n * @param {I} action The action to mediate for.\n * @return {Promise<O extends IActorOutput>} A promise that resolves to the mediation result.\n */\n public async mediateTestable(action: I): Promise<TestResult<O, TS>> {\n // Mediate to one actor and run the action on it\n const actorResult = await this.mediateActor(action);\n return actorResult.mapAsync((actor, sideData) => actor.runObservable(action, sideData));\n }\n\n /**\n * Mediate for the given action.\n *\n * This will send the test action on all actors in the bus.\n * The action will be run on the actor that tests _best_,\n * of which the result will be returned.\n *\n * @param {I} action The action to mediate for.\n * @return {Promise<O extends IActorOutput>} A promise that resolves to the mediation result.\n */\n public async mediate(action: I): Promise<O> {\n const testable = await this.mediateTestable(action);\n return testable.getOrThrow();\n }\n\n /**\n * Mediate for the given action with the given actor test results for the action.\n *\n * One actor must be returned that provided the _best_ test result.\n * How '_best_' is interpreted, depends on the implementation of the Mediator.\n *\n * @param {I} action The action to mediate for.\n * @param {IActorReply<A extends Actor<I, T, O>, I extends IAction, T extends IActorTest,\n * O extends IActorOutput>[]} testResults The actor test results for the action.\n * @return {Promise<A extends Actor<I, T, O>>} A promise that resolves to the _best_ actor.\n */\n protected abstract mediateWith(action: I, testResults: IActorReply<A, I, T, O, TS>[]): Promise<TestResult<A, TS>>;\n\n /**\n * Construct a human-friendly failure message that accumulates the given actors's failure messages.\n * @param action The action that was executed.\n * @param actorFailures The failure messages that were collected from actor tests based on the given executed action.\n * @protected\n */\n protected constructFailureMessage(action: I, actorFailures: string[]): string {\n const prefix = `\\n `;\n const failMessage = this.bus.failMessage\n .replaceAll(/\\$\\{(.*?)\\}/gu, (match, key) => Mediator\n .getObjectValue({ action }, key.split('.')) || match);\n return `${failMessage}\\n Error messages of failing actors:${prefix}${actorFailures.join(prefix)}`;\n }\n\n protected static getObjectValue(obj: any, path: string[]): any {\n if (path.length === 0) {\n return obj;\n }\n if (obj) {\n return Mediator.getObjectValue(obj[path[0]], path.slice(1));\n }\n return undefined;\n }\n}\n\nexport interface IMediatorArgs<\n A extends Actor<I, T, O, TS>,\nI extends IAction,\nT extends IActorTest,\nO extends IActorOutput,\nTS = undefined,\n> {\n /**\n * The name for this mediator.\n * @default {<rdf:subject>}\n */\n name: string;\n /**\n * The bus this mediator will mediate over.\n */\n bus: Bus<A, I, T, O, TS>;\n}\n\nexport type Mediate<I extends IAction, O extends IActorOutput, T extends IActorTest = IActorTest, TS = undefined> =\nMediator<Actor<I, T, O, TS>, I, T, O, TS>;\n"]}