@lvce-editor/shared-process 0.0.2
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 +41 -0
- package/bin/sharedProcess.js +3 -0
- package/index.js +6 -0
- package/package.json +96 -0
- package/src/parts/Assert/Assert.js +57 -0
- package/src/parts/Callback/Callback.js +48 -0
- package/src/parts/ChildProcess/ChildProcess.js +98 -0
- package/src/parts/ClipBoard/ClipBoard.ipc.js +7 -0
- package/src/parts/ClipBoard/ClipBoard.js +23 -0
- package/src/parts/ClipBoard/ClipBoardGnome.js +78 -0
- package/src/parts/ClipBoard/ClipBoardNoop.js +14 -0
- package/src/parts/ClipBoard/ClipBoardWindows.js +22 -0
- package/src/parts/Command/Command.js +264 -0
- package/src/parts/Configuration/Configuration.ipc.js +7 -0
- package/src/parts/Configuration/Configuration.js +39 -0
- package/src/parts/Credentials/Credentials.ipc.js +10 -0
- package/src/parts/Credentials/Credentials.js +69 -0
- package/src/parts/Debug/Debug.js +3 -0
- package/src/parts/Developer/Developer.ipc.js +20 -0
- package/src/parts/Developer/Developer.js +132 -0
- package/src/parts/Download/Download.js +33 -0
- package/src/parts/Electron/Electron.ipc.js +19 -0
- package/src/parts/Electron/Electron.js +99 -0
- package/src/parts/Env/Env.js +3 -0
- package/src/parts/Error/Error.js +30 -0
- package/src/parts/ErrorHandling/ErrorHandling.js +40 -0
- package/src/parts/Exec/Exec.js +16 -0
- package/src/parts/Extension/Extension.js +7 -0
- package/src/parts/ExtensionHost/ExtensionHost.ipc.js +80 -0
- package/src/parts/ExtensionHost/ExtensionHost.js +163 -0
- package/src/parts/ExtensionHost/ExtensionHostBraceCompletion.js +14 -0
- package/src/parts/ExtensionHost/ExtensionHostClosingTag.js +14 -0
- package/src/parts/ExtensionHost/ExtensionHostColorTheme.js +60 -0
- package/src/parts/ExtensionHost/ExtensionHostCommand.js +19 -0
- package/src/parts/ExtensionHost/ExtensionHostCompletion.js +12 -0
- package/src/parts/ExtensionHost/ExtensionHostDefinition.js +12 -0
- package/src/parts/ExtensionHost/ExtensionHostDiagnostic.js +7 -0
- package/src/parts/ExtensionHost/ExtensionHostFileSystem.js +23 -0
- package/src/parts/ExtensionHost/ExtensionHostFormatting.js +4 -0
- package/src/parts/ExtensionHost/ExtensionHostHover.js +12 -0
- package/src/parts/ExtensionHost/ExtensionHostIconTheme.js +35 -0
- package/src/parts/ExtensionHost/ExtensionHostImplementation.js +12 -0
- package/src/parts/ExtensionHost/ExtensionHostKeyBindings.js +23 -0
- package/src/parts/ExtensionHost/ExtensionHostLanguages.js +84 -0
- package/src/parts/ExtensionHost/ExtensionHostManagement.js +26 -0
- package/src/parts/ExtensionHost/ExtensionHostOutput.js +3 -0
- package/src/parts/ExtensionHost/ExtensionHostQuickPick.js +6 -0
- package/src/parts/ExtensionHost/ExtensionHostReference.js +12 -0
- package/src/parts/ExtensionHost/ExtensionHostRename.js +27 -0
- package/src/parts/ExtensionHost/ExtensionHostSemanticTokens.js +10 -0
- package/src/parts/ExtensionHost/ExtensionHostSourceControl.js +15 -0
- package/src/parts/ExtensionHost/ExtensionHostStats.js +3 -0
- package/src/parts/ExtensionHost/ExtensionHostStatusBar.js +7 -0
- package/src/parts/ExtensionHost/ExtensionHostTabCompletion.js +12 -0
- package/src/parts/ExtensionHost/ExtensionHostTextDocument.js +35 -0
- package/src/parts/ExtensionHost/ExtensionHostTypeDefinition.js +12 -0
- package/src/parts/ExtensionHost/ExtensionHostWorkspace.js +3 -0
- package/src/parts/ExtensionManagement/ExtensionManagement.ipc.js +11 -0
- package/src/parts/ExtensionManagement/ExtensionManagement.js +319 -0
- package/src/parts/FileSystem/FileSystem.ipc.js +32 -0
- package/src/parts/FileSystem/FileSystem.js +228 -0
- package/src/parts/Git/Git.js +58 -0
- package/src/parts/Json/Json.js +67 -0
- package/src/parts/JsonFile/JsonFile.js +14 -0
- package/src/parts/JsonRpc/JsonRpc.js +22 -0
- package/src/parts/Native/Native.ipc.js +6 -0
- package/src/parts/Native/Native.js +14 -0
- package/src/parts/OutputChannel/OutputChannel.ipc.js +51 -0
- package/src/parts/OutputChannel/OutputChannel.js +37 -0
- package/src/parts/ParentIpc/ParentIpc.js +203 -0
- package/src/parts/Path/Path.js +17 -0
- package/src/parts/Platform/Platform.ipc.js +18 -0
- package/src/parts/Platform/Platform.js +165 -0
- package/src/parts/Preferences/Preferences.ipc.js +6 -0
- package/src/parts/Preferences/Preferences.js +75 -0
- package/src/parts/PrettyError/PrettyError.js +86 -0
- package/src/parts/Process/Process.ipc.js +7 -0
- package/src/parts/Process/Process.js +7 -0
- package/src/parts/Queue/Queue.js +35 -0
- package/src/parts/RequiresSocket/RequiresSocket.js +11 -0
- package/src/parts/RgPath/RgPath.js +1 -0
- package/src/parts/Root/Root.js +6 -0
- package/src/parts/Search/Search.ipc.js +6 -0
- package/src/parts/Search/Search.js +101 -0
- package/src/parts/SearchFile/SearchFile.ipc.js +6 -0
- package/src/parts/SearchFile/SearchFile.js +51 -0
- package/src/parts/Socket/Socket.js +132 -0
- package/src/parts/Stats/Stats.js +45 -0
- package/src/parts/Terminal/Terminal.ipc.js +45 -0
- package/src/parts/Terminal/Terminal.js +161 -0
- package/src/parts/TextDocument/TextDocument.ipc.js +6 -0
- package/src/parts/TextDocument/TextDocument.js +37 -0
- package/src/parts/Trace/Trace.js +15 -0
- package/src/parts/Trash/Trash.js +11 -0
- package/src/parts/WebSocketServer/WebSocketServer.ipc.js +6 -0
- package/src/parts/WebSocketServer/WebSocketServer.js +43 -0
- package/src/parts/Workspace/Workspace.ipc.js +7 -0
- package/src/parts/Workspace/Workspace.js +107 -0
- package/src/sharedProcessMain.js +61 -0
- package/test/Callback.test.js +42 -0
- package/test/ClipBoard.test.js +105 -0
- package/test/Credentials.test.js +147 -0
- package/test/Developer.test.js +34 -0
- package/test/Electron.test.js +93 -0
- package/test/Error.test.js +16 -0
- package/test/Exec.test.js +25 -0
- package/test/ExtensionHost.test.js +127 -0
- package/test/ExtensionHostColorTheme.test.js +141 -0
- package/test/ExtensionHostCommand.test.js +27 -0
- package/test/ExtensionHostCompletion.test.js +45 -0
- package/test/ExtensionHostDefinition.test.js +35 -0
- package/test/ExtensionHostDiagnostic.test.js +23 -0
- package/test/ExtensionHostFileSystem.test.js +91 -0
- package/test/ExtensionHostFormatting.test.js +27 -0
- package/test/ExtensionHostIconTheme.test.js +73 -0
- package/test/ExtensionHostLanguages.test.js +212 -0
- package/test/ExtensionHostOutput.test.js +23 -0
- package/test/ExtensionHostRename.test.js +59 -0
- package/test/ExtensionHostSemanticTokens.test.js +26 -0
- package/test/ExtensionHostTabCompletion.test.js +35 -0
- package/test/ExtensionHostTextDocument.test.js +61 -0
- package/test/ExtensionHostTypeDefinition.test.js +35 -0
- package/test/ExtensionHostWorkspace.test.js +21 -0
- package/test/ExtensionManagement.test.js +408 -0
- package/test/FileSystem.test.js +294 -0
- package/test/Json.test.js +25 -0
- package/test/Native.test.js +31 -0
- package/test/OutputChannel.test.js +68 -0
- package/test/Path.test.js +17 -0
- package/test/Platform.test.js +61 -0
- package/test/Preferences.test.js +140 -0
- package/test/Process.test.js +9 -0
- package/test/RgPath.test.js +5 -0
- package/test/Search.test.js +45 -0
- package/test/SearchFile.test.js +80 -0
- package/test/Terminal.test.js +53 -0
- package/test/Trash.test.js +34 -0
- package/test/WebSocketServer.test.js +98 -0
- package/test/fixture-search-1/index.html +10 -0
- package/test/fixture-search-file-1/fileA +0 -0
- package/test/fixture-search-file-1/fileB +0 -0
- package/test/fixture-search-file-1/nested/fileC +0 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { mkdtemp } from 'node:fs/promises'
|
|
2
|
+
import { tmpdir } from 'node:os'
|
|
3
|
+
import { join, sep } from 'node:path'
|
|
4
|
+
import { writeFile } from '../src/parts/FileSystem/FileSystem.js'
|
|
5
|
+
import * as Search from '../src/parts/Search/Search.js'
|
|
6
|
+
|
|
7
|
+
const getTmpDir = () => {
|
|
8
|
+
return mkdtemp(join(tmpdir(), 'foo-'))
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const fixPath = (path) => {
|
|
12
|
+
return path.replaceAll('/', sep)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
test('search', async () => {
|
|
16
|
+
const tmpDir = await getTmpDir()
|
|
17
|
+
await writeFile(
|
|
18
|
+
join(tmpDir, 'index.html'),
|
|
19
|
+
`<!DOCTYPE html>
|
|
20
|
+
<html lang="en">
|
|
21
|
+
<head>
|
|
22
|
+
<meta charset="UTF-8" />
|
|
23
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
24
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
25
|
+
<title>Document</title>
|
|
26
|
+
</head>
|
|
27
|
+
<body></body>
|
|
28
|
+
</html>
|
|
29
|
+
`
|
|
30
|
+
)
|
|
31
|
+
expect(await Search.search(tmpDir, 'Document')).toEqual({
|
|
32
|
+
results: [
|
|
33
|
+
[
|
|
34
|
+
fixPath('./index.html'),
|
|
35
|
+
[
|
|
36
|
+
{
|
|
37
|
+
absoluteOffset: 208,
|
|
38
|
+
preview: ' <title>Document</title>\n',
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
],
|
|
42
|
+
],
|
|
43
|
+
stats: expect.any(Object),
|
|
44
|
+
})
|
|
45
|
+
})
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { mkdtemp } from 'node:fs/promises'
|
|
2
|
+
import { tmpdir } from 'node:os'
|
|
3
|
+
import { dirname, join, sep } from 'node:path'
|
|
4
|
+
import { fileURLToPath } from 'node:url'
|
|
5
|
+
import { mkdir, writeFile } from '../src/parts/FileSystem/FileSystem.js'
|
|
6
|
+
import { searchFile } from '../src/parts/SearchFile/SearchFile.js'
|
|
7
|
+
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
9
|
+
|
|
10
|
+
const getTmpDir = () => {
|
|
11
|
+
return mkdtemp(join(tmpdir(), 'foo-'))
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const fixPath = (path) => {
|
|
15
|
+
return path.replaceAll('/', sep)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let tmpDir
|
|
19
|
+
|
|
20
|
+
beforeAll(async () => {
|
|
21
|
+
tmpDir = await getTmpDir()
|
|
22
|
+
await writeFile(join(tmpDir, 'fileA'), '')
|
|
23
|
+
await writeFile(join(tmpDir, 'fileB'), '')
|
|
24
|
+
await mkdir(join(tmpDir, 'nested'))
|
|
25
|
+
await writeFile(join(tmpDir, 'nested', 'fileC'), '')
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test('searchFile - exact match', async () => {
|
|
29
|
+
expect(await searchFile(tmpDir, 'fileA')).toEqual([
|
|
30
|
+
fixPath('fileA'),
|
|
31
|
+
fixPath('fileB'),
|
|
32
|
+
fixPath('nested/fileC'),
|
|
33
|
+
])
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
test('searchFile - match filename in nested folder', async () => {
|
|
37
|
+
expect(await searchFile(tmpDir, 'fileC')).toEqual([
|
|
38
|
+
fixPath('fileA'),
|
|
39
|
+
fixPath('fileB'),
|
|
40
|
+
fixPath('nested/fileC'),
|
|
41
|
+
])
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
test('searchFile - match files that start with searchTerm', async () => {
|
|
45
|
+
expect(await searchFile(tmpDir, 'file')).toEqual([
|
|
46
|
+
fixPath('fileA'),
|
|
47
|
+
fixPath('fileB'),
|
|
48
|
+
fixPath('nested/fileC'),
|
|
49
|
+
])
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
test('searchFile - match files that contain searchTerm', async () => {
|
|
53
|
+
expect(await searchFile(tmpDir, 'ile')).toEqual([
|
|
54
|
+
fixPath('fileA'),
|
|
55
|
+
fixPath('fileB'),
|
|
56
|
+
fixPath('nested/fileC'),
|
|
57
|
+
])
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
test('searchFile - match files that end with searchTerm', async () => {
|
|
61
|
+
expect(await searchFile(tmpDir, 'eA')).toEqual([
|
|
62
|
+
fixPath('fileA'),
|
|
63
|
+
fixPath('fileB'),
|
|
64
|
+
fixPath('nested/fileC'),
|
|
65
|
+
])
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
test('searchFile - no matching files', async () => {
|
|
69
|
+
expect(
|
|
70
|
+
await searchFile(`${__dirname}/fixture-search-file-1`, 'non-existing')
|
|
71
|
+
).toEqual([fixPath('fileA'), fixPath('fileB'), fixPath('nested/fileC')])
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
test('searchFile - empty string', async () => {
|
|
75
|
+
expect(await searchFile(`${__dirname}/fixture-search-file-1`, '')).toEqual([
|
|
76
|
+
fixPath('fileA'),
|
|
77
|
+
fixPath('fileB'),
|
|
78
|
+
fixPath('nested/fileC'),
|
|
79
|
+
])
|
|
80
|
+
})
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Buffer } from 'node:buffer'
|
|
2
|
+
import waitForExpect from 'wait-for-expect'
|
|
3
|
+
import * as Platform from '../src/parts/Platform/Platform.js'
|
|
4
|
+
import * as Terminal from '../src/parts/Terminal/Terminal.js'
|
|
5
|
+
|
|
6
|
+
afterEach(() => {
|
|
7
|
+
Terminal.disposeAll()
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
test.skip('Terminal', async () => {
|
|
11
|
+
if (Platform.isWindows()) {
|
|
12
|
+
// TODO add windows test
|
|
13
|
+
return
|
|
14
|
+
}
|
|
15
|
+
let allData = ''
|
|
16
|
+
const socket = {
|
|
17
|
+
send(message) {
|
|
18
|
+
const parsed = JSON.parse(message)
|
|
19
|
+
console.log({ parsed })
|
|
20
|
+
const data = Buffer.from(parsed.params[2].data).toString()
|
|
21
|
+
allData += data
|
|
22
|
+
console.log({ allData })
|
|
23
|
+
},
|
|
24
|
+
on(event, listener) {},
|
|
25
|
+
}
|
|
26
|
+
Terminal.create(socket, 0, '/tmp')
|
|
27
|
+
Terminal.write(0, 'abc')
|
|
28
|
+
await waitForExpect(() => {
|
|
29
|
+
expect(allData).toContain('abc')
|
|
30
|
+
// expect(true).toBe(false)
|
|
31
|
+
// expect(allData).toContain('abc')
|
|
32
|
+
// expect(socket.send).toHaveBeenCalledWith('abc')
|
|
33
|
+
})
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
// test.skip('Terminal echo', async () => {
|
|
37
|
+
// await new Promise((resolve) => {
|
|
38
|
+
// // @ts-ignore
|
|
39
|
+
// const terminal = create({
|
|
40
|
+
// env: {
|
|
41
|
+
// TEST: '`',
|
|
42
|
+
// },
|
|
43
|
+
// handleData(data) {
|
|
44
|
+
// if (data.toString().includes('`')) {
|
|
45
|
+
// terminal.dispose()
|
|
46
|
+
// // @ts-ignore
|
|
47
|
+
// resolve()
|
|
48
|
+
// }
|
|
49
|
+
// },
|
|
50
|
+
// })
|
|
51
|
+
// terminal.write('echo $TEST\n')
|
|
52
|
+
// })
|
|
53
|
+
// })
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jest } from '@jest/globals'
|
|
2
|
+
|
|
3
|
+
afterEach(() => {
|
|
4
|
+
jest.resetAllMocks()
|
|
5
|
+
})
|
|
6
|
+
|
|
7
|
+
jest.unstable_mockModule('trash', () => {
|
|
8
|
+
return {
|
|
9
|
+
default: jest.fn(() => {
|
|
10
|
+
throw new Error('not implemented')
|
|
11
|
+
}),
|
|
12
|
+
}
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
const trash = await import('trash')
|
|
16
|
+
const Trash = await import('../src/parts/Trash/Trash.js')
|
|
17
|
+
|
|
18
|
+
test('trash', async () => {
|
|
19
|
+
// @ts-ignore
|
|
20
|
+
trash.default.mockImplementation(() => {})
|
|
21
|
+
await Trash.trash('/test')
|
|
22
|
+
expect(trash.default).toHaveBeenCalledTimes(1)
|
|
23
|
+
expect(trash.default).toHaveBeenCalledWith('/test')
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
test('trash - error', async () => {
|
|
27
|
+
// @ts-ignore
|
|
28
|
+
trash.default.mockImplementation(() => {
|
|
29
|
+
throw new TypeError('x is not a function')
|
|
30
|
+
})
|
|
31
|
+
await expect(Trash.trash('/test')).rejects.toThrowError(
|
|
32
|
+
new Error('Failed to move item to trash: x is not a function')
|
|
33
|
+
)
|
|
34
|
+
})
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import http from 'node:http'
|
|
2
|
+
import { mkdtemp, writeFile } from 'node:fs/promises'
|
|
3
|
+
import { tmpdir } from 'node:os'
|
|
4
|
+
import { join } from 'node:path'
|
|
5
|
+
import { WebSocket } from 'ws'
|
|
6
|
+
import * as WebSocketServer from '../src/parts/WebSocketServer/WebSocketServer.js'
|
|
7
|
+
|
|
8
|
+
const getTmpDir = () => {
|
|
9
|
+
return mkdtemp(join(tmpdir(), 'foo-'))
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
test('WebSocketServer', async () => {
|
|
13
|
+
const httpServer = http.createServer((req, res) => {
|
|
14
|
+
WebSocketServer.handleUpgrade(
|
|
15
|
+
{
|
|
16
|
+
headers: req.headers,
|
|
17
|
+
method: req.method,
|
|
18
|
+
},
|
|
19
|
+
req.socket
|
|
20
|
+
)
|
|
21
|
+
})
|
|
22
|
+
const port = await new Promise((resolve, reject) => {
|
|
23
|
+
httpServer.listen(0, () => {
|
|
24
|
+
const address = httpServer.address()
|
|
25
|
+
if (address === null || typeof address === 'string') {
|
|
26
|
+
reject(new Error('unexpected address type'))
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
resolve(address.port)
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
const webSocket = new WebSocket(`ws://localhost:${port}`)
|
|
33
|
+
await new Promise((resolve) => {
|
|
34
|
+
webSocket.onopen = () => {
|
|
35
|
+
resolve(undefined)
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
const messageBufferPromise = new Promise((resolve) => {
|
|
39
|
+
webSocket.on('message', (message) => {
|
|
40
|
+
resolve(message)
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
const tmpDir = await getTmpDir()
|
|
44
|
+
await writeFile(join(tmpDir, 'abc.txt'), 'abc')
|
|
45
|
+
webSocket.send(
|
|
46
|
+
JSON.stringify({
|
|
47
|
+
jsonrpc: '2.0',
|
|
48
|
+
method: /* FileSystem.readFile */ 'FileSystem.readFile',
|
|
49
|
+
params: [join(tmpDir, 'abc.txt')],
|
|
50
|
+
id: 1,
|
|
51
|
+
})
|
|
52
|
+
)
|
|
53
|
+
const messageBuffer = await messageBufferPromise
|
|
54
|
+
const messageString = messageBuffer.toString()
|
|
55
|
+
const message = JSON.parse(messageString)
|
|
56
|
+
expect(message).toEqual({
|
|
57
|
+
id: 1,
|
|
58
|
+
jsonrpc: '2.0',
|
|
59
|
+
result: 'abc',
|
|
60
|
+
})
|
|
61
|
+
webSocket.close()
|
|
62
|
+
httpServer.close()
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
// TODO have e2e test for socket error handling (e.g. rangeError or connection died or EPIPE)
|
|
66
|
+
|
|
67
|
+
// TODO how to emit and test error?
|
|
68
|
+
test.skip('WebSocketServer - handle socket error', async () => {
|
|
69
|
+
const httpServer = http.createServer((req, res) => {
|
|
70
|
+
WebSocketServer.handleUpgrade(
|
|
71
|
+
{
|
|
72
|
+
headers: req.headers,
|
|
73
|
+
method: req.method,
|
|
74
|
+
},
|
|
75
|
+
req.socket
|
|
76
|
+
)
|
|
77
|
+
req.socket._destroy(new RangeError('invalid range specified'), () => {})
|
|
78
|
+
// setInterval(() => {
|
|
79
|
+
// req.socket.emit('error', new RangeError('invalid range specified'))
|
|
80
|
+
// }, 100)
|
|
81
|
+
})
|
|
82
|
+
const port = await new Promise((resolve, reject) => {
|
|
83
|
+
httpServer.listen(0, () => {
|
|
84
|
+
const address = httpServer.address()
|
|
85
|
+
if (address === null || typeof address === 'string') {
|
|
86
|
+
reject(new Error('unexpected address type'))
|
|
87
|
+
return
|
|
88
|
+
}
|
|
89
|
+
resolve(address.port)
|
|
90
|
+
})
|
|
91
|
+
})
|
|
92
|
+
const webSocket = new ws.WebSocket(`ws://localhost:${port}`)
|
|
93
|
+
await new Promise((resolve) => {
|
|
94
|
+
webSocket.onopen = () => {
|
|
95
|
+
resolve()
|
|
96
|
+
}
|
|
97
|
+
})
|
|
98
|
+
})
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Document</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body></body>
|
|
10
|
+
</html>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|