@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.js
CHANGED
|
@@ -12,7 +12,6 @@ var hookRunner = require('@tinkoff/hook-runner');
|
|
|
12
12
|
var tokensCommon = require('@tramvai/tokens-common');
|
|
13
13
|
var react = require('@tramvai/react');
|
|
14
14
|
var experiments = require('@tramvai/experiments');
|
|
15
|
-
var hoistNonReactStatics = require('hoist-non-react-statics');
|
|
16
15
|
var pathOr = require('@tinkoff/utils/object/pathOr');
|
|
17
16
|
var flatten = require('@tinkoff/utils/array/flatten');
|
|
18
17
|
var state = require('@tramvai/state');
|
|
@@ -32,6 +31,7 @@ var toArray = require('@tinkoff/utils/array/toArray');
|
|
|
32
31
|
var LRU = require('@tinkoff/lru-cache-nano');
|
|
33
32
|
var tokensServer = require('@tramvai/tokens-server');
|
|
34
33
|
var papi = require('@tramvai/papi');
|
|
34
|
+
var nodeAbortController = require('node-abort-controller');
|
|
35
35
|
var jsxRuntime = require('react/jsx-runtime');
|
|
36
36
|
var tokensRender = require('@tramvai/tokens-render');
|
|
37
37
|
var tokensChildApp = require('@tramvai/tokens-child-app');
|
|
@@ -39,7 +39,6 @@ var tokensChildApp = require('@tramvai/tokens-child-app');
|
|
|
39
39
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
40
40
|
|
|
41
41
|
var eachObj__default = /*#__PURE__*/_interopDefaultLegacy(eachObj);
|
|
42
|
-
var hoistNonReactStatics__default = /*#__PURE__*/_interopDefaultLegacy(hoistNonReactStatics);
|
|
43
42
|
var pathOr__default = /*#__PURE__*/_interopDefaultLegacy(pathOr);
|
|
44
43
|
var flatten__default = /*#__PURE__*/_interopDefaultLegacy(flatten);
|
|
45
44
|
var isEmpty__default = /*#__PURE__*/_interopDefaultLegacy(isEmpty);
|
|
@@ -95,24 +94,17 @@ class BundleManager {
|
|
|
95
94
|
// preload `lazy` components then register actions and reducers
|
|
96
95
|
if (pageComponent && bundle.components[pageComponent]) {
|
|
97
96
|
const componentOrLoader = bundle.components[pageComponent];
|
|
98
|
-
const component =
|
|
99
|
-
? (await componentOrLoader.load()).default
|
|
100
|
-
: componentOrLoader;
|
|
101
|
-
// manually hoist static properties from preloaded component to loadable wrapper,
|
|
102
|
-
// this open access to current page component static properties outside before rendering
|
|
103
|
-
if (componentOrLoader !== component) {
|
|
104
|
-
hoistNonReactStatics__default["default"](componentOrLoader, component);
|
|
105
|
-
}
|
|
97
|
+
const component = await react.resolveLazyComponent(componentOrLoader);
|
|
106
98
|
// allow page components to register any other components
|
|
107
|
-
if (component
|
|
99
|
+
if ('components' in component) {
|
|
108
100
|
eachObj__default["default"]((cmp, name) => {
|
|
109
101
|
this.componentRegistry.add(name, cmp, pageComponent);
|
|
110
102
|
}, component.components);
|
|
111
103
|
}
|
|
112
|
-
if (component
|
|
104
|
+
if ('actions' in component) {
|
|
113
105
|
this.actionRegistry.add(pageComponent, component.actions);
|
|
114
106
|
}
|
|
115
|
-
if (component
|
|
107
|
+
if ('reducers' in component) {
|
|
116
108
|
component.reducers.forEach((reducer) => {
|
|
117
109
|
this.dispatcher.registerStore(reducer);
|
|
118
110
|
});
|
|
@@ -393,14 +385,18 @@ const resolveDi = (type, status, diContainer, providers) => {
|
|
|
393
385
|
return di;
|
|
394
386
|
};
|
|
395
387
|
class CommandLineRunner {
|
|
396
|
-
constructor({ lines, rootDi, logger, metrics, }) {
|
|
388
|
+
constructor({ lines, rootDi, logger, metrics, executionContextManager, }) {
|
|
389
|
+
this.executionContextByDi = new WeakMap();
|
|
390
|
+
this.abortControllerByDi = new WeakMap();
|
|
397
391
|
this.lines = lines;
|
|
398
392
|
this.rootDi = rootDi;
|
|
399
393
|
this.log = logger('command:command-line-runner');
|
|
400
394
|
this.metrics = metrics;
|
|
395
|
+
this.executionContextManager = executionContextManager;
|
|
401
396
|
}
|
|
402
397
|
run(type, status, providers, customDi) {
|
|
403
398
|
const di = customDi !== null && customDi !== void 0 ? customDi : resolveDi(type, status, this.rootDi, providers);
|
|
399
|
+
const rootExecutionContext = di.get({ token: tokensCommon.ROOT_EXECUTION_CONTEXT_TOKEN, optional: true });
|
|
404
400
|
this.log.debug({
|
|
405
401
|
event: 'command-run',
|
|
406
402
|
type,
|
|
@@ -412,13 +408,27 @@ class CommandLineRunner {
|
|
|
412
408
|
const doneMetric = this.createDurationMetric();
|
|
413
409
|
// eslint-disable-next-line promise/no-nesting
|
|
414
410
|
return Promise.resolve()
|
|
415
|
-
.then(() =>
|
|
411
|
+
.then(() => {
|
|
412
|
+
return this.executionContextManager.withContext(rootExecutionContext, `command-line:${line.toString()}`, async (executionContext, abortController) => {
|
|
413
|
+
this.executionContextByDi.set(di, executionContext);
|
|
414
|
+
this.abortControllerByDi.set(di, abortController);
|
|
415
|
+
await this.createLineChain(di, line);
|
|
416
|
+
});
|
|
417
|
+
})
|
|
416
418
|
.finally(() => doneMetric({ line: line.toString() }));
|
|
417
419
|
});
|
|
418
420
|
}, Promise.resolve())
|
|
419
421
|
// После завершения цепочки отдаем context выполнения
|
|
422
|
+
.finally(() => {
|
|
423
|
+
this.executionContextByDi.delete(di);
|
|
424
|
+
this.abortControllerByDi.delete(di);
|
|
425
|
+
})
|
|
420
426
|
.then(() => di));
|
|
421
427
|
}
|
|
428
|
+
resolveExecutionContextFromDi(di) {
|
|
429
|
+
var _a;
|
|
430
|
+
return (_a = this.executionContextByDi.get(di)) !== null && _a !== void 0 ? _a : null;
|
|
431
|
+
}
|
|
422
432
|
createLineChain(di, line) {
|
|
423
433
|
let lineInstance;
|
|
424
434
|
try {
|
|
@@ -470,12 +480,15 @@ class CommandLineRunner {
|
|
|
470
480
|
return Promise.resolve()
|
|
471
481
|
.then(() => instance())
|
|
472
482
|
.catch((err) => {
|
|
483
|
+
var _a;
|
|
473
484
|
this.log[errors.isSilentError(err) ? 'debug' : 'error']({
|
|
474
485
|
event: 'line-error',
|
|
475
486
|
error: err,
|
|
476
487
|
line: line.toString(),
|
|
477
488
|
command: name,
|
|
478
489
|
});
|
|
490
|
+
// in case if any error happens during line execution results from other line handlers will not be used anyway
|
|
491
|
+
(_a = this.abortControllerByDi.get(di)) === null || _a === void 0 ? void 0 : _a.abort();
|
|
479
492
|
this.throwError(err, di);
|
|
480
493
|
});
|
|
481
494
|
}
|
|
@@ -529,7 +542,7 @@ exports.CommandModule = class CommandModule {
|
|
|
529
542
|
exports.CommandModule = tslib.__decorate([
|
|
530
543
|
core.Module({
|
|
531
544
|
providers: [
|
|
532
|
-
{
|
|
545
|
+
dippy.provide({
|
|
533
546
|
// Раннер процессов
|
|
534
547
|
provide: core.COMMAND_LINE_RUNNER_TOKEN,
|
|
535
548
|
scope: dippy.Scope.SINGLETON,
|
|
@@ -542,14 +555,27 @@ exports.CommandModule = tslib.__decorate([
|
|
|
542
555
|
token: tokensMetrics.METRICS_MODULE_TOKEN,
|
|
543
556
|
optional: true,
|
|
544
557
|
},
|
|
558
|
+
executionContextManager: tokensCommon.EXECUTION_CONTEXT_MANAGER_TOKEN,
|
|
545
559
|
},
|
|
546
|
-
},
|
|
547
|
-
{
|
|
560
|
+
}),
|
|
561
|
+
dippy.provide({
|
|
562
|
+
provide: tokensCommon.COMMAND_LINE_EXECUTION_CONTEXT_TOKEN,
|
|
563
|
+
useFactory: ({ di, commandLineRunner, }) => {
|
|
564
|
+
return () => {
|
|
565
|
+
return commandLineRunner.resolveExecutionContextFromDi(di);
|
|
566
|
+
};
|
|
567
|
+
},
|
|
568
|
+
deps: {
|
|
569
|
+
di: core.DI_TOKEN,
|
|
570
|
+
commandLineRunner: core.COMMAND_LINE_RUNNER_TOKEN,
|
|
571
|
+
},
|
|
572
|
+
}),
|
|
573
|
+
dippy.provide({
|
|
548
574
|
// Дефолтный список команл
|
|
549
575
|
provide: core.COMMAND_LINES_TOKEN,
|
|
550
576
|
scope: dippy.Scope.SINGLETON,
|
|
551
577
|
useValue: lines$1,
|
|
552
|
-
},
|
|
578
|
+
}),
|
|
553
579
|
],
|
|
554
580
|
})
|
|
555
581
|
], exports.CommandModule);
|
|
@@ -601,14 +627,19 @@ const actionTramvaiReducer = state.createReducer('actionTramvai', initalState).o
|
|
|
601
627
|
serverState: payload,
|
|
602
628
|
}));
|
|
603
629
|
|
|
630
|
+
/**
|
|
631
|
+
* @deprecated only for compatibility with legacy createAction
|
|
632
|
+
*/
|
|
604
633
|
const actionType = {
|
|
605
634
|
global: 'global',
|
|
606
635
|
local: 'local',
|
|
607
636
|
};
|
|
608
637
|
|
|
638
|
+
const DEFAULT_CONDITIONS = {};
|
|
609
639
|
class ActionChecker {
|
|
610
640
|
// eslint-disable-next-line max-params
|
|
611
641
|
constructor(globalConditionals, payload, parameters, executionState, type) {
|
|
642
|
+
var _a;
|
|
612
643
|
this.globalConditionals = globalConditionals;
|
|
613
644
|
this.payload = payload;
|
|
614
645
|
this.parameters = parameters;
|
|
@@ -622,7 +653,7 @@ class ActionChecker {
|
|
|
622
653
|
// если экшен был уже выполнен, то считаем, что его не нужно больше выполнять
|
|
623
654
|
this.status = executionState.status !== 'success';
|
|
624
655
|
}
|
|
625
|
-
this.conditions = parameters.conditions;
|
|
656
|
+
this.conditions = (_a = parameters.conditions) !== null && _a !== void 0 ? _a : DEFAULT_CONDITIONS;
|
|
626
657
|
}
|
|
627
658
|
check() {
|
|
628
659
|
this.globalConditionals.forEach((filter) => {
|
|
@@ -639,6 +670,7 @@ class ActionChecker {
|
|
|
639
670
|
}
|
|
640
671
|
forbid() {
|
|
641
672
|
this.executionState.status = 'forbidden';
|
|
673
|
+
this.executionState.forbiddenBy = this.key;
|
|
642
674
|
this.forbiddenMarker = true;
|
|
643
675
|
}
|
|
644
676
|
allow() {
|
|
@@ -652,12 +684,16 @@ class ActionChecker {
|
|
|
652
684
|
}
|
|
653
685
|
}
|
|
654
686
|
|
|
687
|
+
const EMPTY_DEPS = {};
|
|
688
|
+
const DEFAULT_PAYLOAD = {};
|
|
655
689
|
const getParameters = (action) => action[core.ACTION_PARAMETERS];
|
|
656
690
|
class ActionExecution {
|
|
657
|
-
constructor({
|
|
691
|
+
constructor({ store, context, di, executionContextManager, actionConditionals, transformAction, }) {
|
|
658
692
|
this.actionConditionals = flatten__default["default"](actionConditionals !== null && actionConditionals !== void 0 ? actionConditionals : []);
|
|
659
693
|
this.context = context;
|
|
694
|
+
this.store = store;
|
|
660
695
|
this.di = di;
|
|
696
|
+
this.executionContextManager = executionContextManager;
|
|
661
697
|
this.execution = new Map();
|
|
662
698
|
this.transformAction = transformAction || identity__default["default"];
|
|
663
699
|
const initialState = store.getState(actionTramvaiReducer);
|
|
@@ -667,32 +703,64 @@ class ActionExecution {
|
|
|
667
703
|
}, initialState.serverState);
|
|
668
704
|
}
|
|
669
705
|
}
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
const
|
|
674
|
-
|
|
706
|
+
async runInContext(executionContext, action, ...params) {
|
|
707
|
+
var _a, _b;
|
|
708
|
+
let parameters;
|
|
709
|
+
const payload = (_a = params[0]) !== null && _a !== void 0 ? _a : DEFAULT_PAYLOAD;
|
|
710
|
+
// TODO: replace type with pure context usage
|
|
711
|
+
const type = (executionContext === null || executionContext === void 0 ? void 0 : executionContext.values.pageActions) === true ? actionType.global : actionType.local;
|
|
712
|
+
// TODO: remove else branch after migration to new declareAction
|
|
713
|
+
if (core.isTramvaiAction(action)) {
|
|
714
|
+
parameters = action;
|
|
715
|
+
}
|
|
716
|
+
else {
|
|
717
|
+
this.transformAction(action);
|
|
718
|
+
parameters = getParameters(action);
|
|
719
|
+
}
|
|
720
|
+
const executionState = this.getExecutionState(parameters.name);
|
|
675
721
|
if (!this.canExecuteAction(payload, parameters, executionState, type)) {
|
|
676
|
-
|
|
722
|
+
switch (parameters.conditionsFailResult) {
|
|
723
|
+
case 'reject':
|
|
724
|
+
return Promise.reject(new errors.ConditionFailError({
|
|
725
|
+
conditionName: (_b = executionState.forbiddenBy) !== null && _b !== void 0 ? _b : 'unknown',
|
|
726
|
+
targetName: parameters.name,
|
|
727
|
+
}));
|
|
728
|
+
default:
|
|
729
|
+
return Promise.resolve();
|
|
730
|
+
}
|
|
677
731
|
}
|
|
678
|
-
const deps = parameters.deps ? this.di.getOfDeps(parameters.deps) : {};
|
|
679
732
|
executionState.status = 'pending';
|
|
680
|
-
return
|
|
681
|
-
|
|
682
|
-
.
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
733
|
+
return this.executionContextManager.withContext(executionContext, {
|
|
734
|
+
name: parameters.name,
|
|
735
|
+
values: (executionContext === null || executionContext === void 0 ? void 0 : executionContext.values.pageActions) === true ? { pageActions: false } : undefined,
|
|
736
|
+
}, (executionActionContext, abortController) => {
|
|
737
|
+
const context = this.createActionContext(executionContext, executionActionContext, abortController, parameters);
|
|
738
|
+
return Promise.resolve()
|
|
739
|
+
.then(() => {
|
|
740
|
+
if (core.isTramvaiAction(action)) {
|
|
741
|
+
return action.fn.apply(context, params);
|
|
742
|
+
}
|
|
743
|
+
return action(this.context, payload, context.deps);
|
|
744
|
+
})
|
|
745
|
+
.then((data) => {
|
|
746
|
+
executionState.status = 'success';
|
|
747
|
+
return data;
|
|
748
|
+
})
|
|
749
|
+
.catch((err) => {
|
|
750
|
+
executionState.status = 'failed';
|
|
751
|
+
throw err;
|
|
752
|
+
});
|
|
689
753
|
});
|
|
690
754
|
}
|
|
691
|
-
|
|
692
|
-
|
|
755
|
+
async run(action, ...params) {
|
|
756
|
+
return this.runInContext(null, action, ...params);
|
|
757
|
+
}
|
|
758
|
+
getExecutionState(name) {
|
|
759
|
+
let executionState = this.execution.get(name);
|
|
760
|
+
// TODO: probably do not need to create executionState on client as it is not used
|
|
693
761
|
if (!executionState) {
|
|
694
762
|
executionState = { status: 'pending', state: {} };
|
|
695
|
-
this.execution.set(
|
|
763
|
+
this.execution.set(name, executionState);
|
|
696
764
|
}
|
|
697
765
|
return executionState;
|
|
698
766
|
}
|
|
@@ -700,6 +768,17 @@ class ActionExecution {
|
|
|
700
768
|
const actionChecker = new ActionChecker(this.actionConditionals, payload, parameters, executionState, type);
|
|
701
769
|
return actionChecker.check();
|
|
702
770
|
}
|
|
771
|
+
createActionContext(parentExecutionContext, actionExecutionContext, abortController, parameters) {
|
|
772
|
+
return {
|
|
773
|
+
abortController,
|
|
774
|
+
abortSignal: actionExecutionContext === null || actionExecutionContext === void 0 ? void 0 : actionExecutionContext.abortSignal,
|
|
775
|
+
executeAction: this.runInContext.bind(this, actionExecutionContext),
|
|
776
|
+
deps: parameters.deps ? this.di.getOfDeps(parameters.deps) : EMPTY_DEPS,
|
|
777
|
+
actionType: (parentExecutionContext === null || parentExecutionContext === void 0 ? void 0 : parentExecutionContext.values.pageActions) ? 'page' : 'standalone',
|
|
778
|
+
dispatch: this.store.dispatch,
|
|
779
|
+
getState: this.store.getState,
|
|
780
|
+
};
|
|
781
|
+
}
|
|
703
782
|
}
|
|
704
783
|
|
|
705
784
|
const GLOBAL_PARAMETER = '@@global';
|
|
@@ -729,56 +808,59 @@ class ActionRegistry {
|
|
|
729
808
|
}
|
|
730
809
|
}
|
|
731
810
|
|
|
732
|
-
const payload = {};
|
|
733
811
|
class ActionPageRunner {
|
|
734
|
-
constructor(
|
|
735
|
-
this.
|
|
736
|
-
this.
|
|
737
|
-
this.limitTime = limitTime;
|
|
738
|
-
this.log = logger('action:action-page-runner');
|
|
812
|
+
constructor(deps) {
|
|
813
|
+
this.deps = deps;
|
|
814
|
+
this.log = deps.logger('action:action-page-runner');
|
|
739
815
|
}
|
|
740
816
|
// TODO stopRunAtError нужен только для редиректов на стороне сервера в экшенах. И нужно пересмотреть реализацию редиректов
|
|
741
817
|
runActions(actions, stopRunAtError = () => false) {
|
|
742
|
-
return
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
const
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
};
|
|
760
|
-
const actionMapper = (action) => {
|
|
761
|
-
return Promise.resolve()
|
|
762
|
-
.then(() => this.actionExecution.run(action, payload, actionType.global))
|
|
763
|
-
.catch((error) => {
|
|
764
|
-
const parameters = action[core.ACTION_PARAMETERS];
|
|
765
|
-
this.log.error({
|
|
766
|
-
error,
|
|
767
|
-
event: `action-execution-error`,
|
|
768
|
-
message: `${parameters.name} execution error`,
|
|
818
|
+
return this.deps.executionContextManager.withContext(this.deps.commandLineExecutionContext(), { name: 'pageActions', values: { pageActions: true } }, (executionContext, abortController) => {
|
|
819
|
+
return new Promise((resolve, reject) => {
|
|
820
|
+
const timeoutMarker = setTimeout(() => {
|
|
821
|
+
this.log.warn(`page actions has exceeded timeout of ${this.deps.limitTime}ms, ignore some results of execution`);
|
|
822
|
+
abortController.abort();
|
|
823
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
824
|
+
endChecker();
|
|
825
|
+
}, this.deps.limitTime);
|
|
826
|
+
const endChecker = () => {
|
|
827
|
+
clearTimeout(timeoutMarker);
|
|
828
|
+
const result = {};
|
|
829
|
+
// TODO: dehydrate only actions on first level as inner actions are running on client despite their execution on server
|
|
830
|
+
this.deps.actionExecution.execution.forEach((value, key) => {
|
|
831
|
+
// достаем значения экшенов, которые успешно выполнились, остальные выполнятся на клиенте
|
|
832
|
+
if (value.status === 'success') {
|
|
833
|
+
result[key] = value;
|
|
834
|
+
}
|
|
769
835
|
});
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
836
|
+
this.syncStateActions(result);
|
|
837
|
+
resolve();
|
|
838
|
+
};
|
|
839
|
+
const actionMapper = (action) => {
|
|
840
|
+
return Promise.resolve()
|
|
841
|
+
.then(() => this.deps.actionExecution.runInContext(executionContext, action))
|
|
842
|
+
.catch((error) => {
|
|
843
|
+
if (!errors.isSilentError(error)) {
|
|
844
|
+
const parameters = core.isTramvaiAction(action) ? action : action[core.ACTION_PARAMETERS];
|
|
845
|
+
this.log.error({
|
|
846
|
+
error,
|
|
847
|
+
event: `action-execution-error`,
|
|
848
|
+
message: `${parameters.name} execution error`,
|
|
849
|
+
});
|
|
850
|
+
}
|
|
851
|
+
if (stopRunAtError(error)) {
|
|
852
|
+
clearTimeout(timeoutMarker);
|
|
853
|
+
reject(error);
|
|
854
|
+
}
|
|
855
|
+
});
|
|
856
|
+
};
|
|
857
|
+
// eslint-disable-next-line promise/catch-or-return
|
|
858
|
+
Promise.all(actions.map(actionMapper)).then(endChecker);
|
|
859
|
+
});
|
|
778
860
|
});
|
|
779
861
|
}
|
|
780
862
|
syncStateActions(success) {
|
|
781
|
-
return this.store.dispatch(actionServerStateEvent(success));
|
|
863
|
+
return this.deps.store.dispatch(actionServerStateEvent(success));
|
|
782
864
|
}
|
|
783
865
|
}
|
|
784
866
|
|
|
@@ -856,23 +938,26 @@ ActionModule = tslib.__decorate([
|
|
|
856
938
|
context: tokensCommon.CONTEXT_TOKEN,
|
|
857
939
|
store: tokensCommon.STORE_TOKEN,
|
|
858
940
|
di: core.DI_TOKEN,
|
|
941
|
+
executionContextManager: tokensCommon.EXECUTION_CONTEXT_MANAGER_TOKEN,
|
|
859
942
|
transformAction: {
|
|
860
943
|
token: 'actionTransformAction',
|
|
861
944
|
optional: true,
|
|
862
945
|
},
|
|
863
946
|
},
|
|
864
947
|
}),
|
|
865
|
-
{
|
|
948
|
+
core.provide({
|
|
866
949
|
provide: tokensCommon.ACTION_PAGE_RUNNER_TOKEN,
|
|
867
950
|
scope: core.Scope.REQUEST,
|
|
868
951
|
useClass: ActionPageRunner,
|
|
869
952
|
deps: {
|
|
870
953
|
actionExecution: tokensCommon.ACTION_EXECUTION_TOKEN,
|
|
954
|
+
executionContextManager: tokensCommon.EXECUTION_CONTEXT_MANAGER_TOKEN,
|
|
955
|
+
commandLineExecutionContext: tokensCommon.COMMAND_LINE_EXECUTION_CONTEXT_TOKEN,
|
|
871
956
|
store: tokensCommon.STORE_TOKEN,
|
|
872
957
|
limitTime: 'limitActionGlobalTimeRun',
|
|
873
958
|
logger: tokensCommon.LOGGER_TOKEN,
|
|
874
959
|
},
|
|
875
|
-
},
|
|
960
|
+
}),
|
|
876
961
|
{
|
|
877
962
|
provide: 'limitActionGlobalTimeRun',
|
|
878
963
|
useValue: 500,
|
|
@@ -1014,6 +1099,58 @@ CacheModule = tslib.__decorate([
|
|
|
1014
1099
|
})
|
|
1015
1100
|
], CacheModule);
|
|
1016
1101
|
|
|
1102
|
+
const EMPTY_VALUES = {};
|
|
1103
|
+
const normalizeOptions = (nameOrOptions) => {
|
|
1104
|
+
return typeof nameOrOptions === 'string' ? { name: nameOrOptions } : nameOrOptions;
|
|
1105
|
+
};
|
|
1106
|
+
class ExecutionContextManager {
|
|
1107
|
+
async withContext(parentContext, nameOrOptions, cb) {
|
|
1108
|
+
const options = normalizeOptions(nameOrOptions);
|
|
1109
|
+
const { name, values: selfValues = EMPTY_VALUES } = options;
|
|
1110
|
+
const contextName = parentContext ? `${parentContext.name}.${name}` : name;
|
|
1111
|
+
if (parentContext === null || parentContext === void 0 ? void 0 : parentContext.abortSignal.aborted) {
|
|
1112
|
+
throw new errors.ExecutionAbortError({
|
|
1113
|
+
message: `Execution aborted in context "${contextName}"`,
|
|
1114
|
+
contextName,
|
|
1115
|
+
});
|
|
1116
|
+
}
|
|
1117
|
+
const abortController = new nodeAbortController.AbortController();
|
|
1118
|
+
let abortListener;
|
|
1119
|
+
let values = selfValues;
|
|
1120
|
+
if (parentContext) {
|
|
1121
|
+
values = {
|
|
1122
|
+
...parentContext.values,
|
|
1123
|
+
...selfValues,
|
|
1124
|
+
};
|
|
1125
|
+
abortListener = () => {
|
|
1126
|
+
abortController.abort();
|
|
1127
|
+
};
|
|
1128
|
+
// abort child context AbortController if parent AbortController was aborted
|
|
1129
|
+
parentContext.abortSignal.addEventListener('abort', abortListener);
|
|
1130
|
+
}
|
|
1131
|
+
const context = {
|
|
1132
|
+
name: contextName,
|
|
1133
|
+
abortSignal: abortController.signal,
|
|
1134
|
+
values,
|
|
1135
|
+
};
|
|
1136
|
+
try {
|
|
1137
|
+
const result = await cb(context, abortController);
|
|
1138
|
+
return result;
|
|
1139
|
+
}
|
|
1140
|
+
catch (error) {
|
|
1141
|
+
if (!error.executionContextName) {
|
|
1142
|
+
error.executionContextName = context.name;
|
|
1143
|
+
}
|
|
1144
|
+
throw error;
|
|
1145
|
+
}
|
|
1146
|
+
finally {
|
|
1147
|
+
if (abortListener) {
|
|
1148
|
+
parentContext.abortSignal.removeEventListener('abort', abortListener);
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1017
1154
|
exports.CommonModule = class CommonModule {
|
|
1018
1155
|
};
|
|
1019
1156
|
exports.CommonModule = tslib.__decorate([
|
|
@@ -1084,6 +1221,10 @@ exports.CommonModule = tslib.__decorate([
|
|
|
1084
1221
|
store: tokensCommon.STORE_TOKEN,
|
|
1085
1222
|
},
|
|
1086
1223
|
}),
|
|
1224
|
+
core.provide({
|
|
1225
|
+
provide: tokensCommon.EXECUTION_CONTEXT_MANAGER_TOKEN,
|
|
1226
|
+
useClass: ExecutionContextManager,
|
|
1227
|
+
}),
|
|
1087
1228
|
...providers$2,
|
|
1088
1229
|
],
|
|
1089
1230
|
})
|
|
@@ -1174,6 +1315,7 @@ Object.defineProperty(exports, 'COOKIE_MANAGER_TOKEN', {
|
|
|
1174
1315
|
get: function () { return moduleCookie.COOKIE_MANAGER_TOKEN; }
|
|
1175
1316
|
});
|
|
1176
1317
|
exports.ActionExecution = ActionExecution;
|
|
1318
|
+
exports.ExecutionContextManager = ExecutionContextManager;
|
|
1177
1319
|
exports.alwaysCondition = alwaysCondition;
|
|
1178
1320
|
exports.createConsumerContext = createConsumerContext;
|
|
1179
1321
|
exports.onlyBrowser = onlyBrowser;
|
|
@@ -5,7 +5,7 @@ declare global {
|
|
|
5
5
|
}
|
|
6
6
|
}
|
|
7
7
|
export declare const providers: ({
|
|
8
|
-
provide: import("@tinkoff/dippy
|
|
8
|
+
provide: import("@tinkoff/dippy").BaseTokenInterface<{
|
|
9
9
|
stores: Record<string, any>;
|
|
10
10
|
}>;
|
|
11
11
|
useFactory: () => any;
|
|
@@ -13,12 +13,12 @@ export declare const providers: ({
|
|
|
13
13
|
deps?: undefined;
|
|
14
14
|
multi?: undefined;
|
|
15
15
|
} | {
|
|
16
|
-
provide: import("@tinkoff/dippy
|
|
16
|
+
provide: import("@tinkoff/dippy").MultiTokenInterface<import("@tramvai/core").Command>;
|
|
17
17
|
useFactory: ({ commandLineRunner, }: {
|
|
18
18
|
commandLineRunner: typeof COMMAND_LINE_RUNNER_TOKEN;
|
|
19
19
|
}) => () => Promise<import("@tinkoff/dippy").Container>;
|
|
20
20
|
deps: {
|
|
21
|
-
commandLineRunner: import("@tinkoff/dippy
|
|
21
|
+
commandLineRunner: import("@tinkoff/dippy").BaseTokenInterface<import("@tramvai/tokens-core").CommandLine>;
|
|
22
22
|
};
|
|
23
23
|
multi: boolean;
|
|
24
24
|
scope?: undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tramvai/module-common",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.20.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
@@ -28,30 +28,31 @@
|
|
|
28
28
|
"build-for-publish": "true"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@tinkoff/errors": "0.2
|
|
32
|
-
"@tinkoff/hook-runner": "0.
|
|
31
|
+
"@tinkoff/errors": "0.3.2",
|
|
32
|
+
"@tinkoff/hook-runner": "0.4.2",
|
|
33
33
|
"@tinkoff/lru-cache-nano": "^7.8.1",
|
|
34
|
-
"@tinkoff/pubsub": "0.
|
|
35
|
-
"@tinkoff/url": "0.
|
|
36
|
-
"@tramvai/experiments": "2.
|
|
37
|
-
"@tramvai/module-cookie": "2.
|
|
38
|
-
"@tramvai/module-environment": "2.
|
|
39
|
-
"@tramvai/module-log": "2.
|
|
40
|
-
"@tramvai/tokens-child-app": "2.
|
|
41
|
-
"@tramvai/tokens-common": "2.
|
|
42
|
-
"@tramvai/tokens-render": "2.
|
|
43
|
-
"hoist-non-react-statics": "^3.3.1"
|
|
34
|
+
"@tinkoff/pubsub": "0.5.2",
|
|
35
|
+
"@tinkoff/url": "0.8.2",
|
|
36
|
+
"@tramvai/experiments": "2.20.0",
|
|
37
|
+
"@tramvai/module-cookie": "2.20.0",
|
|
38
|
+
"@tramvai/module-environment": "2.20.0",
|
|
39
|
+
"@tramvai/module-log": "2.20.0",
|
|
40
|
+
"@tramvai/tokens-child-app": "2.20.0",
|
|
41
|
+
"@tramvai/tokens-common": "2.20.0",
|
|
42
|
+
"@tramvai/tokens-render": "2.20.0",
|
|
43
|
+
"hoist-non-react-statics": "^3.3.1",
|
|
44
|
+
"node-abort-controller": "^3.0.1"
|
|
44
45
|
},
|
|
45
46
|
"peerDependencies": {
|
|
46
|
-
"@tinkoff/dippy": "0.
|
|
47
|
+
"@tinkoff/dippy": "0.8.2",
|
|
47
48
|
"@tinkoff/utils": "^2.1.2",
|
|
48
|
-
"@tramvai/cli": "2.
|
|
49
|
-
"@tramvai/core": "2.
|
|
50
|
-
"@tramvai/papi": "2.
|
|
51
|
-
"@tramvai/react": "2.
|
|
52
|
-
"@tramvai/state": "2.
|
|
53
|
-
"@tramvai/tokens-metrics": "2.
|
|
54
|
-
"@tramvai/tokens-server": "2.
|
|
49
|
+
"@tramvai/cli": "2.20.0",
|
|
50
|
+
"@tramvai/core": "2.20.0",
|
|
51
|
+
"@tramvai/papi": "2.20.0",
|
|
52
|
+
"@tramvai/react": "2.20.0",
|
|
53
|
+
"@tramvai/state": "2.20.0",
|
|
54
|
+
"@tramvai/tokens-metrics": "2.20.0",
|
|
55
|
+
"@tramvai/tokens-server": "2.20.0",
|
|
55
56
|
"react": ">=16.14.0",
|
|
56
57
|
"tslib": "^2.0.3"
|
|
57
58
|
},
|