@lvce-editor/shared-process 0.23.2 → 0.24.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/shared-process",
3
- "version": "0.23.2",
3
+ "version": "0.24.0",
4
4
  "main": "index.js",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -18,12 +18,12 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "@lvce-editor/assert": "^1.2.0",
21
- "@lvce-editor/extension-host-helper-process": "0.23.2",
21
+ "@lvce-editor/extension-host-helper-process": "0.24.0",
22
22
  "@lvce-editor/ipc": "^2.1.0",
23
23
  "@lvce-editor/json-rpc": "^1.0.0",
24
24
  "@lvce-editor/jsonc-parser": "^1.1.0",
25
25
  "@lvce-editor/pretty-error": "^1.5.0",
26
- "@lvce-editor/pty-host": "0.23.2",
26
+ "@lvce-editor/pty-host": "0.24.0",
27
27
  "@lvce-editor/verror": "^1.1.2",
28
28
  "@lvce-editor/web-socket-server": "^1.1.0",
29
29
  "debug": "^4.3.4",
@@ -0,0 +1,37 @@
1
+ import { readdir } from 'node:fs/promises'
2
+
3
+ const generateTestOverviewHtml = (dirents) => {
4
+ const pre = `<!DOCTYPE html>
5
+ <html lang="en">
6
+ <head>
7
+ <meta charset="UTF-8" />
8
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
9
+ <title>Tests</title>
10
+ </head>
11
+ <body>
12
+ <h1>Tests</h1>
13
+ <p>Available Tests</p>
14
+ <ul>
15
+ `
16
+ let middle = ``
17
+ // TODO properly escape name
18
+ for (const dirent of dirents) {
19
+ if (dirent.endsWith('.js') && !dirent.startsWith('_')) {
20
+ const name = dirent.slice(0, -'.js'.length)
21
+ middle += ` <li><a href="./${name}.html">${name}</a></li>
22
+ `
23
+ }
24
+ }
25
+
26
+ const post = ` </ul>
27
+ </body>
28
+ </html>
29
+ `
30
+ return pre + middle + post
31
+ }
32
+
33
+ export const createTestOverview = async (testPathSrc) => {
34
+ const dirents = await readdir(testPathSrc)
35
+ const testOverviewHtml = generateTestOverviewHtml(dirents)
36
+ return testOverviewHtml
37
+ }
@@ -0,0 +1,8 @@
1
+ import * as ElectronWebContentsView from './ElectronWebContentsView.js'
2
+
3
+ export const name = 'ElectronWebContentsView'
4
+
5
+ export const Commands = {
6
+ createWebContentsView: ElectronWebContentsView.createWebContentsView,
7
+ disposeWebContentsView: ElectronWebContentsView.disposeWebContentsView,
8
+ }
@@ -0,0 +1,15 @@
1
+ import * as ElectronWebContents from '../ElectronWebContents/ElectronWebContents.js'
2
+ import * as ParentIpc from '../ParentIpc/ParentIpc.js'
3
+
4
+ export const createWebContentsView = async (ipc, restoreId, fallthroughKeyBindings) => {
5
+ const webContentsId = await ParentIpc.invoke('ElectronWebContentsView.createWebContentsView', restoreId)
6
+ // TODO get window id from renderer worker
7
+ await ParentIpc.invoke('ElectronWebContentsView.attachEventListeners', webContentsId)
8
+ console.log({ webContentsId })
9
+ return webContentsId
10
+ }
11
+
12
+ export const disposeWebContentsView = async (id) => {
13
+ await ParentIpc.invoke('ElectronWebContentsView.disposeWebContentsView', id)
14
+ await ElectronWebContents.dispose(id)
15
+ }
@@ -0,0 +1,20 @@
1
+ import * as ElectronWebContentsViewFunctions from './ElectronWebContentsViewFunctions.js'
2
+
3
+ export const name = 'ElectronWebContentsViewFunctions'
4
+
5
+ export const Commands = {
6
+ resizeBrowserView: ElectronWebContentsViewFunctions.resizeBrowserView,
7
+ setIframeSrc: ElectronWebContentsViewFunctions.setIframeSrc,
8
+ focus: ElectronWebContentsViewFunctions.focus,
9
+ openDevtools: ElectronWebContentsViewFunctions.openDevtools,
10
+ reload: ElectronWebContentsViewFunctions.reload,
11
+ forward: ElectronWebContentsViewFunctions.forward,
12
+ backward: ElectronWebContentsViewFunctions.backward,
13
+ cancelNavigation: ElectronWebContentsViewFunctions.cancelNavigation,
14
+ show: ElectronWebContentsViewFunctions.show,
15
+ hide: ElectronWebContentsViewFunctions.hide,
16
+ inspectElement: ElectronWebContentsViewFunctions.inspectElement,
17
+ copyImageAt: ElectronWebContentsViewFunctions.copyImageAt,
18
+ setFallthroughKeyBindings: ElectronWebContentsViewFunctions.setFallthroughKeyBindings,
19
+ getStats: ElectronWebContentsViewFunctions.getStats,
20
+ }
@@ -0,0 +1,50 @@
1
+ import * as ParentIpc from '../ParentIpc/ParentIpc.js'
2
+ import * as ElectronWebContents from '../ElectronWebContents/ElectronWebContents.js'
3
+
4
+ export const resizeBrowserView = (id, x, y, width, height) => {
5
+ return ParentIpc.invoke('ElectronWebContentsViewFunctions.resizeBrowserView', id, x, y, width, height)
6
+ }
7
+
8
+ export const setIframeSrc = async (id, iframeSrc) => {
9
+ return ParentIpc.invoke('ElectronWebContentsViewFunctions.setIframeSrc', id, iframeSrc)
10
+ }
11
+
12
+ const callFunction = (id, functionName) => {
13
+ return ParentIpc.invoke('ElectronWebContents.callFunction', id, functionName)
14
+ }
15
+
16
+ export const focus = ElectronWebContents.focus
17
+
18
+ export const openDevtools = ElectronWebContents.openDevtools
19
+
20
+ export const reload = ElectronWebContents.reload
21
+
22
+ export const forward = ElectronWebContents.forward
23
+
24
+ export const backward = ElectronWebContents.backward
25
+
26
+ export const cancelNavigation = (id) => {
27
+ return ParentIpc.invoke('ElectronWebContentsViewFunctions.cancelNavigation', id)
28
+ }
29
+
30
+ export const show = (id) => {
31
+ return ParentIpc.invoke('ElectronWebContentsViewFunctions.show', id)
32
+ }
33
+
34
+ export const hide = (id) => {
35
+ return ParentIpc.invoke('ElectronWebContentsViewFunctions.hide', id)
36
+ }
37
+
38
+ export const inspectElement = ElectronWebContents.inspectElement
39
+
40
+ export const copyImageAt = (id, x, y) => {
41
+ return ParentIpc.invoke('ElectronWebContentsViewFunctions.copyImageAt', id, x, y)
42
+ }
43
+
44
+ export const setFallthroughKeyBindings = (fallthroughKeyBindings) => {
45
+ return ParentIpc.invoke('ElectronWebContentsViewFunctions.setFallthroughKeyBindings', fallthroughKeyBindings)
46
+ }
47
+
48
+ export const getStats = (id) => {
49
+ return ParentIpc.invoke('ElectronWebContents.getStats', id)
50
+ }
@@ -28,6 +28,7 @@ export const install = async ({ path }) => {
28
28
  }
