UNPKG

7.16 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.Plugin = void 0;
4const tslib_1 = require("tslib");
5const plugin_utils_1 = require("@remixproject/plugin-utils");
6class Plugin {
7 constructor(profile) {
8 this.profile = profile;
9 this.activateService = {};
10 this.requestQueue = [];
11 this.options = {};
12 }
13 get name() {
14 return this.profile.name;
15 }
16 get methods() {
17 return this.profile.methods;
18 }
19 set methods(methods) {
20 this.profile.methods = methods;
21 }
22 activate() {
23 if (this.onActivation)
24 this.onActivation();
25 }
26 deactivate() {
27 if (this.onDeactivation)
28 this.onDeactivation();
29 }
30 setOptions(options = {}) {
31 this.options = Object.assign(Object.assign({}, this.options), options);
32 }
33 /** Call a method from this plugin */
34 callPluginMethod(key, args) {
35 var _a;
36 const path = (_a = this.currentRequest) === null || _a === void 0 ? void 0 : _a.path;
37 const method = plugin_utils_1.getMethodPath(key, path);
38 if (!(method in this)) {
39 throw new Error(`Method ${method} is not implemented by ${this.profile.name}`);
40 }
41 return this[method](...args);
42 }
43 /** Add a request to the list of current requests */
44 addRequest(request, method, args) {
45 return new Promise((resolve, reject) => {
46 // Add a new request to the queue
47 this.requestQueue.push(() => tslib_1.__awaiter(this, void 0, void 0, function* () {
48 this.currentRequest = request;
49 let timedout = false;
50 const letcontinue = () => {
51 if (timedout) {
52 const { from } = this.currentRequest;
53 const params = args.map(arg => JSON.stringify(arg)).join(', ');
54 const error = `[TIMED OUT]: Call to method "${method}" from "${from}" to plugin "${this.profile.name}" has timed out with arguments ${params}."`;
55 reject(error);
56 }
57 // Remove current request and call next
58 delete this.currentRequest;
59 this.requestQueue.shift();
60 if (this.requestQueue.length !== 0)
61 this.requestQueue[0]();
62 };
63 const ref = setTimeout(() => {
64 timedout = true;
65 letcontinue();
66 }, this.options.queueTimeout || 10000);
67 try {
68 const result = yield this.callPluginMethod(method, args);
69 delete this.currentRequest;
70 if (timedout)
71 return;
72 resolve(result);
73 }
74 catch (err) {
75 delete this.currentRequest;
76 reject(err);
77 }
78 clearTimeout(ref);
79 letcontinue();
80 }));
81 // If there is only one request waiting, call it
82 if (this.requestQueue.length === 1) {
83 this.requestQueue[0]();
84 }
85 });
86 }
87 /**
88 * Ask the plugin manager if current request can call a specific method
89 * @param method The method to call
90 * @param message An optional message to show to the user
91 */
92 askUserPermission(method, message) {
93 // Internal call
94 if (!this.currentRequest) {
95 return Promise.resolve(true);
96 }
97 // External call
98 if (this.methods.includes(method)) {
99 const from = this.currentRequest.from;
100 const to = this.name;
101 return this.call('manager', 'canCall', from, to, method, message);
102 }
103 else {
104 return Promise.resolve(false);
105 }
106 }
107 /**
108 * Called by the engine when a plugin try to activate it
109 * @param from the profile of the plugin activating this plugin
110 * @param method method used to activate this plugin if any
111 */
112 canActivate(from, method) {
113 return tslib_1.__awaiter(this, void 0, void 0, function* () {
114 return true;
115 });
116 }
117 /**
118 * Called by the engine when a plugin try to deactivate it
119 * @param from the profile of the plugin deactivating this plugin
120 */
121 canDeactivate(from) {
122 return tslib_1.__awaiter(this, void 0, void 0, function* () {
123 return true;
124 });
125 }
126 /////////////
127 // SERVICE //
128 /////////////
129 /**
130 * Create a service under the client node
131 * @param name The name of the service
132 * @param service The service
133 */
134 createService(name, service) {
135 return tslib_1.__awaiter(this, void 0, void 0, function* () {
136 if (this.methods && this.methods.includes(name)) {
137 throw new Error('A service cannot have the same name as an exposed method');
138 }
139 const _service = plugin_utils_1.createService(name, service);
140 yield plugin_utils_1.activateService(this, _service);
141 return _service;
142 });
143 }
144 /**
145 * Prepare a service to be lazy loaded
146 * @param name The name of the subservice inside this service
147 * @param factory A function to create the service on demand
148 */
149 prepareService(name, factory) {
150 return this.activateService[name] = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
151 if (this.methods && this.methods.includes(name)) {
152 throw new Error('A service cannot have the same name as an exposed method');
153 }
154 const service = yield factory();
155 const _service = plugin_utils_1.createService(name, service);
156 yield plugin_utils_1.activateService(this, _service);
157 delete this.activateService[name];
158 return _service;
159 });
160 }
161 /** Listen on an event from another plugin */
162 on(name, key, cb) {
163 throw new Error(`Cannot use method "on" from plugin "${this.name}". It is not registered in the engine yet.`);
164 }
165 /** Listen once an event from another plugin then remove event listener */
166 once(name, key, cb) {
167 throw new Error(`Cannot use method "once" from plugin "${this.name}". It is not registered in the engine yet.`);
168 }
169 /** Stop listening on an event from another plugin */
170 off(name, key) {
171 throw new Error(`Cannot use method "off" from plugin "${this.name}". It is not registered in the engine yet.`);
172 }
173 /** Call a method of another plugin */
174 call(name, key, ...payload) {
175 return tslib_1.__awaiter(this, void 0, void 0, function* () {
176 throw new Error(`Cannot use method "call" from plugin "${this.name}". It is not registered in the engine yet.`);
177 });
178 }
179 /** Emit an event */
180 emit(key, ...payload) {
181 throw new Error(`Cannot use method "emit" from plugin "${this.name}". It is not registered in the engine yet.`);
182 }
183}
184exports.Plugin = Plugin;
185//# sourceMappingURL=abstract.js.map
\No newline at end of file