@lvce-editor/shared-process 0.37.5 → 0.37.7

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.37.5",
3
+ "version": "0.37.7",
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.3.0",
21
- "@lvce-editor/extension-host-helper-process": "0.37.5",
21
+ "@lvce-editor/extension-host-helper-process": "0.37.7",
22
22
  "@lvce-editor/ipc": "^11.0.1",
23
23
  "@lvce-editor/json-rpc": "^4.2.0",
24
24
  "@lvce-editor/jsonc-parser": "^1.5.0",
@@ -35,7 +35,7 @@
35
35
  "@lvce-editor/preview-process": "^3.9.0",
36
36
  "@lvce-editor/pty-host": "^2.1.0",
37
37
  "@lvce-editor/search-process": "^3.2.0",
38
- "@lvce-editor/typescript-compile-process": "^1.4.0",
38
+ "@lvce-editor/typescript-compile-process": "^1.5.0",
39
39
  "open": "^10.1.0",
40
40
  "tail": "^2.2.6",
41
41
  "tmp-promise": "^3.0.3",
@@ -0,0 +1,15 @@
1
+ import * as FileSystemDisk from './FileSystemDisk.js';
2
+ export const name = 'FileSystemDisk';
3
+ export const Commands = {
4
+ chmod: FileSystemDisk.chmod,
5
+ copy: FileSystemDisk.copy,
6
+ getPathSeparator: FileSystemDisk.getPathSeparator,
7
+ mkdir: FileSystemDisk.mkdir,
8
+ readDirWithFileTypes: FileSystemDisk.readDirWithFileTypes,
9
+ readFile: FileSystemDisk.readFile,
10
+ readJson: FileSystemDisk.readJson,
11
+ remove: FileSystemDisk.remove,
12
+ rename: FileSystemDisk.rename,
13
+ stat: FileSystemDisk.stat,
14
+ writeFile: FileSystemDisk.writeFile,
15
+ };
@@ -0,0 +1,247 @@
1
+ // TODO lazyload chokidar and trash (but doesn't work currently because of bug with jest)
2
+ import * as fs from 'node:fs/promises';
3
+ import * as os from 'node:os';
4
+ import * as Assert from '../Assert/Assert.js';
5
+ import * as EncodingType from '../EncodingType/EncodingType.js';
6
+ import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js';
7
+ import { FileNotFoundError } from '../FileNotFoundError/FileNotFoundError.js';
8
+ import * as GetDirentType from '../GetDirentType/GetDirentType.js';
9
+ import * as IsEnoentError from '../IsEnoentError/IsEnoentError.js';
10
+ import * as Trash from '../Trash/Trash.js';
11
+ import { VError } from '../VError/VError.js';
12
+ import { fileURLToPath } from 'node:url';
13
+ const assertUri = (uri) => {
14
+ if (!uri.startsWith('file://')) {
15
+ throw new Error(`path must be a valid file uri`);
16
+ }
17
+ };
18
+ export const copy = async (sourceUri, targetUri) => {
19
+ try {
20
+ assertUri(sourceUri);
21
+ assertUri(targetUri);
22
+ const source = fileURLToPath(sourceUri);
23
+ const target = fileURLToPath(targetUri);
24
+ await fs.cp(source, target, { recursive: true });
25
+ }
26
+ catch (error) {
27
+ if (error && error.message && error.message.startsWith('Invalid src or dest: cp returned EINVAL (src and dest cannot be the same)')) {
28
+ throw new VError(`Failed to copy "${sourceUri}" to "${targetUri}": src and dest cannot be the same`);
29
+ }
30
+ throw new VError(error, `Failed to copy "${sourceUri}" to "${targetUri}"`);
31
+ }
32
+ };
33
+ /**
34
+ *
35
+ * @param {string} uri
36
+ * @param {BufferEncoding} encoding
37
+ * @returns
38
+ */
39
+ export const readFile = async (uri, encoding = EncodingType.Utf8) => {
40
+ try {
41
+ Assert.string(uri);
42
+ assertUri(uri);
43
+ const path = fileURLToPath(uri);
44
+ const content = await fs.readFile(path, encoding);
45
+ return content;
46
+ }
47
+ catch (error) {
48
+ if (IsEnoentError.isEnoentError(error)) {
49
+ throw new FileNotFoundError(uri);
50
+ }
51
+ throw new VError(error, `Failed to read file "${uri}"`);
52
+ }
53
+ };
54
+ /**
55
+ *
56
+ * @param {string} uri
57
+ * @param {string} content
58
+ * @param {BufferEncoding} encoding
59
+ */
60
+ export const writeFile = async (uri, content, encoding = EncodingType.Utf8) => {
61
+ try {
62
+ assertUri(uri);
63
+ Assert.string(uri);
64
+ Assert.string(content);
65
+ const path = fileURLToPath(uri);
66
+ // queue would be more correct for concurrent writes but also slower
67
+ // Queue.add(`writeFile/${path}`, () =>
68
+ await fs.writeFile(path, content, encoding);
69
+ }
70
+ catch (error) {
71
+ if (IsEnoentError.isEnoentError(error)) {
72
+ throw new FileNotFoundError(uri);
73
+ }
74
+ throw new VError(error, `Failed to write to file "${uri}"`);
75
+ }
76
+ };
77
+ const isOkayToRemove = (path) => {
78
+ if (path === '/') {
79
+ return false;
80
+ }
81
+ if (path === '~') {
82
+ return false;
83
+ }
84
+ if (path === os.homedir()) {
85
+ return false;
86
+ }
87
+ return true;
88
+ };
89
+ export const remove = async (uri) => {
90
+ assertUri(uri);
91
+ const path = fileURLToPath(uri);
92
+ if (!isOkayToRemove(path)) {
93
+ console.warn('not removing path');
94
+ return;
95
+ }
96
+ // TODO lazyload trash (doesn't work currently because of bug with jest)
97
+ // const { trash } = await import('../../wrap/trash.js')
98
+ try {
99
+ await Trash.trash(path);
100
+ }
101
+ catch (error) {
102
+ throw new VError(error, `Failed to remove "${uri}"`);
103
+ }
104
+ };
105
+ export const forceRemove = async (uri) => {
106
+ assertUri(uri);
107
+ const path = fileURLToPath(uri);
108
+ if (!isOkayToRemove(path)) {
109
+ console.warn('not removing path');
110
+ return;
111
+ }
112
+ try {
113
+ await fs.rm(path, { force: true, recursive: true });
114
+ }
115
+ catch (error) {
116
+ throw new VError(error, `Failed to remove "${uri}"`);
117
+ }
118
+ };
119
+ export const exists = async (uri) => {
120
+ try {
121
+ assertUri(uri);
122
+ const path = fileURLToPath(uri);
123
+ await fs.access(uri);
124
+ return true;
125
+ }
126
+ catch {
127
+ return false;
128
+ }
129
+ };
130
+ /**
131
+ * @param {import('fs').Dirent} dirent
132
+ */
133
+ const toPrettyDirent = (dirent) => {
134
+ return {
135
+ name: dirent.name,
136
+ type: GetDirentType.getDirentType(dirent),
137
+ };
138
+ };
139
+ export const readDirWithFileTypes = async (uri) => {
140
+ try {
141
+ assertUri(uri);
142
+ const path = fileURLToPath(uri);
143
+ const dirents = await fs.readdir(path, { withFileTypes: true });
144
+ const prettyDirents = dirents.map(toPrettyDirent);
145
+ return prettyDirents;
146
+ }
147
+ catch (error) {
148
+ throw new VError(error, `Failed to read directory "${uri}"`);
149
+ }
150
+ };
151
+ export const readDir = async (uri) => {
152
+ try {
153
+ const path = fileURLToPath(uri);
154
+ const dirents = await fs.readdir(path);
155
+ return dirents;
156
+ }
157
+ catch (error) {
158
+ if (IsEnoentError.isEnoentError(error)) {
159
+ throw new FileNotFoundError(uri);
160
+ }
161
+ throw new VError(error, `Failed to read directory "${uri}"`);
162
+ }
163
+ };
164
+ export const mkdir = async (uri) => {
165
+ try {
166
+ assertUri(uri);
167
+ const path = fileURLToPath(uri);
168
+ await fs.mkdir(path, { recursive: true });
169
+ }
170
+ catch (error) {
171
+ throw new VError(error, `Failed to create directory "${uri}"`);
172
+ }
173
+ };
174
+ const fallbackRename = async (oldUri, newUri) => {
175
+ try {
176
+ const oldPath = fileURLToPath(oldUri);
177
+ const newPath = fileURLToPath(newUri);
178
+ await fs.cp(oldPath, newPath, { recursive: true });
179
+ await fs.rm(oldPath, { recursive: true });
180
+ }
181
+ catch (error) {
182
+ throw new VError(error, `Failed to rename "${oldUri}" to "${newUri}"`);
183
+ }
184
+ };
185
+ export const rename = async (oldUri, newUri) => {
186
+ try {
187
+ const oldPath = fileURLToPath(oldUri);
188
+ const newPath = fileURLToPath(newUri);
189
+ await fs.rename(oldPath, newPath);
190
+ }
191
+ catch (error) {
192
+ if (error && error.code === ErrorCodes.EXDEV) {
193
+ return fallbackRename(oldUri, newUri);
194
+ }
195
+ throw new VError(error, `Failed to rename "${oldUri}" to "${newUri}"`);
196
+ }
197
+ };
198
+ export const getPathSeparator = () => {
199
+ return '/';
200
+ };
201
+ // TODO handle error
202
+ export const stat = async (uri) => {
203
+ const path = fileURLToPath(uri);
204
+ const stats = await fs.stat(path);
205
+ const type = GetDirentType.getDirentType(stats);
206
+ return type;
207
+ };
208
+ export const chmod = async (uri, permissions) => {
209
+ const path = fileURLToPath(uri);
210
+ await fs.chmod(path, permissions);
211
+ };
212
+ export const copyFile = async (fromUri, toUri) => {
213
+ try {
214
+ const fromPath = fileURLToPath(fromUri);
215
+ const toPath = fileURLToPath(toUri);
216
+ await fs.copyFile(fromPath, toPath);
217
+ }
218
+ catch (error) {
219
+ throw new VError(error, `Failed to copy file from ${fromUri} to ${toUri}`);
220
+ }
221
+ };
222
+ export const cp = async (fromUri, toUri) => {
223
+ try {
224
+ const fromPath = fileURLToPath(fromUri);
225
+ const toPath = fileURLToPath(toUri);
226
+ await fs.cp(fromPath, toPath, { recursive: true });
227
+ }
228
+ catch (error) {
229
+ throw new VError(error, `Failed to copy folder from ${fromUri} to ${toUri}`);
230
+ }
231
+ };
232
+ export const readJson = async (uri) => {
233
+ try {
234
+ Assert.string(uri);
235
+ assertUri(uri);
236
+ const path = fileURLToPath(uri);
237
+ const content = await fs.readFile(path, 'utf8');
238
+ const parsed = JSON.parse(content);
239
+ return parsed;
240
+ }
241
+ catch (error) {
242
+ if (IsEnoentError.isEnoentError(error)) {
243
+ throw new FileNotFoundError(uri);
244
+ }
245
+ throw new VError(error, `Failed to read file as json "${uri}"`);
246
+ }
247
+ };
@@ -133,6 +133,8 @@ export const load = (moduleId) => {
133
133
  return import('../WebViewServer/WebViewServer.ipc.js');
134
134
  case ModuleId.GetExtensions:
135
135
  return import('../GetExtensions/GetExtensions.ipc.js');
136
+ case ModuleId.FileSystemDisk:
137
+ return import('../FileSystemDisk/FileSystemDisk.ipc.js');
136
138
  default:
137
139
  throw new Error(`module ${moduleId} not found`);
138
140
  }
