aboutsummaryrefslogtreecommitdiffstats
path: root/src/stores
diff options
context:
space:
mode:
Diffstat (limited to 'src/stores')
-rw-r--r--src/stores/AppStore.ts2
-rw-r--r--src/stores/FeaturesStore.ts2
-rw-r--r--src/stores/GlobalErrorStore.ts27
-rw-r--r--src/stores/RecipesStore.ts10
-rw-r--r--src/stores/RequestStore.ts3
-rw-r--r--src/stores/ServicesStore.ts10
-rw-r--r--src/stores/UserStore.ts17
-rw-r--r--src/stores/lib/CachedRequest.ts (renamed from src/stores/lib/CachedRequest.js)49
-rw-r--r--src/stores/lib/Request.ts (renamed from src/stores/lib/Request.js)106
9 files changed, 115 insertions, 111 deletions
diff --git a/src/stores/AppStore.ts b/src/stores/AppStore.ts
index aab279e59..2db90bfa0 100644
--- a/src/stores/AppStore.ts
+++ b/src/stores/AppStore.ts
@@ -494,7 +494,7 @@ export default class AppStore extends TypedStore {
494 ), 494 ),
495 ); 495 );
496 496
497 await clearAppCache._promise; 497 await clearAppCache.promise;
498 498
499 await sleep(ms('1s')); 499 await sleep(ms('1s'));
500 500
diff --git a/src/stores/FeaturesStore.ts b/src/stores/FeaturesStore.ts
index ed0c6c17b..5f43ccf84 100644
--- a/src/stores/FeaturesStore.ts
+++ b/src/stores/FeaturesStore.ts
@@ -45,7 +45,7 @@ export default class FeaturesStore extends TypedStore {
45 this._monitorLoginStatus.bind(this), 45 this._monitorLoginStatus.bind(this),
46 ]); 46 ]);
47 47
48 await this.featuresRequest._promise; 48 await this.featuresRequest.promise;
49 setTimeout(this._setupFeatures.bind(this), 1); 49 setTimeout(this._setupFeatures.bind(this), 1);
50 } 50 }
51 51
diff --git a/src/stores/GlobalErrorStore.ts b/src/stores/GlobalErrorStore.ts
index c42e9a4af..be86563d0 100644
--- a/src/stores/GlobalErrorStore.ts
+++ b/src/stores/GlobalErrorStore.ts
@@ -1,4 +1,5 @@
1import { observable, action, makeObservable } from 'mobx'; 1import { observable, action, makeObservable } from 'mobx';
2import { Response } from 'electron';
2import { Actions } from '../actions/lib/actions'; 3import { Actions } from '../actions/lib/actions';
3import { ApiInterface } from '../api'; 4import { ApiInterface } from '../api';
4import { Stores } from '../@types/stores.types'; 5import { Stores } from '../@types/stores.types';
@@ -11,12 +12,8 @@ interface Message {
11 message?: string; 12 message?: string;
12 status?: number; 13 status?: number;
13 }; 14 };
14 request?: { 15 request?: Request;
15 result: any; 16 response?: Response;
16 wasExecuted: any;
17 method: any;
18 };
19 response?: any;
20 server?: any; 17 server?: any;
21 info?: any; 18 info?: any;
22 url?: string; 19 url?: string;
@@ -28,7 +25,7 @@ export default class GlobalErrorStore extends TypedStore {
28 25
29 @observable messages: Message[] = []; 26 @observable messages: Message[] = [];
30 27
31 @observable response: object = {}; 28 @observable response: Response = {} as Response;
32 29
33 // TODO: Get rid of the @ts-ignores in this function. 30 // TODO: Get rid of the @ts-ignores in this function.
34 constructor(stores: Stores, api: ApiInterface, actions: Actions) { 31 constructor(stores: Stores, api: ApiInterface, actions: Actions) {
@@ -85,21 +82,15 @@ export default class GlobalErrorStore extends TypedStore {
85 } 82 }
86 } 83 }
87 84
88 @action _handleRequests = async (request: { 85 @action _handleRequests = async (request: Request): Promise<void> => {
89 isError: any;
90 error: { json: () => object | PromiseLike<object> };
91 result: any;
92 wasExecuted: any;
93 _method: any;
94 }): Promise<void> => {
95 if (request.isError) { 86 if (request.isError) {
96 this.error = request.error; 87 this.error = request.error;
97 88
98 if (request.error.json) { 89 if (request.error && request.error.json) {
99 try { 90 try {
100 this.response = await request.error.json(); 91 this.response = await request.error.json();
101 } catch { 92 } catch {
102 this.response = {}; 93 this.response = {} as Response;
103 } 94 }
104 if (this.error?.status === 401) { 95 if (this.error?.status === 401) {
105 window['ferdium'].stores.app.authRequestFailed = true; 96 window['ferdium'].stores.app.authRequestFailed = true;
@@ -111,8 +102,8 @@ export default class GlobalErrorStore extends TypedStore {
111 request: { 102 request: {
112 result: request.result, 103 result: request.result,
113 wasExecuted: request.wasExecuted, 104 wasExecuted: request.wasExecuted,
114 method: request._method, 105 method: request.method,
115 }, 106 } as Request,
116 error: this.error, 107 error: this.error,
117 response: this.response, 108 response: this.response,
118 server: window['ferdium'].stores.settings.app.server, 109 server: window['ferdium'].stores.settings.app.server,
diff --git a/src/stores/RecipesStore.ts b/src/stores/RecipesStore.ts
index 25304e97c..07f1343f8 100644
--- a/src/stores/RecipesStore.ts
+++ b/src/stores/RecipesStore.ts
@@ -74,8 +74,8 @@ export default class RecipesStore extends TypedStore {
74 74
75 // Actions 75 // Actions
76 async _install({ recipeId }): Promise<Recipe> { 76 async _install({ recipeId }): Promise<Recipe> {
77 const recipe = await this.installRecipeRequest.execute(recipeId)._promise; 77 const recipe = await this.installRecipeRequest.execute(recipeId).promise;
78 await this.allRecipesRequest.invalidate({ immediately: true })._promise; 78 await this.allRecipesRequest.invalidate({ immediately: true }).promise;
79 79
80 return recipe; 80 return recipe;
81 } 81 }
@@ -128,7 +128,7 @@ export default class RecipesStore extends TypedStore {
128 const update = updates[i]; 128 const update = updates[i];
129 129
130 this.actions.recipe.install({ recipeId: update }); 130 this.actions.recipe.install({ recipeId: update });
131 await this.installRecipeRequest._promise; 131 await this.installRecipeRequest.promise;
132 132
133 this.installRecipeRequest.reset(); 133 this.installRecipeRequest.reset();
134 134
@@ -158,10 +158,10 @@ export default class RecipesStore extends TypedStore {
158 debug(`Recipe ${recipeId} is not installed, trying to install it`); 158 debug(`Recipe ${recipeId} is not installed, trying to install it`);
159 159
160 const recipe = await this.installRecipeRequest.execute(recipeId) 160 const recipe = await this.installRecipeRequest.execute(recipeId)
161 ._promise; 161 .promise;
162 if (recipe) { 162 if (recipe) {
163 await this.allRecipesRequest.invalidate({ immediately: true }) 163 await this.allRecipesRequest.invalidate({ immediately: true })
164 ._promise; 164 .promise;
165 router.push(`/settings/services/add/${recipeId}`); 165 router.push(`/settings/services/add/${recipeId}`);
166 } else { 166 } else {
167 router.push('/settings/recipes'); 167 router.push('/settings/recipes');
diff --git a/src/stores/RequestStore.ts b/src/stores/RequestStore.ts
index 279615e50..807f2d126 100644
--- a/src/stores/RequestStore.ts
+++ b/src/stores/RequestStore.ts
@@ -37,6 +37,9 @@ export default class RequestStore extends TypedStore {
37 ); 37 );
38 38
39 this.registerReactions([this._autoRetry.bind(this)]); 39 this.registerReactions([this._autoRetry.bind(this)]);
40
41 this.userInfoRequest = {} as CachedRequest;
42 this.servicesRequest = {} as CachedRequest;
40 } 43 }
41 44
42 async setup(): Promise<void> { 45 async setup(): Promise<void> {
diff --git a/src/stores/ServicesStore.ts b/src/stores/ServicesStore.ts
index 74810b81f..4fdd9d5ad 100644
--- a/src/stores/ServicesStore.ts
+++ b/src/stores/ServicesStore.ts
@@ -477,7 +477,7 @@ export default class ServicesStore extends TypedStore {
477 : this._cleanUpTeamIdAndCustomUrl(recipeId, serviceData); 477 : this._cleanUpTeamIdAndCustomUrl(recipeId, serviceData);
478 478
479 const response = await this.createServiceRequest.execute(recipeId, data) 479 const response = await this.createServiceRequest.execute(recipeId, data)
480 ._promise; 480 .promise;
481 481
482 this.allServicesRequest.patch(result => { 482 this.allServicesRequest.patch(result => {
483 if (!result) return; 483 if (!result) return;
@@ -536,7 +536,7 @@ export default class ServicesStore extends TypedStore {
536 536
537 const newData = serviceData; 537 const newData = serviceData;
538 if (serviceData.iconFile) { 538 if (serviceData.iconFile) {
539 await request._promise; 539 await request.promise;
540 540
541 newData.iconUrl = request.result.data.iconUrl; 541 newData.iconUrl = request.result.data.iconUrl;
542 newData.hasCustomUploadedIcon = true; 542 newData.hasCustomUploadedIcon = true;
@@ -562,7 +562,7 @@ export default class ServicesStore extends TypedStore {
562 ); 562 );
563 }); 563 });
564 564
565 await request._promise; 565 await request.promise;
566 this.actionStatus = request.result.status; 566 this.actionStatus = request.result.status;
567 567
568 if (service.isEnabled) { 568 if (service.isEnabled) {
@@ -596,7 +596,7 @@ export default class ServicesStore extends TypedStore {
596 remove(result, (c: Service) => c.id === serviceId); 596 remove(result, (c: Service) => c.id === serviceId);
597 }); 597 });
598 598
599 await request._promise; 599 await request.promise;
600 this.actionStatus = request.result.status; 600 this.actionStatus = request.result.status;
601 } 601 }
602 602
@@ -637,7 +637,7 @@ export default class ServicesStore extends TypedStore {
637 @action async _clearCache({ serviceId }) { 637 @action async _clearCache({ serviceId }) {
638 this.clearCacheRequest.reset(); 638 this.clearCacheRequest.reset();
639 const request = this.clearCacheRequest.execute(serviceId); 639 const request = this.clearCacheRequest.execute(serviceId);
640 await request._promise; 640 await request.promise;
641 } 641 }
642 642
643 @action _setIsActive(service: Service, state: boolean): void { 643 @action _setIsActive(service: Service, state: boolean): void {
diff --git a/src/stores/UserStore.ts b/src/stores/UserStore.ts
index c5e67c966..6c8f8f20b 100644
--- a/src/stores/UserStore.ts
+++ b/src/stores/UserStore.ts
@@ -187,7 +187,7 @@ export default class UserStore extends TypedStore {
187 187
188 // Actions 188 // Actions
189 @action async _login({ email, password }): Promise<void> { 189 @action async _login({ email, password }): Promise<void> {
190 const authToken = await this.loginRequest.execute(email, password)._promise; 190 const authToken = await this.loginRequest.execute(email, password).promise;
191 this._setUserData(authToken); 191 this._setUserData(authToken);
192 192
193 this.stores.router.push('/'); 193 this.stores.router.push('/');
@@ -209,6 +209,8 @@ export default class UserStore extends TypedStore {
209 plan, 209 plan,
210 currency, 210 currency,
211 }): Promise<void> { 211 }): Promise<void> {
212 // TODO - [TS DEBT] Need to find a way proper to implement promise's then and catch in request class
213 // @ts-ignore
212 const authToken = await this.signupRequest.execute({ 214 const authToken = await this.signupRequest.execute({
213 firstname, 215 firstname,
214 lastname, 216 lastname,
@@ -231,14 +233,14 @@ export default class UserStore extends TypedStore {
231 @action async _retrievePassword({ email }): Promise<void> { 233 @action async _retrievePassword({ email }): Promise<void> {
232 const request = this.passwordRequest.execute(email); 234 const request = this.passwordRequest.execute(email);
233 235
234 await request._promise; 236 await request.promise;
235 this.actionStatus = request.result.status || []; 237 this.actionStatus = request.result.status || [];
236 } 238 }
237 239
238 @action async _invite({ invites }): Promise<void> { 240 @action async _invite({ invites }): Promise<void> {
239 const data = invites.filter(invite => invite.email !== ''); 241 const data = invites.filter(invite => invite.email !== '');
240 242
241 const response = await this.inviteRequest.execute(data)._promise; 243 const response = await this.inviteRequest.execute(data).promise;
242 244
243 this.actionStatus = response.status || []; 245 this.actionStatus = response.status || [];
244 246
@@ -251,8 +253,7 @@ export default class UserStore extends TypedStore {
251 @action async _update({ userData }): Promise<void> { 253 @action async _update({ userData }): Promise<void> {
252 if (!this.isLoggedIn) return; 254 if (!this.isLoggedIn) return;
253 255
254 const response = await this.updateUserInfoRequest.execute(userData) 256 const response = await this.updateUserInfoRequest.execute(userData).promise;
255 ._promise;
256 257
257 this.getUserInfoRequest.patch(() => response.data); 258 this.getUserInfoRequest.patch(() => response.data);
258 this.actionStatus = response.status || []; 259 this.actionStatus = response.status || [];
@@ -299,7 +300,7 @@ export default class UserStore extends TypedStore {
299 data: service, 300 data: service,
300 }); 301 });
301 // eslint-disable-next-line no-await-in-loop 302 // eslint-disable-next-line no-await-in-loop
302 await this.stores.services.createServiceRequest._promise; 303 await this.stores.services.createServiceRequest.promise;
303 } 304 }
304 305
305 this.isImportLegacyServicesExecuting = false; 306 this.isImportLegacyServicesExecuting = false;
@@ -349,7 +350,7 @@ export default class UserStore extends TypedStore {
349 if (this.isLoggedIn) { 350 if (this.isLoggedIn) {
350 let data; 351 let data;
351 try { 352 try {
352 data = await this.getUserInfoRequest.execute()._promise; 353 data = await this.getUserInfoRequest.execute().promise;
353 } catch { 354 } catch {
354 return; 355 return;
355 } 356 }
@@ -406,7 +407,7 @@ export default class UserStore extends TypedStore {
406 407
407 async _migrateUserLocale(): Promise<void> { 408 async _migrateUserLocale(): Promise<void> {
408 try { 409 try {
409 await this.getUserInfoRequest._promise; 410 await this.getUserInfoRequest.promise;
410 } catch { 411 } catch {
411 return; 412 return;
412 } 413 }
diff --git a/src/stores/lib/CachedRequest.js b/src/stores/lib/CachedRequest.ts
index a6dd47f7d..25cc365e2 100644
--- a/src/stores/lib/CachedRequest.js
+++ b/src/stores/lib/CachedRequest.ts
@@ -3,29 +3,33 @@ import { isEqual, remove } from 'lodash';
3import Request from './Request'; 3import Request from './Request';
4 4
5export default class CachedRequest extends Request { 5export default class CachedRequest extends Request {
6 _apiCalls = []; 6 _apiCalls: any[] = [];
7 7
8 _isInvalidated = true; 8 _isInvalidated = true;
9 9
10 execute(...callArgs) { 10 execute(...callArgs): this {
11 // Do not continue if this request is already loading 11 // Do not continue if this request is already loading
12 if (this._isWaitingForResponse) return this; 12 if (this.isWaitingForResponse) {
13 return this;
14 }
13 15
14 // Very simple caching strategy -> only continue if the call / args changed 16 // Very simple caching strategy -> only continue if the call / args changed
15 // or the request was invalidated manually from outside 17 // or the request was invalidated manually from outside
16 const existingApiCall = this._findApiCall(callArgs); 18 const existingApiCall = this._findApiCall(callArgs);
17 19
18 // Invalidate if new or different api call will be done 20 // Invalidate if new or different api call will be done
19 if (existingApiCall && existingApiCall !== this._currentApiCall) { 21 if (existingApiCall && existingApiCall !== this.currentApiCall) {
20 this._isInvalidated = true; 22 this._isInvalidated = true;
21 this._currentApiCall = existingApiCall; 23 this.currentApiCall = existingApiCall;
22 } else if (!existingApiCall) { 24 } else if (!existingApiCall) {
23 this._isInvalidated = true; 25 this._isInvalidated = true;
24 this._currentApiCall = this._addApiCall(callArgs); 26 this.currentApiCall = this._addApiCall(callArgs);
25 } 27 }
26 28
27 // Do not continue if this request is not invalidated (see above) 29 // Do not continue if this request is not invalidated (see above)
28 if (!this._isInvalidated) return this; 30 if (!this._isInvalidated) {
31 return this;
32 }
29 33
30 // This timeout is necessary to avoid warnings from mobx 34 // This timeout is necessary to avoid warnings from mobx
31 // regarding triggering actions as side-effect of getters 35 // regarding triggering actions as side-effect of getters
@@ -41,18 +45,18 @@ export default class CachedRequest extends Request {
41 ); 45 );
42 46
43 // Issue api call & save it as promise that is handled to update the results of the operation 47 // Issue api call & save it as promise that is handled to update the results of the operation
44 this._promise = new Promise(resolve => { 48 this.promise = new Promise(resolve => {
45 this._api[this._method](...callArgs) 49 this.api[this.method](...callArgs)
46 .then(result => { 50 .then(result => {
47 setTimeout( 51 setTimeout(
48 action(() => { 52 action(() => {
49 this.result = result; 53 this.result = result;
50 if (this._currentApiCall) this._currentApiCall.result = result; 54 if (this.currentApiCall) this.currentApiCall.result = result;
51 this.isExecuting = false; 55 this.isExecuting = false;
52 this.isError = false; 56 this.isError = false;
53 this.wasExecuted = true; 57 this.wasExecuted = true;
54 this._isInvalidated = false; 58 this._isInvalidated = false;
55 this._isWaitingForResponse = false; 59 this.isWaitingForResponse = false;
56 this._triggerHooks(); 60 this._triggerHooks();
57 resolve(result); 61 resolve(result);
58 }), 62 }),
@@ -68,7 +72,7 @@ export default class CachedRequest extends Request {
68 this.isExecuting = false; 72 this.isExecuting = false;
69 this.isError = true; 73 this.isError = true;
70 this.wasExecuted = true; 74 this.wasExecuted = true;
71 this._isWaitingForResponse = false; 75 this.isWaitingForResponse = false;
72 this._triggerHooks(); 76 this._triggerHooks();
73 // reject(error); 77 // reject(error);
74 }), 78 }),
@@ -78,26 +82,27 @@ export default class CachedRequest extends Request {
78 ); 82 );
79 }); 83 });
80 84
81 this._isWaitingForResponse = true; 85 this.isWaitingForResponse = true;
82 return this; 86 return this;
83 } 87 }
84 88
85 // eslint-disable-next-line unicorn/no-object-as-default-parameter 89 static defaultOptions = { immediately: false };
86 invalidate(options = { immediately: false }) { 90
91 invalidate(options = CachedRequest.defaultOptions): this {
87 this._isInvalidated = true; 92 this._isInvalidated = true;
88 if (options.immediately && this._currentApiCall) { 93 if (options.immediately && this.currentApiCall) {
89 return this.execute(...this._currentApiCall.args); 94 return this.execute(...this.currentApiCall.args);
90 } 95 }
91 return this; 96 return this;
92 } 97 }
93 98
94 patch(modify) { 99 patch(modify): Promise<this> {
95 return new Promise(resolve => { 100 return new Promise(resolve => {
96 setTimeout( 101 setTimeout(
97 action(() => { 102 action(() => {
98 const override = modify(this.result); 103 const override = modify(this.result);
99 if (override !== undefined) this.result = override; 104 if (override !== undefined) this.result = override;
100 if (this._currentApiCall) this._currentApiCall.result = this.result; 105 if (this.currentApiCall) this.currentApiCall.result = this.result;
101 resolve(this); 106 resolve(this);
102 }), 107 }),
103 0, 108 0,
@@ -105,17 +110,17 @@ export default class CachedRequest extends Request {
105 }); 110 });
106 } 111 }
107 112
108 removeCacheForCallWith(...args) { 113 removeCacheForCallWith(...args: any): void {
109 remove(this._apiCalls, c => isEqual(c.args, args)); 114 remove(this._apiCalls, c => isEqual(c.args, args));
110 } 115 }
111 116
112 _addApiCall(args) { 117 _addApiCall(args: any) {
113 const newCall = { args, result: null }; 118 const newCall = { args, result: null };
114 this._apiCalls.push(newCall); 119 this._apiCalls.push(newCall);
115 return newCall; 120 return newCall;
116 } 121 }
117 122
118 _findApiCall(args) { 123 _findApiCall(args: any) {
119 return this._apiCalls.find(c => isEqual(c.args, args)); 124 return this._apiCalls.find(c => isEqual(c.args, args));
120 } 125 }
121} 126}
diff --git a/src/stores/lib/Request.js b/src/stores/lib/Request.ts
index 60c943a42..f9424ac99 100644
--- a/src/stores/lib/Request.js
+++ b/src/stores/lib/Request.ts
@@ -1,16 +1,18 @@
1import { observable, action, computed, makeObservable } from 'mobx'; 1import { observable, action, computed, makeObservable } from 'mobx';
2import { isEqual } from 'lodash/fp'; 2import { isEqual } from 'lodash/fp';
3 3
4type Hook = (request: Request) => void;
5
4export default class Request { 6export default class Request {
5 static _hooks = []; 7 static _hooks: Hook[] = [];
6 8
7 static registerHook(hook) { 9 static registerHook(hook: Hook) {
8 Request._hooks.push(hook); 10 Request._hooks.push(hook);
9 } 11 }
10 12
11 @observable result = null; 13 @observable result: any = null;
12 14
13 @observable error = null; 15 @observable error: any = null;
14 16
15 @observable isExecuting = false; 17 @observable isExecuting = false;
16 18
@@ -18,43 +20,47 @@ export default class Request {
18 20
19 @observable wasExecuted = false; 21 @observable wasExecuted = false;
20 22
21 @action _reset() { 23 promise: any = Promise;
22 this.error = null;
23 this.result = null;
24 this.isExecuting = false;
25 this.isError = false;
26 this.wasExecuted = false;
27 this._isWaitingForResponse = false;
28 this._promise = Promise;
29 24
30 return this; 25 protected api: any = {};
31 }
32 26
33 _promise = Promise; 27 method = '';
34 28
35 _api = {}; 29 protected isWaitingForResponse = false;
36 30
37 _method = ''; 31 protected currentApiCall: any = null;
38 32
39 _isWaitingForResponse = false; 33 retry = () => this.reload();
40 34
41 _currentApiCall = null; 35 reset = () => this._reset();
42 36
43 constructor(api, method) { 37 constructor(api, method) {
44 makeObservable(this); 38 makeObservable(this);
45 39
46 this._api = api; 40 this.api = api;
47 this._method = method; 41 this.method = method;
42 }
43
44 @action _reset(): this {
45 this.error = null;
46 this.result = null;
47 this.isExecuting = false;
48 this.isError = false;
49 this.wasExecuted = false;
50 this.isWaitingForResponse = false;
51 this.promise = Promise;
52
53 return this;
48 } 54 }
49 55
50 execute(...callArgs) { 56 execute(...callArgs: any[]): this {
51 // Do not continue if this request is already loading 57 // Do not continue if this request is already loading
52 if (this._isWaitingForResponse) return this; 58 if (this.isWaitingForResponse) return this;
53 59
54 if (!this._api[this._method]) { 60 if (!this.api[this.method]) {
55 throw new Error( 61 throw new Error(
56 `Missing method <${this._method}> on api object:`, 62 `Missing method <${this.method}> on api object:`,
57 this._api, 63 this.api,
58 ); 64 );
59 } 65 }
60 66
@@ -68,18 +74,18 @@ export default class Request {
68 ); 74 );
69 75
70 // Issue api call & save it as promise that is handled to update the results of the operation 76 // Issue api call & save it as promise that is handled to update the results of the operation
71 this._promise = new Promise((resolve, reject) => { 77 this.promise = new Promise((resolve, reject) => {
72 this._api[this._method](...callArgs) 78 this.api[this.method](...callArgs)
73 .then(result => { 79 .then(result => {
74 setTimeout( 80 setTimeout(
75 action(() => { 81 action(() => {
76 this.error = null; 82 this.error = null;
77 this.result = result; 83 this.result = result;
78 if (this._currentApiCall) this._currentApiCall.result = result; 84 if (this.currentApiCall) this.currentApiCall.result = result;
79 this.isExecuting = false; 85 this.isExecuting = false;
80 this.isError = false; 86 this.isError = false;
81 this.wasExecuted = true; 87 this.wasExecuted = true;
82 this._isWaitingForResponse = false; 88 this.isWaitingForResponse = false;
83 this._triggerHooks(); 89 this._triggerHooks();
84 resolve(result); 90 resolve(result);
85 }), 91 }),
@@ -95,7 +101,7 @@ export default class Request {
95 this.isExecuting = false; 101 this.isExecuting = false;
96 this.isError = true; 102 this.isError = true;
97 this.wasExecuted = true; 103 this.wasExecuted = true;
98 this._isWaitingForResponse = false; 104 this.isWaitingForResponse = false;
99 this._triggerHooks(); 105 this._triggerHooks();
100 reject(error); 106 reject(error);
101 }), 107 }),
@@ -105,51 +111,49 @@ export default class Request {
105 ); 111 );
106 }); 112 });
107 113
108 this._isWaitingForResponse = true; 114 this.isWaitingForResponse = true;
109 this._currentApiCall = { args: callArgs, result: null }; 115 this.currentApiCall = { args: callArgs, result: null };
110 return this; 116 return this;
111 } 117 }
112 118
113 reload() { 119 reload(): this {
114 const args = this._currentApiCall ? this._currentApiCall.args : []; 120 const args = this.currentApiCall ? this.currentApiCall.args : [];
115 this.error = null; 121 this.error = null;
116 return this.execute(...args); 122 return this.execute(...args);
117 } 123 }
118 124
119 retry = () => this.reload(); 125 isExecutingWithArgs(...args: any[]): boolean {
120
121 isExecutingWithArgs(...args) {
122 return ( 126 return (
123 this.isExecuting && 127 this.isExecuting &&
124 this._currentApiCall && 128 this.currentApiCall &&
125 isEqual(this._currentApiCall.args, args) 129 isEqual(this.currentApiCall.args, args)
126 ); 130 );
127 } 131 }
128 132
129 @computed get isExecutingFirstTime() { 133 @computed get isExecutingFirstTime(): boolean {
130 return !this.wasExecuted && this.isExecuting; 134 return !this.wasExecuted && this.isExecuting;
131 } 135 }
132 136
133 /* eslint-disable unicorn/no-thenable */ 137 /* eslint-disable unicorn/no-thenable */
134 then(...args) { 138 then(...args: any[]) {
135 if (!this._promise) 139 if (!this.promise)
136 throw new Error( 140 throw new Error(
137 'You have to call Request::execute before you can access it as promise', 141 'You have to call Request::execute before you can access it as promise',
138 ); 142 );
139 return this._promise.then(...args); 143 return this.promise.then(...args);
140 } 144 }
141 145
142 catch(...args) { 146 catch(...args: any[]) {
143 if (!this._promise) 147 if (!this.promise)
144 throw new Error( 148 throw new Error(
145 'You have to call Request::execute before you can access it as promise', 149 'You have to call Request::execute before you can access it as promise',
146 ); 150 );
147 return this._promise.catch(...args); 151 return this.promise.catch(...args);
148 } 152 }
149 153
150 _triggerHooks() { 154 _triggerHooks(): void {
151 for (const hook of Request._hooks) hook(this); 155 for (const hook of Request._hooks) {
156 hook(this);
157 }
152 } 158 }
153
154 reset = () => this._reset();
155} 159}