mirror of
https://github.com/rxliuli/apps.apple.com.git
synced 2025-11-09 22:00:32 +00:00
97 lines
4.3 KiB
JavaScript
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
|