29
29
  const outDir = Path.join(extensionsPath, id)
30
30
  await FileSystem.remove(outDir)
31
+ await FileSystem.mkdir(Path.dirname(outDir))
31
32
  await FileSystem.rename(cachedExtensionPath, outDir)
32
33
  } catch (error) {
33
34
  throw new VError(error, `Failed to install ${path}`)
@@ -5,6 +5,7 @@ import * as GetElectronFileResponseRelativePath from '../GetElectronFileResponse
5
5
  import * as GetEtag from '../GetEtag/GetEtag.js'
6
6
  import * as GetHeaders from '../GetHeaders/GetHeaders.js'
7
7
  import * as HttpStatusCode from '../HttpStatusCode/HttpStatusCode.js'
8
+ import * as GetNotFoundResponse from '../GetNotFoundResponse/GetNotFoundResponse.js'
8
9
  import * as IsEnoentError from '../IsEnoentError/IsEnoentError.js'
9
10
  import * as Logger from '../Logger/Logger.js'
10
11
 
@@ -26,7 +27,7 @@ export const getElectronFileResponse = async (url, request) => {
26
27
  }
27
28
  }
28
29
  }
29
- const content = await GetElectronFileResponseContent.getElectronFileResponseContent(absolutePath, url)
30
+ const content = await GetElectronFileResponseContent.getElectronFileResponseContent(request, absolutePath, url)
30
31
  const headers = GetHeaders.getHeaders(absolutePath)
