@lvce-editor/shared-process 0.21.3 → 0.21.5

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 (36) hide show
  1. package/package.json +6 -5
  2. package/src/parts/AddSemiColon/AddSemiColon.js +5 -0
  3. package/src/parts/AppWindow/AppWindow.js +3 -1
  4. package/src/parts/Assert/Assert.js +1 -59
  5. package/src/parts/Character/Character.js +1 -0
  6. package/src/parts/ContentSecurityPolicy/ContentSecurityPolicy.js +16 -0
  7. package/src/parts/ContentSecurityPolicyWorker/ContentSecurityPolicyWorker.js +14 -0
  8. package/src/parts/CpuProfile/CpuProfile.js +1 -1
  9. package/src/parts/CreateCpuProfile/CreateCpuProfile.js +4 -4
  10. package/src/parts/CrossOriginEmbedderPolicy/CrossOriginEmbedderPolicy.js +2 -0
  11. package/src/parts/CrossOriginOpenerPolicy/CrossOriginOpenerPolicy.js +2 -0
  12. package/src/parts/Env/Env.js +1 -1
  13. package/src/parts/Exec/Exec.js +1 -1
  14. package/src/parts/ExportStatic/ExportStatic.js +10 -9
  15. package/src/parts/ExtensionManifests/ExtensionManifestsFromLinkedExtensionsFolder.js +2 -2
  16. package/src/parts/GetElectronFileResponse/GetElectronFileResponse.ipc.js +7 -0
  17. package/src/parts/GetElectronFileResponse/GetElectronFileResponse.js +23 -0
  18. package/src/parts/GetElectronFileResponseAbsolutePath/GetElectronFileResponseAbsolutePath.js +35 -0
  19. package/src/parts/GetElectronFileResponseRelativePath/GetElectronFileResponseRelativePath.js +8 -0
  20. package/src/parts/GetFirstWebSocketEvent/GetFirstWebSocketEvent.js +4 -20
  21. package/src/parts/GetHeaders/GetHeaders.js +52 -0
  22. package/src/parts/GetMimeType/GetMimeType.js +23 -0
  23. package/src/parts/GetPsOutput/GetPsOutput.js +2 -3
  24. package/src/parts/GetStatusString/GetStatusString.js +5 -5
  25. package/src/parts/GetTitleBarItems/GetTitleBarItems.js +46 -0
  26. package/src/parts/HandleWebSocket/HandleWebSocket.js +1 -1
  27. package/src/parts/Header/Header.js +1 -0
  28. package/src/parts/IpcChildWithElectronUtilityProcess/IpcChildWithElectronUtilityProcess.js +1 -1
  29. package/src/parts/IpcParentWithNodeForkedProcess/IpcParentWithNodeForkedProcess.js +3 -3
  30. package/src/parts/MimeType/MimeType.js +37 -0
  31. package/src/parts/Module/Module.js +2 -0
  32. package/src/parts/ModuleId/ModuleId.js +1 -0
  33. package/src/parts/ModuleMap/ModuleMap.js +2 -0
  34. package/src/parts/Platform/Platform.js +3 -3
  35. package/src/parts/ToTextSearchResult/ToTextSearchResult.js +2 -2
  36. package/src/parts/AssertionError/AssertionError.js +0 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/shared-process",
3
- "version": "0.21.3",
3
+ "version": "0.21.5",
4
4
  "main": "index.js",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -18,12 +18,13 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "@babel/code-frame": "^7.23.5",
21
- "@lvce-editor/extension-host": "0.21.3",
22
- "@lvce-editor/extension-host-helper-process": "0.21.3",
21
+ "@lvce-editor/assert": "^1.0.1",
22
+ "@lvce-editor/extension-host": "0.21.5",
23
+ "@lvce-editor/extension-host-helper-process": "0.21.5",
23
24
  "@lvce-editor/json-rpc": "^0.4.0",
24
25
  "@lvce-editor/jsonc-parser": "^1.1.0",
25
26
  "@lvce-editor/pretty-error": "^1.3.0",
26
- "@lvce-editor/pty-host": "0.21.3",
27
+ "@lvce-editor/pty-host": "0.21.5",
27
28
  "@lvce-editor/verror": "^1.1.2",
28
29
  "debug": "^4.3.4",
29
30
  "execa": "^8.0.1",
