docker-client-mx 1.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +233 -0
- package/bin/docker-client-mx.js +42 -0
- package/build/icons/icon-1024.png +0 -0
- package/build/icons/icon-128.png +0 -0
- package/build/icons/icon-16.png +0 -0
- package/build/icons/icon-256.png +0 -0
- package/build/icons/icon-32.png +0 -0
- package/build/icons/icon-48.png +0 -0
- package/build/icons/icon-512.png +0 -0
- package/build/icons/icon-64.png +0 -0
- package/build/icons/icon.ico +0 -0
- package/build/icons/icon.iconset/icon_128x128.png +0 -0
- package/build/icons/icon.iconset/icon_128x128@2x.png +0 -0
- package/build/icons/icon.iconset/icon_16x16.png +0 -0
- package/build/icons/icon.iconset/icon_16x16@2x.png +0 -0
- package/build/icons/icon.iconset/icon_256x256.png +0 -0
- package/build/icons/icon.iconset/icon_256x256@2x.png +0 -0
- package/build/icons/icon.iconset/icon_32x32.png +0 -0
- package/build/icons/icon.iconset/icon_32x32@2x.png +0 -0
- package/build/icons/icon.iconset/icon_512x512.png +0 -0
- package/build/icons/icon.iconset/icon_512x512@2x.png +0 -0
- package/build/icons/icon.png +0 -0
- package/dist/docker-desktop-mx/browser/chunk-64WWLMUP.js +39 -0
- package/dist/docker-desktop-mx/browser/chunk-N4VBBC4W.js +1 -0
- package/dist/docker-desktop-mx/browser/favicon.ico +0 -0
- package/dist/docker-desktop-mx/browser/index.html +14 -0
- package/dist/docker-desktop-mx/browser/main-CTIRTSOI.js +5 -0
- package/dist/docker-desktop-mx/browser/styles-JS3HDDI4.css +1 -0
- package/dist-electron/api.js +10 -0
- package/dist-electron/api.js.map +1 -0
- package/dist-electron/assistant-key.js +70 -0
- package/dist-electron/assistant-key.js.map +1 -0
- package/dist-electron/assistant-models.js +19 -0
- package/dist-electron/assistant-models.js.map +1 -0
- package/dist-electron/assistant-tools.js +335 -0
- package/dist-electron/assistant-tools.js.map +1 -0
- package/dist-electron/assistant.js +302 -0
- package/dist-electron/assistant.js.map +1 -0
- package/dist-electron/attention.js +75 -0
- package/dist-electron/attention.js.map +1 -0
- package/dist-electron/channels.js +113 -0
- package/dist-electron/channels.js.map +1 -0
- package/dist-electron/compose-files.js +104 -0
- package/dist-electron/compose-files.js.map +1 -0
- package/dist-electron/compose.js +271 -0
- package/dist-electron/compose.js.map +1 -0
- package/dist-electron/container-events.js +188 -0
- package/dist-electron/container-events.js.map +1 -0
- package/dist-electron/containers.js +165 -0
- package/dist-electron/containers.js.map +1 -0
- package/dist-electron/context-menu.js +56 -0
- package/dist-electron/context-menu.js.map +1 -0
- package/dist-electron/contexts.js +346 -0
- package/dist-electron/contexts.js.map +1 -0
- package/dist-electron/crash.js +129 -0
- package/dist-electron/crash.js.map +1 -0
- package/dist-electron/diagnosis.js +338 -0
- package/dist-electron/diagnosis.js.map +1 -0
- package/dist-electron/docker-client.js +284 -0
- package/dist-electron/docker-client.js.map +1 -0
- package/dist-electron/engine.js +145 -0
- package/dist-electron/engine.js.map +1 -0
- package/dist-electron/event-store.js +146 -0
- package/dist-electron/event-store.js.map +1 -0
- package/dist-electron/events.js +132 -0
- package/dist-electron/events.js.map +1 -0
- package/dist-electron/exec.js +138 -0
- package/dist-electron/exec.js.map +1 -0
- package/dist-electron/files.js +407 -0
- package/dist-electron/files.js.map +1 -0
- package/dist-electron/health.js +92 -0
- package/dist-electron/health.js.map +1 -0
- package/dist-electron/host-overview.js +50 -0
- package/dist-electron/host-overview.js.map +1 -0
- package/dist-electron/host-shell.js +196 -0
- package/dist-electron/host-shell.js.map +1 -0
- package/dist-electron/i18n.js +58 -0
- package/dist-electron/i18n.js.map +1 -0
- package/dist-electron/image-history.js +87 -0
- package/dist-electron/image-history.js.map +1 -0
- package/dist-electron/images.js +141 -0
- package/dist-electron/images.js.map +1 -0
- package/dist-electron/ipc.js +783 -0
- package/dist-electron/ipc.js.map +1 -0
- package/dist-electron/links.js +46 -0
- package/dist-electron/links.js.map +1 -0
- package/dist-electron/logs.js +153 -0
- package/dist-electron/logs.js.map +1 -0
- package/dist-electron/main.js +494 -0
- package/dist-electron/main.js.map +1 -0
- package/dist-electron/merged-logs.js +127 -0
- package/dist-electron/merged-logs.js.map +1 -0
- package/dist-electron/navigation.js +37 -0
- package/dist-electron/navigation.js.map +1 -0
- package/dist-electron/ndjson.js +30 -0
- package/dist-electron/ndjson.js.map +1 -0
- package/dist-electron/networks.js +507 -0
- package/dist-electron/networks.js.map +1 -0
- package/dist-electron/port-conflicts.js +106 -0
- package/dist-electron/port-conflicts.js.map +1 -0
- package/dist-electron/preload.js +257 -0
- package/dist-electron/preload.js.map +1 -0
- package/dist-electron/pull.js +220 -0
- package/dist-electron/pull.js.map +1 -0
- package/dist-electron/redact.js +129 -0
- package/dist-electron/redact.js.map +1 -0
- package/dist-electron/registry-auth.js +150 -0
- package/dist-electron/registry-auth.js.map +1 -0
- package/dist-electron/renew.js +162 -0
- package/dist-electron/renew.js.map +1 -0
- package/dist-electron/restart-policy.js +58 -0
- package/dist-electron/restart-policy.js.map +1 -0
- package/dist-electron/run-command.js +146 -0
- package/dist-electron/run-command.js.map +1 -0
- package/dist-electron/run.js +151 -0
- package/dist-electron/run.js.map +1 -0
- package/dist-electron/self-update.js +163 -0
- package/dist-electron/self-update.js.map +1 -0
- package/dist-electron/servers.js +108 -0
- package/dist-electron/servers.js.map +1 -0
- package/dist-electron/settings.js +146 -0
- package/dist-electron/settings.js.map +1 -0
- package/dist-electron/ssh.js +574 -0
- package/dist-electron/ssh.js.map +1 -0
- package/dist-electron/stats.js +209 -0
- package/dist-electron/stats.js.map +1 -0
- package/dist-electron/streams.js +63 -0
- package/dist-electron/streams.js.map +1 -0
- package/dist-electron/system.js +123 -0
- package/dist-electron/system.js.map +1 -0
- package/dist-electron/terminal-transcript.js +55 -0
- package/dist-electron/terminal-transcript.js.map +1 -0
- package/dist-electron/updates.js +136 -0
- package/dist-electron/updates.js.map +1 -0
- package/dist-electron/volume-backup.js +203 -0
- package/dist-electron/volume-backup.js.map +1 -0
- package/dist-electron/volume-files.js +124 -0
- package/dist-electron/volume-files.js.map +1 -0
- package/dist-electron/volumes.js +253 -0
- package/dist-electron/volumes.js.map +1 -0
- package/dist-electron/wiring-watch.js +93 -0
- package/dist-electron/wiring-watch.js.map +1 -0
- package/dist-electron/wiring.js +71 -0
- package/dist-electron/wiring.js.map +1 -0
- package/dist-electron/wsl.js +167 -0
- package/dist-electron/wsl.js.map +1 -0
- package/package.json +125 -0
|
@@ -0,0 +1,494 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const electron_1 = require("electron");
|
|
37
|
+
const electron_updater_1 = require("electron-updater");
|
|
38
|
+
const node_fs_1 = require("node:fs");
|
|
39
|
+
const path = __importStar(require("node:path"));
|
|
40
|
+
const crash_1 = require("./crash");
|
|
41
|
+
const docker_client_1 = require("./docker-client");
|
|
42
|
+
const ipc_1 = require("./ipc");
|
|
43
|
+
const host_shell_1 = require("./host-shell");
|
|
44
|
+
const volume_files_1 = require("./volume-files");
|
|
45
|
+
const links_1 = require("./links");
|
|
46
|
+
const assistant_key_1 = require("./assistant-key");
|
|
47
|
+
const channels_1 = require("./channels");
|
|
48
|
+
const context_menu_1 = require("./context-menu");
|
|
49
|
+
const i18n_1 = require("./i18n");
|
|
50
|
+
const navigation_1 = require("./navigation");
|
|
51
|
+
const self_update_1 = require("./self-update");
|
|
52
|
+
const settings_1 = require("./settings");
|
|
53
|
+
/*
|
|
54
|
+
* Drie manieren om te draaien: uit de installer (verpakt), via npm (niet verpakt, maar gestart
|
|
55
|
+
* door bin/docker-client-mx.js met --from-npm) en als ontwikkelversie uit deze repository.
|
|
56
|
+
* Alleen die laatste is "dev": een eigen naam, een eigen map, en de dev-server als die er is.
|
|
57
|
+
*/
|
|
58
|
+
const FROM_NPM = process.argv.includes('--from-npm');
|
|
59
|
+
const IS_DEV = !electron_1.app.isPackaged && !FROM_NPM;
|
|
60
|
+
// Gezet door `npm run dev`; zonder deze variabele laden we altijd de gebouwde bestanden,
|
|
61
|
+
// zodat `electron .` na een build precies doet wat de installer straks ook doet.
|
|
62
|
+
const devServerUrl = IS_DEV ? process.env['ELECTRON_RENDERER_URL'] : undefined;
|
|
63
|
+
const PROD_INDEX = path.join(__dirname, '../dist/docker-desktop-mx/browser/index.html');
|
|
64
|
+
/*
|
|
65
|
+
* Op Windows draagt het programmabestand zijn eigen pictogram, maar dat geldt niet voor
|
|
66
|
+
* `electron .` tijdens het ontwikkelen en ook niet voor Linux. Ontbreekt het bestand -- er is
|
|
67
|
+
* nog geen `npm run icons` gedraaid -- dan laten we het weg in plaats van Electron ernaar te
|
|
68
|
+
* laten zoeken.
|
|
69
|
+
*/
|
|
70
|
+
const ICON = path.join(__dirname, '../build/icons/icon-256.png');
|
|
71
|
+
/** Het systeemvak tekent op 16 px (32 bij 200%); een klein bronbestand blijft daar scherp. */
|
|
72
|
+
const TRAY_ICON = path.join(__dirname, '../build/icons/icon-32.png');
|
|
73
|
+
/** Hoe de app zich noemt in het systeemvak; de ontwikkelversie is zo van de echte te onderscheiden. */
|
|
74
|
+
const APP_TITLE = IS_DEV ? 'Docker Client MX (dev)' : 'Docker Client MX';
|
|
75
|
+
/** Zelfde als `appId` in electron-builder.json: Windows koppelt meldingen aan deze naam. */
|
|
76
|
+
const APP_ID = 'com.martijnschimmel.dockerdesktopmx';
|
|
77
|
+
/**
|
|
78
|
+
* Waarmee Windows de app start bij aanmelden. Dan geen venster, alleen het systeemvak: wie
|
|
79
|
+
* inlogt wil niet meteen een venster van deze app voor zijn neus, maar wel de meldingen.
|
|
80
|
+
*/
|
|
81
|
+
const HIDDEN_ARG = '--hidden';
|
|
82
|
+
/** Hoe vaak het tray-menu kijkt of de engine er nog is. */
|
|
83
|
+
const TRAY_STATUS_MS = 15_000;
|
|
84
|
+
let mainWindow = null;
|
|
85
|
+
let tray = null;
|
|
86
|
+
/** De laatst bekende engine-status, zodat het tray-menu opnieuw op te bouwen is zonder ping. */
|
|
87
|
+
let trayEngineUp = null;
|
|
88
|
+
/** Alleen via "Afsluiten" in het tray-menu; het venster sluiten laat de app doorlopen. */
|
|
89
|
+
let quitting = false;
|
|
90
|
+
/** De uitleg dat de app doorloopt, komt één keer per sessie en niet bij elke keer sluiten. */
|
|
91
|
+
let toldAboutTray = false;
|
|
92
|
+
/**
|
|
93
|
+
* Meldingen die nog op het scherm of in het meldingencentrum staan. Zonder verwijzing ruimt de
|
|
94
|
+
* garbage collector het object op, en dan doet een klik erop niets meer.
|
|
95
|
+
*/
|
|
96
|
+
const liveNotifications = new Set();
|
|
97
|
+
function show(notification, onClick) {
|
|
98
|
+
liveNotifications.add(notification);
|
|
99
|
+
notification.on('click', () => {
|
|
100
|
+
liveNotifications.delete(notification);
|
|
101
|
+
onClick();
|
|
102
|
+
});
|
|
103
|
+
notification.on('close', () => liveNotifications.delete(notification));
|
|
104
|
+
notification.show();
|
|
105
|
+
}
|
|
106
|
+
function createWindow() {
|
|
107
|
+
const window = new electron_1.BrowserWindow({
|
|
108
|
+
width: 1280,
|
|
109
|
+
height: 1080,
|
|
110
|
+
minWidth: 1280,
|
|
111
|
+
minHeight: 600,
|
|
112
|
+
show: false,
|
|
113
|
+
backgroundColor: '#1b1b1f',
|
|
114
|
+
...((0, node_fs_1.existsSync)(ICON) ? { icon: ICON } : {}),
|
|
115
|
+
webPreferences: {
|
|
116
|
+
preload: path.join(__dirname, 'preload.js'),
|
|
117
|
+
contextIsolation: true,
|
|
118
|
+
nodeIntegration: false,
|
|
119
|
+
sandbox: true,
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
mainWindow = window;
|
|
123
|
+
(0, ipc_1.attachWindow)(window);
|
|
124
|
+
window.once('ready-to-show', () => window.show());
|
|
125
|
+
window.on('closed', () => {
|
|
126
|
+
mainWindow = null;
|
|
127
|
+
explainTrayOnce();
|
|
128
|
+
});
|
|
129
|
+
// Externe links openen in de standaardbrowser, niet in een Electron-venster, en alleen als
|
|
130
|
+
// het http of https is: zie isExternalUrl.
|
|
131
|
+
window.webContents.setWindowOpenHandler(({ url }) => {
|
|
132
|
+
if ((0, links_1.isExternalUrl)(url)) {
|
|
133
|
+
void electron_1.shell.openExternal(url);
|
|
134
|
+
}
|
|
135
|
+
return { action: 'deny' };
|
|
136
|
+
});
|
|
137
|
+
// De rechtermuisknop: knippen, kopiëren en plakken, links, en in de ontwikkelversie inspecteren.
|
|
138
|
+
window.webContents.on('context-menu', (_event, params) => {
|
|
139
|
+
const items = (0, context_menu_1.contextMenuItems)(params, {
|
|
140
|
+
openExternal: (url) => {
|
|
141
|
+
void electron_1.shell.openExternal(url);
|
|
142
|
+
},
|
|
143
|
+
copyText: (text) => {
|
|
144
|
+
void electron_1.clipboard.writeText(text);
|
|
145
|
+
},
|
|
146
|
+
inspect: IS_DEV ? (x, y) => window.webContents.inspectElement(x, y) : null,
|
|
147
|
+
});
|
|
148
|
+
if (items.length > 0) {
|
|
149
|
+
electron_1.Menu.buildFromTemplate(items).popup({ window });
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
// Een link zonder target="_blank" zou het venster zelf laten wegnavigeren, weg van de app en
|
|
153
|
+
// de preload. Dat nooit; een http(s)-adres gaat dan alsnog naar de browser.
|
|
154
|
+
window.webContents.on('will-navigate', (event, url) => {
|
|
155
|
+
if ((0, links_1.isAppNavigation)(url, devServerUrl)) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
event.preventDefault();
|
|
159
|
+
if ((0, links_1.isExternalUrl)(url)) {
|
|
160
|
+
void electron_1.shell.openExternal(url);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
if (devServerUrl === undefined) {
|
|
164
|
+
void window.loadFile(PROD_INDEX);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
void window.loadURL(devServerUrl);
|
|
168
|
+
window.webContents.openDevTools({ mode: 'detach' });
|
|
169
|
+
}
|
|
170
|
+
return window;
|
|
171
|
+
}
|
|
172
|
+
/** Het venster naar voren, of een nieuw als het gesloten was. */
|
|
173
|
+
function showWindow() {
|
|
174
|
+
if (mainWindow === null) {
|
|
175
|
+
return createWindow();
|
|
176
|
+
}
|
|
177
|
+
if (mainWindow.isMinimized()) {
|
|
178
|
+
mainWindow.restore();
|
|
179
|
+
}
|
|
180
|
+
mainWindow.show();
|
|
181
|
+
mainWindow.focus();
|
|
182
|
+
return mainWindow;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Opent de app op een route. Is er al een venster, dan krijgt dat de route; anders bewaren we
|
|
186
|
+
* hem tot het nieuwe venster er klaar voor is (zie navigation.ts).
|
|
187
|
+
*/
|
|
188
|
+
function openAt(route) {
|
|
189
|
+
if (mainWindow === null) {
|
|
190
|
+
(0, navigation_1.setPendingRoute)(route);
|
|
191
|
+
createWindow();
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
showWindow().webContents.send(channels_1.CHANNELS.navigationNavigate, route);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Wie het venster sluit en daarna niets meer ziet, denkt dat de app weg is. Eén keer per
|
|
198
|
+
* sessie zeggen we waar hij gebleven is.
|
|
199
|
+
*/
|
|
200
|
+
function explainTrayOnce() {
|
|
201
|
+
if (quitting || toldAboutTray || tray === null || !electron_1.Notification.isSupported()) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
toldAboutTray = true;
|
|
205
|
+
const notice = new electron_1.Notification({
|
|
206
|
+
title: (0, i18n_1.t)({ en: `${APP_TITLE} keeps running`, nl: `${APP_TITLE} draait door`, de: `${APP_TITLE} läuft weiter`, fr: `${APP_TITLE} continue de tourner`, es: `${APP_TITLE} sigue en marcha` }),
|
|
207
|
+
body: (0, i18n_1.t)({
|
|
208
|
+
en: 'You can find it in the system tray. Container crashes are reported; quit from the menu there.',
|
|
209
|
+
nl: 'Je vindt hem in het systeemvak. Crashes van containers worden gemeld; afsluiten doe je via het menu daar.',
|
|
210
|
+
de: 'Sie finden es im Infobereich. Abstürze von Containern werden gemeldet; beenden können Sie es über das Menü dort.',
|
|
211
|
+
fr: 'Vous le trouverez dans la zone de notification. Les crashs de conteneurs y sont signalés ; quittez depuis son menu.',
|
|
212
|
+
es: 'Lo encuentras en el área de notificación. Los fallos de los contenedores se avisan; para salir, usa el menú de ahí.',
|
|
213
|
+
}),
|
|
214
|
+
silent: true,
|
|
215
|
+
});
|
|
216
|
+
show(notice, () => showWindow());
|
|
217
|
+
}
|
|
218
|
+
function notifyCrash(notice) {
|
|
219
|
+
if (!electron_1.Notification.isSupported() || !(0, settings_1.notificationsEnabled)(notice.kind)) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const text = (0, crash_1.describeCrash)(notice);
|
|
223
|
+
show(new electron_1.Notification({ title: text.title, body: text.body }), () => openAt((0, navigation_1.containerRoute)(notice.id, notice.name)));
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Een container die draait maar zijn netwerk of zijn poorten kwijt is. Klikken opent hem: daar staat
|
|
227
|
+
* de balk met de knop die het rechtzet.
|
|
228
|
+
*/
|
|
229
|
+
function notifyWiring(item) {
|
|
230
|
+
if (!electron_1.Notification.isSupported() || !(0, settings_1.wiringNotificationsEnabled)()) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
const name = item.name;
|
|
234
|
+
const ports = item.kind === 'ports' ? item.ports.map((gap) => String(gap.hostPort ?? gap.containerPort)).join(', ') : '';
|
|
235
|
+
const body = item.kind === 'network'
|
|
236
|
+
? (0, i18n_1.t)({
|
|
237
|
+
en: `Running, but not attached to ${item.network}. Nothing reaches it over that network.`,
|
|
238
|
+
nl: `Draait, maar hangt niet aan ${item.network}. Via dat netwerk bereikt niets hem.`,
|
|
239
|
+
de: `Läuft, hängt aber nicht an ${item.network}. Über dieses Netzwerk erreicht ihn nichts.`,
|
|
240
|
+
fr: `Tourne, mais n’est pas relié à ${item.network}. Rien ne le joint par ce réseau.`,
|
|
241
|
+
es: `Funciona, pero no está conectado a ${item.network}. Nada lo alcanza por esa red.`,
|
|
242
|
+
})
|
|
243
|
+
: (0, i18n_1.t)({
|
|
244
|
+
en: `Running, but not publishing ${ports}.`,
|
|
245
|
+
nl: `Draait, maar publiceert ${ports} niet.`,
|
|
246
|
+
de: `Läuft, veröffentlicht ${ports} aber nicht.`,
|
|
247
|
+
fr: `Tourne, mais ne publie pas ${ports}.`,
|
|
248
|
+
es: `Funciona, pero no publica ${ports}.`,
|
|
249
|
+
});
|
|
250
|
+
const title = (0, i18n_1.t)({
|
|
251
|
+
en: `${name} is not connected`,
|
|
252
|
+
nl: `${name} is niet aangesloten`,
|
|
253
|
+
de: `${name} ist nicht angeschlossen`,
|
|
254
|
+
fr: `${name} n’est pas relié`,
|
|
255
|
+
es: `${name} no está conectado`,
|
|
256
|
+
});
|
|
257
|
+
show(new electron_1.Notification({ title, body }), () => openAt((0, navigation_1.containerRoute)(item.id, item.name)));
|
|
258
|
+
}
|
|
259
|
+
/** Een nieuwe versie staat klaar: dat mag de gebruiker weten, ook met het venster dicht. */
|
|
260
|
+
function notifyUpdateReady(version) {
|
|
261
|
+
if (!electron_1.Notification.isSupported()) {
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
const notice = new electron_1.Notification({
|
|
265
|
+
title: (0, i18n_1.t)({
|
|
266
|
+
en: `Version ${version} is ready`,
|
|
267
|
+
nl: `Versie ${version} staat klaar`,
|
|
268
|
+
de: `Version ${version} liegt bereit`,
|
|
269
|
+
fr: `La version ${version} est prête`,
|
|
270
|
+
es: `La versión ${version} está lista`,
|
|
271
|
+
}),
|
|
272
|
+
body: (0, i18n_1.t)({
|
|
273
|
+
en: 'It will be installed when you quit the app. To install now, use the system tray or the settings.',
|
|
274
|
+
nl: 'Wordt geïnstalleerd als je de app afsluit. Nu al kan via het systeemvak of de instellingen.',
|
|
275
|
+
de: 'Sie wird installiert, wenn Sie die App beenden. Für sofort: über den Infobereich oder die Einstellungen.',
|
|
276
|
+
fr: 'Elle sera installée quand vous quitterez l’application. Pour l’installer tout de suite, passez par la zone de notification ou les paramètres.',
|
|
277
|
+
es: 'Se instalará cuando cierres la aplicación. Para instalarla ahora, usa el área de notificación o los ajustes.',
|
|
278
|
+
}),
|
|
279
|
+
silent: true,
|
|
280
|
+
});
|
|
281
|
+
show(notice, () => openAt('/settings'));
|
|
282
|
+
}
|
|
283
|
+
/** Het menu van het systeemvak, met de engine-status als niet-klikbare regel. */
|
|
284
|
+
function buildTrayMenu(engineUp) {
|
|
285
|
+
const status = engineUp === null
|
|
286
|
+
? (0, i18n_1.t)({ en: 'Engine: not known yet', nl: 'Engine: nog niet bekend', de: 'Engine: noch nicht bekannt', fr: 'Engine : pas encore connu', es: 'Engine: todavía no se sabe' })
|
|
287
|
+
: engineUp
|
|
288
|
+
? (0, i18n_1.t)({ en: 'Engine running', nl: 'Engine draait', de: 'Engine läuft', fr: 'Engine en cours', es: 'Engine en marcha' })
|
|
289
|
+
: (0, i18n_1.t)({ en: 'Engine unreachable', nl: 'Engine niet bereikbaar', de: 'Engine nicht erreichbar', fr: 'Engine injoignable', es: 'Engine inaccesible' });
|
|
290
|
+
const update = (0, self_update_1.readAppUpdate)().status;
|
|
291
|
+
return electron_1.Menu.buildFromTemplate([
|
|
292
|
+
{ label: (0, i18n_1.t)({ en: 'Open', nl: 'Openen', de: 'Öffnen', fr: 'Ouvrir', es: 'Abrir' }), click: () => showWindow() },
|
|
293
|
+
{ type: 'separator' },
|
|
294
|
+
{ label: status, enabled: false },
|
|
295
|
+
{ type: 'separator' },
|
|
296
|
+
...(update.state === 'ready'
|
|
297
|
+
? [
|
|
298
|
+
{ label: (0, i18n_1.t)({
|
|
299
|
+
en: `Restart and update to ${update.version}`,
|
|
300
|
+
nl: `Herstarten en bijwerken naar ${update.version}`,
|
|
301
|
+
de: `Neu starten und auf ${update.version} aktualisieren`,
|
|
302
|
+
fr: `Redémarrer et mettre à jour vers ${update.version}`,
|
|
303
|
+
es: `Reiniciar y actualizar a ${update.version}`,
|
|
304
|
+
}), click: () => (0, self_update_1.installAppUpdate)() },
|
|
305
|
+
{ type: 'separator' },
|
|
306
|
+
]
|
|
307
|
+
: []),
|
|
308
|
+
{
|
|
309
|
+
label: (0, i18n_1.t)({ en: 'Quit', nl: 'Afsluiten', de: 'Beenden', fr: 'Quitter', es: 'Salir' }),
|
|
310
|
+
click: () => {
|
|
311
|
+
quitting = true;
|
|
312
|
+
electron_1.app.quit();
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
]);
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Een ping en niet de volledige engine-status: die kijkt bij een onbereikbare daemon ook of
|
|
319
|
+
* er een WSL-distro te starten is, en dat is elke vijftien seconden te veel werk voor één regel.
|
|
320
|
+
*/
|
|
321
|
+
async function refreshTrayStatus() {
|
|
322
|
+
let up;
|
|
323
|
+
try {
|
|
324
|
+
await (0, docker_client_1.getConnection)().docker.ping();
|
|
325
|
+
up = true;
|
|
326
|
+
}
|
|
327
|
+
catch {
|
|
328
|
+
up = false;
|
|
329
|
+
}
|
|
330
|
+
trayEngineUp = up;
|
|
331
|
+
updateTray();
|
|
332
|
+
}
|
|
333
|
+
/** Menu en tooltip uit de laatst bekende status; ook na het wisselen van taal. */
|
|
334
|
+
function updateTray() {
|
|
335
|
+
if (tray === null) {
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
tray.setContextMenu(buildTrayMenu(trayEngineUp));
|
|
339
|
+
if (trayEngineUp !== null) {
|
|
340
|
+
const status = trayEngineUp ? (0, i18n_1.t)({ en: 'engine running', nl: 'engine draait', de: 'Engine läuft', fr: 'engine en cours', es: 'engine en marcha' }) : (0, i18n_1.t)({
|
|
341
|
+
en: 'engine unreachable',
|
|
342
|
+
nl: 'engine niet bereikbaar',
|
|
343
|
+
de: 'Engine nicht erreichbar',
|
|
344
|
+
fr: 'engine injoignable',
|
|
345
|
+
es: 'engine inaccesible',
|
|
346
|
+
});
|
|
347
|
+
tray.setToolTip(`${APP_TITLE} · ${status}`);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
function createTray() {
|
|
351
|
+
if (!(0, node_fs_1.existsSync)(TRAY_ICON)) {
|
|
352
|
+
// Zonder pictogram is een tray-icoon een leeg vakje; dan liever geen, en sluit het venster
|
|
353
|
+
// de app zoals voorheen.
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
tray = new electron_1.Tray(electron_1.nativeImage.createFromPath(TRAY_ICON));
|
|
357
|
+
tray.setToolTip(APP_TITLE);
|
|
358
|
+
tray.setContextMenu(buildTrayMenu(null));
|
|
359
|
+
tray.on('click', () => showWindow());
|
|
360
|
+
(0, i18n_1.onLanguageChange)(() => updateTray());
|
|
361
|
+
void refreshTrayStatus();
|
|
362
|
+
setInterval(() => void refreshTrayStatus(), TRAY_STATUS_MS).unref();
|
|
363
|
+
}
|
|
364
|
+
/*
|
|
365
|
+
* Naam en gebruikersmap altijd zelf, niet afgeleid van package.json. Die naam had eerst een scope
|
|
366
|
+
* (@martijn-on-fhir/…), en heet sinds 1.35 `docker-client-mx`; de instellingen en het thema
|
|
367
|
+
* staan al sinds het begin in `docker-desktop-mx`, en die horen niet te verhuizen.
|
|
368
|
+
*
|
|
369
|
+
* De ontwikkelversie krijgt een eigen map. Anders delen `npm start` en de geïnstalleerde app
|
|
370
|
+
* settings.json en het slot hieronder: wie ontwikkelt moet dan steeds de geïnstalleerde app
|
|
371
|
+
* afsluiten, en een instelling die je in de ene omzet, staat ongemerkt ook in de andere om.
|
|
372
|
+
* De npm-versie deelt de map wel met de installer: het is dezelfde app, anders geleverd.
|
|
373
|
+
*/
|
|
374
|
+
electron_1.app.setName(APP_TITLE);
|
|
375
|
+
electron_1.app.setPath('userData', path.join(electron_1.app.getPath('appData'), IS_DEV ? 'docker-desktop-mx-dev' : 'docker-desktop-mx'));
|
|
376
|
+
// Eén app tegelijk. Met een tray-icoon is een tweede start bijna altijd iemand die het venster
|
|
377
|
+
// zoekt; dan krijgt hij het venster van de eerste in plaats van een tweede app ernaast. Het slot
|
|
378
|
+
// hangt aan de gebruikersmap, dus de ontwikkelversie hierboven heeft zijn eigen slot.
|
|
379
|
+
if (!electron_1.app.requestSingleInstanceLock()) {
|
|
380
|
+
electron_1.app.quit();
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
electron_1.app.on('second-instance', () => showWindow());
|
|
384
|
+
void electron_1.app.whenReady().then(() => {
|
|
385
|
+
/*
|
|
386
|
+
* De standaardmenubalk van Electron gaat helemaal niet over deze app: Bestand, Bewerken,
|
|
387
|
+
* Beeld en Venster zijn wat Electron zelf meelevert, en er staat niets in wat je hier zou
|
|
388
|
+
* willen. Weg dus.
|
|
389
|
+
*
|
|
390
|
+
* Behalve op macOS. Daar hoort het menu bij de menubalk bovenin en niet bij het venster, en
|
|
391
|
+
* lopen Cmd+C, Cmd+V en Cmd+Q erlangs. Zonder menu kun je daar niets meer kopiëren in de
|
|
392
|
+
* terminal of de inspect-weergave.
|
|
393
|
+
*/
|
|
394
|
+
if (process.platform !== 'darwin') {
|
|
395
|
+
electron_1.Menu.setApplicationMenu(null);
|
|
396
|
+
}
|
|
397
|
+
// Windows toont alleen meldingen van een app-id met een snelkoppeling in het Startmenu. De
|
|
398
|
+
// installer maakt die voor APP_ID; bij `npm start` is er geen, en dan verdwijnt elke melding
|
|
399
|
+
// stil. Daar gebruiken we het pad van electron.exe, zoals Electron zelf aanraadt.
|
|
400
|
+
if (process.platform === 'win32') {
|
|
401
|
+
electron_1.app.setAppUserModelId(electron_1.app.isPackaged ? APP_ID : process.execPath);
|
|
402
|
+
}
|
|
403
|
+
(0, settings_1.configureSettings)({
|
|
404
|
+
read: () => {
|
|
405
|
+
try {
|
|
406
|
+
return (0, node_fs_1.readFileSync)(path.join(electron_1.app.getPath('userData'), 'settings.json'), 'utf8');
|
|
407
|
+
}
|
|
408
|
+
catch {
|
|
409
|
+
return null;
|
|
410
|
+
}
|
|
411
|
+
},
|
|
412
|
+
write: (text) => (0, node_fs_1.writeFileSync)(path.join(electron_1.app.getPath('userData'), 'settings.json'), text),
|
|
413
|
+
// Dezelfde argumenten bij lezen en schrijven: Windows onderscheidt een aanmeldingsitem op
|
|
414
|
+
// pad plus argumenten, en anders ziet getLoginItemSettings het item niet terug.
|
|
415
|
+
loginItem: electron_1.app.isPackaged
|
|
416
|
+
? {
|
|
417
|
+
get: () => electron_1.app.getLoginItemSettings({ args: [HIDDEN_ARG] }).openAtLogin,
|
|
418
|
+
set: (on) => electron_1.app.setLoginItemSettings({ openAtLogin: on, args: [HIDDEN_ARG] }),
|
|
419
|
+
}
|
|
420
|
+
: null,
|
|
421
|
+
});
|
|
422
|
+
// Alleen de geïnstalleerde app op Windows; zie self-update.ts. `autoUpdater` wordt pas
|
|
423
|
+
// hier aangesproken, en electron-updater maakt hem pas dan aan.
|
|
424
|
+
(0, self_update_1.configureSelfUpdate)({
|
|
425
|
+
updater: electron_1.app.isPackaged && process.platform === 'win32' ? electron_updater_1.autoUpdater : null,
|
|
426
|
+
currentVersion: electron_1.app.getVersion(),
|
|
427
|
+
automatic: () => (0, settings_1.autoUpdateEnabled)(),
|
|
428
|
+
changed: (info) => {
|
|
429
|
+
for (const window of electron_1.BrowserWindow.getAllWindows()) {
|
|
430
|
+
window.webContents.send(channels_1.CHANNELS.appUpdateChanged, info);
|
|
431
|
+
}
|
|
432
|
+
if (info.status.state === 'ready') {
|
|
433
|
+
tray?.setContextMenu(buildTrayMenu(trayEngineUp));
|
|
434
|
+
}
|
|
435
|
+
},
|
|
436
|
+
ready: (version) => notifyUpdateReady(version),
|
|
437
|
+
beforeInstall: () => {
|
|
438
|
+
quitting = true;
|
|
439
|
+
},
|
|
440
|
+
});
|
|
441
|
+
// De sleutel voor Claude, versleuteld met DPAPI. Een eigen bestand, niet settings.json.
|
|
442
|
+
const keyFile = path.join(electron_1.app.getPath('userData'), 'claude-key.bin');
|
|
443
|
+
(0, assistant_key_1.configureKeyStore)({
|
|
444
|
+
available: () => electron_1.safeStorage.isEncryptionAvailable(),
|
|
445
|
+
encrypt: (text) => electron_1.safeStorage.encryptString(text),
|
|
446
|
+
decrypt: (data) => electron_1.safeStorage.decryptString(data),
|
|
447
|
+
read: () => {
|
|
448
|
+
try {
|
|
449
|
+
return (0, node_fs_1.readFileSync)(keyFile);
|
|
450
|
+
}
|
|
451
|
+
catch {
|
|
452
|
+
return null;
|
|
453
|
+
}
|
|
454
|
+
},
|
|
455
|
+
write: (data) => (0, node_fs_1.writeFileSync)(keyFile, data),
|
|
456
|
+
remove: () => (0, node_fs_1.rmSync)(keyFile, { force: true }),
|
|
457
|
+
});
|
|
458
|
+
(0, ipc_1.registerIpcHandlers)();
|
|
459
|
+
createTray();
|
|
460
|
+
(0, ipc_1.startCrashWatch)(notifyCrash, notifyWiring);
|
|
461
|
+
// Na aanmelden alleen het systeemvak, tenzij er geen systeemvak is: dan zou de app
|
|
462
|
+
// onzichtbaar draaien zonder manier om hem te openen.
|
|
463
|
+
if (!process.argv.includes(HIDDEN_ARG) || tray === null) {
|
|
464
|
+
createWindow();
|
|
465
|
+
}
|
|
466
|
+
electron_1.app.on('activate', () => {
|
|
467
|
+
if (electron_1.BrowserWindow.getAllWindows().length === 0) {
|
|
468
|
+
createWindow();
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
/** Of de hulpcontainers al opgeruimd zijn; dan mag het afsluiten door. */
|
|
474
|
+
let helpersRemoved = false;
|
|
475
|
+
electron_1.app.on('before-quit', (event) => {
|
|
476
|
+
quitting = true;
|
|
477
|
+
// De geschiedenis van de tab Gebeurtenissen; anders is wat er de laatste seconden bij kwam weg.
|
|
478
|
+
(0, ipc_1.flushEventHistory)();
|
|
479
|
+
// Eén keer wachten tot ze echt weg zijn; daarna opnieuw afsluiten, en dan gaat het door.
|
|
480
|
+
// De host-terminal en de volume-inkijk hebben allebei een hulpcontainer die niet mag blijven.
|
|
481
|
+
if (!helpersRemoved && ((0, host_shell_1.hasHostShells)() || (0, volume_files_1.hasVolumeBrowser)())) {
|
|
482
|
+
event.preventDefault();
|
|
483
|
+
helpersRemoved = true;
|
|
484
|
+
void Promise.all([(0, host_shell_1.removeHostShells)(), (0, volume_files_1.closeVolumeBrowser)()]).finally(() => electron_1.app.quit());
|
|
485
|
+
}
|
|
486
|
+
});
|
|
487
|
+
// Met een tray-icoon blijft de app draaien als het laatste venster dicht gaat; zonder (geen
|
|
488
|
+
// pictogram gevonden) sluit hij zoals voorheen, behalve op macOS waar dat de gewoonte is.
|
|
489
|
+
electron_1.app.on('window-all-closed', () => {
|
|
490
|
+
if (tray === null && process.platform !== 'darwin') {
|
|
491
|
+
electron_1.app.quit();
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../electron/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MergedLogsWatcher = void 0;
|
|
4
|
+
exports.sortByTime = sortByTime;
|
|
5
|
+
const channels_1 = require("./channels");
|
|
6
|
+
const logs_1 = require("./logs");
|
|
7
|
+
/**
|
|
8
|
+
* Hoeveel regels we per container ophalen bij het aanhaken. Met tien containers is dat duizend
|
|
9
|
+
* regels aan geschiedenis; genoeg om te zien wat er net gebeurde, weinig genoeg om de pagina
|
|
10
|
+
* niet te laten stollen bij het openen.
|
|
11
|
+
*/
|
|
12
|
+
const TAIL = 100;
|
|
13
|
+
/**
|
|
14
|
+
* De bundelvertraging van deze watcher, bovenop die van de losse streams. Regels van tien
|
|
15
|
+
* containers komen in tien aparte bundels binnen; hier worden ze één bundel, en pas dan is
|
|
16
|
+
* sorteren op tijd zinvol.
|
|
17
|
+
*/
|
|
18
|
+
const MERGE_MS = 150;
|
|
19
|
+
/**
|
|
20
|
+
* Docker zet er een tijd voor als je erom vraagt, maar niet elke container doet dat even
|
|
21
|
+
* netjes en een enkele regel komt zonder. Regels zonder tijd houden hun plek in de bundel in
|
|
22
|
+
* plaats van bovenaan of onderaan te landen.
|
|
23
|
+
*/
|
|
24
|
+
function sortByTime(lines) {
|
|
25
|
+
return [...lines].sort((a, b) => {
|
|
26
|
+
if (a.timestamp === null || b.timestamp === null) {
|
|
27
|
+
return a.id - b.id;
|
|
28
|
+
}
|
|
29
|
+
return a.timestamp === b.timestamp ? a.id - b.id : a.timestamp.localeCompare(b.timestamp);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Houdt één logstroom bij die uit alle draaiende containers samenkomt.
|
|
34
|
+
*
|
|
35
|
+
* Dezelfde opzet als StatsWatcher: de pagina zegt welke containers meedoen, en deze klasse
|
|
36
|
+
* zorgt dat de open streams daarmee overeenkomen. De containerlijst komt uit de events-stream,
|
|
37
|
+
* dus een container die start of stopt haakt vanzelf aan of af.
|
|
38
|
+
*/
|
|
39
|
+
class MergedLogsWatcher {
|
|
40
|
+
sender;
|
|
41
|
+
open;
|
|
42
|
+
streams = new Map();
|
|
43
|
+
opening = new Set();
|
|
44
|
+
sources = new Map();
|
|
45
|
+
batch = [];
|
|
46
|
+
timer = null;
|
|
47
|
+
nextId = 1;
|
|
48
|
+
stopped = false;
|
|
49
|
+
constructor(sender, open = logs_1.openLogStream) {
|
|
50
|
+
this.sender = sender;
|
|
51
|
+
this.open = open;
|
|
52
|
+
}
|
|
53
|
+
/** Laat de open streams overeenkomen met `sources`. Een lege lijst zet alles stil. */
|
|
54
|
+
async watch(sources) {
|
|
55
|
+
if (this.stopped) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
this.sources = new Map(sources.map((source) => [source.containerId, source]));
|
|
59
|
+
this.closeUnwanted();
|
|
60
|
+
const toOpen = sources.filter((source) => !this.streams.has(source.containerId) && !this.opening.has(source.containerId));
|
|
61
|
+
await Promise.all(toOpen.map((source) => this.openOne(source)));
|
|
62
|
+
}
|
|
63
|
+
/** Alles dicht. Wordt aangeroepen als het venster verdwijnt of de context omgaat. */
|
|
64
|
+
stop() {
|
|
65
|
+
this.stopped = true;
|
|
66
|
+
this.sources = new Map();
|
|
67
|
+
this.closeUnwanted();
|
|
68
|
+
if (this.timer !== null) {
|
|
69
|
+
clearTimeout(this.timer);
|
|
70
|
+
this.timer = null;
|
|
71
|
+
}
|
|
72
|
+
this.batch = [];
|
|
73
|
+
}
|
|
74
|
+
async openOne(source) {
|
|
75
|
+
const id = source.containerId;
|
|
76
|
+
this.opening.add(id);
|
|
77
|
+
try {
|
|
78
|
+
const stream = await this.open(id, TAIL, (lines) => this.push(id, lines));
|
|
79
|
+
// Tussen het openen en het binnenkomen kan de container alweer weggevallen zijn, of het
|
|
80
|
+
// venster gesloten. Dan hoort deze stream er niet meer te zijn.
|
|
81
|
+
if (this.stopped || !this.sources.has(id)) {
|
|
82
|
+
stream.destroy();
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
this.streams.set(id, stream);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// Een container die net gestopt is geeft geen logs meer. Dat is geen fout om te melden:
|
|
89
|
+
// de events-stream ververst de lijst toch al.
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
this.opening.delete(id);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
closeUnwanted() {
|
|
96
|
+
for (const [id, stream] of this.streams) {
|
|
97
|
+
if (!this.sources.has(id)) {
|
|
98
|
+
stream.destroy();
|
|
99
|
+
this.streams.delete(id);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
push(containerId, lines) {
|
|
104
|
+
const source = this.sources.get(containerId);
|
|
105
|
+
if (source === undefined || this.stopped) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
for (const line of lines) {
|
|
109
|
+
this.batch.push({ ...line, id: this.nextId++, source });
|
|
110
|
+
}
|
|
111
|
+
if (this.timer === null) {
|
|
112
|
+
this.timer = setTimeout(() => this.flush(), MERGE_MS);
|
|
113
|
+
this.timer.unref();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
flush() {
|
|
117
|
+
this.timer = null;
|
|
118
|
+
if (this.batch.length === 0) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const lines = sortByTime(this.batch);
|
|
122
|
+
this.batch = [];
|
|
123
|
+
this.sender.send(channels_1.CHANNELS.logsAllLines, lines);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
exports.MergedLogsWatcher = MergedLogsWatcher;
|
|
127
|
+
//# sourceMappingURL=merged-logs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merged-logs.js","sourceRoot":"","sources":["../electron/merged-logs.ts"],"names":[],"mappings":"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"}
|