@lvce-editor/shared-process 0.26.4 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/package.json +6 -7
  2. package/src/parts/ConnectIpcToElectron/ConnectIpcToElectron.js +4 -2
  3. package/src/parts/Download/Download.js +2 -22
  4. package/src/parts/DownloadAndExtract/DownloadAndExtract.js +2 -16
  5. package/src/parts/EmbedsProcessState/EmbedsProcessState.js +12 -0
  6. package/src/parts/GetHttpErrorMessage/GetHttpErrorMessage.js +1 -1
  7. package/src/parts/GetLatestReleaseVersion/GetLatestReleaseVersion.js +7 -4
  8. package/src/parts/GetPortTuple/GetPortTuple.js +8 -2
  9. package/src/parts/HandleMessagePortForEmbedsProcess/HandleMessagePortForEmbedsProcess.ipc.js +1 -0
  10. package/src/parts/HandleMessagePortForEmbedsProcess/HandleMessagePortForEmbedsProcess.js +12 -0
  11. package/src/parts/IpcParentWithElectronUtilityProcess/IpcParentWithElectronUtilityProcess.js +1 -1
  12. package/src/parts/LaunchEmbedsProcess/LaunchEmbedsProcess.js +1 -1
  13. package/src/parts/LaunchNetworkProcess/LaunchNetworkProcess.js +15 -0
  14. package/src/parts/LaunchSearchProcess/LaunchSearchProcess.js +3 -3
  15. package/src/parts/ModuleMap/ModuleMap.js +1 -0
  16. package/src/parts/NetworkProcess/NetworkProcess.js +18 -0
  17. package/src/parts/NetworkProcessPath/NetworkProcessPath.js +1 -0
  18. package/src/parts/Platform/Platform.js +3 -3
  19. package/src/parts/TemporaryMessagePort/TemporaryMessagePort.js +2 -2
  20. package/src/parts/GetFirstNodeWorkerEvent/GetFirstNodeWorkerEvent.js +0 -8
  21. package/src/parts/HasPositiveMemoryUsage/HasPositiveMemoryUsage.js +0 -3
  22. package/src/parts/IpcChildWithElectronMessagePort/IpcChildWithElectronMessagePort.js +0 -53
  23. package/src/parts/IsDlOpenError/IsDlOpenError.js +0 -4
  24. package/src/parts/LeftCut/LeftCut.js +0 -19
  25. package/src/parts/ParseInt/ParseInt.js +0 -3
  26. package/src/parts/Trace/Trace.js +0 -13
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/shared-process",
3
- "version": "0.26.4",
3
+ "version": "0.27.0",
4
4
  "main": "index.js",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -18,25 +18,24 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "@lvce-editor/assert": "^1.2.0",
21
- "@lvce-editor/extension-host-helper-process": "0.26.4",
22
- "@lvce-editor/ipc": "^8.0.0",
21
+ "@lvce-editor/extension-host-helper-process": "0.27.0",
22
+ "@lvce-editor/ipc": "^8.0.1",
23
23
  "@lvce-editor/json-rpc": "^1.3.0",
24
24
  "@lvce-editor/jsonc-parser": "^1.2.0",
25
+ "@lvce-editor/network-process": "0.27.0",
25
26
  "@lvce-editor/pretty-error": "^1.5.0",
26
- "@lvce-editor/pty-host": "0.26.4",
27
+ "@lvce-editor/pty-host": "0.27.0",
27
28
  "@lvce-editor/verror": "^1.2.0",
28
29
  "@lvce-editor/web-socket-server": "^1.1.0",
29
30
  "debug": "^4.3.4",
30
31
  "execa": "^8.0.1",
31
32
  "exit-hook": "^4.0.0",
32
- "got": "^14.2.1",
33
33
  "is-object": "^1.0.2",
34
- "p-queue": "^8.0.1",
35
34
  "tar-fs": "^3.0.6",
36
35
  "xdg-basedir": "^5.1.0"
37
36
  },