@@ -40,7 +41,7 @@
40
41
  "optionalDependencies": {
41
42
  "@lvce-editor/ripgrep": "^1.0.1",
42
43
  "extract-zip": "^2.0.1",
43
- "open": "^9.1.0",
44
+ "open": "^10.0.0",
44
45
  "symlink-dir": "^5.2.0",
45
46
  "tail": "^2.2.6",
46
47
  "tmp-promise": "^3.0.3",
@@ -0,0 +1,5 @@
1
+ import * as Character from '../Character/Character.js'
2
+
3
+ export const addSemicolon = (line) => {
4
+ return line + Character.SemiColon
5
+ }
@@ -1,5 +1,6 @@
1
1
  import * as DefaultUrl from '../DefaultUrl/DefaultUrl.js'
2
2
  import * as GetAppWindowOptions from '../GetAppWindowOptions/GetAppWindowOptions.js'
3
+ import * as GetTitleBarItems from '../GetTitleBarItems/GetTitleBarItems.js'
3
4
  import * as ParentIpc from '../ParentIpc/ParentIpc.js'
4
5
  import * as Preferences from '../Preferences/Preferences.js'
5
6
  import * as Screen from '../Screen/Screen.js'
@@ -7,7 +8,8 @@ import * as Screen from '../Screen/Screen.js'
7
8
  export const createAppWindow = async (preferences, parsedArgs, workingDirectory, url = DefaultUrl.defaultUrl) => {
8
9
  const { width, height } = await Screen.getBounds()
9
10
  const windowOptions = GetAppWindowOptions.getAppWindowOptions(preferences, width, height)
10
- return ParentIpc.invoke('AppWindow.createAppWindow2', windowOptions, parsedArgs, workingDirectory, url)
11
+ const titleBarItems = GetTitleBarItems.getTitleBarItems()
12
+ return ParentIpc.invoke('AppWindow.createAppWindow2', windowOptions, parsedArgs, workingDirectory, titleBarItems, url)
11
13
  }
12
14
 
13
15
  export const openNew = async (url) => {
@@ -1,59 +1 @@
1
- import { AssertionError } from '../AssertionError/AssertionError.js'
2
-
3
- const getType = (value) => {
4
- switch (typeof value) {
5
- case 'number':
6
- return 'number'
7
- case 'function':
8
- return 'function'
9
- case 'string':
10
- return 'string'
11
- case 'object':
12
- if (value === null) {
13
- return 'null'
14
- }
15
- if (Array.isArray(value)) {
16
- return 'array'
17
- }
18
- return 'object'
19
- case 'boolean':
20
- return 'boolean'
21
- default:
22
- return 'unknown'
23
- }
24
- }
25
-
26
- export const object = (value) => {
27
- const type = getType(value)
28
- if (type !== 'object') {
29
- throw new AssertionError('expected value to be of type object')
30
- }
31
- }
32
-
33
- export const number = (value) => {
34
- const type = getType(value)
35
- if (type !== 'number') {
36
- throw new AssertionError('expected value to be of type number')
37
- }
38
- }
39
-
40
- export const array = (value) => {
41
- const type = getType(value)
42
- if (type !== 'array') {
43
- throw new AssertionError('expected value to be of type array')
44
- }
45
- }
46
-
47
- export const string = (value) => {
48
- const type = getType(value)
49
- if (type !== 'string') {
50
- throw new AssertionError('expected value to be of type string')
51
- }
52
- }
53
-
54
- export const boolean = (value) => {
55
- const type = getType(value)
56
- if (type !== 'boolean') {
57
- throw new AssertionError('expected value to be of type boolean')
58
- }
59
- }
1
+ export * from '@lvce-editor/assert'
@@ -9,3 +9,4 @@ export const Space = ' '
9
9
  export const Tab = '\t'
10
10
  export const Underline = '_'
11
11
  export const T = 't'
12
+ export const SemiColon = ';'
@@ -0,0 +1,16 @@
1
+ import * as Character from '../Character/Character.js'
2
+ import * as AddSemiColon from '../AddSemiColon/AddSemiColon.js'
3
+
4
+ export const key = 'Content-Security-Policy'
5
+
6
+ export const value = [
7
+ `default-src 'none'`,
8
+ `font-src 'self'`,
9
+ `frame-src *`,
10
+ `img-src 'self' https: data:`,
11
+ `script-src 'self'`,
12
+ `media-src 'self'`,
13
+ `style-src 'self'`,
14
+ ]
15
+ .map(AddSemiColon.addSemicolon)
16
+ .join(Character.Space)
@@ -0,0 +1,14 @@
1
+ import * as Character from '../Character/Character.js'
2
+ import * as AddSemiColon from '../AddSemiColon/AddSemiColon.js'
3
+
4
+ export const key = 'Content-Security-Policy'
5
+
6
+ // prettier-ignore
7
+ export const value = [
8
+ `default-src 'none'`,
9
+ `connect-src 'self'`,
10
+ `script-src 'self'`,
11
+ `font-src 'self'`,
12
+ ]
13
+ .map(AddSemiColon.addSemicolon)
14
+ .join(Character.Space)
@@ -1,6 +1,6 @@
1
+ import { writeFileSync } from 'node:fs'
1
2
  import { Session } from 'node:inspector'
2
3
  import * as Timeout from '../Timeout/Timeout.js'
3
- import { writeFileSync } from 'node:fs'
4
4
 
5
5
  export const createProfile = async () => {
6
6
  const session = new Session()
@@ -1,7 +1,7 @@
1
1
  import { writeFile } from 'node:fs/promises'
2
- import got from 'got'
3
2
  import { tmpdir } from 'node:os'
4
3
  import { join } from 'node:path'
4
+ import got from 'got'
5
5
  import { WebSocket } from 'ws'
6
6
  import * as DevtoolsProtocolRpc from '../DevtoolsProtocolRpc/DevtoolsProtocolRpc.js'
7
7
 
@@ -29,7 +29,7 @@ export const createCpuProfile = async (pid) => {
29
29
  // AttachDebugger.attachDebugger(pid)
30
30
  const response = await got('http://localhost:9229/json/list').json()
31
31
  const first = response[0]
32
- const webSocketDebuggerUrl = first.webSocketDebuggerUrl
32
+ const { webSocketDebuggerUrl } = first
33
33
  const ipc = createConnection(webSocketDebuggerUrl)
34
34
 
35
35
  await new Promise((r) => {
@@ -37,7 +37,7 @@ export const createCpuProfile = async (pid) => {
37
37
  })
38
38
  const rpc = DevtoolsProtocolRpc.create(ipc)
39
39
  const result = await rpc.invoke('Debugger.enable')
40
- const debuggerId = result.result.debuggerId
40
+ const { debuggerId } = result.result
41
41
  console.log({ debuggerId })
42
42
  const p = await rpc.invoke('Profiler.enable')
43
43
  await rpc.invoke('Profiler.start')
@@ -46,7 +46,7 @@ export const createCpuProfile = async (pid) => {
46
46
  })
47
47
  const profileResult = await rpc.invoke('Profiler.stop')
48
48
  console.log({ profileResult })
49
- const profile = profileResult.result.profile
49
+ const { profile } = profileResult.result
50
50
  const profilePath = join(tmpdir(), 'node-profile.cpuprofile')
51
51
  const profileString = JSON.stringify(profile)
52
52
  await writeFile(profilePath, profileString)
@@ -0,0 +1,2 @@
1
+ export const key = 'Cross-Origin-Embedder-Policy'
2
+ export const value = 'require-corp'
@@ -0,0 +1,2 @@
1
+ export const key = 'Cross-Origin-Opener-Policy'
2
+ export const value = 'same-origin'
@@ -18,4 +18,4 @@ export const getRipGrepPath = () => {
18
18
  return process.env.RIP_GREP_PATH
19
19
  }
20
20
 
21
- export const env = process.env
21
+ export const {env} = process
@@ -1,5 +1,5 @@
1
- import * as Assert from '../Assert/Assert.js'
2
1
  import { execa } from 'execa'
2
+ import * as Assert from '../Assert/Assert.js'
3
3
 
4
4
  /**
5
5
  *
@@ -1,8 +1,8 @@
1
- import { isAbsolute, join } from 'path'
1
+ import { existsSync } from 'node:fs'
2
+ import { isAbsolute, join } from 'node:path'
2
3
  import * as FileSystem from '../FileSystem/FileSystem.js'
3
4
  import * as JsonFile from '../JsonFile/JsonFile.js'
4
5
  import * as Path from '../Path/Path.js'
5
- import { existsSync } from 'fs'
6
6
 
7
7
  // TODO
8
8
  // - implement this for syntax highlighting projects
@@ -185,7 +185,7 @@ const applyOverrides = async ({ root, commitHash, pathPrefix }) => {
185
185
  )
186
186
  }
187
187
  await replace(Path.join(root, 'dist', 'index.html'), `/${commitHash}`, `${pathPrefix}/${commitHash}`)
188
- await replace(Path.join(root, 'dist', 'index.html'), `/manifest.json`, `${pathPrefix}/manifest.json`)
188
+ await replace(Path.join(root, 'dist', 'index.html'), `/${commitHash}/manifest.json`, `${pathPrefix}/${commitHash}/manifest.json`)
189
189
 
190
190
  if (pathPrefix) {
191
191
  await replace(
@@ -203,18 +203,18 @@ const applyOverrides = async ({ root, commitHash, pathPrefix }) => {
203
203
  )
204
204
  }
205
205
  if (pathPrefix) {
206
- await replace(Path.join(root, 'dist', 'manifest.json'), `/${commitHash}`, `${pathPrefix}/${commitHash}`)
207
- await replace(Path.join(root, 'dist', 'manifest.json'), `"start_url": "/"`, `"start_url": "${pathPrefix}"`)
206
+ await replace(Path.join(root, 'dist', commitHash, 'manifest.json'), `/${commitHash}`, `${pathPrefix}/${commitHash}`)
207
+ await replace(Path.join(root, 'dist', commitHash, 'manifest.json'), `"start_url": "/"`, `"start_url": "${pathPrefix}"`)
208
208
  await replace(Path.join(root, 'dist', commitHash, 'css', 'App.css'), `/${commitHash}`, `${pathPrefix}/${commitHash}`)
209
209
  await replace(Path.join(root, 'dist', commitHash, 'css', 'parts', 'Symbol.css'), `/${commitHash}`, `${pathPrefix}/${commitHash}`)
210
210
  }
211
211
  }
212
212
 
213
- const addExtensionSeo = async ({ root, name, description }) => {
213
+ const addExtensionSeo = async ({ root, name, description, commitHash }) => {
214
214
  await replace(Path.join(root, 'dist', 'index.html'), '<title>Code Editor</title>', `<title>${name}</title>`)
215
- await replace(Path.join(root, 'dist', 'manifest.json'), `"name": "Code Editor Web - OSS"`, `"name": "${name}"`)
216
- await replace(Path.join(root, 'dist', 'manifest.json'), `"short_name": "Web - OSS"`, `"short_name": "${name}"`)
217
- await replace(Path.join(root, 'dist', 'manifest.json'), `"description": "Web Code Editor."`, `"description": "${description}"`)
215
+ await replace(Path.join(root, 'dist', commitHash, 'manifest.json'), `"name": "Code Editor Web - OSS"`, `"name": "${name}"`)
216
+ await replace(Path.join(root, 'dist', commitHash, 'manifest.json'), `"short_name": "Web - OSS"`, `"short_name": "${name}"`)
217
+ await replace(Path.join(root, 'dist', commitHash, 'manifest.json'), `"description": "Web Code Editor."`, `"description": "${description}"`)
218
218
  await replace(
219
219
  Path.join(root, 'dist', 'index.html'),
220
220
  '<meta name="description" content="Online Code Editor" />',
@@ -340,6 +340,7 @@ const addExtension = async ({ root, extensionPath, commitHash, pathPrefix }) =>
340
340
  const description = extensionJson.description || ''
341
341
  await addExtensionSeo({
342
342
  root,
343
+ commitHash,
343
344
  name,
344
345
  description,
345
346
  })
@@ -1,4 +1,4 @@
1
- import { readlink } from 'fs/promises'
1
+ import { readlink } from 'node:fs/promises'
2
2
  import * as ExtensionManifest from '../ExtensionManifest/ExtensionManifest.js'
3
3
  import * as ExtensionManifestStatus from '../ExtensionManifestStatus/ExtensionManifestStatus.js'
4
4
  import * as FileSystem from '../FileSystem/FileSystem.js'
@@ -20,7 +20,7 @@ const readSymlinks = (absolutePaths) => {
20
20
  }
21
21
 
22
22
  const mergeWithSymLinks = (manifests, symlinks) => {
23
- const length = manifests.length
23
+ const {length} = manifests
24
24
  const merged = []
25
25
  for (let i = 0; i < length; i++) {
26
26
  const manifest = manifests[i]
@@ -0,0 +1,7 @@
1
+ import * as GetElectronFileResponse from './GetElectronFileResponse.js'
2
+
3
+ export const name = 'GetElectronFileResponse'
4
+
5
+ export const Commands = {
6
+ getElectronFileResponse: GetElectronFileResponse.getElectronFileResponse,
7
+ }
@@ -0,0 +1,23 @@
1
+ import { readFile } from 'fs/promises'
2
+ import * as GetElectronFileResponseAbsolutePath from '../GetElectronFileResponseAbsolutePath/GetElectronFileResponseAbsolutePath.js'
3
+ import * as GetElectronFileResponseRelativePath from '../GetElectronFileResponseRelativePath/GetElectronFileResponseRelativePath.js'
4
+ import * as GetHeaders from '../GetHeaders/GetHeaders.js'
5
+ import * as Platform from '../Platform/Platform.js'
6
+
7
+ export const getElectronFileResponse = async (url) => {
8
+ const pathName = GetElectronFileResponseRelativePath.getElectronFileResponseRelativePath(url)
9
+ const absolutePath = GetElectronFileResponseAbsolutePath.getElectronFileResponseAbsolutePath(pathName)
10
+ let content = await readFile(absolutePath)
11
+ if (!Platform.isProduction && url === `${Platform.scheme}://-/`) {
12
+ // @ts-ignore
13
+ content = content.toString().replace(' <link rel="manifest" href="/manifest.json" crossorigin="use-credentials" />\n', '')
14
+ }
15
+ const headers = GetHeaders.getHeaders(absolutePath)
16
+ return {
17
+ body: content,
18
+ init: {
19
+ status: 200,
20
+ headers,
21
+ },
22
+ }
23
+ }
@@ -0,0 +1,35 @@
1
+ import { tmpdir } from 'node:os'
2
+ import { join } from 'node:path'
3
+ import { fileURLToPath } from 'node:url'
4
+ import * as Path from '../Path/Path.js'
5
+ import * as Platform from '../Platform/Platform.js'
6
+ import * as Root from '../Root/Root.js'
7
+
8
+ export const getElectronFileResponseAbsolutePath = (pathName) => {
9
+ // TODO remove if/else in prod (use replacement)
10
+ if (pathName === `/` || pathName.startsWith(`/?`)) {
11
+ return Path.join(Root.root, 'static', 'index.html')
12
+ }
13
+ if (pathName.startsWith(`/packages`)) {
14
+ return Path.join(Root.root, pathName)
15
+ }
16
+ if (pathName.startsWith(`/static`)) {
17
+ return Path.join(Root.root, pathName)
18
+ }
19
+ if (pathName.startsWith(`/extensions`)) {
20
+ return Path.join(Root.root, pathName)
21
+ }
22
+ // TODO maybe have a separate protocol for remote, e.g. vscode has vscode-remote
23
+ if (pathName.startsWith(`/remote`)) {
24
+ const uri = pathName.slice('/remote'.length)
25
+ if (Platform.isWindows) {
26
+ return fileURLToPath(`file://` + uri)
27
+ }
28
+ return uri
29
+ }
30
+ if (pathName.startsWith('/process-explorer/process-explorer-theme.css')) {
31
+ const processExplorerThemeCss = join(tmpdir(), 'process-explorer-theme.css')
32
+ return processExplorerThemeCss
33
+ }
34
+ return Path.join(Root.root, 'static', pathName)
35
+ }
@@ -0,0 +1,8 @@
1
+ import * as Platform from '../Platform/Platform.js'
2
+
3
+ export const getElectronFileResponseRelativePath = (requestUrl) => {
4
+ const decoded = decodeURI(requestUrl)
5
+ const { scheme } = Platform
6
+ const pathName = decoded.slice(`${scheme}://-`.length)
7
+ return pathName
8
+ }
@@ -1,4 +1,5 @@
1
1
  import * as FirstWebSocketEventType from '../FirstWebSocketEventType/FirstWebSocketEventType.js'
2
+ import * as GetFirstEvent from '../GetFirstEvent/GetFirstEvent.js'
2
3
  import * as WebSocketReadyState from '../WebSocketReadyState/WebSocketReadyState.js'
3
4
 
4
5
  export const getFirstWebSocketEvent = async (webSocket) => {
@@ -16,26 +17,9 @@ export const getFirstWebSocketEvent = async (webSocket) => {
16
17
  default:
17
18
  break
18
19
  }
19
- const { type, event } = await new Promise((resolve) => {
20
- const cleanup = (value) => {
21
- webSocket.off('open', handleOpen)
22
- webSocket.off('close', handleClose)
23
- resolve(value)
24
- }
25
- const handleOpen = (event) => {
26
- cleanup({
27
- type: FirstWebSocketEventType.Open,
28
- event,
29
- })
30
- }
31
- const handleClose = (event) => {
32
- cleanup({
33
- type: FirstWebSocketEventType.Close,
34
- event,
35
- })
36
- }
37
- webSocket.on('open', handleOpen)
38
- webSocket.on('close', handleClose)
20
+ const { type, event } = await GetFirstEvent.getFirstEvent(webSocket, {
21
+ open: FirstWebSocketEventType.Open,
22
+ close: FirstWebSocketEventType.Close,
39
23
  })
40
24
  return { type, event }
41
25
  }
@@ -0,0 +1,52 @@
1
+ import { extname } from 'path'
2
+ import * as ContentSecurityPolicy from '../ContentSecurityPolicy/ContentSecurityPolicy.js'
3
+ import * as ContentSecurityPolicyWorker from '../ContentSecurityPolicyWorker/ContentSecurityPolicyWorker.js'
4
+ import * as CrossOriginEmbedderPolicy from '../CrossOriginEmbedderPolicy/CrossOriginEmbedderPolicy.js'
5
+ import * as CrossOriginOpenerPolicy from '../CrossOriginOpenerPolicy/CrossOriginOpenerPolicy.js'
6
+ import * as GetMimeType from '../GetMimeType/GetMimeType.js'
7
+
8
+ const getHeadersMainFrame = () => {
9
+ return {
10
+ [ContentSecurityPolicy.key]: ContentSecurityPolicy.value,
11
+ [CrossOriginOpenerPolicy.key]: CrossOriginOpenerPolicy.value,
12
+ [CrossOriginEmbedderPolicy.key]: CrossOriginEmbedderPolicy.value,
13
+ }
14
+ }
15
+
16
+ const getHeadersWorker = () => {
17
+ return {
18
+ [CrossOriginEmbedderPolicy.key]: CrossOriginEmbedderPolicy.value,
19
+ [ContentSecurityPolicyWorker.key]: ContentSecurityPolicyWorker.value,
20
+ }
21
+ }
22
+
23
+ const getHeadersDefault = () => {
24
+ return {}
25
+ }
26
+
27
+ const getExtraHeaders = (url, fileExtension) => {
28
+ switch (fileExtension) {
29
+ case '.html':
30
+ return getHeadersMainFrame()
31
+ case '.js':
32
+ if (url.endsWith('WorkerMain.js')) {
33
+ return getHeadersWorker()
34
+ }
35
+ return getHeadersDefault()
36
+ default:
37
+ return getHeadersDefault()
38
+ }
39
+ }
40
+
41
+ export const getHeaders = (absolutePath) => {
42
+ const extension = extname(absolutePath)
43
+ const mime = GetMimeType.getMimeType(extension)
44
+ const headers = {
45
+ 'Content-Type': mime,
46
+ }
47
+ const extraHeaders = getExtraHeaders(absolutePath, extension)
48
+ return {
49
+ ...headers,
50
+ ...extraHeaders,
51
+ }
52
+ }
@@ -0,0 +1,23 @@
1
+ import * as MimeType from '../MimeType/MimeType.js'
2
+
3
+ export const getMimeType = (fileExtension) => {
4
+ switch (fileExtension) {
5
+ case '.html':
6
+ return MimeType.TextHtml
7
+ case '.css':
8
+ return MimeType.TextCss
9
+ case '.ttf':
10
+ return MimeType.FontTtf
11
+ case '.js':
12
+ return MimeType.TextJavaScript
13
+ case '.svg':
14
+ return MimeType.ImageSvgXml
15
+ case '.png':
16
+ return MimeType.ImagePng
17
+ case '.json':
18
+ return MimeType.ApplicationJson
19
+ default:
20
+ console.warn(`unsupported file extension: ${fileExtension}`)
21
+ return ''
22
+ }
23
+ }
@@ -1,7 +1,7 @@
1
- import { VError } from '../VError/VError.js'
2
1
  import { execFile as _execFile } from 'node:child_process'
3
- import * as Signal from '../Signal/Signal.js'
4
2
  import { promisify } from 'node:util'
3
+ import * as Signal from '../Signal/Signal.js'
4
+ import { VError } from '../VError/VError.js'
5
5
 
6
6
  const execFile = promisify(_execFile)
7
7
 
@@ -14,7 +14,6 @@ export const getPsOutput = async () => {
14
14
  if (error && error.signal === Signal.SIGINT) {
15
15
  return ''
16
16
  }
17
- // @ts-ignore
18
17
  throw new VError(error, `Failed to execute ps`)
19
18
  }
20
19
  }
@@ -1,6 +1,6 @@
1
+ import * as Os from 'node:os'
1
2
  import * as Platform from '../Platform/Platform.js'
2
3
  import * as ByteSize from '../ByteSize/ByteSize.js'
3
- import * as Os from 'node:os'
4
4
 
5
5
  const UiStrings = {
6
6
  OsVersion: 'Os Version',
@@ -11,7 +11,7 @@ const UiStrings = {
11
11
  const visitVersion = {
12
12
  key: UiStrings.OsVersion,
13
13
  getValue() {
14
- const version = Platform.version
14
+ const { version } = Platform
15
15
  return version
16
16
  },
17
17
  }
@@ -24,9 +24,9 @@ const visitCpus = {
24
24
  return ''
25
25
  }
26
26
  const firstCpu = cpus[0]
27
- const model = firstCpu.model
27
+ const { model } = firstCpu
28
28
  const cpuLength = cpus.length
29
- const speed = firstCpu.speed
29
+ const { speed } = firstCpu
30
30
  return `${model} (${cpuLength} x ${speed})`
31
31
  },
32
32
  }
@@ -56,7 +56,7 @@ const combineVisitors = (visitors) => {
56
56
  const longestKeyLength = getLongestKeyLength(visitors)
57
57
  const result = []
58
58
  for (const visitor of visitors) {
59
- const key = visitor.key
59
+ const { key } = visitor
60
60
  const value = visitor.getValue()
61
61
  result.push(`${key}: ${value}`)
62
62
  }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @enum {string}
3
+ */
4
+ const UiStrings = {
5
+ File: 'File',
6
+ Edit: 'Edit',
7
+ Selection: 'Selection',
8
+ View: 'View',
9
+ Go: 'Go',
10
+ Run: 'Run',
11
+ Terminal: 'Terminal',
12
+ Window: 'Window',
13
+ Help: 'Help',
14
+ }
15
+
16
+ export const getTitleBarItems = () => {
17
+ return [
18
+ {
19
+ label: UiStrings.File,
20
+ },
21
+ {
22
+ label: UiStrings.Edit,
23
+ },
24
+ {
25
+ label: UiStrings.Selection,
26
+ },
27
+ {
28
+ label: UiStrings.View,
29
+ },
30
+ {
31
+ label: UiStrings.Go,
32
+ },
33
+ {
34
+ label: UiStrings.Run,
35
+ },
36
+ {
37
+ label: UiStrings.Terminal,
38
+ },
39
+ {
40
+ label: UiStrings.Window,
41
+ },
42
+ {
43
+ label: UiStrings.Help,
44
+ },
45
+ ]
46
+ }
@@ -7,7 +7,7 @@ export const handleWebSocket = async (message, handle) => {
7
7
  try {
8
8
  Assert.object(message)
9
9
  Assert.object(handle)
10
- const headers = message.headers
10
+ const { headers } = message
11
11
  if (!headers) {
12
12
  throw new VError('missing websocket headers')
13
13
  }
@@ -0,0 +1 @@
1
+ export const ContentType = 'Content-Type'
@@ -1,6 +1,6 @@
1
1
  export const listen = () => {
2
2
  // @ts-ignore
3
- const parentPort = process.parentPort
3
+ const { parentPort } = process
4
4
  if (!parentPort) {
5
5
  throw new Error('parent port must be defined')
6
6
  }
@@ -1,8 +1,8 @@
1
- import * as Assert from '../Assert/Assert.js'
2
1
  import { fork } from 'node:child_process'
3
- import * as GetFirstNodeChildProcessEvent from '../GetFirstNodeChildProcessEvent/GetFirstNodeChildProcessEvent.js'
4
- import * as FirstNodeWorkerEventType from '../FirstNodeWorkerEventType/FirstNodeWorkerEventType.js'
2
+ import * as Assert from '../Assert/Assert.js'
5
3
  import { ChildProcessError } from '../ChildProcessError/ChildProcessError.js'
4
+ import * as FirstNodeWorkerEventType from '../FirstNodeWorkerEventType/FirstNodeWorkerEventType.js'
5
+ import * as GetFirstNodeChildProcessEvent from '../GetFirstNodeChildProcessEvent/GetFirstNodeChildProcessEvent.js'
6
6
  import { VError } from '../VError/VError.js'
7
7
 
8
8
  export const create = async ({ path, argv = [], env, execArgv = [], stdio = 'inherit', name = 'child process' }) => {
@@ -0,0 +1,37 @@
1
+ export const ApplicationFontWoff = 'application/font-woff'
2
+ export const ApplicationJson = 'aplication/json'
3
+ export const AudioMidi = 'audio/midi'
4
+ export const AudioMpeg = 'audio/mpeg'
5
+ export const AudioOgg = 'audio/ogg'
6
+ export const AudioOpus = 'audio/opus'
7
+ export const AudioXaac = 'audio/x-aac'
8
+ export const AudioXMsWma = 'audio/x-ms-wma'
9
+ export const AudioXWav = 'audio/x-wav'
10
+ export const FontTtf = 'font/ttf'
11
+ export const ImageAvif = 'image/avif'
12
+ export const ImageBmp = 'image/bmp'
13
+ export const ImageGif = 'image/gif'
14
+ export const ImageJpg = 'image/jpg'
15
+ export const ImagePng = 'image/png'
16
+ export const ImageSvgXml = 'image/svg+xml'
17
+ export const ImageTiff = 'image/tiff'
18
+ export const ImageVndAdobePhotoShop = 'image/vnd.adobe.photoshop'
19
+ export const ImageWebp = 'image/webp'
20
+ export const ImageXIcon = 'image/x-icon'
21
+ export const ImageXTga = 'image/x-tga'
22
+ export const TextCalendar = 'text/calendar'
23
+ export const TextCss = 'text/css'
24
+ export const TextCvs = 'text/csv'
25
+ export const TextHtml = 'text/html'
26
+ export const TextJavaScript = 'text/javascript'
27
+ export const TextPlain = 'text/plain'
28
+ export const TextXml = 'text/xml'
29
+ export const VideoMp4 = 'video/mp4'
30
+ export const VideoMpeg = 'video/mpeg'
31
+ export const VideoQuickTime = 'video/quicktime'
32
+ export const VideoWebm = 'video/webm'
33
+ export const VideoXFlv = 'video/x-flv'
34
+ export const VideoXMatroska = 'video/x-matroska'
35
+ export const VideoXMsVideo = 'video/x-msvideo'
36
+ export const VideoXMsWmv = 'video/x-ms-wmv'
37
+ export const VideoXSgiMovie = 'video/x-sgi-movie'
@@ -134,6 +134,8 @@ export const load = (moduleId) => {
134
134
  return import('../HandleMessagePortForTerminalProcess/HandleMessagePortForTerminalProcess.ipc.js')
135
135
  case ModuleId.TemporaryMessagePort:
136
136
  return import('../TemporaryMessagePort/TemporaryMessagePort.ipc.js')
137
+ case ModuleId.GetElectronFileResponse:
138
+ return import('../GetElectronFileResponse/GetElectronFileResponse.ipc.js')
137
139
  default:
138
140
  throw new Error(`module ${moduleId} not found`)
139
141
  }
@@ -66,3 +66,4 @@ export const HandleElectronReady = 59
66
66
  export const HandleWindowAllClosed = 60
67
67
  export const HandleMessagePortForTerminalProcess = 61
68
68
  export const TemporaryMessagePort = 62
69
+ export const GetElectronFileResponse = 63
@@ -289,6 +289,8 @@ export const getModuleId = (commandId) => {
289
289
  return ModuleId.HandleMessagePortForTerminalProcess
290
290
  case 'TemporaryMessagePort.handlePort':
291
291
  return ModuleId.TemporaryMessagePort
292
+ case 'GetElectronFileResponse.getElectronFileResponse':
293
+ return ModuleId.GetElectronFileResponse
292
294
  default:
293
295
  throw new CommandNotFoundError(commandId)
294
296
  }
@@ -61,11 +61,11 @@ export const getSetupName = () => {
61
61
  return 'Lvce-Setup'
62
62
  }
63
63
 
64
- export const version = '0.21.3'
64
+ export const version = '0.21.5'
65
65
 
66
- export const commit = '21796c8'
66
+ export const commit = 'ce18293'
67
67
 
68
- export const date = '2023-12-16T09:10:52.000Z'
68
+ export const date = '2023-12-22T15:56:21.000Z'
69
69
 
70
70
  export const getVersion = () => {
71
71
  return version
@@ -6,11 +6,11 @@ export const toTextSearchResult = (parsedLine, remaining, charsBefore, charsAfte
6
6
  const parsedLineData = parsedLine.data
7
7
  const lines = ParseRipGrepLines.parseRipGrepLines(parsedLineData)
8
8
  const lineNumber = parsedLineData.line_number
9
- const submatches = parsedLineData.submatches
9
+ const { submatches } = parsedLineData
10
10
  const linesLength = lines.length
11
11
  for (const submatch of submatches) {
12
12
  const previewStart = Math.max(submatch.start - charsBefore, 0)
13
- let actualStart = previewStart
13
+ const actualStart = previewStart
14
14
  const previewEnd = Math.min(submatch.end + charsAfter, linesLength)
15
15
  const previewText = lines.slice(actualStart, previewEnd)
16
16
  results.push({
@@ -1,6 +0,0 @@
1
- export class AssertionError extends Error {
2
- constructor(message) {
3
- super(message)
4
- this.name = 'AssertionError'
5
- }
6
- }