@lvce-editor/shared-process 0.106.4 → 0.107.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/package.json +2 -2
- package/src/parts/BuiltinExtensionsPath/BuiltinExtensionsPath.js +1 -1
- package/src/parts/ExtensionNodeProcessIpc/ExtensionNodeProcessIpc.js +15 -0
- package/src/parts/HandleMessagePortForExtensionNodeProcess/HandleMessagePortForExtensionNodeProcess.ipc.js +7 -0
- package/src/parts/HandleMessagePortForExtensionNodeProcess/HandleMessagePortForExtensionNodeProcess.js +35 -0
- package/src/parts/HandleWebSocketForExtensionNodeProcess/HandleWebSocketForExtensionNodeProcess.js +23 -0
- package/src/parts/HandleWebSocketModule/HandleWebSocketModule.js +3 -0
- package/src/parts/Module/Module.js +2 -0
- package/src/parts/ModuleId/ModuleId.js +1 -0
- package/src/parts/ModuleMap/ModuleMap.js +2 -0
- package/src/parts/Platform/Platform.js +3 -3
- package/src/parts/PreloadUrl/PreloadUrl.js +1 -1
- package/src/parts/ProtocolType/ProtocolType.js +1 -0
- package/src/parts/RequiresSocket/RequiresSocket.js +1 -0
- package/src/parts/ResolveExtensionNodeProcess/ResolveExtensionNodeProcess.js +55 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lvce-editor/shared-process",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.107.0",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@lvce-editor/assert": "1.9.0",
|
|
21
|
-
"@lvce-editor/extension-host-helper-process": "0.
|
|
21
|
+
"@lvce-editor/extension-host-helper-process": "0.107.0",
|
|
22
22
|
"@lvce-editor/ipc": "16.12.0",
|
|
23
23
|
"@lvce-editor/json-rpc": "8.7.0",
|
|
24
24
|
"@lvce-editor/jsonc-parser": "1.5.0",
|
|
@@ -3,6 +3,6 @@ import { fileURLToPath } from 'url'
|
|
|
3
3
|
|
|
4
4
|
export const getBuiltinExtensionsPath = () => {
|
|
5
5
|
const staticServerPath = fileURLToPath(import.meta.resolve('@lvce-editor/static-server'))
|
|
6
|
-
const builtinExtensionsPath = join(staticServerPath, '..', '..', 'static', '
|
|
6
|
+
const builtinExtensionsPath = join(staticServerPath, '..', '..', 'static', '64c8cbf', 'extensions')
|
|
7
7
|
return builtinExtensionsPath
|
|
8
8
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as HandleIpc from '../HandleIpc/HandleIpc.js'
|
|
2
|
+
import * as IpcParent from '../IpcParent/IpcParent.js'
|
|
3
|
+
import * as ResolveExtensionNodeProcess from '../ResolveExtensionNodeProcess/ResolveExtensionNodeProcess.js'
|
|
4
|
+
|
|
5
|
+
export const create = async ({ extensionId, method, rpcId } ) => {
|
|
6
|
+
const { name, path } = await ResolveExtensionNodeProcess.resolveExtensionNodeProcess(extensionId, rpcId)
|
|
7
|
+
const ipc = await IpcParent.create({
|
|
8
|
+
execArgv: [],
|
|
9
|
+
method,
|
|
10
|
+
name,
|
|
11
|
+
path,
|
|
12
|
+
})
|
|
13
|
+
HandleIpc.handleIpc(ipc)
|
|
14
|
+
return ipc
|
|
15
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as HandleMessagePortForExtensionNodeProcess from './HandleMessagePortForExtensionNodeProcess.js'
|
|
2
|
+
|
|
3
|
+
export const name = 'HandleMessagePortForExtensionNodeProcess'
|
|
4
|
+
|
|
5
|
+
export const Commands = {
|
|
6
|
+
handleMessagePortForExtensionNodeProcess: HandleMessagePortForExtensionNodeProcess.handleMessagePortForExtensionNodeProcess,
|
|
7
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as Assert from '../Assert/Assert.js'
|
|
2
|
+
import * as ExtensionNodeProcessIpc from '../ExtensionNodeProcessIpc/ExtensionNodeProcessIpc.js'
|
|
3
|
+
import * as IpcParentType from '../IpcParentType/IpcParentType.js'
|
|
4
|
+
import * as JsonRpc from '../JsonRpc/JsonRpc.js'
|
|
5
|
+
|
|
6
|
+
export const handleMessagePortForExtensionNodeProcess = async (
|
|
7
|
+
rendererWorkerIpc,
|
|
8
|
+
port,
|
|
9
|
+
extensionId,
|
|
10
|
+
rpcId,
|
|
11
|
+
) => {
|
|
12
|
+
Assert.object(port)
|
|
13
|
+
Assert.string(extensionId)
|
|
14
|
+
Assert.string(rpcId)
|
|
15
|
+
const ipc = await ExtensionNodeProcessIpc.create({
|
|
16
|
+
extensionId,
|
|
17
|
+
method: IpcParentType.ElectronUtilityProcess,
|
|
18
|
+
rpcId,
|
|
19
|
+
})
|
|
20
|
+
const dispose = () => {
|
|
21
|
+
ipc.dispose()
|
|
22
|
+
}
|
|
23
|
+
const removeRendererCloseListener = () => {
|
|
24
|
+
rendererWorkerIpc.off('close', dispose)
|
|
25
|
+
}
|
|
26
|
+
rendererWorkerIpc.on('close', dispose)
|
|
27
|
+
ipc.on('close', removeRendererCloseListener)
|
|
28
|
+
try {
|
|
29
|
+
await JsonRpc.invokeAndTransfer(ipc, 'NodeRpcProcess.handleElectronMessagePort', port)
|
|
30
|
+
} catch (error) {
|
|
31
|
+
removeRendererCloseListener()
|
|
32
|
+
ipc.dispose()
|
|
33
|
+
throw error
|
|
34
|
+
}
|
|
35
|
+
}
|
package/src/parts/HandleWebSocketForExtensionNodeProcess/HandleWebSocketForExtensionNodeProcess.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as ExtensionNodeProcessIpc from '../ExtensionNodeProcessIpc/ExtensionNodeProcessIpc.js'
|
|
2
|
+
import * as IpcParentType from '../IpcParentType/IpcParentType.js'
|
|
3
|
+
import * as JsonRpc from '../JsonRpc/JsonRpc.js'
|
|
4
|
+
|
|
5
|
+
export const handleWebSocket = async (message, handle) => {
|
|
6
|
+
const url = new URL(message.url, 'http://localhost')
|
|
7
|
+
const extensionId = url.searchParams.get('extensionId')
|
|
8
|
+
const rpcId = url.searchParams.get('rpcId')
|
|
9
|
+
if (!extensionId || !rpcId) {
|
|
10
|
+
throw new Error('Remote extension node process request is incomplete')
|
|
11
|
+
}
|
|
12
|
+
const ipc = await ExtensionNodeProcessIpc.create({
|
|
13
|
+
extensionId,
|
|
14
|
+
method: IpcParentType.NodeForkedProcess,
|
|
15
|
+
rpcId,
|
|
16
|
+
})
|
|
17
|
+
try {
|
|
18
|
+
await JsonRpc.invokeAndTransfer(ipc, 'NodeRpcProcess.handleWebSocket', handle, message)
|
|
19
|
+
} catch (error) {
|
|
20
|
+
ipc.dispose()
|
|
21
|
+
throw error
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as HandleWebSocketForClipBoardProcess from '../HandleWebSocketForClipBoardProcess/HandleWebSocketForClipBoardProcess.js'
|
|
2
2
|
import * as HandleWebSocketForExtensionHostHelperProcess from '../HandleWebSocketForExtensionHostHelperProcess/HandleWebSocketForExtensionHostHelperProcess.js'
|
|
3
|
+
import * as HandleWebSocketForExtensionNodeProcess from '../HandleWebSocketForExtensionNodeProcess/HandleWebSocketForExtensionNodeProcess.js'
|
|
3
4
|
import * as HandleWebSocketForFileSystemProcess from '../HandleWebSocketForFileSystemProcess/HandleWebSocketForFileSystemProcess.js'
|
|
4
5
|
import * as HandleWebSocketForProcessExplorer from '../HandleWebSocketForProcessExplorer/HandleWebSocketForProcessExplorer.js'
|
|
5
6
|
import * as HandleWebSocketForSearchProcess from '../HandleWebSocketForSearchProcess/HandleWebSocketForSearchProcess.js'
|
|
@@ -18,6 +19,8 @@ export const load = (protocol) => {
|
|
|
18
19
|
return HandleWebSocketForClipBoardProcess
|
|
19
20
|
case ProtocolType.ExtensionHostHelperProcess:
|
|
20
21
|
return HandleWebSocketForExtensionHostHelperProcess
|
|
22
|
+
case ProtocolType.ExtensionNodeProcess:
|
|
23
|
+
return HandleWebSocketForExtensionNodeProcess
|
|
21
24
|
case ProtocolType.FileSystemProcess:
|
|
22
25
|
return HandleWebSocketForFileSystemProcess
|
|
23
26
|
case ProtocolType.ProcessExplorer:
|
|
@@ -88,6 +88,8 @@ export const load = (moduleId) => {
|
|
|
88
88
|
return import('../HandleMessagePortForEmbedsProcess/HandleMessagePortForEmbedsProcess.ipc.js')
|
|
89
89
|
case ModuleId.HandleMessagePortForExtensionHostHelperProcess:
|
|
90
90
|
return import('../HandleMessagePortForExtensionHostHelperProcess/HandleMessagePortForExtensionHostHelperProcess.ipc.js')
|
|
91
|
+
case ModuleId.HandleMessagePortForExtensionNodeProcess:
|
|
92
|
+
return import('../HandleMessagePortForExtensionNodeProcess/HandleMessagePortForExtensionNodeProcess.ipc.js')
|
|
91
93
|
case ModuleId.HandleMessagePortForFileSystemProcess:
|
|
92
94
|
return import('../HandleMessagePortForFileSystemProcess/HandleMessagePortForFileSystemProcess.ipc.js')
|
|
93
95
|
case ModuleId.HandleMessagePortForProcessExplorer:
|
|
@@ -184,6 +184,8 @@ export const getModuleId = (commandId) => {
|
|
|
184
184
|
case 'HandleMessagePortForExtensionHostHelperProcess.handleMessagePortForExtensionHostHelperProcess':
|
|
185
185
|
case 'HandleMessagePortForExtensionHostHelperProcess.handlePreloadedMessagePortForExtensionHostHelperProcess':
|
|
186
186
|
return ModuleId.HandleMessagePortForExtensionHostHelperProcess
|
|
187
|
+
case 'HandleMessagePortForExtensionNodeProcess.handleMessagePortForExtensionNodeProcess':
|
|
188
|
+
return ModuleId.HandleMessagePortForExtensionNodeProcess
|
|
187
189
|
case 'HandleMessagePortForFileSystemProcess.handleMessagePortForFileSystemProcess':
|
|
188
190
|
return ModuleId.HandleMessagePortForFileSystemProcess
|
|
189
191
|
case 'HandleMessagePortForProcessExplorer.handleMessagePortForProcessExplorer':
|
|
@@ -61,11 +61,11 @@ export const getSetupName = () => {
|
|
|
61
61
|
return 'Lvce-Setup'
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
export const version = '0.
|
|
64
|
+
export const version = '0.107.0'
|
|
65
65
|
|
|
66
|
-
export const commit = '
|
|
66
|
+
export const commit = '64c8cbf'
|
|
67
67
|
|
|
68
|
-
export const date = '2026-08-22T16:
|
|
68
|
+
export const date = '2026-08-22T16:38:17.000Z'
|
|
69
69
|
|
|
70
70
|
export const getVersion = () => {
|
|
71
71
|
return version
|
|
@@ -2,5 +2,5 @@ import { join } from 'node:path'
|
|
|
2
2
|
import * as Root from '../Root/Root.js'
|
|
3
3
|
|
|
4
4
|
export const getPreloadUrl = () => {
|
|
5
|
-
return join(Root.root, 'static', '
|
|
5
|
+
return join(Root.root, 'static', '64c8cbf', 'packages', 'preload', 'dist', 'index.js')
|
|
6
6
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export const ExtensionHost = 'extension-host'
|
|
2
2
|
export const ExtensionHostHelperProcess = 'extension-host-helper-process'
|
|
3
|
+
export const ExtensionNodeProcess = 'extension-node-process'
|
|
3
4
|
export const SearchProcess = 'search-process'
|
|
4
5
|
export const ProcessExplorer = 'process-explorer'
|
|
5
6
|
export const FileSystemProcess = 'file-system-process'
|
|
@@ -11,6 +11,7 @@ const METHODS_THAT_REQUIRE_SOCKET = new Set([
|
|
|
11
11
|
'IncrementalTextSearch.start',
|
|
12
12
|
'ElectronApplicationMenu.setItems',
|
|
13
13
|
'HandleMessagePortForExtensionHostHelperProcess.handleMessagePortForExtensionHostHelperProcess',
|
|
14
|
+
'HandleMessagePortForExtensionNodeProcess.handleMessagePortForExtensionNodeProcess',
|
|
14
15
|
'ElectronBrowserView.createBrowserView',
|
|
15
16
|
'ElectronWebContentsView.createWebContentsView',
|
|
16
17
|
'FileWatcher.dispose',
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { readFile, realpath } from 'node:fs/promises'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import * as ExtensionManagement from '../ExtensionManagement/ExtensionManagement.js'
|
|
4
|
+
|
|
5
|
+
const idRegex = /^[A-Za-z0-9][A-Za-z0-9._-]*$/
|
|
6
|
+
const schemeRegex = /^[A-Za-z][A-Za-z\d+.-]*:/
|
|
7
|
+
|
|
8
|
+
const isInside = (parent, child) => child === parent || child.startsWith(`${parent}${path.sep}`)
|
|
9
|
+
|
|
10
|
+
const validateId = (value, name) => {
|
|
11
|
+
if (!idRegex.test(value)) {
|
|
12
|
+
throw new Error(`Invalid extension node process ${name}`)
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const getExtension = async (extensionId) => {
|
|
17
|
+
const extensions = await ExtensionManagement.getExtensions()
|
|
18
|
+
const extension = extensions.find((candidate) => candidate?.id === extensionId)
|
|
19
|
+
if (!extension || typeof extension.path !== 'string') {
|
|
20
|
+
throw new Error(`Extension ${extensionId} is not installed`)
|
|
21
|
+
}
|
|
22
|
+
return extension
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
export const resolveExtensionNodeProcess = async (extensionId, rpcId) => {
|
|
31
|
+
validateId(extensionId, 'extension id')
|
|
32
|
+
validateId(rpcId, 'rpc id')
|
|
33
|
+
const extension = await getExtension(extensionId)
|
|
34
|
+
const extensionRoot = await realpath(extension.path)
|
|
35
|
+
const manifestPath = await realpath(path.join(extensionRoot, 'extension.json'))
|
|
36
|
+
if (!isInside(extensionRoot, manifestPath)) {
|
|
37
|
+
throw new Error('Extension manifest escapes the extension root')
|
|
38
|
+
}
|
|
39
|
+
const manifest = JSON.parse(await readFile(manifestPath, 'utf8'))
|
|
40
|
+
const rpc = manifest.rpc?.find((candidate) => candidate?.id === rpcId)
|
|
41
|
+
if (!rpc || rpc.type !== 'node-process' || typeof rpc.url !== 'string') {
|
|
42
|
+
throw new Error(`Node process ${rpcId} is not declared by extension ${extensionId}`)
|
|
43
|
+
}
|
|
44
|
+
if (!rpc.url || path.isAbsolute(rpc.url) || path.win32.isAbsolute(rpc.url) || schemeRegex.test(rpc.url)) {
|
|
45
|
+
throw new Error(`Node process ${rpcId} must use a relative url`)
|
|
46
|
+
}
|
|
47
|
+
const processPath = await realpath(path.resolve(extensionRoot, rpc.url))
|
|
48
|
+
if (!isInside(extensionRoot, processPath)) {
|
|
49
|
+
throw new Error('Extension node process path escapes the extension root')
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
name: `Extension ${extensionId}: ${typeof rpc.name === 'string' && rpc.name ? rpc.name : rpcId}`,
|
|
53
|
+
path: processPath,
|
|
54
|
+
}
|
|
55
|
+
}
|