38
37
  "optionalDependencies": {
39
- "@lvce-editor/ripgrep": "^1.0.2",
38
+ "@lvce-editor/ripgrep": "^1.1.0",
40
39
  "open": "^10.1.0",
41
40
  "tail": "^2.2.6",
42
41
  "tmp-promise": "^3.0.3",
@@ -4,6 +4,8 @@ import * as JsonRpc from '../JsonRpc/JsonRpc.js';
4
4
  import * as ParentIpc from '../ParentIpc/ParentIpc.js';
5
5
  export const connectIpcToElectron = async (ipc, ipcId = IpcId.Unknown) => {
6
6
  const { port1, port2 } = await GetPortTuple.getPortTuple();
7
- await JsonRpc.invokeAndTransfer(ipc, [port1], 'HandleElectronMessagePort.handleElectronMessagePort', IpcId.MainProcess);
8
- await ParentIpc.invokeAndTransfer('HandleElectronMessagePort.handleElectronMessagePort', [port2], ipcId);
7
+ await Promise.all([
8
+ JsonRpc.invokeAndTransfer(ipc, [port1], 'HandleElectronMessagePort.handleElectronMessagePort', IpcId.MainProcess),
9
+ ParentIpc.invokeAndTransfer('HandleElectronMessagePort.handleElectronMessagePort', [port2], ipcId),
10
+ ]);
9
11
  };
@@ -1,24 +1,4 @@
1
- import got, { RequestError } from 'got';
2
- import { createWriteStream } from 'node:fs';
3
- import { mkdir, rm } from 'node:fs/promises';
4
- import { pipeline } from 'node:stream/promises';
5
- import * as Path from '../Path/Path.js';
6
- import { VError } from '../VError/VError.js';
1
+ import * as NetworkProcess from '../NetworkProcess/NetworkProcess.js';
7
2
  export const download = async (url, outFile) => {
8
- try {
9
- await mkdir(Path.dirname(outFile), { recursive: true });
10
- await pipeline(got.stream(url), createWriteStream(outFile));
11
- }
12
- catch (error) {
13
- try {
14
- await rm(outFile);
15
- }
16
- catch {
17
- // ignore
18
- }
19
- if (error instanceof RequestError) {
20
- throw new VError(`Failed to download "${url}": ${error.message}`);
21
- }
22
- throw new VError(error, `Failed to download "${url}"`);
23
- }
3
+ return NetworkProcess.invoke('Download.download', url, outFile);
24
4
  };
@@ -1,18 +1,4 @@
1
- import { pipeline } from 'node:stream/promises';
2
- import { createGunzip } from 'node:zlib';
3
- import got, { RequestError } from 'got';
4
- import tar from 'tar-fs';
5
- import { VError } from '../VError/VError.js';
1
+ import * as NetworkProcess from '../NetworkProcess/NetworkProcess.js';
6
2
  export const downloadAndExtractTarGz = async ({ url, outDir, strip }) => {
7
- try {
8
- await pipeline(got.stream(url), createGunzip(), tar.extract(outDir, {
9
- strip,
10
- }));
11
- }
12
- catch (error) {
13
- if (error && error instanceof RequestError) {
14
- throw new VError(`Failed to download ${url}: ${error.message}`);
15
- }
16
- throw error;
17
- }
3
+ return NetworkProcess.invoke('Download.downloadAndExtractTarGz', { url, outDir, strip });
18
4
  };
@@ -0,0 +1,12 @@
1
+ const state = {
2
+ ref: 0,
3
+ };
4
+ export const increment = () => {
5
+ state.ref++;
6
+ };
7
+ export const get = () => {
8
+ return state.ref;
9
+ };
10
+ export const decrement = async () => {
11
+ state.ref--;
12
+ };
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  *
3
- * @param {HTTPError} error
3
+ * @param {any} error
4
4
  */
5
5
  export const getHttpErrorMessage = (error) => {
6
6
  try {
@@ -1,5 +1,5 @@
1
- import got, { HTTPError } from 'got';
2
1
  import * as GetHttpErrorMessage from '../GetHttpErrorMessage/GetHttpErrorMessage.js';
2
+ import * as NetworkProcess from '../NetworkProcess/NetworkProcess.js';
3
3
  import { VError } from '../VError/VError.js';
4
4
  const parseVersionFromUrl = (url, repository) => {
5
5
  if (!url.includes('releases/tag')) {
@@ -17,13 +17,16 @@ const parseVersionFromUrl = (url, repository) => {
17
17
  };
18
18
  export const getLatestReleaseVersion = async (repository) => {
19
19
  try {
20
- const json = await got.head(`https://github.com/${repository}/releases/latest`);
21
- const finalUrl = json.url;
20
+ const url = `https://github.com/${repository}/releases/latest`;
21
+ const finalUrl = await NetworkProcess.invoke('Download.getUrl', {
22
+ method: 'HEAD',
23
+ url,
24
+ });
22
25
  const version = parseVersionFromUrl(finalUrl, repository);
23
26
  return version;
24
27
  }
25
28
  catch (error) {
26
- if (error instanceof HTTPError) {
29
+ if (error && error.name === 'HTTPError') {
27
30
  const httpErrorMessage = GetHttpErrorMessage.getHttpErrorMessage(error);
28
31
  throw new VError(`Failed to get latest release for ${repository}: ${httpErrorMessage}`);
29
32
  }
@@ -1,6 +1,12 @@
1
+ import { VError } from '@lvce-editor/verror';
1
2
  import * as TemporaryMessagePort from '../TemporaryMessagePort/TemporaryMessagePort.js';
2
3
  // workaround for MessageChannelMain not being available in utility process
3
4
  export const getPortTuple = async () => {
4
- const { port1, port2 } = await TemporaryMessagePort.getPortTuple();
5
- return { port1, port2 };
5
+ try {
6
+ const { port1, port2 } = await TemporaryMessagePort.getPortTuple();
7
+ return { port1, port2 };
8
+ }
9
+ catch (error) {
10
+ throw new VError(error, `Failed to get port tuple`);
11
+ }
6
12
  };
@@ -2,4 +2,5 @@ import * as HandleMessagePortForEmbedsProcess from './HandleMessagePortForEmbeds
2
2
  export const name = 'HandleMessagePortForEmbedsProcess';
3
3
  export const Commands = {
4
4
  handleMessagePortForEmbedsProcess: HandleMessagePortForEmbedsProcess.handleMessagePortForEmbedsProcess,
5
+ handleEmbedsProcessIpcClosed: HandleMessagePortForEmbedsProcess.handleEmbedsProcessIpcClosed,
5
6
  };
@@ -1,7 +1,19 @@
1
+ import * as EmbedsProcess from '../EmbedsProcess/EmbedsProcess.js';
2
+ import * as EmbedsProcessState from '../EmbedsProcessState/EmbedsProcessState.js';
1
3
  import * as HandleIncomingIpc from '../HandleIncomingIpc/HandleIncomingIpc.js';
2
4
  import * as IpcId from '../IpcId/IpcId.js';
3
5
  export const handleMessagePortForEmbedsProcess = (port, ipcId) => {
6
+ EmbedsProcessState.increment();
4
7
  return HandleIncomingIpc.handleIncomingIpc(IpcId.EmbedsProcess, port, {
5
8
  ipcId,
6
9
  });
7
10
  };
11
+ export const handleEmbedsProcessIpcClosed = async () => {
12
+ EmbedsProcessState.decrement();
13
+ if (EmbedsProcessState.get() === 0) {
14
+ const promise = EmbedsProcess.state.ipc;
15
+ EmbedsProcess.state.ipc = undefined;
16
+ const ipc = await promise;
17
+ ipc.dispose();
18
+ }
19
+ };
@@ -12,7 +12,7 @@ export const create = async (options) => {
12
12
  });
13
13
  const { port1, port2 } = await GetPortTuple.getPortTuple();
14
14
  // TODO use uuid instead of name
15
- await TemporaryMessagePort.sendTo(options.name, port2);
15
+ await TemporaryMessagePort.sendTo(options.name, port2, options.ipcId);
16
16
  port1.start();
17
17
  return port1;
18
18
  };
@@ -11,9 +11,9 @@ export const launchEmbedsProcess = async () => {
11
11
  argv: [],
12
12
  stdio: 'inherit',
13
13
  name: 'Embeds Process',
14
+ ipcId: IpcId.SharedProcess,
14
15
  });
15
16
  HandleIpc.handleIpc(ipc);
16
17
  await ConnectIpcToElectron.connectIpcToElectron(ipc, IpcId.EmbedsProcess);
17
- HandleIpc.unhandleIpc(ipc);
18
18
  return ipc;
19
19
  };
@@ -0,0 +1,15 @@
1
+ import * as NetworkProcessPath from '../NetworkProcessPath/NetworkProcessPath.js';
2
+ import * as HandleIpc from '../HandleIpc/HandleIpc.js';
3
+ import * as IpcParent from '../IpcParent/IpcParent.js';
4
+ import * as IpcParentType from '../IpcParentType/IpcParentType.js';
5
+ export const launchNetworkProcess = async () => {
6
+ const networkProcess = await IpcParent.create({
7
+ method: IpcParentType.ElectronUtilityProcess,
8
+ path: NetworkProcessPath.networkProcessPath,
9
+ argv: [],
10
+ stdio: 'inherit',
11
+ name: 'Network Process',
12
+ });
13
+ HandleIpc.handleIpc(networkProcess);
14
+ return networkProcess;
15
+ };
@@ -3,13 +3,13 @@ import * as HandleIpc from '../HandleIpc/HandleIpc.js';
3
3
  import * as IpcParent from '../IpcParent/IpcParent.js';
4
4
  import * as IpcParentType from '../IpcParentType/IpcParentType.js';
5
5
  export const launchSearchProcess = async () => {
6
- const embedsProcess = await IpcParent.create({
6
+ const searchProcess = await IpcParent.create({
7
7
  method: IpcParentType.ElectronUtilityProcess,
8
8
  path: SearchProcessPath.searchProcessPath,
9
9
  argv: [],
10
10
  stdio: 'inherit',
11
11
  name: 'Search Process',
12
12
  });
13
- HandleIpc.handleIpc(embedsProcess);
14
- return embedsProcess;
13
+ HandleIpc.handleIpc(searchProcess);
14
+ return searchProcess;
15
15
  };
@@ -275,6 +275,7 @@ export const getModuleId = (commandId) => {
275
275
  case 'ContentSecurityPolicy.set':
276
276
  return ModuleId.ContentSecurityPolicy;
277
277
  case 'HandleMessagePortForEmbedsProcess.handleMessagePortForEmbedsProcess':
278
+ case 'HandleMessagePortForEmbedsProcess.handleEmbedsProcessIpcClosed':
278
279
  return ModuleId.HandleMessagePortForEmbedsProcess;
279
280
  case 'HandleMessagePortForProcessExplorer.handleMessagePortForProcessExplorer':
280
281
  return ModuleId.HandleMessagePortForProcessExplorer;
@@ -0,0 +1,18 @@
1
+ import * as LaunchNetworkProcess from '../LaunchNetworkProcess/LaunchNetworkProcess.js';
2
+ import * as JsonRpc from '../JsonRpc/JsonRpc.js';
3
+ export const state = {
4
+ /**
5
+ * @type {any}
6
+ */
7
+ ipc: undefined,
8
+ };
9
+ export const getOrCreate = async () => {
10
+ if (!state.ipc) {
11
+ state.ipc = LaunchNetworkProcess.launchNetworkProcess();
12
+ }
13
+ return state.ipc;
14
+ };
15
+ export const invoke = async (method, ...params) => {
16
+ const ipc = await getOrCreate();
17
+ return JsonRpc.invoke(ipc, method, ...params);
18
+ };
@@ -0,0 +1 @@
1
+ export { networkProcessPath } from '@lvce-editor/network-process';
@@ -41,9 +41,9 @@ export const getAppImageName = () => {
41
41
  export const getSetupName = () => {
42
42
  return 'Lvce-Setup';
43
43
  };
44
- export const version = '0.26.4';
45
- export const commit = '59e174c';
46
- export const date = '2024-04-28T08:40:44.000Z';
44
+ export const version = '0.27.0';
45
+ export const commit = 'b9ba170';
46
+ export const date = '2024-04-28T20:59:28.000Z';
47
47
  export const getVersion = () => {
48
48
  return version;
49
49
  };
@@ -17,10 +17,10 @@ export const getPortTuple = async () => {
17
17
  port2,
18
18
  };
19
19
  };
20
- export const sendTo = async (name, port) => {
20
+ export const sendTo = async (name, port, ipcId) => {
21
21
  Assert.string(name);
22
22
  Assert.object(port);
23
- await ParentIpc.invokeAndTransfer('TemporaryMessagePort.sendTo', [port], name);
23
+ await ParentIpc.invokeAndTransfer('TemporaryMessagePort.sendTo', [port], name, ipcId);
24
24
  };
25
25
  export const handlePorts = (port1, port2, id1, id2) => {
26
26
  Assert.number(id1);
@@ -1,8 +0,0 @@
1
- import * as FirstNodeWorkerEventType from '../FirstNodeWorkerEventType/FirstNodeWorkerEventType.js';
2
- import * as GetFirstEvent from '../GetFirstEvent/GetFirstEvent.js';
3
- export const getFirstNodeWorkerEvent = (worker) => {
4
- return GetFirstEvent.getFirstEvent(worker, {
5
- exit: FirstNodeWorkerEventType.Exit,
6
- error: FirstNodeWorkerEventType.Error,
7
- });
8
- };
@@ -1,3 +0,0 @@
1
- export const hasPositiveMemoryUsage = (process) => {
2
- return process.memory >= 0;
3
- };
@@ -1,53 +0,0 @@
1
- import { IpcError } from '../IpcError/IpcError.js';
2
- import * as IsMessagePortMain from '../IsMessagePortMain/IsMessagePortMain.js';
3
- export const listen = ({ messagePort }) => {
4
- if (!IsMessagePortMain.isMessagePortMain(messagePort)) {
5
- throw new IpcError('port must be of type MessagePortMain');
6
- }
7
- return messagePort;
8
- };
9
- const getActualData = (event) => {
10
- const { data, ports } = event;
11
- if (ports.length === 0) {
12
- return data;
13
- }
14
- return {
15
- ...data,
16
- params: [...ports, ...data.params],
17
- };
18
- };
19
- export const wrap = (messagePort) => {
20
- return {
21
- messagePort,
22
- on(event, listener) {
23
- if (event === 'message') {
24
- const wrappedListener = (event) => {
25
- const actualData = getActualData(event);
26
- listener(actualData);
27
- };
28
- this.messagePort.on(event, wrappedListener);
29
- }
30
- else if (event === 'close') {
31
- this.messagePort.on('close', listener);
32
- }
33
- else {
34
- throw new Error('unsupported event type');
35
- }
36
- },
37
- off(event, listener) {
38
- this.messagePort.off(event, listener);
39
- },
40
- send(message) {
41
- this.messagePort.postMessage(message);
42
- },
43
- sendAndTransfer(message, transfer) {
44
- this.messagePort.postMessage(message, transfer);
45
- },
46
- dispose() {
47
- this.messagePort.close();
48
- },
49
- start() {
50
- this.messagePort.start();
51
- },
52
- };
53
- };
@@ -1,4 +0,0 @@
1
- import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js';
2
- export const isDlOpenError = (error) => {
3
- return error && error instanceof Error && 'code' in error && error.code === ErrorCodes.ERR_DLOPEN_FAILED;
4
- };
@@ -1,19 +0,0 @@
1
- const RE_WORD = /\b/g;
2
- export const leftCut = (text, final, charsBefore) => {
3
- if (text.length < charsBefore) {
4
- return text.length;
5
- }
6
- let i = 0;
7
- while (RE_WORD.test(text)) {
8
- if (final - RE_WORD.lastIndex < charsBefore) {
9
- break;
10
- }
11
- i = RE_WORD.lastIndex;
12
- RE_WORD.lastIndex++;
13
- }
14
- RE_WORD.lastIndex = 0;
15
- if (final - i > charsBefore + 10) {
16
- return final - charsBefore;
17
- }
18
- return i;
19
- };
@@ -1,3 +0,0 @@
1
- export const parseInt = (string) => {
2
- return Number.parseInt(string, 10);
3
- };
@@ -1,13 +0,0 @@
1
- import * as Env from '../Env/Env.js';
2
- export const LEVEL = {
3
- DEFAULT: 1,
4
- VERBOSE: 2,
5
- };
6
- export const state = {
7
- level: LEVEL.VERBOSE,
8
- };
9
- export const trace = Env.getNodeEnv() === 'test'
10
- ? () => { }
11
- : (...args) => {
12
- console.info('[Trace]', ...args);
13
- };