@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.browser.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, provide, commandLineListTokens, COMMAND_LINE_RUNNER_TOKEN, COMMAND_LINES_TOKEN, DI_TOKEN, ACTION_PARAMETERS, ACTIONS_LIST_TOKEN, IS_DI_CHILD_CONTAINER_TOKEN, BUNDLE_LIST_TOKEN } from '@tramvai/core';
|
|
3
|
+
import { createBundle, Scope, Module, provide, commandLineListTokens, COMMAND_LINE_RUNNER_TOKEN, COMMAND_LINES_TOKEN, DI_TOKEN, isTramvaiAction, ACTION_PARAMETERS, ACTIONS_LIST_TOKEN, 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, STORE_TOKEN, RESPONSE_MANAGER_TOKEN, RESPONSE, ACTION_EXECUTION_TOKEN, LOGGER_TOKEN, PUBSUB_FACTORY_TOKEN, PUBSUB_TOKEN, ROOT_PUBSUB_TOKEN, INITIAL_APP_STATE_TOKEN, ACTION_REGISTRY_TOKEN, ACTION_CONDITIONALS, CONTEXT_TOKEN, ACTION_PAGE_RUNNER_TOKEN, DISPATCHER_TOKEN, DISPATCHER_CONTEXT_TOKEN, STORE_MIDDLEWARE, CREATE_CACHE_TOKEN, CLEAR_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, STORE_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, INITIAL_APP_STATE_TOKEN, ACTION_REGISTRY_TOKEN, ACTION_CONDITIONALS, CONTEXT_TOKEN, ACTION_PAGE_RUNNER_TOKEN, DISPATCHER_TOKEN, DISPATCHER_CONTEXT_TOKEN, STORE_MIDDLEWARE, CREATE_CACHE_TOKEN, CLEAR_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 as provide$1, 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';
|
|
@@ -28,6 +27,7 @@ import uniq from '@tinkoff/utils/array/uniq';
|
|
|
28
27
|
import difference from '@tinkoff/utils/array/difference';
|
|
29
28
|
import toArray from '@tinkoff/utils/array/toArray';
|
|
30
29
|
import LRU from '@tinkoff/lru-cache-nano';
|
|
30
|
+
import { AbortController } from 'node-abort-controller';
|
|
31
31
|
import { jsx } from 'react/jsx-runtime';
|
|
32
32
|
import { EXTEND_RENDER } from '@tramvai/tokens-render';
|
|
33
33
|
import { CHILD_APP_COMMON_INITIAL_STATE_TOKEN, CHILD_APP_INTERNAL_CONFIG_TOKEN, CHILD_APP_INTERNAL_ROOT_DI_BORROW_TOKEN, commandLineListTokens as commandLineListTokens$1 } from '@tramvai/tokens-child-app';
|
|
@@ -75,24 +75,17 @@ class BundleManager {
|
|
|
75
75
|
// preload `lazy` components then register actions and reducers
|
|
76
76
|
if (pageComponent && bundle.components[pageComponent]) {
|
|
77
77
|
const componentOrLoader = bundle.components[pageComponent];
|
|
78
|
-
const component =
|
|
79
|
-
? (await componentOrLoader.load()).default
|
|
80
|
-
: componentOrLoader;
|
|
81
|
-
// manually hoist static properties from preloaded component to loadable wrapper,
|
|
82
|
-
// this open access to current page component static properties outside before rendering
|
|
83
|
-
if (componentOrLoader !== component) {
|
|
84
|
-
hoistNonReactStatics(componentOrLoader, component);
|
|
85
|
-
}
|
|
78
|
+
const component = await resolveLazyComponent(componentOrLoader);
|
|
86
79
|
// allow page components to register any other components
|
|
87
|
-
if (component
|
|
80
|
+
if ('components' in component) {
|
|
88
81
|
eachObj((cmp, name) => {
|
|
89
82
|
this.componentRegistry.add(name, cmp, pageComponent);
|
|
90
83
|
}, component.components);
|
|
91
84
|
}
|
|
92
|
-
if (component
|
|
85
|
+
if ('actions' in component) {
|
|
93
86
|
this.actionRegistry.add(pageComponent, component.actions);
|
|
94
87
|
}
|
|
95
|
-
if (component
|
|
88
|
+
if ('reducers' in component) {
|
|
96
89
|
component.reducers.forEach((reducer) => {
|
|
97
90
|
this.dispatcher.registerStore(reducer);
|
|
98
91
|
});
|
|
@@ -378,14 +371,18 @@ const resolveDi = (type, status, diContainer, providers) => {
|
|
|
378
371
|
return di;
|
|
379
372
|
};
|
|
380
373
|
class CommandLineRunner {
|
|
381
|
-
constructor({ lines, rootDi, logger, metrics, }) {
|
|
374
|
+
constructor({ lines, rootDi, logger, metrics, executionContextManager, }) {
|
|
375
|
+
this.executionContextByDi = new WeakMap();
|
|
376
|
+
this.abortControllerByDi = new WeakMap();
|
|
382
377
|
this.lines = lines;
|
|
383
378
|
this.rootDi = rootDi;
|
|
384
379
|
this.log = logger('command:command-line-runner');
|
|
385
380
|
this.metrics = metrics;
|
|
381
|
+
this.executionContextManager = executionContextManager;
|
|
386
382
|
}
|
|
387
383
|
run(type, status, providers, customDi) {
|
|
388
384
|
const di = customDi !== null && customDi !== void 0 ? customDi : resolveDi(type, status, this.rootDi, providers);
|
|
385
|
+
const rootExecutionContext = di.get({ token: ROOT_EXECUTION_CONTEXT_TOKEN, optional: true });
|
|
389
386
|
this.log.debug({
|
|
390
387
|
event: 'command-run',
|
|
391
388
|
type,
|
|
@@ -397,13 +394,27 @@ class CommandLineRunner {
|
|
|
397
394
|
const doneMetric = this.createDurationMetric();
|
|
398
395
|
// eslint-disable-next-line promise/no-nesting
|
|
399
396
|
return Promise.resolve()
|
|
400
|
-
.then(() =>
|
|
397
|
+
.then(() => {
|
|
398
|
+
return this.executionContextManager.withContext(rootExecutionContext, `command-line:${line.toString()}`, async (executionContext, abortController) => {
|
|
399
|
+
this.executionContextByDi.set(di, executionContext);
|
|
400
|
+
this.abortControllerByDi.set(di, abortController);
|
|
401
|
+
await this.createLineChain(di, line);
|
|
402
|
+
});
|
|
403
|
+
})
|
|
401
404
|
.finally(() => doneMetric({ line: line.toString() }));
|
|
402
405
|
});
|
|
403
406
|
}, Promise.resolve())
|
|
404
407
|
// После завершения цепочки отдаем context выполнения
|
|
408
|
+
.finally(() => {
|
|
409
|
+
this.executionContextByDi.delete(di);
|
|
410
|
+
this.abortControllerByDi.delete(di);
|
|
411
|
+
})
|
|
405
412
|
.then(() => di));
|
|
406
413
|
}
|
|
414
|
+
resolveExecutionContextFromDi(di) {
|
|
415
|
+
var _a;
|
|
416
|
+
return (_a = this.executionContextByDi.get(di)) !== null && _a !== void 0 ? _a : null;
|
|
417
|
+
}
|
|
407
418
|
createLineChain(di, line) {
|
|
408
419
|
let lineInstance;
|
|
409
420
|
try {
|
|
@@ -455,12 +466,15 @@ class CommandLineRunner {
|
|
|
455
466
|
return Promise.resolve()
|
|
456
467
|
.then(() => instance())
|
|
457
468
|
.catch((err) => {
|
|
469
|
+
var _a;
|
|
458
470
|
this.log[isSilentError(err) ? 'debug' : 'error']({
|
|
459
471
|
event: 'line-error',
|
|
460
472
|
error: err,
|
|
461
473
|
line: line.toString(),
|
|
462
474
|
command: name,
|
|
463
475
|
});
|
|
476
|
+
// in case if any error happens during line execution results from other line handlers will not be used anyway
|
|
477
|
+
(_a = this.abortControllerByDi.get(di)) === null || _a === void 0 ? void 0 : _a.abort();
|
|
464
478
|
this.throwError(err, di);
|
|
465
479
|
});
|
|
466
480
|
}
|
|
@@ -514,7 +528,7 @@ let CommandModule = class CommandModule {
|
|
|
514
528
|
CommandModule = __decorate([
|
|
515
529
|
Module({
|
|
516
530
|
providers: [
|
|
517
|
-
{
|
|
531
|
+
provide$1({
|
|
518
532
|
// Раннер процессов
|
|
519
533
|
provide: COMMAND_LINE_RUNNER_TOKEN,
|
|
520
534
|
scope: Scope$1.SINGLETON,
|
|
@@ -527,14 +541,27 @@ CommandModule = __decorate([
|
|
|
527
541
|
token: METRICS_MODULE_TOKEN,
|
|
528
542
|
optional: true,
|
|
529
543
|
},
|
|
544
|
+
executionContextManager: EXECUTION_CONTEXT_MANAGER_TOKEN,
|
|
530
545
|
},
|
|
531
|
-
},
|
|
532
|
-
{
|
|
546
|
+
}),
|
|
547
|
+
provide$1({
|
|
548
|
+
provide: COMMAND_LINE_EXECUTION_CONTEXT_TOKEN,
|
|
549
|
+
useFactory: ({ di, commandLineRunner, }) => {
|
|
550
|
+
return () => {
|
|
551
|
+
return commandLineRunner.resolveExecutionContextFromDi(di);
|
|
552
|
+
};
|
|
553
|
+
},
|
|
554
|
+
deps: {
|
|
555
|
+
di: DI_TOKEN,
|
|
556
|
+
commandLineRunner: COMMAND_LINE_RUNNER_TOKEN,
|
|
557
|
+
},
|
|
558
|
+
}),
|
|
559
|
+
provide$1({
|
|
533
560
|
// Дефолтный список команл
|
|
534
561
|
provide: COMMAND_LINES_TOKEN,
|
|
535
562
|
scope: Scope$1.SINGLETON,
|
|
536
563
|
useValue: lines$1,
|
|
537
|
-
},
|
|
564
|
+
}),
|
|
538
565
|
],
|
|
539
566
|
})
|
|
540
567
|
], CommandModule);
|
|
@@ -602,14 +629,19 @@ const actionTramvaiReducer = createReducer('actionTramvai', initalState).on(acti
|
|
|
602
629
|
serverState: payload,
|
|
603
630
|
}));
|
|
604
631
|
|
|
632
|
+
/**
|
|
633
|
+
* @deprecated only for compatibility with legacy createAction
|
|
634
|
+
*/
|
|
605
635
|
const actionType = {
|
|
606
636
|
global: 'global',
|
|
607
637
|
local: 'local',
|
|
608
638
|
};
|
|
609
639
|
|
|
640
|
+
const DEFAULT_CONDITIONS = {};
|
|
610
641
|
class ActionChecker {
|
|
611
642
|
// eslint-disable-next-line max-params
|
|
612
643
|
constructor(globalConditionals, payload, parameters, executionState, type) {
|
|
644
|
+
var _a;
|
|
613
645
|
this.globalConditionals = globalConditionals;
|
|
614
646
|
this.payload = payload;
|
|
615
647
|
this.parameters = parameters;
|
|
@@ -623,7 +655,7 @@ class ActionChecker {
|
|
|
623
655
|
// если экшен был уже выполнен, то считаем, что его не нужно больше выполнять
|
|
624
656
|
this.status = executionState.status !== 'success';
|
|
625
657
|
}
|
|
626
|
-
this.conditions = parameters.conditions;
|
|
658
|
+
this.conditions = (_a = parameters.conditions) !== null && _a !== void 0 ? _a : DEFAULT_CONDITIONS;
|
|
627
659
|
}
|
|
628
660
|
check() {
|
|
629
661
|
this.globalConditionals.forEach((filter) => {
|
|
@@ -640,6 +672,7 @@ class ActionChecker {
|
|
|
640
672
|
}
|
|
641
673
|
forbid() {
|
|
642
674
|
this.executionState.status = 'forbidden';
|
|
675
|
+
this.executionState.forbiddenBy = this.key;
|
|
643
676
|
this.forbiddenMarker = true;
|
|
644
677
|
}
|
|
645
678
|
allow() {
|
|
@@ -653,12 +686,16 @@ class ActionChecker {
|
|
|
653
686
|
}
|
|
654
687
|
}
|
|
655
688
|
|
|
689
|
+
const EMPTY_DEPS = {};
|
|
690
|
+
const DEFAULT_PAYLOAD = {};
|
|
656
691
|
const getParameters = (action) => action[ACTION_PARAMETERS];
|
|
657
692
|
class ActionExecution {
|
|
658
|
-
constructor({
|
|
693
|
+
constructor({ store, context, di, executionContextManager, actionConditionals, transformAction, }) {
|
|
659
694
|
this.actionConditionals = flatten(actionConditionals !== null && actionConditionals !== void 0 ? actionConditionals : []);
|
|
660
695
|
this.context = context;
|
|
696
|
+
this.store = store;
|
|
661
697
|
this.di = di;
|
|
698
|
+
this.executionContextManager = executionContextManager;
|
|
662
699
|
this.execution = new Map();
|
|
663
700
|
this.transformAction = transformAction || identity;
|
|
664
701
|
const initialState = store.getState(actionTramvaiReducer);
|
|
@@ -668,32 +705,64 @@ class ActionExecution {
|
|
|
668
705
|
}, initialState.serverState);
|
|
669
706
|
}
|
|
670
707
|
}
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
const
|
|
675
|
-
|
|
708
|
+
async runInContext(executionContext, action, ...params) {
|
|
709
|
+
var _a, _b;
|
|
710
|
+
let parameters;
|
|
711
|
+
const payload = (_a = params[0]) !== null && _a !== void 0 ? _a : DEFAULT_PAYLOAD;
|
|
712
|
+
// TODO: replace type with pure context usage
|
|
713
|
+
const type = (executionContext === null || executionContext === void 0 ? void 0 : executionContext.values.pageActions) === true ? actionType.global : actionType.local;
|
|
714
|
+
// TODO: remove else branch after migration to new declareAction
|
|
715
|
+
if (isTramvaiAction(action)) {
|
|
716
|
+
parameters = action;
|
|
717
|
+
}
|
|
718
|
+
else {
|
|
719
|
+
this.transformAction(action);
|
|
720
|
+
parameters = getParameters(action);
|
|
721
|
+
}
|
|
722
|
+
const executionState = this.getExecutionState(parameters.name);
|
|
676
723
|
if (!this.canExecuteAction(payload, parameters, executionState, type)) {
|
|
677
|
-
|
|
724
|
+
switch (parameters.conditionsFailResult) {
|
|
725
|
+
case 'reject':
|
|
726
|
+
return Promise.reject(new ConditionFailError({
|
|
727
|
+
conditionName: (_b = executionState.forbiddenBy) !== null && _b !== void 0 ? _b : 'unknown',
|
|
728
|
+
targetName: parameters.name,
|
|
729
|
+
}));
|
|
730
|
+
default:
|
|
731
|
+
return Promise.resolve();
|
|
732
|
+
}
|
|
678
733
|
}
|
|
679
|
-
const deps = parameters.deps ? this.di.getOfDeps(parameters.deps) : {};
|
|
680
734
|
executionState.status = 'pending';
|
|
681
|
-
return
|
|
682
|
-
|
|
683
|
-
.
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
735
|
+
return this.executionContextManager.withContext(executionContext, {
|
|
736
|
+
name: parameters.name,
|
|
737
|
+
values: (executionContext === null || executionContext === void 0 ? void 0 : executionContext.values.pageActions) === true ? { pageActions: false } : undefined,
|
|
738
|
+
}, (executionActionContext, abortController) => {
|
|
739
|
+
const context = this.createActionContext(executionContext, executionActionContext, abortController, parameters);
|
|
740
|
+
return Promise.resolve()
|
|
741
|
+
.then(() => {
|
|
742
|
+
if (isTramvaiAction(action)) {
|
|
743
|
+
return action.fn.apply(context, params);
|
|
744
|
+
}
|
|
745
|
+
return action(this.context, payload, context.deps);
|
|
746
|
+
})
|
|
747
|
+
.then((data) => {
|
|
748
|
+
executionState.status = 'success';
|
|
749
|
+
return data;
|
|
750
|
+
})
|
|
751
|
+
.catch((err) => {
|
|
752
|
+
executionState.status = 'failed';
|
|
753
|
+
throw err;
|
|
754
|
+
});
|
|
690
755
|
});
|
|
691
756
|
}
|
|
692
|
-
|
|
693
|
-
|
|
757
|
+
async run(action, ...params) {
|
|
758
|
+
return this.runInContext(null, action, ...params);
|
|
759
|
+
}
|
|
760
|
+
getExecutionState(name) {
|
|
761
|
+
let executionState = this.execution.get(name);
|
|
762
|
+
// TODO: probably do not need to create executionState on client as it is not used
|
|
694
763
|
if (!executionState) {
|
|
695
764
|
executionState = { status: 'pending', state: {} };
|
|
696
|
-
this.execution.set(
|
|
765
|
+
this.execution.set(name, executionState);
|
|
697
766
|
}
|
|
698
767
|
return executionState;
|
|
699
768
|
}
|
|
@@ -701,6 +770,17 @@ class ActionExecution {
|
|
|
701
770
|
const actionChecker = new ActionChecker(this.actionConditionals, payload, parameters, executionState, type);
|
|
702
771
|
return actionChecker.check();
|
|
703
772
|
}
|
|
773
|
+
createActionContext(parentExecutionContext, actionExecutionContext, abortController, parameters) {
|
|
774
|
+
return {
|
|
775
|
+
abortController,
|
|
776
|
+
abortSignal: actionExecutionContext === null || actionExecutionContext === void 0 ? void 0 : actionExecutionContext.abortSignal,
|
|
777
|
+
executeAction: this.runInContext.bind(this, actionExecutionContext),
|
|
778
|
+
deps: parameters.deps ? this.di.getOfDeps(parameters.deps) : EMPTY_DEPS,
|
|
779
|
+
actionType: (parentExecutionContext === null || parentExecutionContext === void 0 ? void 0 : parentExecutionContext.values.pageActions) ? 'page' : 'standalone',
|
|
780
|
+
dispatch: this.store.dispatch,
|
|
781
|
+
getState: this.store.getState,
|
|
782
|
+
};
|
|
783
|
+
}
|
|
704
784
|
}
|
|
705
785
|
|
|
706
786
|
const GLOBAL_PARAMETER = '@@global';
|
|
@@ -730,29 +810,32 @@ class ActionRegistry {
|
|
|
730
810
|
}
|
|
731
811
|
}
|
|
732
812
|
|
|
733
|
-
const payload = {};
|
|
734
813
|
class ActionPageRunner {
|
|
735
|
-
constructor(
|
|
736
|
-
this.
|
|
737
|
-
this.log = logger('action:action-page-runner');
|
|
814
|
+
constructor(deps) {
|
|
815
|
+
this.deps = deps;
|
|
816
|
+
this.log = deps.logger('action:action-page-runner');
|
|
738
817
|
}
|
|
739
818
|
runActions(actions, stopRunAtError = () => false) {
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
819
|
+
return this.deps.executionContextManager.withContext(this.deps.commandLineExecutionContext(), { name: 'pageActions', values: { pageActions: true } }, async (executionContext) => {
|
|
820
|
+
const actionMapper = (action) => {
|
|
821
|
+
return Promise.resolve()
|
|
822
|
+
.then(() => this.deps.actionExecution.runInContext(executionContext, action))
|
|
823
|
+
.catch((error) => {
|
|
824
|
+
if (!isSilentError(error)) {
|
|
825
|
+
const parameters = isTramvaiAction(action) ? action : action[ACTION_PARAMETERS];
|
|
826
|
+
this.log.error({
|
|
827
|
+
error,
|
|
828
|
+
event: `action-execution-error`,
|
|
829
|
+
message: `${parameters.name} execution error`,
|
|
830
|
+
});
|
|
831
|
+
}
|
|
832
|
+
if (stopRunAtError(error)) {
|
|
833
|
+
throw error;
|
|
834
|
+
}
|
|
749
835
|
});
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
});
|
|
754
|
-
};
|
|
755
|
-
return Promise.all(actions.map(actionMapper));
|
|
836
|
+
};
|
|
837
|
+
await Promise.all(actions.map(actionMapper));
|
|
838
|
+
});
|
|
756
839
|
}
|
|
757
840
|
}
|
|
758
841
|
|
|
@@ -830,23 +913,26 @@ ActionModule = __decorate([
|
|
|
830
913
|
context: CONTEXT_TOKEN,
|
|
831
914
|
store: STORE_TOKEN,
|
|
832
915
|
di: DI_TOKEN,
|
|
916
|
+
executionContextManager: EXECUTION_CONTEXT_MANAGER_TOKEN,
|
|
833
917
|
transformAction: {
|
|
834
918
|
token: 'actionTransformAction',
|
|
835
919
|
optional: true,
|
|
836
920
|
},
|
|
837
921
|
},
|
|
838
922
|
}),
|
|
839
|
-
{
|
|
923
|
+
provide({
|
|
840
924
|
provide: ACTION_PAGE_RUNNER_TOKEN,
|
|
841
925
|
scope: Scope.REQUEST,
|
|
842
926
|
useClass: ActionPageRunner,
|
|
843
927
|
deps: {
|
|
844
928
|
actionExecution: ACTION_EXECUTION_TOKEN,
|
|
929
|
+
executionContextManager: EXECUTION_CONTEXT_MANAGER_TOKEN,
|
|
930
|
+
commandLineExecutionContext: COMMAND_LINE_EXECUTION_CONTEXT_TOKEN,
|
|
845
931
|
store: STORE_TOKEN,
|
|
846
932
|
limitTime: 'limitActionGlobalTimeRun',
|
|
847
933
|
logger: LOGGER_TOKEN,
|
|
848
934
|
},
|
|
849
|
-
},
|
|
935
|
+
}),
|
|
850
936
|
{
|
|
851
937
|
provide: 'limitActionGlobalTimeRun',
|
|
852
938
|
useValue: 500,
|
|
@@ -963,6 +1049,58 @@ CacheModule = __decorate([
|
|
|
963
1049
|
})
|
|
964
1050
|
], CacheModule);
|
|
965
1051
|
|
|
1052
|
+
const EMPTY_VALUES = {};
|
|
1053
|
+
const normalizeOptions = (nameOrOptions) => {
|
|
1054
|
+
return typeof nameOrOptions === 'string' ? { name: nameOrOptions } : nameOrOptions;
|
|
1055
|
+
};
|
|
1056
|
+
class ExecutionContextManager {
|
|
1057
|
+
async withContext(parentContext, nameOrOptions, cb) {
|
|
1058
|
+
const options = normalizeOptions(nameOrOptions);
|
|
1059
|
+
const { name, values: selfValues = EMPTY_VALUES } = options;
|
|
1060
|
+
const contextName = parentContext ? `${parentContext.name}.${name}` : name;
|
|
1061
|
+
if (parentContext === null || parentContext === void 0 ? void 0 : parentContext.abortSignal.aborted) {
|
|
1062
|
+
throw new ExecutionAbortError({
|
|
1063
|
+
message: `Execution aborted in context "${contextName}"`,
|
|
1064
|
+
contextName,
|
|
1065
|
+
});
|
|
1066
|
+
}
|
|
1067
|
+
const abortController = new AbortController();
|
|
1068
|
+
let abortListener;
|
|
1069
|
+
let values = selfValues;
|
|
1070
|
+
if (parentContext) {
|
|
1071
|
+
values = {
|
|
1072
|
+
...parentContext.values,
|
|
1073
|
+
...selfValues,
|
|
1074
|
+
};
|
|
1075
|
+
abortListener = () => {
|
|
1076
|
+
abortController.abort();
|
|
1077
|
+
};
|
|
1078
|
+
// abort child context AbortController if parent AbortController was aborted
|
|
1079
|
+
parentContext.abortSignal.addEventListener('abort', abortListener);
|
|
1080
|
+
}
|
|
1081
|
+
const context = {
|
|
1082
|
+
name: contextName,
|
|
1083
|
+
abortSignal: abortController.signal,
|
|
1084
|
+
values,
|
|
1085
|
+
};
|
|
1086
|
+
try {
|
|
1087
|
+
const result = await cb(context, abortController);
|
|
1088
|
+
return result;
|
|
1089
|
+
}
|
|
1090
|
+
catch (error) {
|
|
1091
|
+
if (!error.executionContextName) {
|
|
1092
|
+
error.executionContextName = context.name;
|
|
1093
|
+
}
|
|
1094
|
+
throw error;
|
|
1095
|
+
}
|
|
1096
|
+
finally {
|
|
1097
|
+
if (abortListener) {
|
|
1098
|
+
parentContext.abortSignal.removeEventListener('abort', abortListener);
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
|
|
966
1104
|
let CommonModule = class CommonModule {
|
|
967
1105
|
};
|
|
968
1106
|
CommonModule = __decorate([
|
|
@@ -1033,6 +1171,10 @@ CommonModule = __decorate([
|
|
|
1033
1171
|
store: STORE_TOKEN,
|
|
1034
1172
|
},
|
|
1035
1173
|
}),
|
|
1174
|
+
provide({
|
|
1175
|
+
provide: EXECUTION_CONTEXT_MANAGER_TOKEN,
|
|
1176
|
+
useClass: ExecutionContextManager,
|
|
1177
|
+
}),
|
|
1036
1178
|
...providers$2,
|
|
1037
1179
|
],
|
|
1038
1180
|
})
|
|
@@ -1129,4 +1271,4 @@ CommonChildAppModule = __decorate([
|
|
|
1129
1271
|
})
|
|
1130
1272
|
], CommonChildAppModule);
|
|
1131
1273
|
|
|
1132
|
-
export { ActionExecution, CommandModule, CommonChildAppModule, CommonModule, alwaysCondition, createConsumerContext, onlyBrowser, onlyServer, pageBrowser, pageServer };
|
|
1274
|
+
export { ActionExecution, CommandModule, CommonChildAppModule, CommonModule, ExecutionContextManager, alwaysCondition, createConsumerContext, onlyBrowser, onlyServer, pageBrowser, pageServer };
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { CommonModule } from './CommonModule';
|
|
2
2
|
export { CommandModule } from './command/CommandModule';
|
|
3
3
|
export { ActionExecution } from './actions/actionExecution';
|
|
4
|
+
export { ExecutionContextManager } from './executionContext/executionContextManager';
|
|
4
5
|
export { alwaysCondition, onlyServer, onlyBrowser, pageServer, pageBrowser, } from './actions/ActionModule';
|
|
5
6
|
export { createConsumerContext } from './createConsumerContext/createConsumerContext';
|
|
6
7
|
export { CommonChildAppModule } from './child-app/ChildAppModule';
|