Files
apps.apple.com/node_modules/@jet/environment/dispatching/base/dispatcher.js
2025-11-04 05:03:50 +08:00

97 lines
4.3 KiB
JavaScript

"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