@tramvai/module-common 5.50.0 → 5.53.78

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 +23 -23
@@ -1,10 +1,16 @@
1
1
  import { ACTION_PARAMETERS, isTramvaiAction } from '@tramvai/core';
2
- import { ExecutionAbortError, isSilentError } from '@tinkoff/errors';
2
+ import { PageActionsAbortError, isPageActionsAbortError, isSilentError, ExecutionAbortError } from '@tinkoff/errors';
3
3
  import { actionServerStateEvent } from './actionTramvaiReducer.es.js';
4
4
  import { generateDeferredResolve, generateDeferredReject } from './deferred/clientScriptsUtils.es.js';
5
5
 
6
6
  const DEFAULT_PAYLOAD = {};
7
7
  class ActionPageRunner {
8
+ deps;
9
+ log;
10
+ deferredMap;
11
+ responseTaskManager;
12
+ serverResponseStream;
13
+ isChildAppRunner;
8
14
  constructor(deps) {
9
15
  this.deps = deps;
10
16
  this.log = deps.logger('action:action-page-runner');
@@ -30,7 +36,10 @@ class ActionPageRunner {
30
36
  You can find more detailed information from "action-execution-error" logs, and find relative logs by using the same "x-request-id" header`,
31
37
  unfinishedActions,
32
38
  });
33
- abortController.abort('Page actions were aborted because of timeout');
39
+ abortController.abort(new PageActionsAbortError({
40
+ message: 'Page actions were aborted because of timeout',
41
+ unfinishedActions,
42
+ }));
34
43
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
35
44
  endChecker();
36
45
  }, this.deps.limitTime);
@@ -85,14 +94,17 @@ You can find more detailed information from "action-execution-error" logs, and f
85
94
  const parameters = isTramvaiAction(action) ? action : action[ACTION_PARAMETERS];
86
95
  const actionName = parameters?.name ?? 'unknown';
87
96
  const contextName = `${executionContext.name}.${actionName}`;
88
- this.log.warn({
97
+ const reasonIsObject = typeof executionContext.abortSignal.reason === 'object';
98
+ const timeoutError = reasonIsObject && isPageActionsAbortError(executionContext.abortSignal.reason);
99
+ const silentError = reasonIsObject && isSilentError(executionContext.abortSignal.reason);
100
+ this.log[silentError ? 'info' : 'warn']({
89
101
  error: new ExecutionAbortError({
90
102
  message: `Execution aborted in context "${contextName}"`,
91
103
  contextName,
92
104
  reason: executionContext.abortSignal.reason,
93
105
  }),
94
106
  event: `action-execution-error`,
95
- message: `${actionName} has exceeded timeout of ${this.deps.limitTime}ms, execution results will be ignored.
107
+ message: `${timeoutError ? `${actionName} has exceeded timeout of ${this.deps.limitTime}ms, execution results will be ignored` : `${actionName} execution error`}.
96
108
  This action will be automatically executed on client - https://tramvai.dev/docs/features/data-fetching/action#synchronizing-between-server-and-client
97
109
  If the request in this action takes too long, you can move it to the client using "onlyBrowser" condition or use Deferred Actions.
98
110
  Also, the necessary network accesses may not be present.`,
@@ -101,25 +113,23 @@ Also, the necessary network accesses may not be present.`,
101
113
  return payload;
102
114
  })
103
115
  .catch((error) => {
104
- const isCriticalError = stopRunAtError(error);
116
+ const isStopCommandLineError = stopRunAtError(error);
105
117
  if (process.env.NODE_ENV === 'development') {
106
- if (isCriticalError && this.isChildAppRunner) {
118
+ if (isStopCommandLineError && this.isChildAppRunner) {
107
119
  console.error(`Throwing error ${error.errorName} is not supported in Child Apps, host application command line will not be aborted!`);
108
120
  }
109
121
  }
110
- if (!isSilentError(error)) {
111
- const parameters = isTramvaiAction(action) ? action : action[ACTION_PARAMETERS];
112
- this.log.warn({
113
- error,
114
- event: `action-execution-error`,
115
- message: `${parameters?.name ?? 'unknown'} execution error, ${isCriticalError
116
- ? `${error.name} error are expected and will stop actions execution and prevent page rendering`
117
- : `this action will be automatically executed on client - https://tramvai.dev/docs/features/data-fetching/action#synchronizing-between-server-and-client
122
+ const parameters = isTramvaiAction(action) ? action : action[ACTION_PARAMETERS];
123
+ this.log[isSilentError(error) ? 'info' : 'error']({
124
+ error,
125
+ event: `action-execution-error`,
126
+ message: `${parameters?.name ?? 'unknown'} execution error, ${isStopCommandLineError
127
+ ? `${error.name} error are expected and will stop actions execution and prevent page rendering`
128
+ : `this action will be automatically executed on client - https://tramvai.dev/docs/features/data-fetching/action#synchronizing-between-server-and-client
118
129
  If the request in this action takes too long, you can move it to the client using "onlyBrowser" condition or use Deferred Actions.
119
130
  Also, the necessary network accesses may not be present.`}`,
120
- });
121
- }
122
- if (isCriticalError) {
131
+ });
132
+ if (isStopCommandLineError) {
123
133
  clearTimeout(timeoutMarker);
124
134
  reject(error);
125
135
  }
@@ -9,6 +9,12 @@ var clientScriptsUtils = require('./deferred/clientScriptsUtils.js');
9
9
 
10
10
  const DEFAULT_PAYLOAD = {};
11
11
  class ActionPageRunner {
12
+ deps;
13
+ log;
14
+ deferredMap;
15
+ responseTaskManager;
16
+ serverResponseStream;
17
+ isChildAppRunner;
12
18
  constructor(deps) {
13
19
  this.deps = deps;
14
20
  this.log = deps.logger('action:action-page-runner');
@@ -34,7 +40,10 @@ class ActionPageRunner {
34
40
  You can find more detailed information from "action-execution-error" logs, and find relative logs by using the same "x-request-id" header`,
35
41
  unfinishedActions,
36
42
  });
37
- abortController.abort('Page actions were aborted because of timeout');
43
+ abortController.abort(new errors.PageActionsAbortError({
44
+ message: 'Page actions were aborted because of timeout',
45
+ unfinishedActions,
46
+ }));
38
47
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
39
48
  endChecker();
40
49
  }, this.deps.limitTime);