31
32
  headers['Cache-Control'] = 'public, max-age=0, must-revalidate'
32
33
  if (etag) {
@@ -41,14 +42,7 @@ export const getElectronFileResponse = async (url, request) => {
41
42
  }
42
43
  } catch (error) {
43
44
  if (IsEnoentError.isEnoentError(error)) {
44
- return {
45
- body: 'not-found',
46
- init: {
47
- status: HttpStatusCode.NotFound,
48
- statusText: 'not-found',
49
- headers: {},
50
- },
51
- }
45
+ return GetNotFoundResponse.getNotFoundResponse()
52
46
  }
53
47
  Logger.error(error)
54
48
  return {
@@ -1,26 +1,13 @@
1
1
  import { readFile } from 'node:fs/promises'
2
- import * as IsTypeScriptPath from '../IsTypeScriptPath/IsTypeScriptPath.js'
3
2
  import * as Platform from '../Platform/Platform.js'
4
- import * as Preferences from '../Preferences/Preferences.js'
3
+ import * as ShouldTranspileTypescript from '../ShouldTranspileTypescript/ShouldTranspileTypescript.js'
5
4
  import * as TranspileTypeScript from '../TranspileTypeScript/TranspileTypeScript.js'
6
5
 
7
- let cachedPreferences = undefined
8
-
9
- const getPreferences = () => {
10
- if (!cachedPreferences) {
11
- cachedPreferences = Preferences.getAll()
12
- }
13
- return cachedPreferences
14
- }
15
-
16
- export const getElectronFileResponseContent = async (absolutePath, url) => {
6
+ export const getElectronFileResponseContent = async (request, absolutePath, url) => {
17
7
  let content = await readFile(absolutePath)
18
- if (IsTypeScriptPath.isTypeScriptPath(url)) {
19
- const preferences = await getPreferences()
20
- if (preferences['typescript.transpile'] || process.env['TRANSPILE_TYPESCRIPT']) {
21
- const newContent = await TranspileTypeScript.transpileTypeScript(content.toString())
22
- content = newContent.outputText
23
- }
8
+ if (ShouldTranspileTypescript.shouldTranspileTypescript(request, url)) {
9
+ const newContent = await TranspileTypeScript.transpileTypeScript(content.toString())
10
+ content = newContent.outputText
24
11
  }
25
12
  if (!Platform.isProduction && url === `${Platform.scheme}://-/`) {
26
13
  // @ts-ignore
@@ -0,0 +1,12 @@
1
+ import * as HttpStatusCode from '../HttpStatusCode/HttpStatusCode.js'
2
+
3
+ export const getNotFoundResponse = () => {
4
+ return {
5
+ body: 'not-found',
6
+ init: {
7
+ status: HttpStatusCode.NotFound,
8
+ statusText: 'not-found',
9
+ headers: {},
10
+ },
11
+ }
12
+ }
@@ -0,0 +1,4 @@
1
+ export const getPathName = (request) => {
2
+ const { pathname } = new URL(request.url || '', `https://${request.headers.host}`)
3
+ return pathname
4
+ }
@@ -0,0 +1,13 @@
1
+ import { isAbsolute, join } from 'path'
2
+ import * as Root from '../Root/Root.js'
3
+
4
+ export const getTestPath = () => {
5
+ if (process.env.TEST_PATH) {
6
+ const testPath = process.env.TEST_PATH
7
+ if (isAbsolute(testPath)) {
8
+ return testPath
9
+ }
10
+ return join(process.cwd(), testPath)
11
+ }
12
+ return join(Root.root, 'packages', 'extension-host-worker-tests')
13
+ }
@@ -0,0 +1,45 @@
1
+ import { readFile } from 'node:fs/promises'
2
+ import { join } from 'node:path'
3
+ import * as CreateTestOverview from '../CreateTestOverview/CreateTestOverview.js'
4
+ import * as CrossOriginEmbedderPolicy from '../CrossOriginEmbedderPolicy/CrossOriginEmbedderPolicy.js'
5
+ import * as CrossOriginOpenerPolicy from '../CrossOriginOpenerPolicy/CrossOriginOpenerPolicy.js'
6
+ import * as GetPathName from '../GetPathName/GetPathName.js'
7
+ import * as GetTestPath from '../GetTestPath/GetTestPath.js'
8
+ import * as HttpStatusCode from '../HttpStatusCode/HttpStatusCode.js'
9
+
10
+ export const getTestRequestResponse = async (request, indexHtmlPath) => {
11
+ const pathName = GetPathName.getPathName(request)
12
+ if (pathName.endsWith('.html')) {
13
+ const body = await readFile(indexHtmlPath, 'utf8')
14
+ return {
15
+ body,
16
+ init: {
17
+ status: HttpStatusCode.Ok,
18
+ headers: {},
19
+ },
20
+ }
21
+ }
22
+ if (pathName === '/tests/') {
23
+ const testPath = GetTestPath.getTestPath()
24
+ const testPathSrc = join(testPath, 'src')
25
+ const body = await CreateTestOverview.createTestOverview(testPathSrc)
26
+ return {
27
+ body,
28
+ init: {
29
+ status: HttpStatusCode.MultipleChoices,
30
+ headers: {
31
+ 'Cache-Control': 'public, max-age=0, must-revalidate',
32
+ [CrossOriginEmbedderPolicy.key]: CrossOriginEmbedderPolicy.value,
33
+ [CrossOriginOpenerPolicy.key]: CrossOriginOpenerPolicy.value,
34
+ 'Content-Security-Policy': "default-src 'none'",
35
+ },
36
+ },
37
+ }
38
+ }
39
+ return {
40
+ body: 'not-found',
41
+ init: {
42
+ status: HttpStatusCode.NotFound,
43
+ },
44
+ }
45
+ }
@@ -0,0 +1,7 @@
1
+ import * as HandleRequestTest from './HandleRequestTest.js'
2
+
3
+ export const name = 'HandleRequestTest'
4
+
5
+ export const Commands = {
6
+ handleRequestTest: HandleRequestTest.handleRequestTest,
7
+ }
@@ -0,0 +1,11 @@
1
+ import * as Assert from '../Assert/Assert.js'
2
+ import * as GetTestRequestResponse from '../GetTestRequestResponse/GetTestRequestResponse.js'
3
+ import * as HttpServerResponse from '../HttpServerResponse/HttpServerResponse.js'
4
+
5
+ export const handleRequestTest = async (request, indexHtmlPath, socket) => {
6
+ Assert.object(request)
7
+ Assert.string(indexHtmlPath)
8
+ Assert.object(socket)
9
+ const result = await GetTestRequestResponse.getTestRequestResponse(request, indexHtmlPath)
10
+ HttpServerResponse.send(request, socket, result)
11
+ }
@@ -2,3 +2,4 @@ export const NotFound = 404
2
2
  export const Ok = 200
3
3
  export const ServerError = 500
4
4
  export const NotModifed = 304
5
+ export const MultipleChoices = 300
@@ -58,6 +58,8 @@ export const load = (moduleId) => {
58
58
  return import('../ElectronWindowProcessExplorer/ElectronWindowProcessExplorer.ipc.js')
59
59
  case ModuleId.Exit:
60
60
  return import('../Exit/Exit.ipc.js')
61
+ case ModuleId.HandleRequestTest:
62
+ return import('../HandleRequestTest/HandleRequestTest.ipc.js')
61
63
  case ModuleId.ExtensionHost:
62
64
  return import('../ExtensionHost/ExtensionHost.ipc.js')
63
65
  case ModuleId.ExtensionManagement:
@@ -142,6 +144,10 @@ export const load = (moduleId) => {
142
144
  return import('../HandleMessagePortForExtensionHostHelperProcess/HandleMessagePortForExtensionHostHelperProcess.ipc.js')
143
145
  case ModuleId.ElectronWebContents:
144
146
  return import('../ElectronWebContents/ElectronWebContents.ipc.js')
147
+ case ModuleId.ElectronWebContentsView:
148
+ return import('../ElectronWebContentsView/ElectronWebContentsView.ipc.js')
149
+ case ModuleId.ElectronWebContentsViewFunctions:
150
+ return import('../ElectronWebContentsViewFunctions/ElectronWebContentsViewFunctions.ipc.js')
145
151
  default:
146
152
  throw new Error(`module ${moduleId} not found`)
147
153
  }
@@ -70,3 +70,6 @@ export const GetElectronFileResponse = 63
70
70
  export const HandleRemoteRequest = 64
71
71
  export const HandleMessagePortForExtensionHostHelperProcess = 65
72
72
  export const ElectronWebContents = 66
73
+ export const ElectronWebContentsView = 67
74
+ export const ElectronWebContentsViewFunctions = 68
75
+ export const HandleRequestTest = 69
@@ -151,6 +151,20 @@ export const getModuleId = (commandId) => {
151
151
  case 'ElectronBrowserViewFunctions.setFallthroughKeyBindings':
152
152
  case 'ElectronBrowserViewFunctions.getStats':
153
153
  return ModuleId.ElectronBrowserViewFunctions
154
+ case 'ElectronWebContentsViewFunctions.resizeBrowserView':
155
+ case 'ElectronWebContentsViewFunctions.setIframeSrc':
156
+ case 'ElectronWebContentsViewFunctions.focus':
157
+ case 'ElectronWebContentsViewFunctions.openDevtools':
158
+ case 'ElectronWebContentsViewFunctions.reload':
159
+ case 'ElectronWebContentsViewFunctions.forward':
160
+ case 'ElectronWebContentsViewFunctions.backward':
161
+ case 'ElectronWebContentsViewFunctions.cancelNavigation':
162
+ case 'ElectronWebContentsViewFunctions.hide':
163
+ case 'ElectronWebContentsViewFunctions.inspectElement':
164
+ case 'ElectronWebContentsViewFunctions.copyImageAt':
165
+ case 'ElectronWebContentsViewFunctions.setFallthroughKeyBindings':
166
+ case 'ElectronWebContentsViewFunctions.getStats':
167
+ return ModuleId.ElectronWebContentsViewFunctions
154
168
  case 'FileSystem.chmod':
155
169
  case 'FileSystem.copy':
156
170
  case 'FileSystem.createFile':
@@ -304,6 +318,11 @@ export const getModuleId = (commandId) => {
304
318
  case 'ElectronWebContents.handleContextMenu':
305
319
  case 'ElectronWebContents.handlePageTitleUpdated':
306
320
  return ModuleId.ElectronWebContents
321
+ case 'ElectronWebContentsView.createWebContentsView':
322
+ case 'ElectronWebContentsView.disposeWebContentsView':
323
+ return ModuleId.ElectronWebContentsView
324
+ case 'HandleRequestTest.handleRequestTest':
325
+ return ModuleId.HandleRequestTest
307
326
  default:
308
327
  throw new CommandNotFoundError(commandId)
309
328
  }
@@ -39,6 +39,15 @@ export const parseUrlGithub = (input) => {
39
39
  }
40
40
  }
41
41
  }
42
+
43
+ if (input.includes('/releases/download')) {
44
+ return {
45
+ type: ExtensionInstallType.Url,
46
+ options: {
47
+ url: input,
48
+ },
49
+ }
50
+ }
42
51
  return {
43
52
  type: ExtensionInstallType.ParsingError,
44
53
  options: {
@@ -61,11 +61,11 @@ export const getSetupName = () => {
61
61
  return 'Lvce-Setup'
62
62
  }
63
63
 
64
- export const version = '0.23.2'
64
+ export const version = '0.24.0'
65
65
 
66
- export const commit = '40414a1'
66
+ export const commit = 'b735813'
67
67
 
68
- export const date = '2024-02-12T18:48:06.000Z'
68
+ export const date = '2024-02-22T23:31:24.000Z'
69
69
 
70
70
  export const getVersion = () => {
71
71
  return version
@@ -0,0 +1,12 @@
1
+ import * as IsTypeScriptPath from '../IsTypeScriptPath/IsTypeScriptPath.js'
2
+
3
+ export const shouldTranspileTypescript = (request, url) => {
4
+ if (!IsTypeScriptPath.isTypeScriptPath(url)) {
5
+ return false
6
+ }
7
+ const acceptHeader = request.headers['accept']
8
+ if (acceptHeader === 'text/plain') {
9
+ return false
10
+ }
11
+ return true
12
+ }