@@ -70,3 +70,4 @@ export const FileWatcher = 75;
70
70
  export const WebViewServer = 76;
71
71
  export const Transferrable = 77;
72
72
  export const GetExtensions = 78;
73
+ export const FileSystemDisk = 79;
@@ -288,6 +288,18 @@ export const getModuleId = (commandId) => {
288
288
  return ModuleId.WebViewServer;
289
289
  case 'GetExtensions.getExtensions':
290
290
  return ModuleId.GetExtensions;
291
+ case 'FileSystemDisk.chmod':
292
+ case 'FileSystemDisk.copy':
293
+ case 'FileSystemDisk.getPathSeparator':
294
+ case 'FileSystemDisk.mkdir':
295
+ case 'FileSystemDisk.readDirWithFileTypes':
296
+ case 'FileSystemDisk.readFile':
297
+ case 'FileSystemDisk.remove':
298
+ case 'FileSystemDisk.rename':
299
+ case 'FileSystemDisk.stat':
300
+ case 'FileSystemDisk.readJson':
301
+ case 'FileSystemDisk.writeFile':
302
+ return ModuleId.FileSystemDisk;
291
303
  default:
292
304
  throw new CommandNotFoundError(commandId);
293
305
  }
@@ -41,9 +41,9 @@ export const getAppImageName = () => {
41
41
  export const getSetupName = () => {
42
42
  return 'Lvce-Setup';
43
43
  };
44
- export const version = '0.37.5';
45
- export const commit = '57c2788';
46
- export const date = '2024-10-25T22:31:28.000Z';
44
+ export const version = '0.37.7';
45
+ export const commit = '3c2c8cd';
46
+ export const date = '2024-10-28T20:46:02.000Z';
47
47
  export const getVersion = () => {
48
48
  return version;
49
49
  };
@@ -0,0 +1,73 @@
1
+ import { homedir } from 'node:os';
2
+ import { isAbsolute, join, resolve } from 'node:path';
3
+ import { pathToFileURL } from 'node:url';
4
+ import * as Env from '../Env/Env.js';
5
+ import * as GetWorkspaceId from '../GetWorkspaceId/GetWorkspaceId.js';
6
+ import * as IsAbsolutePath from '../IsAbsolutePath/IsAbsolutePath.js';
7
+ import * as IsElectron from '../IsElectron/IsElectron.js';
8
+ import * as ParentIpc from '../ParentIpc/ParentIpc.js';
9
+ import * as Platform from '../Platform/Platform.js';
10
+ import * as PlatformPaths from '../PlatformPaths/PlatformPaths.js';
11
+ import * as Root from '../Root/Root.js';
12
+ import * as WorkspaceSource from '../WorkspaceSource/WorkspaceSource.js';
13
+ const getAbsolutePath = (path) => {
14
+ if (IsAbsolutePath.isAbsolutePath(path)) {
15
+ return path;
16
+ }
17
+ if (path.startsWith('${cwd}')) {
18
+ path = Root.root + path.slice(5);
19
+ }
20
+ else if (path.startsWith('~')) {
21
+ path = `${homedir()}${path.slice(1)}`;
22
+ }
23
+ path = resolve(path);
24
+ return path;
25
+ };
26
+ const toUri = (path) => {
27
+ return pathToFileURL(path).toString();
28
+ };
29
+ export const resolveRoot = async () => {
30
+ if (IsElectron.isElectron) {
31
+ const argv = await ParentIpc.invoke('Process.getArgv');
32
+ const relevantArgv = argv.slice(2);
33
+ const last = relevantArgv.at(-1);
34
+ if (last && isAbsolute(last)) {
35
+ return {
36
+ path: last,
37
+ uri: toUri(last),
38
+ workspaceId: GetWorkspaceId.getWorkspaceId(last),
39
+ homeDir: PlatformPaths.getHomeDir(),
40
+ homeDirUri: toUri(PlatformPaths.getHomeDir()),
41
+ pathSeparator: Platform.getPathSeparator(),
42
+ source: 'shared-process-default',
43
+ };
44
+ }
45
+ }
46
+ // TODO shared process should have no logic, this should probably be somewhere else
47
+ const folder = Env.getFolder();
48
+ if (!folder) {
49
+ const path = join(Root.root, 'playground');
50
+ return {
51
+ path,
52
+ uri: toUri(path),
53
+ workspaceId: GetWorkspaceId.getWorkspaceId(path),
54
+ homeDir: PlatformPaths.getHomeDir(),
55
+ homeDirUri: toUri(PlatformPaths.getHomeDir()),
56
+ pathSeparator: Platform.getPathSeparator(),
57
+ source: WorkspaceSource.SharedProcessEnv,
58
+ };
59
+ }
60
+ const absolutePath = getAbsolutePath(folder);
61
+ const workspaceId = GetWorkspaceId.getWorkspaceId(absolutePath);
62
+ // TODO this slows down startup a lot (~30-50ms)
63
+ // const workspaceStorage = await getWorkspaceStorage(workspaceId)
64
+ return {
65
+ path: absolutePath,
66
+ uri: toUri(absolutePath),
67
+ workspaceId,
68
+ homeDir: PlatformPaths.getHomeDir(),
69
+ homeDirUri: toUri(PlatformPaths.getHomeDir()),
70
+ pathSeparator: Platform.getPathSeparator(),
71
+ source: WorkspaceSource.SharedProcessDefault,
72
+ };
73
+ };
@@ -1,28 +1,8 @@
1
1
  import { homedir } from 'node:os';
2
- import { isAbsolute, join, resolve } from 'node:path';
3
- import { fileURLToPath, pathToFileURL } from 'node:url';
4
- import * as Env from '../Env/Env.js';
5
- import * as GetWorkspaceId from '../GetWorkspaceId/GetWorkspaceId.js';
6
- import * as IsAbsolutePath from '../IsAbsolutePath/IsAbsolutePath.js';
7
- import * as IsElectron from '../IsElectron/IsElectron.js';
8
- import * as ParentIpc from '../ParentIpc/ParentIpc.js';
2
+ import { fileURLToPath } from 'node:url';
9
3
  import * as Platform from '../Platform/Platform.js';
10
4
  import * as PlatformPaths from '../PlatformPaths/PlatformPaths.js';
11
- import * as Root from '../Root/Root.js';
12
- import * as WorkspaceSource from '../WorkspaceSource/WorkspaceSource.js';
13
- const getAbsolutePath = (path) => {
14
- if (IsAbsolutePath.isAbsolutePath(path)) {
15
- return path;
16
- }
17
- if (path.startsWith('${cwd}')) {
18
- path = Root.root + path.slice(5);
19
- }
20
- else if (path.startsWith('~')) {
21
- path = `${homedir()}${path.slice(1)}`;
22
- }
23
- path = resolve(path);
24
- return path;
25
- };
5
+ import * as ResolveRoot from '../ResolveRoot/ResolveRoot.js';
26
6
  /**
27
7
  * @deprecated use platform instead
28
8
  */
@@ -33,51 +13,7 @@ export const getHomeDir = () => {
33
13
  const homeDir = homedir();
34
14
  return homeDir;
35
15
  };
36
- const toUri = (path) => {
37
- return pathToFileURL(path).toString();
38
- };
39
- export const resolveRoot = async () => {
40
- if (IsElectron.isElectron) {
41
- const argv = await ParentIpc.invoke('Process.getArgv');
42
- const relevantArgv = argv.slice(2);
43
- const last = relevantArgv.at(-1);
44
- if (last && isAbsolute(last)) {
45
- return {
46
- path: last,
47
- uri: toUri(last),
48
- workspaceId: GetWorkspaceId.getWorkspaceId(last),
49
- homeDir: PlatformPaths.getHomeDir(),
50
- pathSeparator: Platform.getPathSeparator(),
51
- source: 'shared-process-default',
52
- };
53
- }
54
- }
55
- // TODO shared process should have no logic, this should probably be somewhere else
56
- const folder = Env.getFolder();
57
- if (!folder) {
58
- const path = join(Root.root, 'playground');
59
- return {
60
- path,
61
- uri: toUri(path),
62
- workspaceId: GetWorkspaceId.getWorkspaceId(path),
63
- homeDir: PlatformPaths.getHomeDir(),
64
- pathSeparator: Platform.getPathSeparator(),
65
- source: WorkspaceSource.SharedProcessEnv,
66
- };
67
- }
68
- const absolutePath = getAbsolutePath(folder);
69
- const workspaceId = GetWorkspaceId.getWorkspaceId(absolutePath);
70
- // TODO this slows down startup a lot (~30-50ms)
71
- // const workspaceStorage = await getWorkspaceStorage(workspaceId)
72
- return {
73
- path: absolutePath,
74
- uri: toUri(absolutePath),
75
- workspaceId,
76
- homeDir: PlatformPaths.getHomeDir(),
77
- pathSeparator: Platform.getPathSeparator(),
78
- source: WorkspaceSource.SharedProcessDefault,
79
- };
80
- };
16
+ export const resolveRoot = ResolveRoot.resolveRoot;
81
17
  export const resolveUri = (uri) => {
82
18
  const path = fileURLToPath(uri);
83
19
  return {