@@ -89,14 +98,17 @@ You can find more detailed information from "action-execution-error" logs, and f
89
98
  const parameters = core.isTramvaiAction(action) ? action : action[core.ACTION_PARAMETERS];
90
99
  const actionName = parameters?.name ?? 'unknown';
91
100
  const contextName = `${executionContext.name}.${actionName}`;
92
- this.log.warn({
101
+ const reasonIsObject = typeof executionContext.abortSignal.reason === 'object';
102
+ const timeoutError = reasonIsObject && errors.isPageActionsAbortError(executionContext.abortSignal.reason);
103
+ const silentError = reasonIsObject && errors.isSilentError(executionContext.abortSignal.reason);
104
+ this.log[silentError ? 'info' : 'warn']({
93
105
  error: new errors.ExecutionAbortError({
94
106
  message: `Execution aborted in context "${contextName}"`,
95
107
  contextName,
96
108
  reason: executionContext.abortSignal.reason,
97
109
  }),
98
110
  event: `action-execution-error`,
99
- message: `${actionName} has exceeded timeout of ${this.deps.limitTime}ms, execution results will be ignored.
111
+ message: `${timeoutError ? `${actionName} has exceeded timeout of ${this.deps.limitTime}ms, execution results will be ignored` : `${actionName} execution error`}.
100
112
  This action will be automatically executed on client - https://tramvai.dev/docs/features/data-fetching/action#synchronizing-between-server-and-client
101
113
  If the request in this action takes too long, you can move it to the client using "onlyBrowser" condition or use Deferred Actions.
102
114
  Also, the necessary network accesses may not be present.`,
@@ -105,25 +117,23 @@ Also, the necessary network accesses may not be present.`,
105
117
  return payload;
106
118
  })
107
119
  .catch((error) => {
108
- const isCriticalError = stopRunAtError(error);
120
+ const isStopCommandLineError = stopRunAtError(error);
109
121
  if (process.env.NODE_ENV === 'development') {
110
- if (isCriticalError && this.isChildAppRunner) {
122
+ if (isStopCommandLineError && this.isChildAppRunner) {
111
123
  console.error(`Throwing error ${error.errorName} is not supported in Child Apps, host application command line will not be aborted!`);
112
124
  }
113
125
  }
114
- if (!errors.isSilentError(error)) {
115
- const parameters = core.isTramvaiAction(action) ? action : action[core.ACTION_PARAMETERS];
116
- this.log.warn({
117
- error,
118
- event: `action-execution-error`,
119
- message: `${parameters?.name ?? 'unknown'} execution error, ${isCriticalError
120
- ? `${error.name} error are expected and will stop actions execution and prevent page rendering`
121
- : `this action will be automatically executed on client - https://tramvai.dev/docs/features/data-fetching/action#synchronizing-between-server-and-client
126
+ const parameters = core.isTramvaiAction(action) ? action : action[core.ACTION_PARAMETERS];
127
+ this.log[errors.isSilentError(error) ? 'info' : 'error']({
128
+ error,
129
+ event: `action-execution-error`,
130
+ message: `${parameters?.name ?? 'unknown'} execution error, ${isStopCommandLineError
131
+ ? `${error.name} error are expected and will stop actions execution and prevent page rendering`
132
+ : `this action will be automatically executed on client - https://tramvai.dev/docs/features/data-fetching/action#synchronizing-between-server-and-client
122
133
  If the request in this action takes too long, you can move it to the client using "onlyBrowser" condition or use Deferred Actions.
123
134
  Also, the necessary network accesses may not be present.`}`,
124
- });
125
- }
126
- if (isCriticalError) {
135
+ });
136
+ if (isStopCommandLineError) {
127
137
  clearTimeout(timeoutMarker);
128
138
  reject(error);
129
139
  }
@@ -5,6 +5,7 @@ import flatten from '@tinkoff/utils/array/flatten';
5
5
 
6
6
  const GLOBAL_PARAMETER = '@@global';
7
7
  class ActionRegistry {
8
+ actions;
8
9
  constructor({ actionsList }) {
9
10
  this.actions = new Map([[GLOBAL_PARAMETER, flatten(actionsList)]]);
10
11
  }
@@ -5,6 +5,7 @@ import flatten from '@tinkoff/utils/array/flatten';
5
5
 
6
6
  const GLOBAL_PARAMETER = '@@global';
7
7
  class ActionRegistry {
8
+ actions;
8
9
  constructor({ actionsList }) {
9
10
  this.actions = new Map([[GLOBAL_PARAMETER, flatten(actionsList)]]);
10
11
  }
@@ -16,6 +16,7 @@ var flatten__default = /*#__PURE__*/_interopDefaultLegacy(flatten);
16
16
 
17
17
  const GLOBAL_PARAMETER = '@@global';
18
18
  class ActionRegistry {
19
+ actions;
19
20
  constructor({ actionsList }) {
20
21
  this.actions = new Map([[GLOBAL_PARAMETER, flatten__default["default"](actionsList)]]);
21
22
  }
@@ -9,7 +9,7 @@ function runInAsyncContext({ app, storage, }) {
9
9
  storage.run({}, done);
10
10
  // prevent memory leaks, because async context can be destroyed after response,
11
11
  // all stored resources will be accumulated in memory, and peak memory allocation will be high
12
- // `onResponse` is not used because is not fired when request was aborted by user (https://fastify.dev/docs/latest/Guides/Detecting-When-Clients-Abort/)
12
+ // `onResponse` is not enough because is not fired when request was aborted by user (https://fastify.dev/docs/latest/Guides/Detecting-When-Clients-Abort/)
13
13
  // TODO: can lead to errors because store will be cleared before reply, but maybe it's ok because response will be ignored?
14
14
  reply.raw.once('close', () => {
15
15
  const store = storage.getStore();
@@ -20,6 +20,16 @@ function runInAsyncContext({ app, storage, }) {
20
20
  }
21
21
  });
22
22
  });
23
+ // we still need to clear store on response, because socket "close" event can not be executed for a long time,
24
+ // because we use `http.Agent` with `keepAlive` enabled, and socket can be reused.
25
+ app.addHook('onResponse', async () => {
26
+ const store = storage.getStore();
27
+ if (store) {
28
+ for (const key in store) {
29
+ delete store[key];
30
+ }
31
+ }
32
+ });
23
33
  }
24
34
  let AsyncLocalStorageModule = class AsyncLocalStorageModule {
25
35
  };
@@ -13,7 +13,7 @@ function runInAsyncContext({ app, storage, }) {
13
13
  storage.run({}, done);
14
14
  // prevent memory leaks, because async context can be destroyed after response,
15
15
  // all stored resources will be accumulated in memory, and peak memory allocation will be high
16
- // `onResponse` is not used because is not fired when request was aborted by user (https://fastify.dev/docs/latest/Guides/Detecting-When-Clients-Abort/)
16
+ // `onResponse` is not enough because is not fired when request was aborted by user (https://fastify.dev/docs/latest/Guides/Detecting-When-Clients-Abort/)
17
17
  // TODO: can lead to errors because store will be cleared before reply, but maybe it's ok because response will be ignored?
18
18
  reply.raw.once('close', () => {
19
19
  const store = storage.getStore();
@@ -24,6 +24,16 @@ function runInAsyncContext({ app, storage, }) {
24
24
  }
25
25
  });
26
26
  });
27
+ // we still need to clear store on response, because socket "close" event can not be executed for a long time,
28
+ // because we use `http.Agent` with `keepAlive` enabled, and socket can be reused.
29
+ app.addHook('onResponse', async () => {
30
+ const store = storage.getStore();
31
+ if (store) {
32
+ for (const key in store) {
33
+ delete store[key];
34
+ }
35
+ }
36
+ });
27
37
  }
28
38
  exports.AsyncLocalStorageModule = class AsyncLocalStorageModule {
29
39
  };
@@ -5,6 +5,8 @@ import { fileSystemPagesEnabled, getAllFileSystemPages, getAllFileSystemLayouts,
5
5
 
6
6
  const FS_PAGES_DEFAULT_BUNDLE = '__default';
7
7
  class BundleManager {
8
+ bundles;
9
+ componentRegistry;
8
10
  constructor({ bundleList, componentRegistry, logger }) {
9
11
  this.bundles = bundleList;
10
12
  this.componentRegistry = componentRegistry;
@@ -5,6 +5,8 @@ import { fileSystemPagesEnabled, getAllFileSystemPages, getAllFileSystemLayouts,
5
5
 
6
6
  const FS_PAGES_DEFAULT_BUNDLE = '__default';
7
7
  class BundleManager {
8
+ bundles;
9
+ componentRegistry;
8
10
  constructor({ bundleList, componentRegistry, logger }) {
9
11
  this.bundles = bundleList;
10
12
  this.componentRegistry = componentRegistry;
@@ -13,6 +13,8 @@ var identity__default = /*#__PURE__*/_interopDefaultLegacy(identity);
13
13
 
14
14
  const FS_PAGES_DEFAULT_BUNDLE = '__default';
15
15
  class BundleManager {
16
+ bundles;
17
+ componentRegistry;
16
18
  constructor({ bundleList, componentRegistry, logger }) {
17
19
  this.bundles = bundleList;
18
20
  this.componentRegistry = componentRegistry;
@@ -1,4 +1,7 @@
1
1
  class CacheWithMetricsProxy {
2
+ cache;
3
+ options;
4
+ metrics;
2
5
  constructor(cache, options, metrics) {
3
6
  this.cache = cache;
4
7
  this.options = options;
@@ -3,6 +3,9 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  class CacheWithMetricsProxy {
6
+ cache;
7
+ options;
8
+ metrics;
6
9
  constructor(cache, options, metrics) {
7
10
  this.cache = cache;
8
11
  this.options = options;
@@ -1,12 +1,22 @@
1
1
  import { createChildContainer } from '@tinkoff/dippy';
2
- import { isSilentError } from '@tinkoff/errors';
2
+ import { ExecutionAbortError, isSilentError } from '@tinkoff/errors';
3
3
  import { ROOT_EXECUTION_CONTEXT_TOKEN } from '@tramvai/tokens-common';
4
4
  import { COMMAND_LINE_TIMING_INFO_TOKEN } from '@tramvai/tokens-core-private';
5
5
 
6
6
  class CommandLineRunner {
7
+ rootDi;
8
+ log;
9
+ hookFactory;
10
+ plugins;
11
+ executionContextManager;
12
+ executionEndHandlers;
13
+ executionContextByDi = new WeakMap();
14
+ abortControllerByDi = new WeakMap();
15
+ lines;
16
+ runLineHook;
17
+ runCommandHook;
18
+ runCommandFnHook;
7
19
  constructor({ rootDi, lines, logger, plugins, hookFactory, executionContextManager, executionEndHandlers, }) {
8
- this.executionContextByDi = new WeakMap();
9
- this.abortControllerByDi = new WeakMap();
10
20
  this.rootDi = rootDi;
11
21
  this.lines = lines;
12
22
  this.hookFactory = hookFactory;
@@ -73,15 +83,16 @@ class CommandLineRunner {
73
83
  timingInfo[commandName].end = performance.now();
74
84
  });
75
85
  });
76
- this.runCommandFnHook.tapPromise('commandLineRunner', async (_, { fn, command, di }) => {
86
+ this.runCommandFnHook.tapPromise('commandLineRunner', async (_, { fn, line, command, di }) => {
77
87
  try {
78
88
  await this.executeCommand(fn, command, di);
79
89
  }
80
90
  catch (error) {
81
91
  // in case if any error happens during line execution results from other line handlers will not be used anyway
82
- this.abortControllerByDi
83
- .get(di)
84
- ?.abort('Execution context were aborted because of one of the commands failed');
92
+ this.abortControllerByDi.get(di)?.abort(new ExecutionAbortError({
93
+ message: 'Execution context were aborted because of one of the commands failed',
94
+ contextName: `command-line:${line}:${command.toString()}`,
95
+ }));
85
96
  throw error;
86
97
  }
87
98
  });
@@ -148,9 +159,6 @@ class CommandLineRunner {
148
159
  line: commandName,
149
160
  command: name,
150
161
  });
151
- if (typeof error === 'object') {
152
- error.di = di;
153
- }
154
162
  throw error;
155
163
  }
156
164
  }
@@ -1,12 +1,22 @@
1
1
  import { createChildContainer } from '@tinkoff/dippy';
2
- import { isSilentError } from '@tinkoff/errors';
2
+ import { ExecutionAbortError, isSilentError } from '@tinkoff/errors';
3
3
  import { ROOT_EXECUTION_CONTEXT_TOKEN } from '@tramvai/tokens-common';
4
4
  import { COMMAND_LINE_TIMING_INFO_TOKEN } from '@tramvai/tokens-core-private';
5
5
 
6
6
  class CommandLineRunner {
7
+ rootDi;
8
+ log;
9
+ hookFactory;
10
+ plugins;
11
+ executionContextManager;
12
+ executionEndHandlers;
13
+ executionContextByDi = new WeakMap();
14
+ abortControllerByDi = new WeakMap();
15
+ lines;
16
+ runLineHook;
17
+ runCommandHook;
18
+ runCommandFnHook;
7
19
  constructor({ rootDi, lines, logger, plugins, hookFactory, executionContextManager, executionEndHandlers, }) {
8
- this.executionContextByDi = new WeakMap();
9
- this.abortControllerByDi = new WeakMap();
10
20
  this.rootDi = rootDi;
11
21
  this.lines = lines;
12
22
  this.hookFactory = hookFactory;
@@ -73,15 +83,16 @@ class CommandLineRunner {
73
83
  timingInfo[commandName].end = performance.now();
74
84
  });
75
85
  });
76
- this.runCommandFnHook.tapPromise('commandLineRunner', async (_, { fn, command, di }) => {
86
+ this.runCommandFnHook.tapPromise('commandLineRunner', async (_, { fn, line, command, di }) => {
77
87
  try {
78
88
  await this.executeCommand(fn, command, di);
79
89
  }
80
90
  catch (error) {
81
91
  // in case if any error happens during line execution results from other line handlers will not be used anyway
82
- this.abortControllerByDi
83
- .get(di)
84
- ?.abort('Execution context were aborted because of one of the commands failed');
92
+ this.abortControllerByDi.get(di)?.abort(new ExecutionAbortError({
93
+ message: 'Execution context were aborted because of one of the commands failed',
94
+ contextName: `command-line:${line}:${command.toString()}`,
95
+ }));
85
96
  throw error;
86
97
  }
87
98
  });
@@ -148,9 +159,6 @@ class CommandLineRunner {
148
159
  line: commandName,
149
160
  command: name,
150
161
  });
151
- if (typeof error === 'object') {
152
- error.di = di;
153
- }
154
162
  throw error;
155
163
  }
156
164
  }
@@ -8,9 +8,19 @@ var tokensCommon = require('@tramvai/tokens-common');
8
8
  var tokensCorePrivate = require('@tramvai/tokens-core-private');
9
9
 
10
10
  class CommandLineRunner {
11
+ rootDi;
12
+ log;
13
+ hookFactory;
14
+ plugins;
15
+ executionContextManager;
16
+ executionEndHandlers;
17
+ executionContextByDi = new WeakMap();
18
+ abortControllerByDi = new WeakMap();
19
+ lines;
20
+ runLineHook;
21
+ runCommandHook;
22
+ runCommandFnHook;
11
23
  constructor({ rootDi, lines, logger, plugins, hookFactory, executionContextManager, executionEndHandlers, }) {
12
- this.executionContextByDi = new WeakMap();
13
- this.abortControllerByDi = new WeakMap();
14
24
  this.rootDi = rootDi;
15
25
  this.lines = lines;
16
26
  this.hookFactory = hookFactory;
@@ -77,15 +87,16 @@ class CommandLineRunner {
77
87
  timingInfo[commandName].end = performance.now();
78
88
  });
79
89
  });
80
- this.runCommandFnHook.tapPromise('commandLineRunner', async (_, { fn, command, di }) => {
90
+ this.runCommandFnHook.tapPromise('commandLineRunner', async (_, { fn, line, command, di }) => {
81
91
  try {
82
92
  await this.executeCommand(fn, command, di);
83
93
  }
84
94
  catch (error) {
85
95
  // in case if any error happens during line execution results from other line handlers will not be used anyway
86
- this.abortControllerByDi
87
- .get(di)
88
- ?.abort('Execution context were aborted because of one of the commands failed');
96
+ this.abortControllerByDi.get(di)?.abort(new errors.ExecutionAbortError({
97
+ message: 'Execution context were aborted because of one of the commands failed',
98
+ contextName: `command-line:${line}:${command.toString()}`,
99
+ }));
89
100
  throw error;
90
101
  }
91
102
  });
@@ -152,9 +163,6 @@ class CommandLineRunner {
152
163
  line: commandName,
153
164
  command: name,
154
165
  });
155
- if (typeof error === 'object') {
156
- error.di = di;
157
- }
158
166
  throw error;
159
167
  }
160
168
  }
@@ -3,6 +3,7 @@ import flatten from '@tinkoff/utils/array/flatten';
3
3
 
4
4
  const DEFAULT_GROUP = '__default';
5
5
  class ComponentRegistry {
6
+ components;
6
7
  constructor({ componentList } = {}) {
7
8
  this.components = {
8
9
  [DEFAULT_GROUP]: Object.assign({}, ...flatten(componentList ?? [])),
@@ -3,6 +3,7 @@ import flatten from '@tinkoff/utils/array/flatten';
3
3
 
4
4
  const DEFAULT_GROUP = '__default';
5
5
  class ComponentRegistry {
6
+ components;
6
7
  constructor({ componentList } = {}) {
7
8
  this.components = {
8
9
  [DEFAULT_GROUP]: Object.assign({}, ...flatten(componentList ?? [])),
@@ -12,6 +12,7 @@ var flatten__default = /*#__PURE__*/_interopDefaultLegacy(flatten);
12
12
 
13
13
  const DEFAULT_GROUP = '__default';
14
14
  class ComponentRegistry {
15
+ components;
15
16
  constructor({ componentList } = {}) {
16
17
  this.components = {
17
18
  [DEFAULT_GROUP]: Object.assign({}, ...flatten__default["default"](componentList ?? [])),
@@ -2,45 +2,49 @@ import { convertAction } from '@tramvai/state';
2
2
  import { ACTION_EXECUTION_TOKEN } from '@tramvai/tokens-common';
3
3
 
4
4
  class ConsumerContext {
5
- constructor({ di, dispatcherContext, pubsub, store }) {
6
- /* Side Effects */
7
- this.executeAction = (action, payload) => {
8
- return this.di.get(ACTION_EXECUTION_TOKEN).run(action, payload);
9
- };
10
- /* State manager */
11
- this.dispatch = (actionOrNameEvent, payload) => {
12
- return new Promise((resolve, reject) => {
13
- try {
14
- resolve(this.store.dispatch(convertAction(actionOrNameEvent, payload)));
15
- }
16
- catch (err) {
17
- reject(err);
18
- }
19
- });
20
- };
21
- this.dispatchWith = (createActionOrType, options) => {
22
- return typeof createActionOrType === 'function'
23
- ? (...args) => this.dispatch(createActionOrType(...args), options)
24
- : (payload) => this.dispatch(createActionOrType, payload);
25
- };
26
- /**
27
- * @deprecated
28
- */
29
- this.getStore = (store) => {
30
- return this.dispatcher.getStore(store);
31
- };
32
- this.dehydrate = () => ({
33
- dispatcher: this.dispatcher.dehydrate(),
5
+ di;
6
+ pubsub;
7
+ dispatcher;
8
+ store;
9
+ /* Side Effects */
10
+ executeAction = (action, payload) => {
11
+ return this.di.get(ACTION_EXECUTION_TOKEN).run(action, payload);
12
+ };
13
+ /* State manager */
14
+ dispatch = (actionOrNameEvent, payload) => {
15
+ return new Promise((resolve, reject) => {
16
+ try {
17
+ resolve(this.store.dispatch(convertAction(actionOrNameEvent, payload)));
18
+ }
19
+ catch (err) {
20
+ reject(err);
21
+ }
34
22
  });
35
- this.getState = (...args) => {
36
- return this.store.getState(args[0]);
37
- };
38
- this.subscribe = (...args) => {
39
- return this.store.subscribe(args[0], args[1]);
40
- };
41
- this.hasStore = (store) => this.dispatcher.hasStore(store);
42
- this.registerStore = (store) => this.dispatcher.registerStore(store);
43
- this.unregisterStore = (store) => this.dispatcher.unregisterStore(store);
23
+ };
24
+ dispatchWith = (createActionOrType, options) => {
25
+ return typeof createActionOrType === 'function'
26
+ ? (...args) => this.dispatch(createActionOrType(...args), options)
27
+ : (payload) => this.dispatch(createActionOrType, payload);
28
+ };
29
+ /**
30
+ * @deprecated
31
+ */
32
+ getStore = (store) => {
33
+ return this.dispatcher.getStore(store);
34
+ };
35
+ dehydrate = () => ({
36
+ dispatcher: this.dispatcher.dehydrate(),
37
+ });
38
+ getState = (...args) => {
39
+ return this.store.getState(args[0]);
40
+ };
41
+ subscribe = (...args) => {
42
+ return this.store.subscribe(args[0], args[1]);
43
+ };
44
+ hasStore = (store) => this.dispatcher.hasStore(store);
45
+ registerStore = (store) => this.dispatcher.registerStore(store);
46
+ unregisterStore = (store) => this.dispatcher.unregisterStore(store);
47
+ constructor({ di, dispatcherContext, pubsub, store }) {
44
48
  this.store = store;
45
49
  // @ts-expect-error
46
50
  this.dispatcher = dispatcherContext;