@tramvai/module-common 5.50.0 → 6.59.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.
Files changed (40) hide show
  1. package/__migrations__/1-als-rename-module.js +12 -23
  2. package/lib/actions/ActionModule.browser.js +14 -3
  3. package/lib/actions/ActionModule.es.js +14 -3
  4. package/lib/actions/ActionModule.js +12 -1
  5. package/lib/actions/actionChecker.browser.js +9 -3
  6. package/lib/actions/actionChecker.es.js +9 -3
  7. package/lib/actions/actionChecker.js +9 -3
  8. package/lib/actions/actionExecution.browser.js +49 -3
  9. package/lib/actions/actionExecution.d.ts +4 -2
  10. package/lib/actions/actionExecution.es.js +49 -3
  11. package/lib/actions/actionExecution.js +49 -3
  12. package/lib/actions/actionPageRunner.browser.browser.js +15 -10
  13. package/lib/actions/actionPageRunner.es.js +27 -17
  14. package/lib/actions/actionPageRunner.js +26 -16
  15. package/lib/actions/actionRegistry.browser.js +1 -0
  16. package/lib/actions/actionRegistry.es.js +1 -0
  17. package/lib/actions/actionRegistry.js +1 -0
  18. package/lib/async-local-storage/server.es.js +11 -1
  19. package/lib/async-local-storage/server.js +11 -1
  20. package/lib/bundleManager/bundleManager.browser.js +2 -0
  21. package/lib/bundleManager/bundleManager.es.js +2 -0
  22. package/lib/bundleManager/bundleManager.js +2 -0
  23. package/lib/cache/cacheWithMetricsProxy.es.js +3 -0
  24. package/lib/cache/cacheWithMetricsProxy.js +3 -0
  25. package/lib/command/commandLineRunner.new.browser.js +18 -10
  26. package/lib/command/commandLineRunner.new.es.js +18 -10
  27. package/lib/command/commandLineRunner.new.js +17 -9
  28. package/lib/componentRegistry/componentRegistry.browser.js +1 -0
  29. package/lib/componentRegistry/componentRegistry.es.js +1 -0
  30. package/lib/componentRegistry/componentRegistry.js +1 -0
  31. package/lib/createConsumerContext/createConsumerContext.browser.js +42 -38
  32. package/lib/createConsumerContext/createConsumerContext.es.js +42 -38
  33. package/lib/createConsumerContext/createConsumerContext.js +42 -38
  34. package/lib/requestManager/requestManager.browser.js +3 -0
  35. package/lib/requestManager/requestManager.es.js +3 -0
  36. package/lib/requestManager/requestManager.js +3 -0
  37. package/lib/responseManager/responseManager.browser.js +4 -0
  38. package/lib/responseManager/responseManager.es.js +4 -0
  39. package/lib/responseManager/responseManager.js +4 -0
  40. package/package.json +25 -25
@@ -1,32 +1,21 @@
1
1
  'use strict';
2
2
 
3
- var tslib = require('tslib');
4
3
  var dependency = require('@tramvai/tools-migrate/lib/dependency');
5
4
 
5
+ // eslint-disable-next-line no-restricted-imports, import/no-extraneous-dependencies
6
6
  // eslint-disable-next-line import/no-default-export
