summaryrefslogtreecommitdiff
path: root/node_modules/@jet/environment/dispatching/base/dispatcher.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/@jet/environment/dispatching/base/dispatcher.js')
-rw-r--r--node_modules/@jet/environment/dispatching/base/dispatcher.js97
1 files changed, 97 insertions, 0 deletions
diff --git a/node_modules/@jet/environment/dispatching/base/dispatcher.js b/node_modules/@jet/environment/dispatching/base/dispatcher.js
new file mode 100644
index 0000000..1b1e62d
--- /dev/null
+++ b/node_modules/@jet/environment/dispatching/base/dispatcher.js
@@ -0,0 +1,97 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.IntentDispatcher = void 0;
+const optional_1 = require("../../types/optional");
+const intent_controller_1 = require("./intent-controller");
+const net_1 = require("../../types/globals/net");
+const types_1 = require("../../types/globals/types");
+/**
+ * A dispatcher is responsible for taking an intent and invoking the controller
+ * registered to handle the intent's kind.
+ *
+ * Adopters can create a project specific dispatcher that composes `IntentDispatcher`
+ * to add additional functionality.
+ *
+ * @example
+ * ```
+ * const intent: SomeIntent = {
+ * $kind: "SomeIntent",
+ * field: "some value"
+ * };
+ * const dispatcher = new IntentDispatcher();
+ * const promise = dispatcher.dispatch(intent)
+ * ```
+ */
+class IntentDispatcher {
+ constructor() {
+ this.dispatchableMap = {};
+ }
+ /**
+ * Registers a controller to handle the intent specified in the `$intentKind` property.
+ * Only one controller can be registered per intent. If register is called multiple times
+ * with controllers for the same intent kind, the dispatcher will use the last registered
+ * controller.
+ * @param intentController - The controller to register.
+ */
+ register(dispatchable) {
+ if ((0, optional_1.isNothing)(dispatchable.$intentKind)) {
+ throw new Error(`Dispatcher cannot register a controller without an $intentKind`);
+ }
+ if (dispatchable.$intentKind in this.dispatchableMap) {
+ throw new Error(`Dispatcher already has a controller registered for ${dispatchable.$intentKind}`);
+ }
+ this.dispatchableMap[dispatchable.$intentKind] = dispatchable;
+ }
+ /**
+ * Performs an intent using the controller registered to handle the provided intent.
+ * Returns a rejected promise if no controller is registered to handle the intent.
+ * @param intent - The intent to perform.
+ * @param objectGraph - An object graph for dependency injection.
+ */
+ async dispatch(intent, objectGraph) {
+ if (intent.$kind === "$static") {
+ // MAINTAINER'S NOTE: We specially handle static intents here to cover two cases:
+ // 1) static intents created and dispatched wholly inside an app's
+ // JavaScript business layer;
+ // 2) static intents created from JavaScript running on an older
+ // version of native JetEngine that does not support static intents
+ // where the intent is boxed in an opaque intent in the platform layer.
+ // Static intents are normally not dispatched across an app's layers.
+ const data = Reflect.get(intent, "$data");
+ if ((0, optional_1.isNothing)(data)) {
+ throw new Error("StaticIntent<R> contains no data");
+ }
+ return data;
+ }
+ const controller = this.dispatchableMap[intent.$kind];
+ if ((0, optional_1.isNothing)(controller) || !(0, intent_controller_1.isIntentController)(controller)) {
+ throw new Error(`No controller registered to handle ${intent.$kind}`);
+ }
+ // Replace the `net` dependency with a proxy which includes instrumentation.
+ const pageIntentInstrumentation = intent.$pageIntentInstrumentation;
+ const network = objectGraph.optional(types_1.net);
+ if ((0, optional_1.isSome)(pageIntentInstrumentation) && (0, optional_1.isSome)(network)) {
+ const proxiedNetwork = new net_1.ProxiedNetwork(network, pageIntentInstrumentation);
+ const modifiedObjectGraph = objectGraph.adding(types_1.net, proxiedNetwork);
+ return await controller.perform(intent, modifiedObjectGraph);
+ }
+ else {
+ return await controller.perform(intent, objectGraph);
+ }
+ }
+ /**
+ * Returns the controller registered for the provided intent.
+ * @param intent - An intent to find the controller for.
+ */
+ controller(intent) {
+ return this.dispatchableMap[intent.$kind];
+ }
+ /**
+ * An array of all registered controllers.
+ */
+ get registeredControllers() {
+ return Object.values(this.dispatchableMap);
+ }
+}
+exports.IntentDispatcher = IntentDispatcher;
+//# sourceMappingURL=dispatcher.js.map \ No newline at end of file