@tramvai/module-common 2.7.1 → 2.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/actions/actionExecution.d.ts +18 -12
- package/lib/actions/actionPageRunner.browser.d.ts +7 -4
- package/lib/actions/actionPageRunner.d.ts +16 -11
- package/lib/actions/constants.d.ts +6 -0
- package/lib/cache/CacheModule.d.ts +1 -1
- package/lib/child-app/command.d.ts +8 -8
- package/lib/command/commandLineRunner.d.ts +7 -2
- package/lib/command/defaultLines.d.ts +10 -10
- package/lib/createConsumerContext/createConsumerContext.d.ts +3 -3
- package/lib/executionContext/executionContextManager.d.ts +5 -0
- package/lib/index.browser.js +208 -66
- package/lib/index.d.ts +1 -0
- package/lib/index.es.js +241 -99
- package/lib/index.js +226 -84
- package/lib/providers/clientProviders.d.ts +3 -3
- package/package.json +22 -21
package/lib/index.es.js
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { __decorate } from 'tslib';
|
|
2
2
|
import eachObj from '@tinkoff/utils/object/each';
|
|
3
|
-
import { createBundle, Scope, Module, commandLineListTokens, COMMAND_LINE_RUNNER_TOKEN, COMMAND_LINES_TOKEN, DI_TOKEN, ACTION_PARAMETERS, ACTIONS_LIST_TOKEN, provide, IS_DI_CHILD_CONTAINER_TOKEN, BUNDLE_LIST_TOKEN } from '@tramvai/core';
|
|
3
|
+
import { createBundle, Scope, Module, commandLineListTokens, COMMAND_LINE_RUNNER_TOKEN, COMMAND_LINES_TOKEN, DI_TOKEN, isTramvaiAction, ACTION_PARAMETERS, ACTIONS_LIST_TOKEN, provide as provide$1, IS_DI_CHILD_CONTAINER_TOKEN, BUNDLE_LIST_TOKEN } from '@tramvai/core';
|
|
4
4
|
import { EnvironmentModule } from '@tramvai/module-environment';
|
|
5
5
|
import { CookieModule } from '@tramvai/module-cookie';
|
|
6
6
|
export { COOKIE_MANAGER_TOKEN } from '@tramvai/module-cookie';
|
|
7
7
|
import { LogModule } from '@tramvai/module-log';
|
|
8
8
|
import { Hooks } from '@tinkoff/hook-runner';
|
|
9
|
-
import { REQUEST_MANAGER_TOKEN, REQUEST, COMBINE_REDUCERS, CONTEXT_TOKEN, RESPONSE_MANAGER_TOKEN, RESPONSE, ACTION_EXECUTION_TOKEN, LOGGER_TOKEN, PUBSUB_FACTORY_TOKEN, PUBSUB_TOKEN, ROOT_PUBSUB_TOKEN, ACTION_REGISTRY_TOKEN, ACTION_CONDITIONALS, STORE_TOKEN, ACTION_PAGE_RUNNER_TOKEN, DISPATCHER_TOKEN, DISPATCHER_CONTEXT_TOKEN, STORE_MIDDLEWARE, INITIAL_APP_STATE_TOKEN, CLEAR_CACHE_TOKEN, CREATE_CACHE_TOKEN, REGISTER_CLEAR_CACHE_TOKEN, HOOK_TOKEN, COMPONENT_REGISTRY_TOKEN, BUNDLE_MANAGER_TOKEN, ADDITIONAL_BUNDLE_TOKEN } from '@tramvai/tokens-common';
|
|
9
|
+
import { REQUEST_MANAGER_TOKEN, REQUEST, COMBINE_REDUCERS, CONTEXT_TOKEN, RESPONSE_MANAGER_TOKEN, RESPONSE, ACTION_EXECUTION_TOKEN, ROOT_EXECUTION_CONTEXT_TOKEN, LOGGER_TOKEN, EXECUTION_CONTEXT_MANAGER_TOKEN, COMMAND_LINE_EXECUTION_CONTEXT_TOKEN, PUBSUB_FACTORY_TOKEN, PUBSUB_TOKEN, ROOT_PUBSUB_TOKEN, ACTION_REGISTRY_TOKEN, ACTION_CONDITIONALS, STORE_TOKEN, ACTION_PAGE_RUNNER_TOKEN, DISPATCHER_TOKEN, DISPATCHER_CONTEXT_TOKEN, STORE_MIDDLEWARE, INITIAL_APP_STATE_TOKEN, CLEAR_CACHE_TOKEN, CREATE_CACHE_TOKEN, REGISTER_CLEAR_CACHE_TOKEN, HOOK_TOKEN, COMPONENT_REGISTRY_TOKEN, BUNDLE_MANAGER_TOKEN, ADDITIONAL_BUNDLE_TOKEN } from '@tramvai/tokens-common';
|
|
10
10
|
export * from '@tramvai/tokens-common';
|
|
11
|
-
import { __lazyErrorHandler } from '@tramvai/react';
|
|
11
|
+
import { resolveLazyComponent, __lazyErrorHandler } from '@tramvai/react';
|
|
12
12
|
import { fileSystemPagesEnabled, getAllFileSystemPages, isFileSystemPageComponent } from '@tramvai/experiments';
|
|
13
|
-
import hoistNonReactStatics from 'hoist-non-react-statics';
|
|
14
13
|
import pathOr from '@tinkoff/utils/object/pathOr';
|
|
15
14
|
import flatten from '@tinkoff/utils/array/flatten';
|
|
16
15
|
import { createEvent, createReducer, convertAction, createDispatcher, devTools, Provider } from '@tramvai/state';
|
|
@@ -18,9 +17,9 @@ import { format } from '@tinkoff/url';
|
|
|
18
17
|
import isEmpty from '@tinkoff/utils/is/empty';
|
|
19
18
|
import values from '@tinkoff/utils/object/values';
|
|
20
19
|
import { METRICS_MODULE_TOKEN } from '@tramvai/tokens-metrics';
|
|
21
|
-
import { createChildContainer, Scope as Scope$1, createToken } from '@tinkoff/dippy';
|
|
20
|
+
import { createChildContainer, provide, Scope as Scope$1, createToken } from '@tinkoff/dippy';
|
|
22
21
|
import noop from '@tinkoff/utils/function/noop';
|
|
23
|
-
import { isSilentError } from '@tinkoff/errors';
|
|
22
|
+
import { isSilentError, ConditionFailError, ExecutionAbortError } from '@tinkoff/errors';
|
|
24
23
|
import { PubSub } from '@tinkoff/pubsub';
|
|
25
24
|
import identity from '@tinkoff/utils/function/identity';
|
|
26
25
|
import objectMap from '@tinkoff/utils/object/map';
|
|
@@ -30,6 +29,7 @@ import toArray from '@tinkoff/utils/array/toArray';
|
|
|
30
29
|
import LRU from '@tinkoff/lru-cache-nano';
|
|
31
30
|
import { SERVER_MODULE_PAPI_PRIVATE_ROUTE } from '@tramvai/tokens-server';
|
|
32
31
|
import { createPapiMethod } from '@tramvai/papi';
|
|
32
|
+
import { AbortController } from 'node-abort-controller';
|
|
33
33
|
import { jsx } from 'react/jsx-runtime';
|
|
34
34
|
import { EXTEND_RENDER } from '@tramvai/tokens-render';
|
|
35
35
|
import { CHILD_APP_INTERNAL_ROOT_DI_BORROW_TOKEN, commandLineListTokens as commandLineListTokens$1 } from '@tramvai/tokens-child-app';
|
|
@@ -77,24 +77,17 @@ class BundleManager {
|
|
|
77
77
|
// preload `lazy` components then register actions and reducers
|
|
78
78
|
if (pageComponent && bundle.components[pageComponent]) {
|
|
79
79
|
const componentOrLoader = bundle.components[pageComponent];
|
|
80
|
-
const component =
|
|
81
|
-
? (await componentOrLoader.load()).default
|
|
82
|
-
: componentOrLoader;
|
|
83
|
-
// manually hoist static properties from preloaded component to loadable wrapper,
|
|
84
|
-
// this open access to current page component static properties outside before rendering
|
|
85
|
-
if (componentOrLoader !== component) {
|
|
86
|
-
hoistNonReactStatics(componentOrLoader, component);
|
|
87
|
-
}
|
|
80
|
+
const component = await resolveLazyComponent(componentOrLoader);
|
|
88
81
|
// allow page components to register any other components
|
|
89
|
-
if (component
|
|
82
|
+
if ('components' in component) {
|
|
90
83
|
eachObj((cmp, name) => {
|
|
91
84
|
this.componentRegistry.add(name, cmp, pageComponent);
|
|
92
85
|
}, component.components);
|
|
93
86
|
}
|
|
94
|
-
if (component
|
|
87
|
+
if ('actions' in component) {
|
|
95
88
|
this.actionRegistry.add(pageComponent, component.actions);
|
|
96
89
|
}
|
|
97
|
-
if (component
|
|
90
|
+
if ('reducers' in component) {
|
|
98
91
|
component.reducers.forEach((reducer) => {
|
|
99
92
|
this.dispatcher.registerStore(reducer);
|
|
100
93
|
});
|
|
@@ -375,14 +368,18 @@ const resolveDi = (type, status, diContainer, providers) => {
|
|
|
375
368
|
return di;
|
|
376
369
|
};
|
|
377
370
|
class CommandLineRunner {
|
|
378
|
-
constructor({ lines, rootDi, logger, metrics, }) {
|
|
371
|
+
constructor({ lines, rootDi, logger, metrics, executionContextManager, }) {
|
|
372
|
+
this.executionContextByDi = new WeakMap();
|
|
373
|
+
this.abortControllerByDi = new WeakMap();
|
|
379
374
|
this.lines = lines;
|
|
380
375
|
this.rootDi = rootDi;
|
|
381
376
|
this.log = logger('command:command-line-runner');
|
|
382
377
|
this.metrics = metrics;
|
|
378
|
+
this.executionContextManager = executionContextManager;
|
|
383
379
|
}
|
|
384
380
|
run(type, status, providers, customDi) {
|
|
385
381
|
const di = customDi !== null && customDi !== void 0 ? customDi : resolveDi(type, status, this.rootDi, providers);
|
|
382
|
+
const rootExecutionContext = di.get({ token: ROOT_EXECUTION_CONTEXT_TOKEN, optional: true });
|
|
386
383
|
this.log.debug({
|
|
387
384
|
event: 'command-run',
|
|
388
385
|
type,
|
|
@@ -394,13 +391,27 @@ class CommandLineRunner {
|
|
|
394
391
|
const doneMetric = this.createDurationMetric();
|
|
395
392
|
// eslint-disable-next-line promise/no-nesting
|
|
396
393
|
return Promise.resolve()
|
|
397
|
-
.then(() =>
|
|
394
|
+
.then(() => {
|
|
395
|
+
return this.executionContextManager.withContext(rootExecutionContext, `command-line:${line.toString()}`, async (executionContext, abortController) => {
|
|
396
|
+
this.executionContextByDi.set(di, executionContext);
|
|
397
|
+
this.abortControllerByDi.set(di, abortController);
|
|
398
|
+
await this.createLineChain(di, line);
|
|
399
|
+
});
|
|
400
|
+
})
|
|
398
401
|
.finally(() => doneMetric({ line: line.toString() }));
|
|
399
402
|
});
|
|
400
403
|
}, Promise.resolve())
|
|
401
404
|
// После завершения цепочки отдаем context выполнения
|
|
405
|
+
.finally(() => {
|
|
406
|
+
this.executionContextByDi.delete(di);
|
|
407
|
+
this.abortControllerByDi.delete(di);
|
|
408
|
+
})
|
|
402
409
|
.then(() => di));
|
|
403
410
|
}
|
|
411
|
+
resolveExecutionContextFromDi(di) {
|
|
412
|
+
var _a;
|
|
413
|
+
return (_a = this.executionContextByDi.get(di)) !== null && _a !== void 0 ? _a : null;
|
|
414
|
+
}
|
|
404
415
|
createLineChain(di, line) {
|
|
405
416
|
let lineInstance;
|
|
406
417
|
try {
|
|
@@ -452,12 +463,15 @@ class CommandLineRunner {
|
|
|
452
463
|
return Promise.resolve()
|
|
453
464
|
.then(() => instance())
|
|
454
465
|
.catch((err) => {
|
|
466
|
+
var _a;
|
|
455
467
|
this.log[isSilentError(err) ? 'debug' : 'error']({
|
|
456
468
|
event: 'line-error',
|
|
457
469
|
error: err,
|
|
458
470
|
line: line.toString(),
|
|
459
471
|
command: name,
|
|
460
472
|
});
|
|
473
|
+
// in case if any error happens during line execution results from other line handlers will not be used anyway
|
|
474
|
+
(_a = this.abortControllerByDi.get(di)) === null || _a === void 0 ? void 0 : _a.abort();
|
|
461
475
|
this.throwError(err, di);
|
|
462
476
|
});
|
|
463
477
|
}
|
|
@@ -511,7 +525,7 @@ let CommandModule = class CommandModule {
|
|
|
511
525
|
CommandModule = __decorate([
|
|
512
526
|
Module({
|
|
513
527
|
providers: [
|
|
514
|
-
{
|
|
528
|
+
provide({
|
|
515
529
|
// Раннер процессов
|
|
516
530
|
provide: COMMAND_LINE_RUNNER_TOKEN,
|
|
517
531
|
scope: Scope$1.SINGLETON,
|
|
@@ -524,14 +538,27 @@ CommandModule = __decorate([
|
|
|
524
538
|
token: METRICS_MODULE_TOKEN,
|
|
525
539
|
optional: true,
|
|
526
540
|
},
|
|
541
|
+
executionContextManager: EXECUTION_CONTEXT_MANAGER_TOKEN,
|
|
527
542
|
},
|
|
528
|
-
},
|
|
529
|
-
{
|
|
543
|
+
}),
|
|
544
|
+
provide({
|
|
545
|
+
provide: COMMAND_LINE_EXECUTION_CONTEXT_TOKEN,
|
|
546
|
+
useFactory: ({ di, commandLineRunner, }) => {
|
|
547
|
+
return () => {
|
|
548
|
+
return commandLineRunner.resolveExecutionContextFromDi(di);
|
|
549
|
+
};
|
|
550
|
+
},
|
|
551
|
+
deps: {
|
|
552
|
+
di: DI_TOKEN,
|
|
553
|
+
commandLineRunner: COMMAND_LINE_RUNNER_TOKEN,
|
|
554
|
+
},
|
|
555
|
+
}),
|
|
556
|
+
provide({
|
|
530
557
|
// Дефолтный список команл
|
|
531
558
|
provide: COMMAND_LINES_TOKEN,
|
|
532
559
|
scope: Scope$1.SINGLETON,
|
|
533
560
|
useValue: lines$1,
|
|
534
|
-
},
|
|
561
|
+
}),
|
|
535
562
|
],
|
|
536
563
|
})
|
|
537
564
|
], CommandModule);
|
|
@@ -583,14 +610,19 @@ const actionTramvaiReducer = createReducer('actionTramvai', initalState).on(acti
|
|
|
583
610
|
serverState: payload,
|
|
584
611
|
}));
|
|
585
612
|
|
|
613
|
+
/**
|
|
614
|
+
* @deprecated only for compatibility with legacy createAction
|
|
615
|
+
*/
|
|
586
616
|
const actionType = {
|
|
587
617
|
global: 'global',
|
|
588
618
|
local: 'local',
|
|
589
619
|
};
|
|
590
620
|
|
|
621
|
+
const DEFAULT_CONDITIONS = {};
|
|
591
622
|
class ActionChecker {
|
|
592
623
|
// eslint-disable-next-line max-params
|
|
593
624
|
constructor(globalConditionals, payload, parameters, executionState, type) {
|
|
625
|
+
var _a;
|
|
594
626
|
this.globalConditionals = globalConditionals;
|
|
595
627
|
this.payload = payload;
|
|
596
628
|
this.parameters = parameters;
|
|
@@ -604,7 +636,7 @@ class ActionChecker {
|
|
|
604
636
|
// если экшен был уже выполнен, то считаем, что его не нужно больше выполнять
|
|
605
637
|
this.status = executionState.status !== 'success';
|
|
606
638
|
}
|
|
607
|
-
this.conditions = parameters.conditions;
|
|
639
|
+
this.conditions = (_a = parameters.conditions) !== null && _a !== void 0 ? _a : DEFAULT_CONDITIONS;
|
|
608
640
|
}
|
|
609
641
|
check() {
|
|
610
642
|
this.globalConditionals.forEach((filter) => {
|
|
@@ -621,6 +653,7 @@ class ActionChecker {
|
|
|
621
653
|
}
|
|
622
654
|
forbid() {
|
|
623
655
|
this.executionState.status = 'forbidden';
|
|
656
|
+
this.executionState.forbiddenBy = this.key;
|
|
624
657
|
this.forbiddenMarker = true;
|
|
625
658
|
}
|
|
626
659
|
allow() {
|
|
@@ -634,12 +667,16 @@ class ActionChecker {
|
|
|
634
667
|
}
|
|
635
668
|
}
|
|
636
669
|
|
|
670
|
+
const EMPTY_DEPS = {};
|
|
671
|
+
const DEFAULT_PAYLOAD = {};
|
|
637
672
|
const getParameters = (action) => action[ACTION_PARAMETERS];
|
|
638
673
|
class ActionExecution {
|
|
639
|
-
constructor({
|
|
674
|
+
constructor({ store, context, di, executionContextManager, actionConditionals, transformAction, }) {
|
|
640
675
|
this.actionConditionals = flatten(actionConditionals !== null && actionConditionals !== void 0 ? actionConditionals : []);
|
|
641
676
|
this.context = context;
|
|
677
|
+
this.store = store;
|
|
642
678
|
this.di = di;
|
|
679
|
+
this.executionContextManager = executionContextManager;
|
|
643
680
|
this.execution = new Map();
|
|
644
681
|
this.transformAction = transformAction || identity;
|
|
645
682
|
const initialState = store.getState(actionTramvaiReducer);
|
|
@@ -649,32 +686,64 @@ class ActionExecution {
|
|
|
649
686
|
}, initialState.serverState);
|
|
650
687
|
}
|
|
651
688
|
}
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
const
|
|
656
|
-
|
|
689
|
+
async runInContext(executionContext, action, ...params) {
|
|
690
|
+
var _a, _b;
|
|
691
|
+
let parameters;
|
|
692
|
+
const payload = (_a = params[0]) !== null && _a !== void 0 ? _a : DEFAULT_PAYLOAD;
|
|
693
|
+
// TODO: replace type with pure context usage
|
|
694
|
+
const type = (executionContext === null || executionContext === void 0 ? void 0 : executionContext.values.pageActions) === true ? actionType.global : actionType.local;
|
|
695
|
+
// TODO: remove else branch after migration to new declareAction
|
|
696
|
+
if (isTramvaiAction(action)) {
|
|
697
|
+
parameters = action;
|
|
698
|
+
}
|
|
699
|
+
else {
|
|
700
|
+
this.transformAction(action);
|
|
701
|
+
parameters = getParameters(action);
|
|
702
|
+
}
|
|
703
|
+
const executionState = this.getExecutionState(parameters.name);
|
|
657
704
|
if (!this.canExecuteAction(payload, parameters, executionState, type)) {
|
|
658
|
-
|
|
705
|
+
switch (parameters.conditionsFailResult) {
|
|
706
|
+
case 'reject':
|
|
707
|
+
return Promise.reject(new ConditionFailError({
|
|
708
|
+
conditionName: (_b = executionState.forbiddenBy) !== null && _b !== void 0 ? _b : 'unknown',
|
|
709
|
+
targetName: parameters.name,
|
|
710
|
+
}));
|
|
711
|
+
default:
|
|
712
|
+
return Promise.resolve();
|
|
713
|
+
}
|
|
659
714
|
}
|
|
660
|
-
const deps = parameters.deps ? this.di.getOfDeps(parameters.deps) : {};
|
|
661
715
|
executionState.status = 'pending';
|
|
662
|
-
return
|
|
663
|
-
|
|
664
|
-
.
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
716
|
+
return this.executionContextManager.withContext(executionContext, {
|
|
717
|
+
name: parameters.name,
|
|
718
|
+
values: (executionContext === null || executionContext === void 0 ? void 0 : executionContext.values.pageActions) === true ? { pageActions: false } : undefined,
|
|
719
|
+
}, (executionActionContext, abortController) => {
|
|
720
|
+
const context = this.createActionContext(executionContext, executionActionContext, abortController, parameters);
|
|
721
|
+
return Promise.resolve()
|
|
722
|
+
.then(() => {
|
|
723
|
+
if (isTramvaiAction(action)) {
|
|
724
|
+
return action.fn.apply(context, params);
|
|
725
|
+
}
|
|
726
|
+
return action(this.context, payload, context.deps);
|
|
727
|
+
})
|
|
728
|
+
.then((data) => {
|
|
729
|
+
executionState.status = 'success';
|
|
730
|
+
return data;
|
|
731
|
+
})
|
|
732
|
+
.catch((err) => {
|
|
733
|
+
executionState.status = 'failed';
|
|
734
|
+
throw err;
|
|
735
|
+
});
|
|
671
736
|
});
|
|
672
737
|
}
|
|
673
|
-
|
|
674
|
-
|
|
738
|
+
async run(action, ...params) {
|
|
739
|
+
return this.runInContext(null, action, ...params);
|
|
740
|
+
}
|
|
741
|
+
getExecutionState(name) {
|
|
742
|
+
let executionState = this.execution.get(name);
|
|
743
|
+
// TODO: probably do not need to create executionState on client as it is not used
|
|
675
744
|
if (!executionState) {
|
|
676
745
|
executionState = { status: 'pending', state: {} };
|
|
677
|
-
this.execution.set(
|
|
746
|
+
this.execution.set(name, executionState);
|
|
678
747
|
}
|
|
679
748
|
return executionState;
|
|
680
749
|
}
|
|
@@ -682,6 +751,17 @@ class ActionExecution {
|
|
|
682
751
|
const actionChecker = new ActionChecker(this.actionConditionals, payload, parameters, executionState, type);
|
|
683
752
|
return actionChecker.check();
|
|
684
753
|
}
|
|
754
|
+
createActionContext(parentExecutionContext, actionExecutionContext, abortController, parameters) {
|
|
755
|
+
return {
|
|
756
|
+
abortController,
|
|
757
|
+
abortSignal: actionExecutionContext === null || actionExecutionContext === void 0 ? void 0 : actionExecutionContext.abortSignal,
|
|
758
|
+
executeAction: this.runInContext.bind(this, actionExecutionContext),
|
|
759
|
+
deps: parameters.deps ? this.di.getOfDeps(parameters.deps) : EMPTY_DEPS,
|
|
760
|
+
actionType: (parentExecutionContext === null || parentExecutionContext === void 0 ? void 0 : parentExecutionContext.values.pageActions) ? 'page' : 'standalone',
|
|
761
|
+
dispatch: this.store.dispatch,
|
|
762
|
+
getState: this.store.getState,
|
|
763
|
+
};
|
|
764
|
+
}
|
|
685
765
|
}
|
|
686
766
|
|
|
687
767
|
const GLOBAL_PARAMETER = '@@global';
|
|
@@ -711,56 +791,59 @@ class ActionRegistry {
|
|
|
711
791
|
}
|
|
712
792
|
}
|
|
713
793
|
|
|
714
|
-
const payload = {};
|
|
715
794
|
class ActionPageRunner {
|
|
716
|
-
constructor(
|
|
717
|
-
this.
|
|
718
|
-
this.
|
|
719
|
-
this.limitTime = limitTime;
|
|
720
|
-
this.log = logger('action:action-page-runner');
|
|
795
|
+
constructor(deps) {
|
|
796
|
+
this.deps = deps;
|
|
797
|
+
this.log = deps.logger('action:action-page-runner');
|
|
721
798
|
}
|
|
722
799
|
// TODO stopRunAtError нужен только для редиректов на стороне сервера в экшенах. И нужно пересмотреть реализацию редиректов
|
|
723
800
|
runActions(actions, stopRunAtError = () => false) {
|
|
724
|
-
return
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
const
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
};
|
|
742
|
-
const actionMapper = (action) => {
|
|
743
|
-
return Promise.resolve()
|
|
744
|
-
.then(() => this.actionExecution.run(action, payload, actionType.global))
|
|
745
|
-
.catch((error) => {
|
|
746
|
-
const parameters = action[ACTION_PARAMETERS];
|
|
747
|
-
this.log.error({
|
|
748
|
-
error,
|
|
749
|
-
event: `action-execution-error`,
|
|
750
|
-
message: `${parameters.name} execution error`,
|
|
801
|
+
return this.deps.executionContextManager.withContext(this.deps.commandLineExecutionContext(), { name: 'pageActions', values: { pageActions: true } }, (executionContext, abortController) => {
|
|
802
|
+
return new Promise((resolve, reject) => {
|
|
803
|
+
const timeoutMarker = setTimeout(() => {
|
|
804
|
+
this.log.warn(`page actions has exceeded timeout of ${this.deps.limitTime}ms, ignore some results of execution`);
|
|
805
|
+
abortController.abort();
|
|
806
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
807
|
+
endChecker();
|
|
808
|
+
}, this.deps.limitTime);
|
|
809
|
+
const endChecker = () => {
|
|
810
|
+
clearTimeout(timeoutMarker);
|
|
811
|
+
const result = {};
|
|
812
|
+
// TODO: dehydrate only actions on first level as inner actions are running on client despite their execution on server
|
|
813
|
+
this.deps.actionExecution.execution.forEach((value, key) => {
|
|
814
|
+
// достаем значения экшенов, которые успешно выполнились, остальные выполнятся на клиенте
|
|
815
|
+
if (value.status === 'success') {
|
|
816
|
+
result[key] = value;
|
|
817
|
+
}
|
|
751
818
|
});
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
819
|
+
this.syncStateActions(result);
|
|
820
|
+
resolve();
|
|
821
|
+
};
|
|
822
|
+
const actionMapper = (action) => {
|
|
823
|
+
return Promise.resolve()
|
|
824
|
+
.then(() => this.deps.actionExecution.runInContext(executionContext, action))
|
|
825
|
+
.catch((error) => {
|
|
826
|
+
if (!isSilentError(error)) {
|
|
827
|
+
const parameters = isTramvaiAction(action) ? action : action[ACTION_PARAMETERS];
|
|
828
|
+
this.log.error({
|
|
829
|
+
error,
|
|
830
|
+
event: `action-execution-error`,
|
|
831
|
+
message: `${parameters.name} execution error`,
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
if (stopRunAtError(error)) {
|
|
835
|
+
clearTimeout(timeoutMarker);
|
|
836
|
+
reject(error);
|
|
837
|
+
}
|
|
838
|
+
});
|
|
839
|
+
};
|
|
840
|
+
// eslint-disable-next-line promise/catch-or-return
|
|
841
|
+
Promise.all(actions.map(actionMapper)).then(endChecker);
|
|
842
|
+
});
|
|
760
843
|
});
|
|
761
844
|
}
|
|
762
845
|
syncStateActions(success) {
|
|
763
|
-
return this.store.dispatch(actionServerStateEvent(success));
|
|
846
|
+
return this.deps.store.dispatch(actionServerStateEvent(success));
|
|
764
847
|
}
|
|
765
848
|
}
|
|
766
849
|
|
|
@@ -829,7 +912,7 @@ ActionModule = __decorate([
|
|
|
829
912
|
useClass: ActionRegistry,
|
|
830
913
|
deps: { actionsList: ACTIONS_LIST_TOKEN },
|
|
831
914
|
},
|
|
832
|
-
provide({
|
|
915
|
+
provide$1({
|
|
833
916
|
provide: ACTION_EXECUTION_TOKEN,
|
|
834
917
|
scope: Scope.REQUEST,
|
|
835
918
|
useClass: ActionExecution,
|
|
@@ -838,23 +921,26 @@ ActionModule = __decorate([
|
|
|
838
921
|
context: CONTEXT_TOKEN,
|
|
839
922
|
store: STORE_TOKEN,
|
|
840
923
|
di: DI_TOKEN,
|
|
924
|
+
executionContextManager: EXECUTION_CONTEXT_MANAGER_TOKEN,
|
|
841
925
|
transformAction: {
|
|
842
926
|
token: 'actionTransformAction',
|
|
843
927
|
optional: true,
|
|
844
928
|
},
|
|
845
929
|
},
|
|
846
930
|
}),
|
|
847
|
-
{
|
|
931
|
+
provide$1({
|
|
848
932
|
provide: ACTION_PAGE_RUNNER_TOKEN,
|
|
849
933
|
scope: Scope.REQUEST,
|
|
850
934
|
useClass: ActionPageRunner,
|
|
851
935
|
deps: {
|
|
852
936
|
actionExecution: ACTION_EXECUTION_TOKEN,
|
|
937
|
+
executionContextManager: EXECUTION_CONTEXT_MANAGER_TOKEN,
|
|
938
|
+
commandLineExecutionContext: COMMAND_LINE_EXECUTION_CONTEXT_TOKEN,
|
|
853
939
|
store: STORE_TOKEN,
|
|
854
940
|
limitTime: 'limitActionGlobalTimeRun',
|
|
855
941
|
logger: LOGGER_TOKEN,
|
|
856
942
|
},
|
|
857
|
-
},
|
|
943
|
+
}),
|
|
858
944
|
{
|
|
859
945
|
provide: 'limitActionGlobalTimeRun',
|
|
860
946
|
useValue: 500,
|
|
@@ -996,6 +1082,58 @@ CacheModule = __decorate([
|
|
|
996
1082
|
})
|
|
997
1083
|
], CacheModule);
|
|
998
1084
|
|
|
1085
|
+
const EMPTY_VALUES = {};
|
|
1086
|
+
const normalizeOptions = (nameOrOptions) => {
|
|
1087
|
+
return typeof nameOrOptions === 'string' ? { name: nameOrOptions } : nameOrOptions;
|
|
1088
|
+
};
|
|
1089
|
+
class ExecutionContextManager {
|
|
1090
|
+
async withContext(parentContext, nameOrOptions, cb) {
|
|
1091
|
+
const options = normalizeOptions(nameOrOptions);
|
|
1092
|
+
const { name, values: selfValues = EMPTY_VALUES } = options;
|
|
1093
|
+
const contextName = parentContext ? `${parentContext.name}.${name}` : name;
|
|
1094
|
+
if (parentContext === null || parentContext === void 0 ? void 0 : parentContext.abortSignal.aborted) {
|
|
1095
|
+
throw new ExecutionAbortError({
|
|
1096
|
+
message: `Execution aborted in context "${contextName}"`,
|
|
1097
|
+
contextName,
|
|
1098
|
+
});
|
|
1099
|
+
}
|
|
1100
|
+
const abortController = new AbortController();
|
|
1101
|
+
let abortListener;
|
|
1102
|
+
let values = selfValues;
|
|
1103
|
+
if (parentContext) {
|
|
1104
|
+
values = {
|
|
1105
|
+
...parentContext.values,
|
|
1106
|
+
...selfValues,
|
|
1107
|
+
};
|
|
1108
|
+
abortListener = () => {
|
|
1109
|
+
abortController.abort();
|
|
1110
|
+
};
|
|
1111
|
+
// abort child context AbortController if parent AbortController was aborted
|
|
1112
|
+
parentContext.abortSignal.addEventListener('abort', abortListener);
|
|
1113
|
+
}
|
|
1114
|
+
const context = {
|
|
1115
|
+
name: contextName,
|
|
1116
|
+
abortSignal: abortController.signal,
|
|
1117
|
+
values,
|
|
1118
|
+
};
|
|
1119
|
+
try {
|
|
1120
|
+
const result = await cb(context, abortController);
|
|
1121
|
+
return result;
|
|
1122
|
+
}
|
|
1123
|
+
catch (error) {
|
|
1124
|
+
if (!error.executionContextName) {
|
|
1125
|
+
error.executionContextName = context.name;
|
|
1126
|
+
}
|
|
1127
|
+
throw error;
|
|
1128
|
+
}
|
|
1129
|
+
finally {
|
|
1130
|
+
if (abortListener) {
|
|
1131
|
+
parentContext.abortSignal.removeEventListener('abort', abortListener);
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
|
|
999
1137
|
let CommonModule = class CommonModule {
|
|
1000
1138
|
};
|
|
1001
1139
|
CommonModule = __decorate([
|
|
@@ -1013,13 +1151,13 @@ CommonModule = __decorate([
|
|
|
1013
1151
|
CacheModule,
|
|
1014
1152
|
],
|
|
1015
1153
|
providers: [
|
|
1016
|
-
provide({
|
|
1154
|
+
provide$1({
|
|
1017
1155
|
// Инстанс хук системы
|
|
1018
1156
|
provide: HOOK_TOKEN,
|
|
1019
1157
|
scope: Scope.SINGLETON,
|
|
1020
1158
|
useClass: Hooks,
|
|
1021
1159
|
}),
|
|
1022
|
-
provide({
|
|
1160
|
+
provide$1({
|
|
1023
1161
|
// Регистр ui компонентов
|
|
1024
1162
|
provide: COMPONENT_REGISTRY_TOKEN,
|
|
1025
1163
|
scope: Scope.SINGLETON,
|
|
@@ -1028,7 +1166,7 @@ CommonModule = __decorate([
|
|
|
1028
1166
|
componentList: { token: 'componentDefaultList', optional: true },
|
|
1029
1167
|
},
|
|
1030
1168
|
}),
|
|
1031
|
-
provide({
|
|
1169
|
+
provide$1({
|
|
1032
1170
|
// Управление бандлами, хранение и получение
|
|
1033
1171
|
provide: BUNDLE_MANAGER_TOKEN,
|
|
1034
1172
|
scope: Scope.SINGLETON,
|
|
@@ -1054,7 +1192,7 @@ CommonModule = __decorate([
|
|
|
1054
1192
|
logger: LOGGER_TOKEN,
|
|
1055
1193
|
},
|
|
1056
1194
|
}),
|
|
1057
|
-
provide({
|
|
1195
|
+
provide$1({
|
|
1058
1196
|
// Клиентский контекст исполнения
|
|
1059
1197
|
provide: CONTEXT_TOKEN,
|
|
1060
1198
|
scope: Scope.REQUEST,
|
|
@@ -1066,6 +1204,10 @@ CommonModule = __decorate([
|
|
|
1066
1204
|
store: STORE_TOKEN,
|
|
1067
1205
|
},
|
|
1068
1206
|
}),
|
|
1207
|
+
provide$1({
|
|
1208
|
+
provide: EXECUTION_CONTEXT_MANAGER_TOKEN,
|
|
1209
|
+
useClass: ExecutionContextManager,
|
|
1210
|
+
}),
|
|
1069
1211
|
...providers$2,
|
|
1070
1212
|
],
|
|
1071
1213
|
})
|
|
@@ -1074,7 +1216,7 @@ CommonModule = __decorate([
|
|
|
1074
1216
|
const providers = [];
|
|
1075
1217
|
|
|
1076
1218
|
const stateProviders = [
|
|
1077
|
-
provide({
|
|
1219
|
+
provide$1({
|
|
1078
1220
|
provide: CHILD_APP_INTERNAL_ROOT_DI_BORROW_TOKEN,
|
|
1079
1221
|
multi: true,
|
|
1080
1222
|
useValue: [DISPATCHER_TOKEN, STORE_TOKEN, CONTEXT_TOKEN],
|
|
@@ -1100,12 +1242,12 @@ const lines = {
|
|
|
1100
1242
|
client: command,
|
|
1101
1243
|
};
|
|
1102
1244
|
const commandProviders = [
|
|
1103
|
-
provide({
|
|
1245
|
+
provide$1({
|
|
1104
1246
|
provide: CHILD_APP_INTERNAL_ROOT_DI_BORROW_TOKEN,
|
|
1105
1247
|
multi: true,
|
|
1106
1248
|
useValue: COMMAND_LINE_RUNNER_TOKEN,
|
|
1107
1249
|
}),
|
|
1108
|
-
provide({
|
|
1250
|
+
provide$1({
|
|
1109
1251
|
provide: COMMAND_LINES_TOKEN,
|
|
1110
1252
|
scope: Scope.SINGLETON,
|
|
1111
1253
|
useValue: lines,
|
|
@@ -1113,7 +1255,7 @@ const commandProviders = [
|
|
|
1113
1255
|
];
|
|
1114
1256
|
|
|
1115
1257
|
const actionsProviders = [
|
|
1116
|
-
provide({
|
|
1258
|
+
provide$1({
|
|
1117
1259
|
provide: CHILD_APP_INTERNAL_ROOT_DI_BORROW_TOKEN,
|
|
1118
1260
|
multi: true,
|
|
1119
1261
|
useValue: [ACTION_EXECUTION_TOKEN, ACTION_PAGE_RUNNER_TOKEN],
|
|
@@ -1134,7 +1276,7 @@ CommonChildAppModule = __decorate([
|
|
|
1134
1276
|
...stateProviders,
|
|
1135
1277
|
...commandProviders,
|
|
1136
1278
|
...actionsProviders,
|
|
1137
|
-
provide({
|
|
1279
|
+
provide$1({
|
|
1138
1280
|
provide: EXTEND_RENDER,
|
|
1139
1281
|
multi: true,
|
|
1140
1282
|
useFactory: ({ context }) => {
|
|
@@ -1151,4 +1293,4 @@ CommonChildAppModule = __decorate([
|
|
|
1151
1293
|
})
|
|
1152
1294
|
], CommonChildAppModule);
|
|
1153
1295
|
|
|
1154
|
-
export { ActionExecution, CommandModule, CommonChildAppModule, CommonModule, alwaysCondition, createConsumerContext, onlyBrowser, onlyServer, pageBrowser, pageServer };
|
|
1296
|
+
export { ActionExecution, CommandModule, CommonChildAppModule, CommonModule, ExecutionContextManager, alwaysCondition, createConsumerContext, onlyBrowser, onlyServer, pageBrowser, pageServer };
|