7
- var _1AlsRenameModule = (function (api) { return tslib.__awaiter(void 0, void 0, void 0, function () {
8
- var packageJSON;
9
- return tslib.__generator(this, function (_a) {
10
- switch (_a.label) {
11
- case 0: return [4 /*yield*/, api.transform(function (_a, _b, _c) {
12
- var source = _a.source;
13
- var j = _b.j;
14
- var printOptions = _c.printOptions;
15
- var parsed = j(source);
16
- if (parsed.renameImportSource('@tramvai-tinkoff/module-async-local-storage', '@tramvai/module-common')) {
17
- return parsed.toSource(printOptions);
18
- }
19
- })];
20
- case 1:
21
- _a.sent();
22
- packageJSON = api.packageJSON.source;
23
- dependency.replaceDependency({
24
- packageJSON: packageJSON,
25
- from: '@tramvai-tinkoff/module-async-local-storage',
26
- });
27
- return [2 /*return*/];
7
+ var _1AlsRenameModule = async (api) => {
8
+ await api.transform(({ source }, { j }, { printOptions }) => {
9
+ const parsed = j(source);
10
+ if (parsed.renameImportSource('@tramvai-tinkoff/module-async-local-storage', '@tramvai/module-common')) {
11
+ return parsed.toSource(printOptions);
28
12
  }
29
13
  });
30
- }); });
14
+ const packageJSON = api.packageJSON.source;
15
+ dependency.replaceDependency({
16
+ packageJSON,
17
+ from: '@tramvai-tinkoff/module-async-local-storage',
18
+ });
19
+ };
31
20
 
32
21
  module.exports = _1AlsRenameModule;
@@ -1,6 +1,6 @@
1
1
  import { __decorate } from 'tslib';
2
- import { Module, provide, Scope, ACTIONS_LIST_TOKEN, DI_TOKEN, optional } from '@tramvai/core';
3
- import { COMBINE_REDUCERS, ACTION_REGISTRY_TOKEN, ACTION_EXECUTION_TOKEN, ACTION_CONDITIONALS, CONTEXT_TOKEN, STORE_TOKEN, EXECUTION_CONTEXT_MANAGER_TOKEN, DEFERRED_ACTIONS_MAP_TOKEN, ACTION_PAGE_RUNNER_TOKEN, COMMAND_LINE_EXECUTION_CONTEXT_TOKEN, LIMIT_ACTION_GLOBAL_TIME_RUN, LOGGER_TOKEN } from '@tramvai/tokens-common';
2
+ import { Module, provide, Scope, ACTIONS_LIST_TOKEN, DI_TOKEN, TAPABLE_HOOK_FACTORY_TOKEN, optional } from '@tramvai/core';
3
+ import { COMBINE_REDUCERS, ACTION_REGISTRY_TOKEN, ACTION_EXECUTION_TOKEN, ACTION_CONDITIONALS, CONTEXT_TOKEN, STORE_TOKEN, ACTION_EXECUTION_HOOKS_TOKEN, EXECUTION_CONTEXT_MANAGER_TOKEN, DEFERRED_ACTIONS_MAP_TOKEN, ACTION_PAGE_RUNNER_TOKEN, COMMAND_LINE_EXECUTION_CONTEXT_TOKEN, LIMIT_ACTION_GLOBAL_TIME_RUN, LOGGER_TOKEN } from '@tramvai/tokens-common';
4
4
  import { SERVER_RESPONSE_TASK_MANAGER, SERVER_RESPONSE_STREAM } from '@tramvai/tokens-server-private';
5
5
  import { ROUTER_TOKEN } from '@tramvai/tokens-router';
6
6
  import { IS_CHILD_APP_DI_TOKEN } from '@tramvai/tokens-child-app';
@@ -33,7 +33,7 @@ ActionModule = __decorate([
33
33
  useValue: actionTramvaiReducer,
34
34
  }),
35
35
  provide({
36
- // Регистер глобальных экшенов
36
+ // Регистр глобальных экшенов
37
37
  provide: ACTION_REGISTRY_TOKEN,
38
38
  scope: Scope.SINGLETON,
39
39
  useClass: ActionRegistry,
@@ -48,6 +48,7 @@ ActionModule = __decorate([
48
48
  context: CONTEXT_TOKEN,
49
49
  store: STORE_TOKEN,
50
50
  di: DI_TOKEN,
51
+ hooks: ACTION_EXECUTION_HOOKS_TOKEN,
51
52
  executionContextManager: EXECUTION_CONTEXT_MANAGER_TOKEN,
52
53
  transformAction: {
53
54
  token: 'actionTransformAction',
@@ -56,6 +57,16 @@ ActionModule = __decorate([
56
57
  deferredActionsMap: DEFERRED_ACTIONS_MAP_TOKEN,
57
58
  },
58
59
  }),
60
+ provide({
61
+ provide: ACTION_EXECUTION_HOOKS_TOKEN,
62
+ useFactory: ({ hookFactory }) => ({
63
+ startExecution: hookFactory.createSync('startActionExecution'),
64
+ endExecution: hookFactory.createSync('endActionExecution'),
65
+ }),
66
+ deps: {
67
+ hookFactory: TAPABLE_HOOK_FACTORY_TOKEN,
68
+ },
69
+ }),
59
70
  provide({
60
71
  provide: ACTION_PAGE_RUNNER_TOKEN,
61
72
  scope: Scope.REQUEST,
@@ -1,6 +1,6 @@
1
1
  import { __decorate } from 'tslib';
2
- import { Module, provide, Scope, ACTIONS_LIST_TOKEN, DI_TOKEN, optional } from '@tramvai/core';
3
- import { COMBINE_REDUCERS, ACTION_REGISTRY_TOKEN, ACTION_EXECUTION_TOKEN, ACTION_CONDITIONALS, CONTEXT_TOKEN, STORE_TOKEN, EXECUTION_CONTEXT_MANAGER_TOKEN, DEFERRED_ACTIONS_MAP_TOKEN, ACTION_PAGE_RUNNER_TOKEN, COMMAND_LINE_EXECUTION_CONTEXT_TOKEN, LIMIT_ACTION_GLOBAL_TIME_RUN, LOGGER_TOKEN } from '@tramvai/tokens-common';
2
+ import { Module, provide, Scope, ACTIONS_LIST_TOKEN, DI_TOKEN, TAPABLE_HOOK_FACTORY_TOKEN, optional } from '@tramvai/core';
3
+ import { COMBINE_REDUCERS, ACTION_REGISTRY_TOKEN, ACTION_EXECUTION_TOKEN, ACTION_CONDITIONALS, CONTEXT_TOKEN, STORE_TOKEN, ACTION_EXECUTION_HOOKS_TOKEN, EXECUTION_CONTEXT_MANAGER_TOKEN, DEFERRED_ACTIONS_MAP_TOKEN, ACTION_PAGE_RUNNER_TOKEN, COMMAND_LINE_EXECUTION_CONTEXT_TOKEN, LIMIT_ACTION_GLOBAL_TIME_RUN, LOGGER_TOKEN } from '@tramvai/tokens-common';
4
4
  import { SERVER_RESPONSE_TASK_MANAGER, SERVER_RESPONSE_STREAM } from '@tramvai/tokens-server-private';
5
5
  import { ROUTER_TOKEN } from '@tramvai/tokens-router';
6
6
  import { IS_CHILD_APP_DI_TOKEN } from '@tramvai/tokens-child-app';
@@ -33,7 +33,7 @@ ActionModule = __decorate([
33
33
  useValue: actionTramvaiReducer,
34
34
  }),
35
35
  provide({
36
- // Регистер глобальных экшенов
36
+ // Регистр глобальных экшенов
37
37
  provide: ACTION_REGISTRY_TOKEN,
38
38
  scope: Scope.SINGLETON,
39
39
  useClass: ActionRegistry,
@@ -48,6 +48,7 @@ ActionModule = __decorate([
48
48
  context: CONTEXT_TOKEN,
49
49
  store: STORE_TOKEN,
50
50
  di: DI_TOKEN,
51
+ hooks: ACTION_EXECUTION_HOOKS_TOKEN,
51
52
  executionContextManager: EXECUTION_CONTEXT_MANAGER_TOKEN,
52
53
  transformAction: {
53
54
  token: 'actionTransformAction',
@@ -56,6 +57,16 @@ ActionModule = __decorate([
56
57
  deferredActionsMap: DEFERRED_ACTIONS_MAP_TOKEN,
57
58
  },
58
59
  }),
60
+ provide({
61
+ provide: ACTION_EXECUTION_HOOKS_TOKEN,
62
+ useFactory: ({ hookFactory }) => ({
63
+ startExecution: hookFactory.createSync('startActionExecution'),
64
+ endExecution: hookFactory.createSync('endActionExecution'),
65
+ }),
66
+ deps: {
67
+ hookFactory: TAPABLE_HOOK_FACTORY_TOKEN,
68
+ },
69
+ }),
59
70
  provide({
60
71
  provide: ACTION_PAGE_RUNNER_TOKEN,
61
72
  scope: Scope.REQUEST,
@@ -31,7 +31,7 @@ exports.ActionModule = tslib.__decorate([
31
31
  useValue: actionTramvaiReducer.actionTramvaiReducer,
32
32
  }),
33
33
  core.provide({
34
- // Регистер глобальных экшенов
34
+ // Регистр глобальных экшенов
35
35
  provide: tokensCommon.ACTION_REGISTRY_TOKEN,
36
36
  scope: core.Scope.SINGLETON,
37
37
  useClass: actionRegistry.ActionRegistry,
@@ -46,6 +46,7 @@ exports.ActionModule = tslib.__decorate([
46
46
  context: tokensCommon.CONTEXT_TOKEN,
47
47
  store: tokensCommon.STORE_TOKEN,
48
48
  di: core.DI_TOKEN,
49
+ hooks: tokensCommon.ACTION_EXECUTION_HOOKS_TOKEN,
49
50
  executionContextManager: tokensCommon.EXECUTION_CONTEXT_MANAGER_TOKEN,
50
51
  transformAction: {
51
52
  token: 'actionTransformAction',
@@ -54,6 +55,16 @@ exports.ActionModule = tslib.__decorate([
54
55
  deferredActionsMap: tokensCommon.DEFERRED_ACTIONS_MAP_TOKEN,
55
56
  },
56
57
  }),
58
+ core.provide({
59
+ provide: tokensCommon.ACTION_EXECUTION_HOOKS_TOKEN,
60
+ useFactory: ({ hookFactory }) => ({
61
+ startExecution: hookFactory.createSync('startActionExecution'),
62
+ endExecution: hookFactory.createSync('endActionExecution'),
63
+ }),
64
+ deps: {
65
+ hookFactory: core.TAPABLE_HOOK_FACTORY_TOKEN,
66
+ },
67
+ }),
57
68
  core.provide({
58
69
  provide: tokensCommon.ACTION_PAGE_RUNNER_TOKEN,
59
70
  scope: core.Scope.REQUEST,
@@ -2,6 +2,15 @@ import { actionType } from './constants.browser.js';
2
2
 
3
3
  const DEFAULT_CONDITIONS = {};
4
4
  class ActionChecker {
5
+ globalConditionals;
6
+ payload;
7
+ parameters;
8
+ executionState;
9
+ type;
10
+ conditions;
11
+ status = true;
12
+ forbiddenMarker = false;
13
+ key = null;
5
14
  // eslint-disable-next-line max-params
6
15
  constructor(globalConditionals, payload, parameters, executionState, type) {
7
16
  this.globalConditionals = globalConditionals;
@@ -9,9 +18,6 @@ class ActionChecker {
9
18
  this.parameters = parameters;
10
19
  this.executionState = executionState;
11
20
  this.type = type;
12
- this.status = true;
13
- this.forbiddenMarker = false;
14
- this.key = null;
15
21
  // для глобальных экшенов мы должны дедублицировать выполнение и меньше выполнять
16
22
  if (type === actionType.global) {
17
23
  // если экшен был уже выполнен, то считаем, что его не нужно больше выполнять
@@ -2,6 +2,15 @@ import { actionType } from './constants.es.js';
2
2
 
3
3
  const DEFAULT_CONDITIONS = {};
4
4
  class ActionChecker {
5
+ globalConditionals;
6
+ payload;
7
+ parameters;
8
+ executionState;
9
+ type;
10
+ conditions;
11
+ status = true;
12
+ forbiddenMarker = false;
13
+ key = null;
5
14
  // eslint-disable-next-line max-params
6
15
  constructor(globalConditionals, payload, parameters, executionState, type) {
7
16
  this.globalConditionals = globalConditionals;
@@ -9,9 +18,6 @@ class ActionChecker {
9
18
  this.parameters = parameters;
10
19
  this.executionState = executionState;
11
20
  this.type = type;
12
- this.status = true;
13
- this.forbiddenMarker = false;
14
- this.key = null;
15
21
  // для глобальных экшенов мы должны дедублицировать выполнение и меньше выполнять
16
22
  if (type === actionType.global) {
17
23
  // если экшен был уже выполнен, то считаем, что его не нужно больше выполнять
@@ -6,6 +6,15 @@ var constants = require('./constants.js');
6
6
 
7
7
  const DEFAULT_CONDITIONS = {};
8
8
  class ActionChecker {
9
+ globalConditionals;
10
+ payload;
11
+ parameters;
12
+ executionState;
13
+ type;
14
+ conditions;
15
+ status = true;
16
+ forbiddenMarker = false;
17
+ key = null;
9
18
  // eslint-disable-next-line max-params
10
19
  constructor(globalConditionals, payload, parameters, executionState, type) {
11
20
  this.globalConditionals = globalConditionals;
@@ -13,9 +22,6 @@ class ActionChecker {
13
22
  this.parameters = parameters;
14
23
  this.executionState = executionState;
15
24
  this.type = type;
16
- this.status = true;
17
- this.forbiddenMarker = false;
18
- this.key = null;
19
25
  // для глобальных экшенов мы должны дедублицировать выполнение и меньше выполнять
20
26
  if (type === constants.actionType.global) {
21
27
  // если экшен был уже выполнен, то считаем, что его не нужно больше выполнять
@@ -11,12 +11,22 @@ import { actionTramvaiReducer } from './actionTramvaiReducer.browser.js';
11
11
  const EMPTY_DEPS = {};
12
12
  const getParameters = (action) => action[ACTION_PARAMETERS];
13
13
  class ActionExecution {
14
- constructor({ store, context, deferredActionsMap, di, executionContextManager, actionConditionals, transformAction, }) {
14
+ execution;
15
+ actionConditionals;
16
+ context;
17
+ deferredActionsMap;
18
+ store;
19
+ hooks;
20
+ executionContextManager;
21
+ di;
22
+ transformAction;
23
+ constructor({ store, context, deferredActionsMap, hooks, di, executionContextManager, actionConditionals, transformAction, }) {
15
24
  this.actionConditionals = flatten(actionConditionals ?? []);
16
25
  this.context = context;
17
26
  this.store = store;
18
27
  this.deferredActionsMap = deferredActionsMap;
19
28
  this.di = di;
29
+ this.hooks = hooks;
20
30
  this.executionContextManager = executionContextManager;
21
31
  this.execution = new Map();
22
32
  this.transformAction = transformAction || identity;
@@ -35,19 +45,33 @@ class ActionExecution {
35
45
  if (!parameters) {
36
46
  throw new Error('Cannot resolve internal data for action. Make sure you are using the result of `declareAction` call as an action');
37
47
  }
48
+ const isDeferredAction = parameters.deferred;
49
+ this.hooks.startExecution.call({
50
+ action,
51
+ deferred: isDeferredAction,
52
+ context: executionContext,
53
+ start: Date.now(),
54
+ });
38
55
  const executionState = this.getExecutionState(parameters.name);
39
56
  if (!this.canExecuteAction(payload, parameters, executionState, type)) {
57
+ const conditionName = executionState.forbiddenBy ?? 'unknown';
58
+ this.hooks.endExecution.call({
59
+ action,
60
+ deferred: isDeferredAction,
61
+ context: executionContext,
62
+ forbidden: conditionName,
63
+ end: Date.now(),
64
+ });
40
65
  switch (parameters.conditionsFailResult) {
41
66
  case 'reject':
42
67
  return Promise.reject(new ConditionFailError({
43
- conditionName: executionState.forbiddenBy ?? 'unknown',
68
+ conditionName,
44
69
  targetName: parameters.name,
45
70
  }));
46
71
  default:
47
72
  return Promise.resolve();
48
73
  }
49
74
  }
50
- const isDeferredAction = parameters.deferred;
51
75
  // will be created when spa run actions mode is "before"
52
76
  if (isDeferredAction && !this.deferredActionsMap.get(action.name)) {
53
77
  const deferred = new Deferred();
@@ -61,6 +85,15 @@ class ActionExecution {
61
85
  values: executionContext?.values.pageActions === true ? { pageActions: false } : undefined,
62
86
  }, (executionActionContext, abortController) => {
63
87
  const context = this.createActionContext(executionContext, executionActionContext, abortController, parameters);
88
+ context.abortSignal.addEventListener('abort', () => {
89
+ this.hooks.endExecution.call({
90
+ action,
91
+ error: new Error('Action aborted'),
92
+ deferred: isDeferredAction,
93
+ context: executionContext,
94
+ end: Date.now(),
95
+ });
96
+ });
64
97
  return Promise.resolve()
65
98
  .then(() => {
66
99
  if (isTramvaiAction(action)) {
@@ -83,10 +116,23 @@ class ActionExecution {
83
116
  })
84
117
  .then((data) => {
85
118
  executionState.status = 'success';
119
+ this.hooks.endExecution.call({
120
+ action,
121
+ deferred: isDeferredAction,
122
+ context: executionContext,
123
+ end: Date.now(),
124
+ });
86
125
  return data;
87
126
  })
88
127
  .catch((err) => {
89
128
  executionState.status = 'failed';
129
+ this.hooks.endExecution.call({
130
+ action,
131
+ deferred: isDeferredAction,
132
+ context: executionContext,
133
+ error: err,
134
+ end: Date.now(),
135
+ });
90
136
  throw err;
91
137
  });
92
138
  });
@@ -1,5 +1,5 @@
1
1
  import type { Action, ActionParameters, DI_TOKEN } from '@tramvai/core';
2
- import type { CONTEXT_TOKEN, ActionCondition, STORE_TOKEN, ActionExecution as Interface, EXECUTION_CONTEXT_MANAGER_TOKEN, ExecutionContext, DEFERRED_ACTIONS_MAP_TOKEN } from '@tramvai/tokens-common';
2
+ import type { CONTEXT_TOKEN, ActionCondition, STORE_TOKEN, ActionExecution as Interface, EXECUTION_CONTEXT_MANAGER_TOKEN, ExecutionContext, DEFERRED_ACTIONS_MAP_TOKEN, ACTION_EXECUTION_HOOKS_TOKEN } from '@tramvai/tokens-common';
3
3
  import type { TramvaiAction } from '@tramvai/types-actions-state-context';
4
4
  import type { ExtractDependencyType } from '@tinkoff/dippy';
5
5
  export declare const getParameters: (action: Action) => ActionParameters<any, any>;
@@ -16,13 +16,15 @@ export declare class ActionExecution implements Interface {
16
16
  private context;
17
17
  private deferredActionsMap;
18
18
  private store;
19
+ private hooks;
19
20
  private executionContextManager;
20
21
  private di;
21
22
  private transformAction;
22
- constructor({ store, context, deferredActionsMap, di, executionContextManager, actionConditionals, transformAction, }: {
23
+ constructor({ store, context, deferredActionsMap, hooks, di, executionContextManager, actionConditionals, transformAction, }: {
23
24
  actionConditionals: (ActionCondition | ActionCondition[])[] | null;
24
25
  store: ExtractDependencyType<typeof STORE_TOKEN>;
25
26
  context: ExtractDependencyType<typeof CONTEXT_TOKEN>;
27
+ hooks: ExtractDependencyType<typeof ACTION_EXECUTION_HOOKS_TOKEN>;
26
28
  deferredActionsMap: ExtractDependencyType<typeof DEFERRED_ACTIONS_MAP_TOKEN>;
27
29
  di: ExtractDependencyType<typeof DI_TOKEN>;
28
30
  executionContextManager: ExtractDependencyType<typeof EXECUTION_CONTEXT_MANAGER_TOKEN>;
@@ -11,12 +11,22 @@ import { actionTramvaiReducer } from './actionTramvaiReducer.es.js';
11
11
  const EMPTY_DEPS = {};
12
12
  const getParameters = (action) => action[ACTION_PARAMETERS];
13
13
  class ActionExecution {
14
- constructor({ store, context, deferredActionsMap, di, executionContextManager, actionConditionals, transformAction, }) {
14
+ execution;
15
+ actionConditionals;
16
+ context;
17
+ deferredActionsMap;
18
+ store;
19
+ hooks;
20
+ executionContextManager;
21
+ di;
22
+ transformAction;
23
+ constructor({ store, context, deferredActionsMap, hooks, di, executionContextManager, actionConditionals, transformAction, }) {
15
24
  this.actionConditionals = flatten(actionConditionals ?? []);
16
25
  this.context = context;
17
26
  this.store = store;
18
27
  this.deferredActionsMap = deferredActionsMap;
19
28
  this.di = di;
29
+ this.hooks = hooks;
20
30
  this.executionContextManager = executionContextManager;
21
31
  this.execution = new Map();
22
32
  this.transformAction = transformAction || identity;
@@ -35,19 +45,33 @@ class ActionExecution {
35
45
  if (!parameters) {
36
46
  throw new Error('Cannot resolve internal data for action. Make sure you are using the result of `declareAction` call as an action');
37
47
  }
48
+ const isDeferredAction = parameters.deferred;
49
+ this.hooks.startExecution.call({
50
+ action,
51
+ deferred: isDeferredAction,
52
+ context: executionContext,
53
+ start: Date.now(),
54
+ });
38
55
  const executionState = this.getExecutionState(parameters.name);
39
56
  if (!this.canExecuteAction(payload, parameters, executionState, type)) {
57
+ const conditionName = executionState.forbiddenBy ?? 'unknown';
58
+ this.hooks.endExecution.call({
59
+ action,
60
+ deferred: isDeferredAction,
61
+ context: executionContext,
62
+ forbidden: conditionName,
63
+ end: Date.now(),
64
+ });
40
65
  switch (parameters.conditionsFailResult) {
41
66
  case 'reject':
42
67
  return Promise.reject(new ConditionFailError({
43
- conditionName: executionState.forbiddenBy ?? 'unknown',
68
+ conditionName,
44
69
  targetName: parameters.name,
45
70
  }));
46
71
  default:
47
72
  return Promise.resolve();
48
73
  }
49
74
  }
50
- const isDeferredAction = parameters.deferred;
51
75
  // will be created when spa run actions mode is "before"
52
76
  if (isDeferredAction && !this.deferredActionsMap.get(action.name)) {
53
77
  const deferred = new Deferred();
@@ -61,6 +85,15 @@ class ActionExecution {
61
85
  values: executionContext?.values.pageActions === true ? { pageActions: false } : undefined,
62
86
  }, (executionActionContext, abortController) => {
63
87
  const context = this.createActionContext(executionContext, executionActionContext, abortController, parameters);
88
+ context.abortSignal.addEventListener('abort', () => {
89
+ this.hooks.endExecution.call({
90
+ action,
91
+ error: new Error('Action aborted'),
92
+ deferred: isDeferredAction,
93
+ context: executionContext,
94
+ end: Date.now(),
95
+ });
96
+ });
64
97
  return Promise.resolve()
65
98
  .then(() => {
66
99
  if (isTramvaiAction(action)) {
@@ -83,10 +116,23 @@ class ActionExecution {
83
116
  })
84
117
  .then((data) => {
85
118
  executionState.status = 'success';
119
+ this.hooks.endExecution.call({
120
+ action,
121
+ deferred: isDeferredAction,
122
+ context: executionContext,
123
+ end: Date.now(),
124
+ });
86
125
  return data;
87
126
  })
88
127
  .catch((err) => {
89
128
  executionState.status = 'failed';
129
+ this.hooks.endExecution.call({
130
+ action,
131
+ deferred: isDeferredAction,
132
+ context: executionContext,
133
+ error: err,
134
+ end: Date.now(),
135
+ });
90
136
  throw err;
91
137
  });
92
138
  });
@@ -22,12 +22,22 @@ var objectMap__default = /*#__PURE__*/_interopDefaultLegacy(objectMap);
22
22
  const EMPTY_DEPS = {};
23
23
  const getParameters = (action) => action[core.ACTION_PARAMETERS];
24
24
  class ActionExecution {
25
- constructor({ store, context, deferredActionsMap, di, executionContextManager, actionConditionals, transformAction, }) {
25
+ execution;
26
+ actionConditionals;
27
+ context;
28
+ deferredActionsMap;
29
+ store;
30
+ hooks;
31
+ executionContextManager;
32
+ di;
33
+ transformAction;
34
+ constructor({ store, context, deferredActionsMap, hooks, di, executionContextManager, actionConditionals, transformAction, }) {
26
35
  this.actionConditionals = flatten__default["default"](actionConditionals ?? []);
27
36
  this.context = context;
28
37
  this.store = store;
29
38
  this.deferredActionsMap = deferredActionsMap;
30
39
  this.di = di;
40
+ this.hooks = hooks;
31
41
  this.executionContextManager = executionContextManager;
32
42
  this.execution = new Map();
33
43
  this.transformAction = transformAction || identity__default["default"];
@@ -46,19 +56,33 @@ class ActionExecution {
46
56
  if (!parameters) {
47
57
  throw new Error('Cannot resolve internal data for action. Make sure you are using the result of `declareAction` call as an action');
48
58
  }
59
+ const isDeferredAction = parameters.deferred;
60
+ this.hooks.startExecution.call({
61
+ action,
62
+ deferred: isDeferredAction,
63
+ context: executionContext,
64
+ start: Date.now(),
65
+ });
49
66
  const executionState = this.getExecutionState(parameters.name);
50
67
  if (!this.canExecuteAction(payload, parameters, executionState, type)) {
68
+ const conditionName = executionState.forbiddenBy ?? 'unknown';
69
+ this.hooks.endExecution.call({
70
+ action,
71
+ deferred: isDeferredAction,
72
+ context: executionContext,
73
+ forbidden: conditionName,
74
+ end: Date.now(),
75
+ });
51
76
  switch (parameters.conditionsFailResult) {
52
77
  case 'reject':
53
78
  return Promise.reject(new errors.ConditionFailError({
54
- conditionName: executionState.forbiddenBy ?? 'unknown',
79
+ conditionName,
55
80
  targetName: parameters.name,
56
81
  }));
57
82
  default:
58
83
  return Promise.resolve();
59
84
  }
60
85
  }
61
- const isDeferredAction = parameters.deferred;
62
86
  // will be created when spa run actions mode is "before"
63
87
  if (isDeferredAction && !this.deferredActionsMap.get(action.name)) {
64
88
  const deferred = new core.Deferred();
@@ -72,6 +96,15 @@ class ActionExecution {
72
96
  values: executionContext?.values.pageActions === true ? { pageActions: false } : undefined,
73
97
  }, (executionActionContext, abortController) => {
74
98
  const context = this.createActionContext(executionContext, executionActionContext, abortController, parameters);
99
+ context.abortSignal.addEventListener('abort', () => {
100
+ this.hooks.endExecution.call({
101
+ action,
102
+ error: new Error('Action aborted'),
103
+ deferred: isDeferredAction,
104
+ context: executionContext,
105
+ end: Date.now(),
106
+ });
107
+ });
75
108
  return Promise.resolve()
76
109
  .then(() => {
77
110
  if (core.isTramvaiAction(action)) {
@@ -94,10 +127,23 @@ class ActionExecution {
94
127
  })
95
128
  .then((data) => {
96
129
  executionState.status = 'success';
130
+ this.hooks.endExecution.call({
131
+ action,
132
+ deferred: isDeferredAction,
133
+ context: executionContext,
134
+ end: Date.now(),
135
+ });
97
136
  return data;
98
137
  })
99
138
  .catch((err) => {
100
139
  executionState.status = 'failed';
140
+ this.hooks.endExecution.call({
141
+ action,
142
+ deferred: isDeferredAction,
143
+ context: executionContext,
144
+ error: err,
145
+ end: Date.now(),
146
+ });
101
147
  throw err;
102
148
  });
103
149
  });
@@ -1,8 +1,11 @@
1
- import { isSilentError } from '@tinkoff/errors';
1
+ import { PageActionsAbortError, isPageActionsAbortError, isSilentError } from '@tinkoff/errors';
2
2
  import { isTramvaiAction, ACTION_PARAMETERS } from '@tramvai/core';
3
3
 
4
4
  const DEFAULT_PAYLOAD = {};
5
5
  class ActionPageRunner {
6
+ deps;
7
+ log;
8
+ isChildAppRunner;
6
9
  constructor(deps) {
7
10
  this.deps = deps;
8
11
  this.log = deps.logger('action:action-page-runner');
@@ -12,7 +15,9 @@ class ActionPageRunner {
12
15
  return this.deps.executionContextManager.withContext(this.deps.commandLineExecutionContext(), { name: 'pageActions', values: { pageActions: true } }, async (executionContext, abortController) => {
13
16
  const unregisterAbortPageActionsHookOnNavigate = this.deps.router.registerHook('beforeNavigate', function abortPageActionsOnNavigation() {
14
17
  unregisterAbortPageActionsHookOnNavigate();
15
- abortController.abort('Page actions were aborted because of route changing');
18
+ abortController.abort(new PageActionsAbortError({
19
+ message: 'Page actions were aborted because of route changing',
20
+ }));
16
21
  return Promise.resolve();
17
22
  });
18
23
  const actionMapper = (action) => {
@@ -22,17 +27,17 @@ class ActionPageRunner {
22
27
  return promise;
23
28
  })
24
29
  .catch((error) => {
25
- if (!isSilentError(error)) {
26
- const parameters = isTramvaiAction(action) ? action : action[ACTION_PARAMETERS];
27
- this.log.error({
28
- error,
29
- event: `action-execution-error`,
30
- message: `An error occurred during "${parameters?.name ?? 'unknown'}" action execution`,
31
- });
32
- }
30
+ const parameters = isTramvaiAction(action) ? action : action[ACTION_PARAMETERS];
31
+ const pageActionsAbortedError = typeof error?.reason === 'object' && isPageActionsAbortError(error?.reason);
32
+ this.log[isSilentError(error) || pageActionsAbortedError ? 'info' : 'error']({
33
+ error,
34
+ event: `action-execution-error`,
35
+ message: `An error occurred during "${parameters?.name ?? 'unknown'}" action execution`,
36
+ });
33
37
  if (stopRunAtError(error)) {
34
38
  if (process.env.NODE_ENV === 'development') {
35
39
  if (this.isChildAppRunner) {
40
+ // eslint-disable-next-line no-console
36
41
  console.error(`Throwing error ${error.errorName} is not supported in Child Apps, host application command line will not be aborted!`);
37
42
  }
38
43
  }