@optimizely/ocp-local-env 1.0.0-beta.10
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/README.md +51 -0
- package/dist/package.json +112 -0
- package/dist/public/bundle.82dc5d29fffb9f205051.js +3 -0
- package/dist/public/bundle.82dc5d29fffb9f205051.js.LICENSE.txt +92 -0
- package/dist/public/bundle.82dc5d29fffb9f205051.js.map +1 -0
- package/dist/public/index.html +1 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +115 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/executor/DestinationExecutor.d.ts +19 -0
- package/dist/src/executor/DestinationExecutor.js +72 -0
- package/dist/src/executor/DestinationExecutor.js.map +1 -0
- package/dist/src/executor/FunctionExecutor.d.ts +67 -0
- package/dist/src/executor/FunctionExecutor.js +189 -0
- package/dist/src/executor/FunctionExecutor.js.map +1 -0
- package/dist/src/executor/JobExecutor.d.ts +79 -0
- package/dist/src/executor/JobExecutor.js +215 -0
- package/dist/src/executor/JobExecutor.js.map +1 -0
- package/dist/src/executor/LifecycleExecutor.d.ts +64 -0
- package/dist/src/executor/LifecycleExecutor.js +167 -0
- package/dist/src/executor/LifecycleExecutor.js.map +1 -0
- package/dist/src/executor/SourceExecutor.d.ts +32 -0
- package/dist/src/executor/SourceExecutor.js +163 -0
- package/dist/src/executor/SourceExecutor.js.map +1 -0
- package/dist/src/executor/watcher.d.ts +62 -0
- package/dist/src/executor/watcher.js +213 -0
- package/dist/src/executor/watcher.js.map +1 -0
- package/dist/src/functions/hello.d.ts +4 -0
- package/dist/src/functions/hello.js +8 -0
- package/dist/src/functions/hello.js.map +1 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +9 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/jobs/dailyJob.d.ts +4 -0
- package/dist/src/jobs/dailyJob.js +8 -0
- package/dist/src/jobs/dailyJob.js.map +1 -0
- package/dist/src/local_engine/LocalFunctionApi.d.ts +17 -0
- package/dist/src/local_engine/LocalFunctionApi.js +54 -0
- package/dist/src/local_engine/LocalFunctionApi.js.map +1 -0
- package/dist/src/local_engine/LocalJobApi.d.ts +67 -0
- package/dist/src/local_engine/LocalJobApi.js +205 -0
- package/dist/src/local_engine/LocalJobApi.js.map +1 -0
- package/dist/src/local_engine/LocalNotifier.d.ts +9 -0
- package/dist/src/local_engine/LocalNotifier.js +26 -0
- package/dist/src/local_engine/LocalNotifier.js.map +1 -0
- package/dist/src/local_engine/local-engine-child-base.d.ts +110 -0
- package/dist/src/local_engine/local-engine-child-base.js +607 -0
- package/dist/src/local_engine/local-engine-child-base.js.map +1 -0
- package/dist/src/local_engine/local-engine-client.d.ts +161 -0
- package/dist/src/local_engine/local-engine-client.js +888 -0
- package/dist/src/local_engine/local-engine-client.js.map +1 -0
- package/dist/src/local_engine/local-engine-types.d.ts +245 -0
- package/dist/src/local_engine/local-engine-types.js +6 -0
- package/dist/src/local_engine/local-engine-types.js.map +1 -0
- package/dist/src/local_engine/local-engine-unified.d.ts +71 -0
- package/dist/src/local_engine/local-engine-unified.js +723 -0
- package/dist/src/local_engine/local-engine-unified.js.map +1 -0
- package/dist/src/local_engine/local-engine-utils.d.ts +68 -0
- package/dist/src/local_engine/local-engine-utils.js +219 -0
- package/dist/src/local_engine/local-engine-utils.js.map +1 -0
- package/dist/src/local_engine/localSDKConfig.d.ts +40 -0
- package/dist/src/local_engine/localSDKConfig.js +247 -0
- package/dist/src/local_engine/localSDKConfig.js.map +1 -0
- package/dist/src/local_engine/storage/BaseKVStoreWrapper.d.ts +37 -0
- package/dist/src/local_engine/storage/BaseKVStoreWrapper.js +110 -0
- package/dist/src/local_engine/storage/BaseKVStoreWrapper.js.map +1 -0
- package/dist/src/local_engine/storage/LocalConfigStore.d.ts +74 -0
- package/dist/src/local_engine/storage/LocalConfigStore.js +178 -0
- package/dist/src/local_engine/storage/LocalConfigStore.js.map +1 -0
- package/dist/src/local_engine/storage/LocalJobStore.d.ts +111 -0
- package/dist/src/local_engine/storage/LocalJobStore.js +249 -0
- package/dist/src/local_engine/storage/LocalJobStore.js.map +1 -0
- package/dist/src/local_engine/storage/LocalKVStore.d.ts +106 -0
- package/dist/src/local_engine/storage/LocalKVStore.js +1061 -0
- package/dist/src/local_engine/storage/LocalKVStore.js.map +1 -0
- package/dist/src/local_engine/storage/LocalNotificationStore.d.ts +28 -0
- package/dist/src/local_engine/storage/LocalNotificationStore.js +149 -0
- package/dist/src/local_engine/storage/LocalNotificationStore.js.map +1 -0
- package/dist/src/local_engine/storage/LocalSecretsStore.d.ts +115 -0
- package/dist/src/local_engine/storage/LocalSecretsStore.js +350 -0
- package/dist/src/local_engine/storage/LocalSecretsStore.js.map +1 -0
- package/dist/src/local_engine/storage/LocalSecretsStoreWrapper.d.ts +19 -0
- package/dist/src/local_engine/storage/LocalSecretsStoreWrapper.js +52 -0
- package/dist/src/local_engine/storage/LocalSecretsStoreWrapper.js.map +1 -0
- package/dist/src/local_engine/storage/LocalSettingsStore.d.ts +168 -0
- package/dist/src/local_engine/storage/LocalSettingsStore.js +509 -0
- package/dist/src/local_engine/storage/LocalSettingsStore.js.map +1 -0
- package/dist/src/local_engine/storage/LocalSettingsStoreWrapper.d.ts +15 -0
- package/dist/src/local_engine/storage/LocalSettingsStoreWrapper.js +28 -0
- package/dist/src/local_engine/storage/LocalSettingsStoreWrapper.js.map +1 -0
- package/dist/src/local_engine/storage/NumberSet.d.ts +21 -0
- package/dist/src/local_engine/storage/NumberSet.js +32 -0
- package/dist/src/local_engine/storage/NumberSet.js.map +1 -0
- package/dist/src/local_engine/storage/SourceDataStore.d.ts +23 -0
- package/dist/src/local_engine/storage/SourceDataStore.js +83 -0
- package/dist/src/local_engine/storage/SourceDataStore.js.map +1 -0
- package/dist/src/local_engine/storage/SourceJobExecutionStore.d.ts +25 -0
- package/dist/src/local_engine/storage/SourceJobExecutionStore.js +61 -0
- package/dist/src/local_engine/storage/SourceJobExecutionStore.js.map +1 -0
- package/dist/src/local_engine/storage/StringSet.d.ts +21 -0
- package/dist/src/local_engine/storage/StringSet.js +32 -0
- package/dist/src/local_engine/storage/StringSet.js.map +1 -0
- package/dist/src/local_engine/types.d.ts +53 -0
- package/dist/src/local_engine/types.js +6 -0
- package/dist/src/local_engine/types.js.map +1 -0
- package/dist/src/local_engine/utils.d.ts +33 -0
- package/dist/src/local_engine/utils.js +143 -0
- package/dist/src/local_engine/utils.js.map +1 -0
- package/dist/src/logging/LogManager.d.ts +246 -0
- package/dist/src/logging/LogManager.js +343 -0
- package/dist/src/logging/LogManager.js.map +1 -0
- package/dist/src/server/api/destinations.d.ts +7 -0
- package/dist/src/server/api/destinations.js +170 -0
- package/dist/src/server/api/destinations.js.map +1 -0
- package/dist/src/server/api/functions.d.ts +7 -0
- package/dist/src/server/api/functions.js +80 -0
- package/dist/src/server/api/functions.js.map +1 -0
- package/dist/src/server/api/jobs.d.ts +10 -0
- package/dist/src/server/api/jobs.js +244 -0
- package/dist/src/server/api/jobs.js.map +1 -0
- package/dist/src/server/api/settings.d.ts +6 -0
- package/dist/src/server/api/settings.js +116 -0
- package/dist/src/server/api/settings.js.map +1 -0
- package/dist/src/server/api/sources.d.ts +7 -0
- package/dist/src/server/api/sources.js +382 -0
- package/dist/src/server/api/sources.js.map +1 -0
- package/dist/src/server/api/stores.d.ts +2 -0
- package/dist/src/server/api/stores.js +341 -0
- package/dist/src/server/api/stores.js.map +1 -0
- package/dist/src/server/api/v1.d.ts +10 -0
- package/dist/src/server/api/v1.js +718 -0
- package/dist/src/server/api/v1.js.map +1 -0
- package/dist/src/server/api.d.ts +8 -0
- package/dist/src/server/api.js +217 -0
- package/dist/src/server/api.js.map +1 -0
- package/dist/src/server/app-discovery.d.ts +5 -0
- package/dist/src/server/app-discovery.js +113 -0
- package/dist/src/server/app-discovery.js.map +1 -0
- package/dist/src/server/config.d.ts +26 -0
- package/dist/src/server/config.js +112 -0
- package/dist/src/server/config.js.map +1 -0
- package/dist/src/server/mockDataGenerator.d.ts +1 -0
- package/dist/src/server/mockDataGenerator.js +154 -0
- package/dist/src/server/mockDataGenerator.js.map +1 -0
- package/dist/src/server/websocket.d.ts +0 -0
- package/dist/src/server/websocket.js +2 -0
- package/dist/src/server/websocket.js.map +1 -0
- package/dist/src/server.d.ts +2 -0
- package/dist/src/server.js +735 -0
- package/dist/src/server.js.map +1 -0
- package/dist/src/types/app.d.ts +154 -0
- package/dist/src/types/app.js +24 -0
- package/dist/src/types/app.js.map +1 -0
- package/dist/src/types/kvstore.d.ts +320 -0
- package/dist/src/types/kvstore.js +5 -0
- package/dist/src/types/kvstore.js.map +1 -0
- package/dist/src/ui/components/App.d.ts +6 -0
- package/dist/src/ui/components/App.js +432 -0
- package/dist/src/ui/components/App.js.map +1 -0
- package/dist/src/ui/components/DestinationBatchEditor.d.ts +7 -0
- package/dist/src/ui/components/DestinationBatchEditor.js +160 -0
- package/dist/src/ui/components/DestinationBatchEditor.js.map +1 -0
- package/dist/src/ui/components/DestinationSchemaViewer.d.ts +7 -0
- package/dist/src/ui/components/DestinationSchemaViewer.js +61 -0
- package/dist/src/ui/components/DestinationSchemaViewer.js.map +1 -0
- package/dist/src/ui/components/DestinationsView.d.ts +14 -0
- package/dist/src/ui/components/DestinationsView.js +68 -0
- package/dist/src/ui/components/DestinationsView.js.map +1 -0
- package/dist/src/ui/components/FunctionsView.d.ts +13 -0
- package/dist/src/ui/components/FunctionsView.js +288 -0
- package/dist/src/ui/components/FunctionsView.js.map +1 -0
- package/dist/src/ui/components/JobsView.d.ts +13 -0
- package/dist/src/ui/components/JobsView.js +320 -0
- package/dist/src/ui/components/JobsView.js.map +1 -0
- package/dist/src/ui/components/KVStoreViewer.d.ts +11 -0
- package/dist/src/ui/components/KVStoreViewer.js +168 -0
- package/dist/src/ui/components/KVStoreViewer.js.map +1 -0
- package/dist/src/ui/components/MetadataModal.d.ts +14 -0
- package/dist/src/ui/components/MetadataModal.js +28 -0
- package/dist/src/ui/components/MetadataModal.js.map +1 -0
- package/dist/src/ui/components/MetadataModal.test.d.ts +1 -0
- package/dist/src/ui/components/MetadataModal.test.js +143 -0
- package/dist/src/ui/components/MetadataModal.test.js.map +1 -0
- package/dist/src/ui/components/NotificationViewer.d.ts +16 -0
- package/dist/src/ui/components/NotificationViewer.js +69 -0
- package/dist/src/ui/components/NotificationViewer.js.map +1 -0
- package/dist/src/ui/components/SecretsStoreViewer.d.ts +11 -0
- package/dist/src/ui/components/SecretsStoreViewer.js +179 -0
- package/dist/src/ui/components/SecretsStoreViewer.js.map +1 -0
- package/dist/src/ui/components/SettingsStoreViewer.d.ts +24 -0
- package/dist/src/ui/components/SettingsStoreViewer.js +132 -0
- package/dist/src/ui/components/SettingsStoreViewer.js.map +1 -0
- package/dist/src/ui/components/SourceDataViewer.d.ts +8 -0
- package/dist/src/ui/components/SourceDataViewer.js +84 -0
- package/dist/src/ui/components/SourceDataViewer.js.map +1 -0
- package/dist/src/ui/components/SourceJobsSection.d.ts +8 -0
- package/dist/src/ui/components/SourceJobsSection.js +99 -0
- package/dist/src/ui/components/SourceJobsSection.js.map +1 -0
- package/dist/src/ui/components/SourceLifecycleSection.d.ts +7 -0
- package/dist/src/ui/components/SourceLifecycleSection.js +58 -0
- package/dist/src/ui/components/SourceLifecycleSection.js.map +1 -0
- package/dist/src/ui/components/SourceSchemaViewer.d.ts +7 -0
- package/dist/src/ui/components/SourceSchemaViewer.js +65 -0
- package/dist/src/ui/components/SourceSchemaViewer.js.map +1 -0
- package/dist/src/ui/components/SourceWebhookEditor.d.ts +8 -0
- package/dist/src/ui/components/SourceWebhookEditor.js +181 -0
- package/dist/src/ui/components/SourceWebhookEditor.js.map +1 -0
- package/dist/src/ui/components/SourcesView.d.ts +14 -0
- package/dist/src/ui/components/SourcesView.js +74 -0
- package/dist/src/ui/components/SourcesView.js.map +1 -0
- package/dist/src/ui/components/StoreViewer.d.ts +16 -0
- package/dist/src/ui/components/StoreViewer.js +86 -0
- package/dist/src/ui/components/StoreViewer.js.map +1 -0
- package/dist/src/ui/components/TabbedConsole.d.ts +17 -0
- package/dist/src/ui/components/TabbedConsole.js +163 -0
- package/dist/src/ui/components/TabbedConsole.js.map +1 -0
- package/dist/src/ui/components/common/DataTree.d.ts +15 -0
- package/dist/src/ui/components/common/DataTree.js +95 -0
- package/dist/src/ui/components/common/DataTree.js.map +1 -0
- package/dist/src/ui/components/common/EyeIcon.d.ts +11 -0
- package/dist/src/ui/components/common/EyeIcon.js +11 -0
- package/dist/src/ui/components/common/EyeIcon.js.map +1 -0
- package/dist/src/ui/hooks/useEntityNavigation.d.ts +72 -0
- package/dist/src/ui/hooks/useEntityNavigation.js +150 -0
- package/dist/src/ui/hooks/useEntityNavigation.js.map +1 -0
- package/dist/src/ui/hooks/useQueryParams.d.ts +6 -0
- package/dist/src/ui/hooks/useQueryParams.js +39 -0
- package/dist/src/ui/hooks/useQueryParams.js.map +1 -0
- package/dist/src/ui/index.d.ts +1 -0
- package/dist/src/ui/index.js +23 -0
- package/dist/src/ui/index.js.map +1 -0
- package/dist/src/ui/store/formStateSlice.d.ts +54 -0
- package/dist/src/ui/store/formStateSlice.js +94 -0
- package/dist/src/ui/store/formStateSlice.js.map +1 -0
- package/dist/src/ui/store/hooks.d.ts +6 -0
- package/dist/src/ui/store/hooks.js +8 -0
- package/dist/src/ui/store/hooks.js.map +1 -0
- package/dist/src/ui/store/index.d.ts +11 -0
- package/dist/src/ui/store/index.js +107 -0
- package/dist/src/ui/store/index.js.map +1 -0
- package/dist/src/utils/functionEndpoints.d.ts +24 -0
- package/dist/src/utils/functionEndpoints.js +45 -0
- package/dist/src/utils/functionEndpoints.js.map +1 -0
- package/package.json +112 -0
|
@@ -0,0 +1,888 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.LocalEngineClient = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* IPC Client for managing child process communication
|
|
9
|
+
*/
|
|
10
|
+
const child_process_1 = require("child_process");
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const local_engine_utils_1 = require("./local-engine-utils");
|
|
13
|
+
const LogManager_1 = require("../logging/LogManager");
|
|
14
|
+
function getLogCategoryFromMessageType(context) {
|
|
15
|
+
switch (context.type) {
|
|
16
|
+
case 'function':
|
|
17
|
+
return LogManager_1.LogCategory.Function;
|
|
18
|
+
case 'lifecycle':
|
|
19
|
+
return LogManager_1.LogCategory.Lifecycle;
|
|
20
|
+
case 'destination':
|
|
21
|
+
return LogManager_1.LogCategory.Destination;
|
|
22
|
+
case 'source':
|
|
23
|
+
return LogManager_1.LogCategory.Source;
|
|
24
|
+
case 'jobs':
|
|
25
|
+
return LogManager_1.LogCategory.Jobs;
|
|
26
|
+
default:
|
|
27
|
+
return LogManager_1.LogCategory.AppRunner;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Process buffered output and log complete lines
|
|
32
|
+
*/
|
|
33
|
+
function processBufferedOutput(buffer, newData, isError, context) {
|
|
34
|
+
const logManager = LogManager_1.LogManager.getInstance();
|
|
35
|
+
const combined = buffer + newData;
|
|
36
|
+
const lines = combined.split('\n');
|
|
37
|
+
// Keep the last incomplete line in the buffer
|
|
38
|
+
const remainingBuffer = lines.pop() || '';
|
|
39
|
+
// Log only valid JSON lines (filters out pretty-printed output)
|
|
40
|
+
lines.forEach(line => {
|
|
41
|
+
const trimmed = line.trim();
|
|
42
|
+
if (trimmed) {
|
|
43
|
+
try {
|
|
44
|
+
// Try to parse as JSON
|
|
45
|
+
const parsed = JSON.parse(trimmed);
|
|
46
|
+
// Only log if it's a valid JSON object (structured log)
|
|
47
|
+
if (typeof parsed === 'object' && parsed !== null) {
|
|
48
|
+
// Log with execution context
|
|
49
|
+
if (context) {
|
|
50
|
+
// Map execution context type to log category enum
|
|
51
|
+
let category = getLogCategoryFromMessageType(context);
|
|
52
|
+
logManager.log({
|
|
53
|
+
source: LogManager_1.LogSource.App,
|
|
54
|
+
category,
|
|
55
|
+
level: isError ? 'error' : 'info',
|
|
56
|
+
message: trimmed,
|
|
57
|
+
context: { id: context.id }
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
// Fallback for app output without context
|
|
62
|
+
logManager.log({
|
|
63
|
+
source: LogManager_1.LogSource.App,
|
|
64
|
+
category: LogManager_1.LogCategory.AppRunner,
|
|
65
|
+
level: isError ? 'error' : 'info',
|
|
66
|
+
message: trimmed,
|
|
67
|
+
context: { id: '' }
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
console.error(trimmed, context);
|
|
73
|
+
}
|
|
74
|
+
// Silently ignore non-JSON lines (pretty-printed output)
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
// Not valid JSON - silently ignore
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
return remainingBuffer;
|
|
82
|
+
}
|
|
83
|
+
class LocalEngineClient {
|
|
84
|
+
constructor() {
|
|
85
|
+
this.connections = new Map();
|
|
86
|
+
this.logManager = LogManager_1.LogManager.getInstance();
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Get the singleton instance of LocalEngineClient
|
|
90
|
+
* This ensures all IPC handlers share the same instance and JobExecutor
|
|
91
|
+
*/
|
|
92
|
+
static getInstance() {
|
|
93
|
+
if (!LocalEngineClient.instance) {
|
|
94
|
+
LocalEngineClient.instance = new LocalEngineClient();
|
|
95
|
+
}
|
|
96
|
+
return LocalEngineClient.instance;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Set the JobExecutor instance for handling job trigger requests
|
|
100
|
+
*/
|
|
101
|
+
setJobExecutor(jobExecutor) {
|
|
102
|
+
this.jobExecutor = jobExecutor;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get or create a connection for the specified app
|
|
106
|
+
*/
|
|
107
|
+
async getConnection(appConfig, appDir) {
|
|
108
|
+
const connectionKey = appConfig.manifest.meta?.app_id || 'unknown';
|
|
109
|
+
let connection = this.connections.get(connectionKey);
|
|
110
|
+
// Check if existing connection is healthy
|
|
111
|
+
if (connection && (0, local_engine_utils_1.isConnectionHealthy)(connection)) {
|
|
112
|
+
connection.lastActivity = Date.now();
|
|
113
|
+
return connection;
|
|
114
|
+
}
|
|
115
|
+
// Clean up old connection if it exists
|
|
116
|
+
if (connection) {
|
|
117
|
+
await this.closeConnection(connectionKey);
|
|
118
|
+
}
|
|
119
|
+
// Create new connection
|
|
120
|
+
connection = await this.createConnection(appConfig, appDir);
|
|
121
|
+
this.connections.set(connectionKey, connection);
|
|
122
|
+
return connection;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Create a new IPC connection using the unified wrapper
|
|
126
|
+
*/
|
|
127
|
+
async createConnection(appConfig, appDir) {
|
|
128
|
+
const wrapperScript = path_1.default.join(__dirname, 'local-engine-unified.js');
|
|
129
|
+
this.logManager.info(LogManager_1.LogSource.System, LogManager_1.LogCategory.AppRunner, 'Starting unified wrapper for app', {
|
|
130
|
+
id: '',
|
|
131
|
+
operation: 'spawn',
|
|
132
|
+
appId: appConfig.manifest.meta?.app_id
|
|
133
|
+
});
|
|
134
|
+
const childProcess = (0, child_process_1.spawn)('node', [wrapperScript], {
|
|
135
|
+
cwd: appDir,
|
|
136
|
+
stdio: ['pipe', 'pipe', 'pipe', 'ipc'],
|
|
137
|
+
env: {
|
|
138
|
+
...process.env,
|
|
139
|
+
DISABLE_LOGMANAGER_CONSOLE: 'true' // Prevent double logging from child process
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
const connection = {
|
|
143
|
+
process: childProcess,
|
|
144
|
+
ready: false,
|
|
145
|
+
pendingRequests: new Map(),
|
|
146
|
+
lastActivity: Date.now(),
|
|
147
|
+
stdoutBuffer: '',
|
|
148
|
+
stderrBuffer: ''
|
|
149
|
+
};
|
|
150
|
+
// Set up message handling
|
|
151
|
+
this.setupMessageHandlers(connection);
|
|
152
|
+
// Set up error handling
|
|
153
|
+
this.setupErrorHandlers(connection);
|
|
154
|
+
// Initialize the child process
|
|
155
|
+
await this.initializeChild(connection, appConfig, appDir);
|
|
156
|
+
return connection;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Set up message handlers for a connection
|
|
160
|
+
*/
|
|
161
|
+
setupMessageHandlers(connection) {
|
|
162
|
+
connection.process.on('message', (message) => {
|
|
163
|
+
try {
|
|
164
|
+
(0, local_engine_utils_1.logIPCMessage)('RECV', message, '[IPC Client]');
|
|
165
|
+
if (!(0, local_engine_utils_1.validateMessage)(message)) {
|
|
166
|
+
this.logManager.error(LogManager_1.LogSource.System, LogManager_1.LogCategory.AppRunner, 'Received invalid message', {
|
|
167
|
+
id: connection.process.pid.toString(),
|
|
168
|
+
messageType: message?.type
|
|
169
|
+
});
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
this.handleChildMessage(connection, message);
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
this.logManager.error(LogManager_1.LogSource.System, LogManager_1.LogCategory.AppRunner, 'Error handling child message', {
|
|
176
|
+
id: 'unknown',
|
|
177
|
+
error
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
// Handle stdout/stderr - processBufferedOutput logs to LogManager
|
|
182
|
+
connection.process.stdout?.on('data', (data) => {
|
|
183
|
+
const output = data.toString();
|
|
184
|
+
connection.stdoutBuffer = processBufferedOutput(connection.stdoutBuffer || '', output, false, connection.currentContext // Pass execution context
|
|
185
|
+
);
|
|
186
|
+
});
|
|
187
|
+
connection.process.stderr?.on('data', (data) => {
|
|
188
|
+
const error = data.toString();
|
|
189
|
+
connection.stderrBuffer = processBufferedOutput(connection.stderrBuffer || '', error, true, connection.currentContext // Pass execution context
|
|
190
|
+
);
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Set up error handlers for a connection
|
|
195
|
+
*/
|
|
196
|
+
setupErrorHandlers(connection) {
|
|
197
|
+
connection.process.on('error', (error) => {
|
|
198
|
+
this.logManager.error(LogManager_1.LogSource.System, LogManager_1.LogCategory.AppRunner, 'Child process error', {
|
|
199
|
+
id: connection.process.pid?.toString() || 'unknown',
|
|
200
|
+
operation: 'error',
|
|
201
|
+
error
|
|
202
|
+
});
|
|
203
|
+
this.handleConnectionError(connection, error);
|
|
204
|
+
});
|
|
205
|
+
connection.process.on('exit', (code, signal) => {
|
|
206
|
+
this.logManager.info(LogManager_1.LogSource.System, LogManager_1.LogCategory.AppRunner, 'Child process exited', {
|
|
207
|
+
id: connection.process.pid?.toString() || 'unknown',
|
|
208
|
+
operation: 'exit',
|
|
209
|
+
exitCode: code ?? undefined,
|
|
210
|
+
signal: signal ?? undefined
|
|
211
|
+
});
|
|
212
|
+
this.handleConnectionExit(connection, code, signal);
|
|
213
|
+
});
|
|
214
|
+
connection.process.on('close', () => {
|
|
215
|
+
this.logManager.info(LogManager_1.LogSource.System, LogManager_1.LogCategory.AppRunner, 'Child process closed', {
|
|
216
|
+
id: connection.process.pid?.toString() || 'unknown',
|
|
217
|
+
operation: 'close'
|
|
218
|
+
});
|
|
219
|
+
connection.ready = false;
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Handle messages from child process
|
|
224
|
+
*/
|
|
225
|
+
handleChildMessage(connection, message) {
|
|
226
|
+
connection.lastActivity = Date.now();
|
|
227
|
+
switch (message.type) {
|
|
228
|
+
case 'ready':
|
|
229
|
+
this.handleReadyMessage(connection);
|
|
230
|
+
break;
|
|
231
|
+
case 'progress':
|
|
232
|
+
this.handleProgressMessage(connection, message);
|
|
233
|
+
break;
|
|
234
|
+
case 'log':
|
|
235
|
+
this.handleLogMessage(connection, message);
|
|
236
|
+
break;
|
|
237
|
+
case 'success':
|
|
238
|
+
this.handleSuccessMessage(connection, message);
|
|
239
|
+
break;
|
|
240
|
+
case 'error':
|
|
241
|
+
this.handleErrorMessage(connection, message);
|
|
242
|
+
break;
|
|
243
|
+
case 'trigger_job':
|
|
244
|
+
this.handleTriggerJobMessage(connection, message);
|
|
245
|
+
break;
|
|
246
|
+
case 'get_job_detail':
|
|
247
|
+
this.handleGetJobDetailMessage(connection, message);
|
|
248
|
+
break;
|
|
249
|
+
case 'get_job_status':
|
|
250
|
+
this.handleGetJobStatusMessage(connection, message);
|
|
251
|
+
break;
|
|
252
|
+
default:
|
|
253
|
+
this.logManager.warn(LogManager_1.LogSource.System, LogManager_1.LogCategory.AppRunner, 'Unknown message type', {
|
|
254
|
+
id: 'unknown',
|
|
255
|
+
messageType: message.type
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Handle ready message from child
|
|
261
|
+
*/
|
|
262
|
+
handleReadyMessage(connection) {
|
|
263
|
+
this.logManager.info(LogManager_1.LogSource.System, LogManager_1.LogCategory.AppRunner, 'Child process is ready', {
|
|
264
|
+
id: connection.process.pid?.toString() || 'unknown'
|
|
265
|
+
});
|
|
266
|
+
connection.ready = true;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Handle progress message from child
|
|
270
|
+
*/
|
|
271
|
+
handleProgressMessage(connection, message) {
|
|
272
|
+
const { requestId, message: progressMsg, progress } = message.data;
|
|
273
|
+
this.logManager.debug(LogManager_1.LogSource.System, LogManager_1.LogCategory.AppRunner, `Progress: ${progressMsg}`, {
|
|
274
|
+
id: requestId || 'unknown',
|
|
275
|
+
messageType: 'progress'
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Handle log message from child
|
|
280
|
+
*/
|
|
281
|
+
handleLogMessage(connection, message) {
|
|
282
|
+
const { level, message: logMsg, requestId } = message.data;
|
|
283
|
+
this.logManager.debug(LogManager_1.LogSource.System, LogManager_1.LogCategory.AppRunner, logMsg, {
|
|
284
|
+
id: requestId || connection.process.pid.toString() || 'unknown',
|
|
285
|
+
messageType: 'log'
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Handle success message from child
|
|
290
|
+
*/
|
|
291
|
+
handleSuccessMessage(connection, message) {
|
|
292
|
+
const { requestId, result } = message.data;
|
|
293
|
+
const pendingRequest = connection.pendingRequests.get(requestId);
|
|
294
|
+
if (pendingRequest) {
|
|
295
|
+
(0, local_engine_utils_1.cleanupPendingRequest)(pendingRequest);
|
|
296
|
+
connection.pendingRequests.delete(requestId);
|
|
297
|
+
pendingRequest.resolve(result);
|
|
298
|
+
// Clear execution context
|
|
299
|
+
if (connection.currentContext?.requestId === requestId) {
|
|
300
|
+
connection.currentContext = undefined;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
this.logManager.warn(LogManager_1.LogSource.System, LogManager_1.LogCategory.AppRunner, 'Received success for unknown request', {
|
|
305
|
+
id: requestId || 'unknown',
|
|
306
|
+
messageType: 'success'
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Handle error message from child
|
|
312
|
+
*/
|
|
313
|
+
handleErrorMessage(connection, message) {
|
|
314
|
+
const { requestId, error: errorMsg, stack } = message.data;
|
|
315
|
+
const pendingRequest = connection.pendingRequests.get(requestId);
|
|
316
|
+
if (pendingRequest) {
|
|
317
|
+
(0, local_engine_utils_1.cleanupPendingRequest)(pendingRequest);
|
|
318
|
+
connection.pendingRequests.delete(requestId);
|
|
319
|
+
const error = (0, local_engine_utils_1.deserializeError)({ message: errorMsg, stack });
|
|
320
|
+
pendingRequest.reject(error);
|
|
321
|
+
// Clear execution context
|
|
322
|
+
if (connection.currentContext?.requestId === requestId) {
|
|
323
|
+
connection.currentContext = undefined;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
this.logManager.warn(LogManager_1.LogSource.System, LogManager_1.LogCategory.AppRunner, 'Received error for unknown request', {
|
|
328
|
+
id: requestId || 'unknown',
|
|
329
|
+
messageType: 'error',
|
|
330
|
+
errorMessage: errorMsg
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Handle job trigger request from child
|
|
336
|
+
*/
|
|
337
|
+
async handleTriggerJobMessage(connection, message) {
|
|
338
|
+
const { jobName, parameters } = message.data;
|
|
339
|
+
const requestId = message.id;
|
|
340
|
+
if (!this.jobExecutor) {
|
|
341
|
+
this.logManager.error(LogManager_1.LogSource.System, LogManager_1.LogCategory.Jobs, 'JobExecutor not available', {
|
|
342
|
+
id: requestId,
|
|
343
|
+
jobName
|
|
344
|
+
});
|
|
345
|
+
// Send error response
|
|
346
|
+
const errorResponse = {
|
|
347
|
+
...(0, local_engine_utils_1.createBaseMessage)('error'),
|
|
348
|
+
type: 'error',
|
|
349
|
+
data: {
|
|
350
|
+
requestId,
|
|
351
|
+
error: 'JobExecutor not initialized',
|
|
352
|
+
executionTime: 0
|
|
353
|
+
}
|
|
354
|
+
};
|
|
355
|
+
(0, local_engine_utils_1.sendIPCMessage)(connection.process, errorResponse);
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
this.logManager.info(LogManager_1.LogSource.System, LogManager_1.LogCategory.Jobs, 'Processing job trigger request from child', {
|
|
359
|
+
id: requestId,
|
|
360
|
+
jobName
|
|
361
|
+
});
|
|
362
|
+
// Execute the job - this returns a response object with success/error info
|
|
363
|
+
const response = await this.jobExecutor.executeJob({
|
|
364
|
+
jobId: jobName,
|
|
365
|
+
parameters: parameters || {}
|
|
366
|
+
});
|
|
367
|
+
// Check if execution failed
|
|
368
|
+
if (!response.success) {
|
|
369
|
+
this.logManager.error(LogManager_1.LogSource.System, LogManager_1.LogCategory.Jobs, 'Job trigger request failed', {
|
|
370
|
+
id: requestId,
|
|
371
|
+
jobName,
|
|
372
|
+
error: response.error
|
|
373
|
+
});
|
|
374
|
+
// Send error response back to child
|
|
375
|
+
const errorResponse = {
|
|
376
|
+
...(0, local_engine_utils_1.createBaseMessage)('error'),
|
|
377
|
+
type: 'error',
|
|
378
|
+
data: {
|
|
379
|
+
requestId,
|
|
380
|
+
error: response.error || 'Failed to trigger job',
|
|
381
|
+
executionTime: 0
|
|
382
|
+
}
|
|
383
|
+
};
|
|
384
|
+
(0, local_engine_utils_1.sendIPCMessage)(connection.process, errorResponse);
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
// Get the execution details
|
|
388
|
+
const execution = this.jobExecutor.getExecution(response.executionId);
|
|
389
|
+
if (!execution) {
|
|
390
|
+
this.logManager.error(LogManager_1.LogSource.System, LogManager_1.LogCategory.Jobs, 'Execution not found after trigger', {
|
|
391
|
+
id: requestId,
|
|
392
|
+
jobName,
|
|
393
|
+
executionId: response.executionId
|
|
394
|
+
});
|
|
395
|
+
const errorResponse = {
|
|
396
|
+
...(0, local_engine_utils_1.createBaseMessage)('error'),
|
|
397
|
+
type: 'error',
|
|
398
|
+
data: {
|
|
399
|
+
requestId,
|
|
400
|
+
error: `Execution not found after trigger: ${response.executionId}`,
|
|
401
|
+
executionTime: 0
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
(0, local_engine_utils_1.sendIPCMessage)(connection.process, errorResponse);
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
this.logManager.info(LogManager_1.LogSource.System, LogManager_1.LogCategory.Jobs, 'Job triggered successfully from child', {
|
|
408
|
+
id: requestId,
|
|
409
|
+
jobName,
|
|
410
|
+
executionId: response.executionId
|
|
411
|
+
});
|
|
412
|
+
// Send success response with execution details
|
|
413
|
+
const successResponse = {
|
|
414
|
+
...(0, local_engine_utils_1.createBaseMessage)('success'),
|
|
415
|
+
type: 'success',
|
|
416
|
+
data: {
|
|
417
|
+
requestId,
|
|
418
|
+
result: {
|
|
419
|
+
jobId: execution.id,
|
|
420
|
+
jobName: execution.jobId,
|
|
421
|
+
status: execution.status,
|
|
422
|
+
parameters: execution.parameters,
|
|
423
|
+
startedAt: execution.startedAt,
|
|
424
|
+
completedAt: execution.completedAt
|
|
425
|
+
},
|
|
426
|
+
executionTime: 0
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
(0, local_engine_utils_1.sendIPCMessage)(connection.process, successResponse);
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Handle job detail request from child
|
|
433
|
+
*/
|
|
434
|
+
async handleGetJobDetailMessage(connection, message) {
|
|
435
|
+
const { requestId, executionId } = message.data;
|
|
436
|
+
const execution = this.jobExecutor?.getExecution(executionId);
|
|
437
|
+
if (!execution) {
|
|
438
|
+
const errorResponse = {
|
|
439
|
+
...(0, local_engine_utils_1.createBaseMessage)('error'),
|
|
440
|
+
type: 'error',
|
|
441
|
+
data: {
|
|
442
|
+
requestId,
|
|
443
|
+
error: `Execution ${executionId} not found`,
|
|
444
|
+
executionTime: 0
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
(0, local_engine_utils_1.sendIPCMessage)(connection.process, errorResponse);
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
// Send success response with execution details
|
|
451
|
+
const successResponse = {
|
|
452
|
+
...(0, local_engine_utils_1.createBaseMessage)('success'),
|
|
453
|
+
type: 'success',
|
|
454
|
+
data: {
|
|
455
|
+
requestId,
|
|
456
|
+
result: {
|
|
457
|
+
jobId: execution.id,
|
|
458
|
+
jobName: execution.jobId,
|
|
459
|
+
status: execution.status,
|
|
460
|
+
parameters: execution.parameters,
|
|
461
|
+
startedAt: execution.startedAt,
|
|
462
|
+
completedAt: execution.completedAt
|
|
463
|
+
},
|
|
464
|
+
executionTime: 0
|
|
465
|
+
}
|
|
466
|
+
};
|
|
467
|
+
(0, local_engine_utils_1.sendIPCMessage)(connection.process, successResponse);
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Handle job status request from child
|
|
471
|
+
*/
|
|
472
|
+
async handleGetJobStatusMessage(connection, message) {
|
|
473
|
+
const { requestId, executionId } = message.data;
|
|
474
|
+
const execution = this.jobExecutor?.getExecution(executionId);
|
|
475
|
+
if (!execution) {
|
|
476
|
+
const errorResponse = {
|
|
477
|
+
...(0, local_engine_utils_1.createBaseMessage)('error'),
|
|
478
|
+
type: 'error',
|
|
479
|
+
data: {
|
|
480
|
+
requestId,
|
|
481
|
+
error: `Execution ${executionId} not found`,
|
|
482
|
+
executionTime: 0
|
|
483
|
+
}
|
|
484
|
+
};
|
|
485
|
+
(0, local_engine_utils_1.sendIPCMessage)(connection.process, errorResponse);
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
// Send success response with just the status
|
|
489
|
+
const successResponse = {
|
|
490
|
+
...(0, local_engine_utils_1.createBaseMessage)('success'),
|
|
491
|
+
type: 'success',
|
|
492
|
+
data: {
|
|
493
|
+
requestId,
|
|
494
|
+
result: {
|
|
495
|
+
status: execution.status
|
|
496
|
+
},
|
|
497
|
+
executionTime: 0
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
(0, local_engine_utils_1.sendIPCMessage)(connection.process, successResponse);
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Handle connection errors
|
|
504
|
+
*/
|
|
505
|
+
handleConnectionError(connection, error) {
|
|
506
|
+
this.logManager.error(LogManager_1.LogSource.System, LogManager_1.LogCategory.AppRunner, 'Connection error', {
|
|
507
|
+
id: connection.process.pid?.toString() || 'unknown',
|
|
508
|
+
operation: 'error',
|
|
509
|
+
error
|
|
510
|
+
});
|
|
511
|
+
// Reject all pending requests
|
|
512
|
+
for (const [requestId, pendingRequest] of connection.pendingRequests) {
|
|
513
|
+
(0, local_engine_utils_1.cleanupPendingRequest)(pendingRequest);
|
|
514
|
+
pendingRequest.reject(new Error(`Connection error: ${error.message}`));
|
|
515
|
+
}
|
|
516
|
+
connection.pendingRequests.clear();
|
|
517
|
+
connection.ready = false;
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Flush remaining buffered output before connection closes
|
|
521
|
+
*/
|
|
522
|
+
flushRemainingBuffers(connection) {
|
|
523
|
+
const logManager = LogManager_1.LogManager.getInstance();
|
|
524
|
+
// Flush stdout buffer if it has content
|
|
525
|
+
if (connection.stdoutBuffer?.trim()) {
|
|
526
|
+
try {
|
|
527
|
+
logManager.log({
|
|
528
|
+
source: LogManager_1.LogSource.App,
|
|
529
|
+
category: LogManager_1.LogCategory.AppRunner,
|
|
530
|
+
level: 'info',
|
|
531
|
+
message: connection.stdoutBuffer.trim(),
|
|
532
|
+
context: { id: 'unknown' }
|
|
533
|
+
});
|
|
534
|
+
connection.stdoutBuffer = '';
|
|
535
|
+
}
|
|
536
|
+
catch (error) {
|
|
537
|
+
this.logManager.error(LogManager_1.LogSource.System, LogManager_1.LogCategory.AppRunner, 'Error flushing stdout buffer', {
|
|
538
|
+
id: 'buffer',
|
|
539
|
+
operation: 'flush',
|
|
540
|
+
error
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
// Flush stderr buffer if it has content
|
|
545
|
+
if (connection.stderrBuffer?.trim()) {
|
|
546
|
+
try {
|
|
547
|
+
logManager.log({
|
|
548
|
+
source: LogManager_1.LogSource.App,
|
|
549
|
+
category: LogManager_1.LogCategory.AppRunner,
|
|
550
|
+
level: 'error',
|
|
551
|
+
message: connection.stderrBuffer.trim(),
|
|
552
|
+
context: { id: 'unknown' }
|
|
553
|
+
});
|
|
554
|
+
connection.stderrBuffer = '';
|
|
555
|
+
}
|
|
556
|
+
catch (error) {
|
|
557
|
+
this.logManager.error(LogManager_1.LogSource.System, LogManager_1.LogCategory.AppRunner, 'Error flushing stderr buffer', {
|
|
558
|
+
id: 'buffer',
|
|
559
|
+
operation: 'flush',
|
|
560
|
+
error
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Handle connection exit
|
|
567
|
+
*/
|
|
568
|
+
handleConnectionExit(connection, code, signal) {
|
|
569
|
+
// Flush any remaining buffered output before handling exit
|
|
570
|
+
this.flushRemainingBuffers(connection);
|
|
571
|
+
// Reject all pending requests
|
|
572
|
+
for (const [requestId, pendingRequest] of connection.pendingRequests) {
|
|
573
|
+
(0, local_engine_utils_1.cleanupPendingRequest)(pendingRequest);
|
|
574
|
+
pendingRequest.reject(new Error(`Child process exited with code ${code}, signal ${signal}`));
|
|
575
|
+
}
|
|
576
|
+
connection.pendingRequests.clear();
|
|
577
|
+
connection.ready = false;
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Initialize child process
|
|
581
|
+
*/
|
|
582
|
+
async initializeChild(connection, appConfig, appDir) {
|
|
583
|
+
return new Promise((resolve, reject) => {
|
|
584
|
+
const timeout = setTimeout(() => {
|
|
585
|
+
reject(new Error('Child process initialization timeout'));
|
|
586
|
+
}, local_engine_utils_1.IPC_CONFIG.DEFAULT_TIMEOUT);
|
|
587
|
+
const checkReady = () => {
|
|
588
|
+
if (connection.ready) {
|
|
589
|
+
clearTimeout(timeout);
|
|
590
|
+
resolve();
|
|
591
|
+
}
|
|
592
|
+
else {
|
|
593
|
+
setTimeout(checkReady, 100);
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
// Send initialization message
|
|
597
|
+
const initMessage = {
|
|
598
|
+
...(0, local_engine_utils_1.createBaseMessage)('initialize'),
|
|
599
|
+
type: 'initialize',
|
|
600
|
+
data: { appConfig, appDir }
|
|
601
|
+
};
|
|
602
|
+
(0, local_engine_utils_1.sendIPCMessage)(connection.process, initMessage);
|
|
603
|
+
(0, local_engine_utils_1.logIPCMessage)('SEND', initMessage, '[IPC Client]');
|
|
604
|
+
checkReady();
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* Get execution type from message type
|
|
609
|
+
*/
|
|
610
|
+
getExecutionType(messageType) {
|
|
611
|
+
if (messageType === 'execute_function')
|
|
612
|
+
return 'function';
|
|
613
|
+
if (messageType === 'execute_lifecycle')
|
|
614
|
+
return 'lifecycle';
|
|
615
|
+
if (messageType.startsWith('execute_destination_'))
|
|
616
|
+
return 'destination';
|
|
617
|
+
if (messageType.startsWith('execute_source_'))
|
|
618
|
+
return 'source';
|
|
619
|
+
if (messageType === 'execute_job')
|
|
620
|
+
return 'jobs';
|
|
621
|
+
return 'function'; // fallback
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Get execution ID from message
|
|
625
|
+
*/
|
|
626
|
+
getExecutionId(message) {
|
|
627
|
+
switch (message.type) {
|
|
628
|
+
case 'execute_function':
|
|
629
|
+
return message.data.functionId;
|
|
630
|
+
case 'execute_lifecycle':
|
|
631
|
+
return message.data.method;
|
|
632
|
+
case 'execute_destination_ready':
|
|
633
|
+
case 'execute_destination_deliver':
|
|
634
|
+
case 'execute_destination_schema':
|
|
635
|
+
return message.data.destinationId;
|
|
636
|
+
case 'execute_source_webhook':
|
|
637
|
+
case 'execute_source_create':
|
|
638
|
+
case 'execute_source_update':
|
|
639
|
+
case 'execute_source_delete':
|
|
640
|
+
case 'execute_source_enable':
|
|
641
|
+
case 'execute_source_pause':
|
|
642
|
+
case 'execute_source_job':
|
|
643
|
+
case 'execute_source_schema':
|
|
644
|
+
return message.data.sourceId;
|
|
645
|
+
case 'execute_job':
|
|
646
|
+
return message.data.jobId;
|
|
647
|
+
default:
|
|
648
|
+
return 'unknown';
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
/**
|
|
652
|
+
* Send a request and wait for response
|
|
653
|
+
*/
|
|
654
|
+
async sendRequest(connection, message, timeoutMs = local_engine_utils_1.IPC_CONFIG.DEFAULT_TIMEOUT) {
|
|
655
|
+
return new Promise((resolve, reject) => {
|
|
656
|
+
const pendingRequest = (0, local_engine_utils_1.createPendingRequest)(message.id, message.type === 'execute_function' ? 'function' : 'lifecycle', resolve, reject, timeoutMs);
|
|
657
|
+
// Set up timeout
|
|
658
|
+
pendingRequest.timeout = (0, local_engine_utils_1.createRequestTimeout)(message.id, timeoutMs, reject, () => connection.pendingRequests.delete(message.id));
|
|
659
|
+
// Set execution context for stdout/stderr capture
|
|
660
|
+
connection.currentContext = {
|
|
661
|
+
type: this.getExecutionType(message.type),
|
|
662
|
+
id: this.getExecutionId(message),
|
|
663
|
+
requestId: message.id,
|
|
664
|
+
startTime: Date.now()
|
|
665
|
+
};
|
|
666
|
+
// Track the request
|
|
667
|
+
connection.pendingRequests.set(message.id, pendingRequest);
|
|
668
|
+
// Send the message
|
|
669
|
+
(0, local_engine_utils_1.logIPCMessage)('SEND', message, '[IPC Client]');
|
|
670
|
+
if (!(0, local_engine_utils_1.sendIPCMessage)(connection.process, message)) {
|
|
671
|
+
(0, local_engine_utils_1.cleanupPendingRequest)(pendingRequest);
|
|
672
|
+
connection.pendingRequests.delete(message.id);
|
|
673
|
+
reject(new Error('Failed to send IPC message'));
|
|
674
|
+
}
|
|
675
|
+
});
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Execute a function using IPC
|
|
679
|
+
*/
|
|
680
|
+
async executeFunction(request, appConfig, appDir) {
|
|
681
|
+
const connection = await this.getConnection(appConfig, appDir);
|
|
682
|
+
const message = {
|
|
683
|
+
...(0, local_engine_utils_1.createBaseMessage)('execute_function'),
|
|
684
|
+
type: 'execute_function',
|
|
685
|
+
data: request
|
|
686
|
+
};
|
|
687
|
+
return this.sendRequest(connection, message);
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* Execute a lifecycle method using IPC
|
|
691
|
+
*/
|
|
692
|
+
async executeLifecycle(request, appConfig, appDir) {
|
|
693
|
+
const connection = await this.getConnection(appConfig, appDir);
|
|
694
|
+
const message = {
|
|
695
|
+
...(0, local_engine_utils_1.createBaseMessage)('execute_lifecycle'),
|
|
696
|
+
type: 'execute_lifecycle',
|
|
697
|
+
data: request
|
|
698
|
+
};
|
|
699
|
+
return this.sendRequest(connection, message);
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Execute a job using IPC
|
|
703
|
+
*/
|
|
704
|
+
async executeJob(request, appConfig, appDir) {
|
|
705
|
+
const connection = await this.getConnection(appConfig, appDir);
|
|
706
|
+
const message = {
|
|
707
|
+
...(0, local_engine_utils_1.createBaseMessage)('execute_job'),
|
|
708
|
+
type: 'execute_job',
|
|
709
|
+
data: request
|
|
710
|
+
};
|
|
711
|
+
return this.sendRequest(connection, message);
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* Execute destination ready() method
|
|
715
|
+
*/
|
|
716
|
+
async executeDestinationReady(destinationId, appConfig) {
|
|
717
|
+
const connection = await this.getConnection(appConfig, appConfig.path);
|
|
718
|
+
const message = {
|
|
719
|
+
...(0, local_engine_utils_1.createBaseMessage)('execute_destination_ready'),
|
|
720
|
+
type: 'execute_destination_ready',
|
|
721
|
+
data: { destinationId } // entryPoint removed
|
|
722
|
+
};
|
|
723
|
+
return this.sendRequest(connection, message);
|
|
724
|
+
}
|
|
725
|
+
/**
|
|
726
|
+
* Execute destination deliver() method
|
|
727
|
+
*/
|
|
728
|
+
async executeDestinationDeliver(destinationId, batch, appConfig) {
|
|
729
|
+
const connection = await this.getConnection(appConfig, appConfig.path);
|
|
730
|
+
const message = {
|
|
731
|
+
...(0, local_engine_utils_1.createBaseMessage)('execute_destination_deliver'),
|
|
732
|
+
type: 'execute_destination_deliver',
|
|
733
|
+
data: { destinationId, batch } // entryPoint removed
|
|
734
|
+
};
|
|
735
|
+
return this.sendRequest(connection, message);
|
|
736
|
+
}
|
|
737
|
+
/**
|
|
738
|
+
* Execute destination schema function
|
|
739
|
+
*/
|
|
740
|
+
async executeDestinationSchema(destinationId, appConfig) {
|
|
741
|
+
const connection = await this.getConnection(appConfig, appConfig.path);
|
|
742
|
+
const message = {
|
|
743
|
+
...(0, local_engine_utils_1.createBaseMessage)('execute_destination_schema'),
|
|
744
|
+
type: 'execute_destination_schema',
|
|
745
|
+
data: { destinationId } // entryPoint removed - local-engine looks it up from manifest
|
|
746
|
+
};
|
|
747
|
+
return this.sendRequest(connection, message);
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* Execute source webhook
|
|
751
|
+
*/
|
|
752
|
+
async executeSourceWebhook(request, appConfig) {
|
|
753
|
+
const connection = await this.getConnection(appConfig, appConfig.path);
|
|
754
|
+
const message = {
|
|
755
|
+
...(0, local_engine_utils_1.createBaseMessage)('execute_source_webhook'),
|
|
756
|
+
type: 'execute_source_webhook',
|
|
757
|
+
data: request
|
|
758
|
+
};
|
|
759
|
+
return this.sendRequest(connection, message);
|
|
760
|
+
}
|
|
761
|
+
/**
|
|
762
|
+
* Execute source create lifecycle
|
|
763
|
+
*/
|
|
764
|
+
async executeSourceCreate(sourceId, guid, appConfig) {
|
|
765
|
+
const connection = await this.getConnection(appConfig, appConfig.path);
|
|
766
|
+
const message = {
|
|
767
|
+
...(0, local_engine_utils_1.createBaseMessage)('execute_source_create'),
|
|
768
|
+
type: 'execute_source_create',
|
|
769
|
+
data: { sourceId, guid, action: 'create' }
|
|
770
|
+
};
|
|
771
|
+
return this.sendRequest(connection, message);
|
|
772
|
+
}
|
|
773
|
+
/**
|
|
774
|
+
* Execute source update lifecycle
|
|
775
|
+
*/
|
|
776
|
+
async executeSourceUpdate(sourceId, guid, appConfig) {
|
|
777
|
+
const connection = await this.getConnection(appConfig, appConfig.path);
|
|
778
|
+
const message = {
|
|
779
|
+
...(0, local_engine_utils_1.createBaseMessage)('execute_source_update'),
|
|
780
|
+
type: 'execute_source_update',
|
|
781
|
+
data: { sourceId, guid, action: 'update' }
|
|
782
|
+
};
|
|
783
|
+
return this.sendRequest(connection, message);
|
|
784
|
+
}
|
|
785
|
+
/**
|
|
786
|
+
* Execute source delete lifecycle
|
|
787
|
+
*/
|
|
788
|
+
async executeSourceDelete(sourceId, guid, appConfig) {
|
|
789
|
+
const connection = await this.getConnection(appConfig, appConfig.path);
|
|
790
|
+
const message = {
|
|
791
|
+
...(0, local_engine_utils_1.createBaseMessage)('execute_source_delete'),
|
|
792
|
+
type: 'execute_source_delete',
|
|
793
|
+
data: { sourceId, guid, action: 'delete' }
|
|
794
|
+
};
|
|
795
|
+
return this.sendRequest(connection, message);
|
|
796
|
+
}
|
|
797
|
+
/**
|
|
798
|
+
* Execute source enable lifecycle
|
|
799
|
+
*/
|
|
800
|
+
async executeSourceEnable(sourceId, guid, appConfig) {
|
|
801
|
+
const connection = await this.getConnection(appConfig, appConfig.path);
|
|
802
|
+
const message = {
|
|
803
|
+
...(0, local_engine_utils_1.createBaseMessage)('execute_source_enable'),
|
|
804
|
+
type: 'execute_source_enable',
|
|
805
|
+
data: { sourceId, guid, action: 'enable' }
|
|
806
|
+
};
|
|
807
|
+
return this.sendRequest(connection, message);
|
|
808
|
+
}
|
|
809
|
+
/**
|
|
810
|
+
* Execute source pause lifecycle
|
|
811
|
+
*/
|
|
812
|
+
async executeSourcePause(sourceId, guid, appConfig) {
|
|
813
|
+
const connection = await this.getConnection(appConfig, appConfig.path);
|
|
814
|
+
const message = {
|
|
815
|
+
...(0, local_engine_utils_1.createBaseMessage)('execute_source_pause'),
|
|
816
|
+
type: 'execute_source_pause',
|
|
817
|
+
data: { sourceId, guid, action: 'pause' }
|
|
818
|
+
};
|
|
819
|
+
return this.sendRequest(connection, message);
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* Execute source job
|
|
823
|
+
*/
|
|
824
|
+
async executeSourceJob(request, appConfig) {
|
|
825
|
+
const connection = await this.getConnection(appConfig, appConfig.path);
|
|
826
|
+
const message = {
|
|
827
|
+
...(0, local_engine_utils_1.createBaseMessage)('execute_source_job'),
|
|
828
|
+
type: 'execute_source_job',
|
|
829
|
+
data: request
|
|
830
|
+
};
|
|
831
|
+
return this.sendRequest(connection, message);
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* Execute source schema
|
|
835
|
+
*/
|
|
836
|
+
async executeSourceSchema(sourceId, appConfig) {
|
|
837
|
+
const connection = await this.getConnection(appConfig, appConfig.path);
|
|
838
|
+
const message = {
|
|
839
|
+
...(0, local_engine_utils_1.createBaseMessage)('execute_source_schema'),
|
|
840
|
+
type: 'execute_source_schema',
|
|
841
|
+
data: { sourceId }
|
|
842
|
+
};
|
|
843
|
+
return this.sendRequest(connection, message);
|
|
844
|
+
}
|
|
845
|
+
/**
|
|
846
|
+
* Close a specific connection
|
|
847
|
+
*/
|
|
848
|
+
async closeConnection(connectionKey) {
|
|
849
|
+
const connection = this.connections.get(connectionKey);
|
|
850
|
+
if (!connection)
|
|
851
|
+
return;
|
|
852
|
+
try {
|
|
853
|
+
// Flush any remaining buffered output before shutdown
|
|
854
|
+
this.flushRemainingBuffers(connection);
|
|
855
|
+
// Send shutdown message
|
|
856
|
+
const shutdownMessage = {
|
|
857
|
+
...(0, local_engine_utils_1.createBaseMessage)('shutdown'),
|
|
858
|
+
type: 'shutdown'
|
|
859
|
+
};
|
|
860
|
+
(0, local_engine_utils_1.sendIPCMessage)(connection.process, shutdownMessage);
|
|
861
|
+
// Wait a bit for graceful shutdown
|
|
862
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
863
|
+
// Force kill if still running
|
|
864
|
+
if (!connection.process.killed) {
|
|
865
|
+
connection.process.kill('SIGTERM');
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
catch (error) {
|
|
869
|
+
this.logManager.warn(LogManager_1.LogSource.System, LogManager_1.LogCategory.AppRunner, 'Error during connection shutdown', {
|
|
870
|
+
id: connection.process.pid?.toString() || 'unknown',
|
|
871
|
+
operation: 'shutdown',
|
|
872
|
+
error
|
|
873
|
+
});
|
|
874
|
+
}
|
|
875
|
+
finally {
|
|
876
|
+
this.connections.delete(connectionKey);
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
/**
|
|
880
|
+
* Close all connections
|
|
881
|
+
*/
|
|
882
|
+
async closeAllConnections() {
|
|
883
|
+
const closePromises = Array.from(this.connections.keys()).map(key => this.closeConnection(key));
|
|
884
|
+
await Promise.all(closePromises);
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
exports.LocalEngineClient = LocalEngineClient;
|
|
888
|
+
//# sourceMappingURL=local-engine-client.js.map
|