@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.
- package/__migrations__/1-als-rename-module.js +12 -23
- package/lib/actions/ActionModule.browser.js +14 -3
- package/lib/actions/ActionModule.es.js +14 -3
- package/lib/actions/ActionModule.js +12 -1
- package/lib/actions/actionChecker.browser.js +9 -3
- package/lib/actions/actionChecker.es.js +9 -3
- package/lib/actions/actionChecker.js +9 -3
- package/lib/actions/actionExecution.browser.js +49 -3
- package/lib/actions/actionExecution.d.ts +4 -2
- package/lib/actions/actionExecution.es.js +49 -3
- package/lib/actions/actionExecution.js +49 -3
- package/lib/actions/actionPageRunner.browser.browser.js +15 -10
- package/lib/actions/actionPageRunner.es.js +27 -17
- package/lib/actions/actionPageRunner.js +26 -16
- package/lib/actions/actionRegistry.browser.js +1 -0
- package/lib/actions/actionRegistry.es.js +1 -0
- package/lib/actions/actionRegistry.js +1 -0
- package/lib/async-local-storage/server.es.js +11 -1
- package/lib/async-local-storage/server.js +11 -1
- package/lib/bundleManager/bundleManager.browser.js +2 -0
- package/lib/bundleManager/bundleManager.es.js +2 -0
- package/lib/bundleManager/bundleManager.js +2 -0
- package/lib/cache/cacheWithMetricsProxy.es.js +3 -0
- package/lib/cache/cacheWithMetricsProxy.js +3 -0
- package/lib/command/commandLineRunner.new.browser.js +18 -10
- package/lib/command/commandLineRunner.new.es.js +18 -10
- package/lib/command/commandLineRunner.new.js +17 -9
- package/lib/componentRegistry/componentRegistry.browser.js +1 -0
- package/lib/componentRegistry/componentRegistry.es.js +1 -0
- package/lib/componentRegistry/componentRegistry.js +1 -0
- package/lib/createConsumerContext/createConsumerContext.browser.js +42 -38
- package/lib/createConsumerContext/createConsumerContext.es.js +42 -38
- package/lib/createConsumerContext/createConsumerContext.js +42 -38
- package/lib/requestManager/requestManager.browser.js +3 -0
- package/lib/requestManager/requestManager.es.js +3 -0
- package/lib/requestManager/requestManager.js +3 -0
- package/lib/responseManager/responseManager.browser.js +4 -0
- package/lib/responseManager/responseManager.es.js +4 -0
- package/lib/responseManager/responseManager.js +4 -0
- package/package.json +23 -23
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { ACTION_PARAMETERS, isTramvaiAction } from '@tramvai/core';
|
|
2
|
-
import {
|
|
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(
|
|
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
|
-
|
|
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
|
|
116
|
+
const isStopCommandLineError = stopRunAtError(error);
|
|
105
117
|
if (process.env.NODE_ENV === 'development') {
|
|
106
|
-
if (
|
|
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
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
|
120
|
+
const isStopCommandLineError = stopRunAtError(error);
|
|
109
121
|
if (process.env.NODE_ENV === 'development') {
|
|
110
|
-
if (
|
|
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
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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
|
}
|
|
@@ -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
|
|
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
|
|
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,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
|
-
|
|
84
|
-
|
|
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
|
-
|
|
84
|
-
|
|
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
|
-
|
|
88
|
-
|
|
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
|
}
|
|
@@ -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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
this.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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;
|