vzcode 1.30.1 → 1.31.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/dist/assets/{index-BOiH3_fC.js → index-D01yzCWj.js} +88 -88
- package/dist/assets/{index-zzK6rRiK.css → index-DTtcN2MP.css} +1 -1
- package/dist/index.html +2 -2
- package/package.json +7 -8
- package/src/client/AIAssist/startAIAssist.ts +0 -24
- package/src/client/App/index.tsx +11 -7
- package/src/client/CodeEditor/getOrCreateEditor.ts +0 -52
- package/src/client/CodeEditor/index.tsx +0 -6
- package/src/client/RunCodeWidget/index.tsx +0 -2
- package/src/client/VZCodeContext.tsx +8 -25
- package/src/client/VZMiddle.tsx +0 -5
- package/src/client/VZSidebar/index.tsx +18 -11
- package/src/client/VZSidebar/styles.scss +27 -7
- package/src/client/VZSidebar/useDragAndDrop.tsx +237 -35
- package/src/client/main.jsx +0 -2
- package/src/client/useFileCRUD.ts +0 -2
- package/src/server/featureFlags.js +2 -6
- package/src/server/setupEnv.js +0 -10
- package/dist/assets/index-Dd8gk_1S.js +0 -447
- package/src/client/CodeEditor/typeScriptCompletions.ts +0 -134
- package/src/client/CodeEditor/typeScriptLinter.ts +0 -47
- package/src/client/useTypeScript/index.ts +0 -48
- package/src/client/useTypeScript/worker/constants.ts +0 -94
- package/src/client/useTypeScript/worker/getTSFileName.ts +0 -4
- package/src/client/useTypeScript/worker/handleMessageAutocompleteRequest.ts +0 -63
- package/src/client/useTypeScript/worker/handleMessageLintRequest.ts +0 -84
- package/src/client/useTypeScript/worker/handleMessageTranspileRequest.ts +0 -20
- package/src/client/useTypeScript/worker/handleMessageUpdateContent.ts +0 -42
- package/src/client/useTypeScript/worker/index.ts +0 -110
- package/src/client/useTypeScript/worker/isTS.ts +0 -3
- package/src/client/useTypeScript/worker/requestTypes.ts +0 -31
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CompletionContext,
|
|
3
|
-
CompletionSource,
|
|
4
|
-
} from '@codemirror/autocomplete';
|
|
5
|
-
import { generateRequestId } from '../generateRequestId';
|
|
6
|
-
import {
|
|
7
|
-
AutocompleteRequest,
|
|
8
|
-
AutocompleteResponse,
|
|
9
|
-
} from '../useTypeScript/worker/requestTypes';
|
|
10
|
-
|
|
11
|
-
export const typeScriptCompletions = ({
|
|
12
|
-
typeScriptWorker,
|
|
13
|
-
fileName,
|
|
14
|
-
}): CompletionSource => {
|
|
15
|
-
const tsComplete: CompletionSource = async (
|
|
16
|
-
completionContext: CompletionContext,
|
|
17
|
-
) => {
|
|
18
|
-
// A random unique ID for this request.
|
|
19
|
-
const requestId = generateRequestId();
|
|
20
|
-
|
|
21
|
-
const fileContent =
|
|
22
|
-
completionContext.state.doc.toString();
|
|
23
|
-
|
|
24
|
-
const autocompleteRequest: AutocompleteRequest = {
|
|
25
|
-
event: 'autocomplete-request',
|
|
26
|
-
|
|
27
|
-
// Location is the file path (string)
|
|
28
|
-
fileName,
|
|
29
|
-
|
|
30
|
-
// Latest file content (string)
|
|
31
|
-
fileContent,
|
|
32
|
-
|
|
33
|
-
// Cursor position (integer, like index in a string)
|
|
34
|
-
position: completionContext.pos,
|
|
35
|
-
|
|
36
|
-
// Unique ID for this request
|
|
37
|
-
requestId,
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
//Prevent completions from appearing on certain characters
|
|
41
|
-
const lastCharacter =
|
|
42
|
-
fileContent[completionContext.pos - 1];
|
|
43
|
-
if (
|
|
44
|
-
[
|
|
45
|
-
'"',
|
|
46
|
-
"'",
|
|
47
|
-
';',
|
|
48
|
-
'(',
|
|
49
|
-
')',
|
|
50
|
-
'{',
|
|
51
|
-
',',
|
|
52
|
-
' ',
|
|
53
|
-
'=',
|
|
54
|
-
'<',
|
|
55
|
-
'>',
|
|
56
|
-
].includes(lastCharacter)
|
|
57
|
-
) {
|
|
58
|
-
return { from: completionContext.pos, options: [] };
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
//Post message to our sharedWorker to get completions.
|
|
62
|
-
typeScriptWorker.postMessage(autocompleteRequest);
|
|
63
|
-
|
|
64
|
-
//An async promise to ensure that we are getting our completion entries
|
|
65
|
-
const tsCompletions = await new Promise((resolve) => {
|
|
66
|
-
typeScriptWorker.onmessage = (message: {
|
|
67
|
-
data: AutocompleteResponse;
|
|
68
|
-
}) => {
|
|
69
|
-
const autocompleteResponse: AutocompleteResponse =
|
|
70
|
-
message.data;
|
|
71
|
-
const { event, requestId, completions } =
|
|
72
|
-
autocompleteResponse;
|
|
73
|
-
if (
|
|
74
|
-
event === 'post-completions' &&
|
|
75
|
-
requestId === requestId
|
|
76
|
-
) {
|
|
77
|
-
resolve(completions);
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
if (!tsCompletions) {
|
|
83
|
-
// console.log('Unable to get completions');
|
|
84
|
-
return { from: completionContext.pos, options: [] };
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Logic to get the text and cursor location in between punctuation.
|
|
88
|
-
// Taken from https://codemirror.net/examples/autocompletion/
|
|
89
|
-
// Also inspired by
|
|
90
|
-
// https://stackblitz.com/edit/codemirror-6-typescript?file=client%2Findex.ts%3AL86
|
|
91
|
-
const from = completionContext.matchBefore(/\w*/).from;
|
|
92
|
-
|
|
93
|
-
// `lastWord` represents the word that the user has partially typed
|
|
94
|
-
// and is currently at the end of the text, immediately before
|
|
95
|
-
// the cursor position.
|
|
96
|
-
const lastWord =
|
|
97
|
-
completionContext.matchBefore(/\w*/).text;
|
|
98
|
-
if (lastWord) {
|
|
99
|
-
// @ts-ignore
|
|
100
|
-
tsCompletions.entries = tsCompletions.entries.filter(
|
|
101
|
-
(completion) =>
|
|
102
|
-
completion.name.startsWith(lastWord),
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
return {
|
|
106
|
-
from: completionContext.pos,
|
|
107
|
-
// @ts-ignore
|
|
108
|
-
options: tsCompletions.entries.map((completion) => ({
|
|
109
|
-
label: completion.name,
|
|
110
|
-
// Applies autocompletions to be seen in the code Editor
|
|
111
|
-
apply: (view) => {
|
|
112
|
-
//Calculation to get the new cursor position after the autocompletion
|
|
113
|
-
const newPosition =
|
|
114
|
-
completionContext.pos +
|
|
115
|
-
completion.name.length -
|
|
116
|
-
lastWord.length;
|
|
117
|
-
view.dispatch({
|
|
118
|
-
changes: {
|
|
119
|
-
from,
|
|
120
|
-
to: completionContext.pos,
|
|
121
|
-
insert: completion.name,
|
|
122
|
-
},
|
|
123
|
-
// Move the cursor to the end of the autocompletion
|
|
124
|
-
selection: {
|
|
125
|
-
anchor: newPosition,
|
|
126
|
-
head: newPosition,
|
|
127
|
-
},
|
|
128
|
-
});
|
|
129
|
-
},
|
|
130
|
-
})),
|
|
131
|
-
};
|
|
132
|
-
};
|
|
133
|
-
return tsComplete;
|
|
134
|
-
};
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import type { Diagnostic } from 'typescript';
|
|
2
|
-
import { generateRequestId } from '../generateRequestId';
|
|
3
|
-
import {
|
|
4
|
-
LinterRequest,
|
|
5
|
-
LinterResponse,
|
|
6
|
-
} from '../useTypeScript/worker/requestTypes';
|
|
7
|
-
|
|
8
|
-
export const typeScriptLinter = ({
|
|
9
|
-
typeScriptWorker,
|
|
10
|
-
fileName,
|
|
11
|
-
shareDBDoc,
|
|
12
|
-
fileId,
|
|
13
|
-
allowGlobals,
|
|
14
|
-
}) => {
|
|
15
|
-
return async () => {
|
|
16
|
-
const requestId = generateRequestId();
|
|
17
|
-
//Get the fileContent from shareDB to pass to web worker
|
|
18
|
-
const fileContent = shareDBDoc.data.files[fileId].text;
|
|
19
|
-
const linterRequest: LinterRequest = {
|
|
20
|
-
event: 'lint-request',
|
|
21
|
-
fileName,
|
|
22
|
-
fileContent,
|
|
23
|
-
requestId,
|
|
24
|
-
allowGlobals,
|
|
25
|
-
};
|
|
26
|
-
typeScriptWorker.postMessage(linterRequest);
|
|
27
|
-
|
|
28
|
-
//An array of diagnostic (CodeMirror) objects.
|
|
29
|
-
const tsErrors: Diagnostic[] = await new Promise(
|
|
30
|
-
(resolve) => {
|
|
31
|
-
typeScriptWorker.onmessage = (message: {
|
|
32
|
-
data: LinterResponse;
|
|
33
|
-
}) => {
|
|
34
|
-
const ErrorData: LinterResponse = message.data;
|
|
35
|
-
const { event, requestId, tsErrors } = ErrorData;
|
|
36
|
-
if (
|
|
37
|
-
event === 'post-error-linter' &&
|
|
38
|
-
requestId === requestId
|
|
39
|
-
) {
|
|
40
|
-
resolve(tsErrors);
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
},
|
|
44
|
-
);
|
|
45
|
-
return tsErrors;
|
|
46
|
-
};
|
|
47
|
-
};
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { useCallback, useEffect, useRef } from 'react';
|
|
2
|
-
import { VizContent } from '@vizhub/viz-types';
|
|
3
|
-
import { autoPrettierDebounceTimeMS } from '../usePrettier';
|
|
4
|
-
|
|
5
|
-
// We don't want to send the message _before_ Prettier runs,
|
|
6
|
-
// so we need to wait at least as long as Prettier takes to run,
|
|
7
|
-
// plus some "wiggle room" which is amount of time it may take
|
|
8
|
-
// to aactually run Prettier and update the document.
|
|
9
|
-
const wiggleRoom = 500;
|
|
10
|
-
|
|
11
|
-
// The time in milliseconds by which auto-saving is debounced.
|
|
12
|
-
const sendMessageDebounceTimeMS =
|
|
13
|
-
autoPrettierDebounceTimeMS + wiggleRoom;
|
|
14
|
-
|
|
15
|
-
export const useTypeScript = ({
|
|
16
|
-
content,
|
|
17
|
-
typeScriptWorker,
|
|
18
|
-
}: {
|
|
19
|
-
content: VizContent;
|
|
20
|
-
typeScriptWorker: Worker;
|
|
21
|
-
}) => {
|
|
22
|
-
// When Content changes, update the TypeScript worker
|
|
23
|
-
// with the new content, but debounced.
|
|
24
|
-
|
|
25
|
-
// This keeps track of the setTimeout ID across renders.
|
|
26
|
-
const debounceTimeoutId = useRef<number | null>(null);
|
|
27
|
-
|
|
28
|
-
const debounceUpdateContent = useCallback(
|
|
29
|
-
(content: VizContent) => {
|
|
30
|
-
// Handle the case where the content has not yet been loaded.
|
|
31
|
-
if (content === null) {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
clearTimeout(debounceTimeoutId.current);
|
|
35
|
-
debounceTimeoutId.current = window.setTimeout(() => {
|
|
36
|
-
typeScriptWorker.postMessage({
|
|
37
|
-
event: 'update-content',
|
|
38
|
-
details: content,
|
|
39
|
-
});
|
|
40
|
-
}, sendMessageDebounceTimeMS);
|
|
41
|
-
},
|
|
42
|
-
[typeScriptWorker],
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
useEffect(() => {
|
|
46
|
-
debounceUpdateContent(content);
|
|
47
|
-
}, [content]);
|
|
48
|
-
};
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import ts from 'typescript';
|
|
2
|
-
|
|
3
|
-
export const compilerOptions: ts.CompilerOptions = {
|
|
4
|
-
target: ts.ScriptTarget.ES2022,
|
|
5
|
-
lib: ['dom', 'es2022'],
|
|
6
|
-
|
|
7
|
-
// Disable warnings around "Any type".
|
|
8
|
-
noImplicitAny: false,
|
|
9
|
-
|
|
10
|
-
// Disable warnings around "Implicit any in parameter".
|
|
11
|
-
noImplicitThis: false,
|
|
12
|
-
|
|
13
|
-
// Allow JavaScript files to be processed
|
|
14
|
-
allowJs: true,
|
|
15
|
-
|
|
16
|
-
// Disable type checking for JavaScript files
|
|
17
|
-
// checkJs: false,
|
|
18
|
-
|
|
19
|
-
// Skip type checking of declaration files
|
|
20
|
-
skipLibCheck: true,
|
|
21
|
-
|
|
22
|
-
// Support React JSX
|
|
23
|
-
jsx: ts.JsxEmit.React,
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
// Be less aggressive for non-TS files,
|
|
27
|
-
// e.g. files that end in .js or .jsx.
|
|
28
|
-
// if (!isTS(fileName)) {
|
|
29
|
-
// This code is for errors like:
|
|
30
|
-
// "Binding element 'data' implicitly has an 'any' type."
|
|
31
|
-
const LINT_ERROR_CODE_ANY = 7031;
|
|
32
|
-
|
|
33
|
-
// This code is for errors like:
|
|
34
|
-
// "Parameter 'selection' implicitly has an 'any' type.""
|
|
35
|
-
const LINT_ERROR_CODE_ANY_PARAM = 7006;
|
|
36
|
-
|
|
37
|
-
// This code is for errors like:
|
|
38
|
-
// "Cannot find module 'd3' or its corresponding type declarations."
|
|
39
|
-
const LINT_ERROR_CODE_IMPORT = 2307;
|
|
40
|
-
|
|
41
|
-
// This code is for errors like:
|
|
42
|
-
// "Variable 'mic' implicitly has type 'any' in some locations where its type cannot be determined."
|
|
43
|
-
const LINT_ERROR_CODE_ANY_TYPE = 7034;
|
|
44
|
-
|
|
45
|
-
// "Element implicitly has an 'any' type because expression
|
|
46
|
-
// of type '"test"' can't be used to index type '{}'."
|
|
47
|
-
const LINT_ERROR_CODE_ANY_TYPE_KEYS = 7053;
|
|
48
|
-
|
|
49
|
-
// "Property 'id' does not exist on type { ... }"
|
|
50
|
-
// Happens on objects with dynamic keys.
|
|
51
|
-
// Not valid in TypeScript, but common in JavaScript.
|
|
52
|
-
const LINT_ERROR_CODE_NON_EXISTENT_PROPERTY = 2339;
|
|
53
|
-
|
|
54
|
-
// "Type 'Set<unknown>' can only be iterated through when using the '--downlevelIteration'
|
|
55
|
-
// flag or with a '--target' of 'es2015' or higher."
|
|
56
|
-
const LINT_ERROR_CODE_ITERATED_THROUGH = 2802;
|
|
57
|
-
|
|
58
|
-
// Argument of type '{ Month: string; High: number; Temp: number; Low: number; }'
|
|
59
|
-
// is not assignable to parameter of type 'never'.
|
|
60
|
-
const LINT_ERROR_CODE_ASSIGNABLE_TO_NEVER = 2345;
|
|
61
|
-
|
|
62
|
-
// Cannot find name 'd3'.
|
|
63
|
-
export const LINT_ERROR_CODE_CANNOT_FIND_NAME = 2304;
|
|
64
|
-
|
|
65
|
-
// Type '{}' is missing the following properties from type '{ indx:
|
|
66
|
-
//Ignore specific TypeScript warning on object reassignment
|
|
67
|
-
const LINT_ERROR_CODE_OBJ_REASSINGMENT = 2739;
|
|
68
|
-
|
|
69
|
-
// Type 'any' is not assignable to type 'never'.
|
|
70
|
-
const LINT_ERROR_CODE_ANY_NOT_ASSIGNABLE_TO_NEVER = 2322;
|
|
71
|
-
|
|
72
|
-
// Ignore potential undefined error for variables
|
|
73
|
-
const LINT_ERROR_CODE_POSSIBLY_UNDEFINED = 18048;
|
|
74
|
-
|
|
75
|
-
// This code is for errors like:
|
|
76
|
-
// "Object is of type 'unknown'."
|
|
77
|
-
const LINT_ERROR_CODE_UNKNOWN = 18046;
|
|
78
|
-
const LINT_ERROR_CODE_UNKNOWN_SYMBOL_ITERATOR = 2488;
|
|
79
|
-
|
|
80
|
-
export const excludedErrorCodes = new Set([
|
|
81
|
-
LINT_ERROR_CODE_ANY,
|
|
82
|
-
LINT_ERROR_CODE_IMPORT,
|
|
83
|
-
LINT_ERROR_CODE_ANY_PARAM,
|
|
84
|
-
LINT_ERROR_CODE_ANY_TYPE,
|
|
85
|
-
LINT_ERROR_CODE_ANY_TYPE_KEYS,
|
|
86
|
-
LINT_ERROR_CODE_NON_EXISTENT_PROPERTY,
|
|
87
|
-
LINT_ERROR_CODE_ITERATED_THROUGH,
|
|
88
|
-
LINT_ERROR_CODE_ASSIGNABLE_TO_NEVER,
|
|
89
|
-
LINT_ERROR_CODE_OBJ_REASSINGMENT,
|
|
90
|
-
LINT_ERROR_CODE_ANY_NOT_ASSIGNABLE_TO_NEVER,
|
|
91
|
-
LINT_ERROR_CODE_UNKNOWN,
|
|
92
|
-
LINT_ERROR_CODE_UNKNOWN_SYMBOL_ITERATOR,
|
|
93
|
-
LINT_ERROR_CODE_POSSIBLY_UNDEFINED,
|
|
94
|
-
]);
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { getTSFileName } from './getTSFileName';
|
|
2
|
-
import { isTS } from './isTS';
|
|
3
|
-
import {
|
|
4
|
-
AutocompleteRequest,
|
|
5
|
-
AutocompleteResponse,
|
|
6
|
-
} from './requestTypes';
|
|
7
|
-
|
|
8
|
-
// This function is called when the worker receives a message with the type
|
|
9
|
-
// 'autocomplete-request'. It gets completions at the specified position in the
|
|
10
|
-
// file and sends them back to the main thread.
|
|
11
|
-
export const handleMessageAutocompleteRequest = async ({
|
|
12
|
-
debug,
|
|
13
|
-
data,
|
|
14
|
-
env,
|
|
15
|
-
setFile,
|
|
16
|
-
}) => {
|
|
17
|
-
if (debug) {
|
|
18
|
-
console.log('autocomplete-request message received');
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// Should not happen.
|
|
22
|
-
if (env === null) {
|
|
23
|
-
console.log('env is null');
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// Example of `data`:
|
|
28
|
-
// {
|
|
29
|
-
// "event": "autocomplete-request",
|
|
30
|
-
// "pos": 8,
|
|
31
|
-
// "location": "index.js",
|
|
32
|
-
// "requestId": "0.9090605799171392"
|
|
33
|
-
// }
|
|
34
|
-
|
|
35
|
-
const autocompleteRequest: AutocompleteRequest = data;
|
|
36
|
-
const { fileName, fileContent, position, requestId } =
|
|
37
|
-
autocompleteRequest;
|
|
38
|
-
|
|
39
|
-
const tsFileName = getTSFileName(fileName);
|
|
40
|
-
|
|
41
|
-
let completions = null;
|
|
42
|
-
if (isTS(tsFileName) && fileContent !== '') {
|
|
43
|
-
// Update the file in the file system to the
|
|
44
|
-
// absolute latest version. This is critical
|
|
45
|
-
// for correct completions.
|
|
46
|
-
setFile(tsFileName, fileContent);
|
|
47
|
-
|
|
48
|
-
completions =
|
|
49
|
-
env.languageService.getCompletionsAtPosition(
|
|
50
|
-
tsFileName,
|
|
51
|
-
position,
|
|
52
|
-
{},
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const autocompleteResponse: AutocompleteResponse = {
|
|
57
|
-
event: 'post-completions',
|
|
58
|
-
completions,
|
|
59
|
-
requestId,
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
postMessage(autocompleteResponse);
|
|
63
|
-
};
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import ts from 'typescript';
|
|
2
|
-
import type { Diagnostic } from '@codemirror/lint';
|
|
3
|
-
import {
|
|
4
|
-
LinterRequest,
|
|
5
|
-
LinterResponse,
|
|
6
|
-
} from './requestTypes';
|
|
7
|
-
import { getTSFileName } from './getTSFileName';
|
|
8
|
-
import { isTS } from './isTS';
|
|
9
|
-
import {
|
|
10
|
-
LINT_ERROR_CODE_CANNOT_FIND_NAME,
|
|
11
|
-
excludedErrorCodes,
|
|
12
|
-
} from './constants';
|
|
13
|
-
|
|
14
|
-
// Inspired by: https://stackblitz.com/edit/codemirror-6-typescript?file=client%2Findex.ts%3AL44-L44
|
|
15
|
-
const convertToCodeMirrorDiagnostic = (
|
|
16
|
-
tsErrors: ts.Diagnostic[],
|
|
17
|
-
): Array<Diagnostic> =>
|
|
18
|
-
tsErrors.map((tsError: ts.Diagnostic) => ({
|
|
19
|
-
from: tsError.start,
|
|
20
|
-
to: tsError.start + tsError.length,
|
|
21
|
-
severity: 'error',
|
|
22
|
-
message:
|
|
23
|
-
typeof tsError.messageText === 'string'
|
|
24
|
-
? tsError.messageText
|
|
25
|
-
: tsError.messageText.messageText,
|
|
26
|
-
}));
|
|
27
|
-
|
|
28
|
-
export const handleMessageLintRequest = async ({
|
|
29
|
-
debug,
|
|
30
|
-
data,
|
|
31
|
-
env,
|
|
32
|
-
setFile,
|
|
33
|
-
}) => {
|
|
34
|
-
if (debug) {
|
|
35
|
-
console.log('Lint Request');
|
|
36
|
-
}
|
|
37
|
-
const linterRequest: LinterRequest = data;
|
|
38
|
-
const { fileName, fileContent, requestId, allowGlobals } =
|
|
39
|
-
linterRequest;
|
|
40
|
-
|
|
41
|
-
const tsFileName = getTSFileName(fileName);
|
|
42
|
-
let tsErrors = [];
|
|
43
|
-
if (isTS(tsFileName) && fileContent !== '') {
|
|
44
|
-
// We are updating the server with the latest content
|
|
45
|
-
// when we autocomplete, so it's always up to date.
|
|
46
|
-
setFile(tsFileName, fileContent);
|
|
47
|
-
|
|
48
|
-
// Creates an array of diagnostic objects containing
|
|
49
|
-
// both semantic and syntactic diagnostics.
|
|
50
|
-
tsErrors = env.languageService
|
|
51
|
-
.getSemanticDiagnostics(tsFileName)
|
|
52
|
-
.concat(
|
|
53
|
-
env.languageService.getSyntacticDiagnostics(
|
|
54
|
-
tsFileName,
|
|
55
|
-
),
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
if (debug) {
|
|
59
|
-
console.log('tsErrors');
|
|
60
|
-
console.log(tsErrors);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
tsErrors = tsErrors.filter(
|
|
64
|
-
(error: { code: number }) => {
|
|
65
|
-
if (
|
|
66
|
-
allowGlobals &&
|
|
67
|
-
error.code === LINT_ERROR_CODE_CANNOT_FIND_NAME
|
|
68
|
-
) {
|
|
69
|
-
return false;
|
|
70
|
-
}
|
|
71
|
-
return !excludedErrorCodes.has(error.code);
|
|
72
|
-
},
|
|
73
|
-
);
|
|
74
|
-
|
|
75
|
-
tsErrors = convertToCodeMirrorDiagnostic(tsErrors);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const linterResponse: LinterResponse = {
|
|
79
|
-
event: 'post-error-linter',
|
|
80
|
-
tsErrors,
|
|
81
|
-
requestId,
|
|
82
|
-
};
|
|
83
|
-
postMessage(linterResponse);
|
|
84
|
-
};
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import ts from 'typescript';
|
|
2
|
-
import { compilerOptions } from './constants';
|
|
3
|
-
|
|
4
|
-
// Handle the transpile-request event, which
|
|
5
|
-
// transpiles TypeScript to JavaScript.
|
|
6
|
-
export const handleMessageTranspileRequest = async ({
|
|
7
|
-
data,
|
|
8
|
-
}) => {
|
|
9
|
-
const tsCode = data.tsCode;
|
|
10
|
-
|
|
11
|
-
const jsCode = ts.transpileModule(tsCode, {
|
|
12
|
-
compilerOptions: compilerOptions,
|
|
13
|
-
}).outputText;
|
|
14
|
-
|
|
15
|
-
postMessage({
|
|
16
|
-
event: 'transpile-response',
|
|
17
|
-
jsCode,
|
|
18
|
-
fileId: data.fileId,
|
|
19
|
-
});
|
|
20
|
-
};
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
VizFile,
|
|
3
|
-
VizFiles,
|
|
4
|
-
VizContent,
|
|
5
|
-
} from '@vizhub/viz-types';
|
|
6
|
-
import { getTSFileName } from './getTSFileName';
|
|
7
|
-
import { isTS } from './isTS';
|
|
8
|
-
|
|
9
|
-
// Handle the update-content event, which
|
|
10
|
-
// updates the files as they change.
|
|
11
|
-
// This handles the cases where:
|
|
12
|
-
// * The file system is populated for the first time.
|
|
13
|
-
// * Files are edited by remote users.
|
|
14
|
-
export const handleMessageUpdateContent = async ({
|
|
15
|
-
debug,
|
|
16
|
-
data,
|
|
17
|
-
setFile,
|
|
18
|
-
}) => {
|
|
19
|
-
if (debug) {
|
|
20
|
-
console.log('update-content message received');
|
|
21
|
-
}
|
|
22
|
-
// Unpack the files
|
|
23
|
-
const content: VizContent = data.details;
|
|
24
|
-
const files: VizFiles = content.files;
|
|
25
|
-
|
|
26
|
-
// Iterate over the files
|
|
27
|
-
for (const fileId of Object.keys(files)) {
|
|
28
|
-
const file: VizFile = files[fileId];
|
|
29
|
-
const { name, text } = file;
|
|
30
|
-
|
|
31
|
-
const tsFileName = getTSFileName(name);
|
|
32
|
-
|
|
33
|
-
if (!isTS(tsFileName)) {
|
|
34
|
-
continue;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
setFile(tsFileName, text);
|
|
38
|
-
// TODO - Handle renaming files.
|
|
39
|
-
// TODO - Handle deleting files.
|
|
40
|
-
// TODO - Handle directories.
|
|
41
|
-
}
|
|
42
|
-
};
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import * as tsvfs from '@typescript/vfs';
|
|
2
|
-
import ts from 'typescript';
|
|
3
|
-
import { compilerOptions } from './constants';
|
|
4
|
-
import { handleMessageUpdateContent } from './handleMessageUpdateContent';
|
|
5
|
-
import { handleMessageAutocompleteRequest } from './handleMessageAutocompleteRequest';
|
|
6
|
-
import { handleMessageLintRequest } from './handleMessageLintRequest';
|
|
7
|
-
import { handleMessageTranspileRequest } from './handleMessageTranspileRequest';
|
|
8
|
-
|
|
9
|
-
let env: tsvfs.VirtualTypeScriptEnvironment = null;
|
|
10
|
-
|
|
11
|
-
const debug = false;
|
|
12
|
-
|
|
13
|
-
// This is a place for things we only do _once_.
|
|
14
|
-
const initializeFileSystem = async () => {
|
|
15
|
-
if (debug) {
|
|
16
|
-
console.log('initializeFileSystem');
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// `true` breaks in a Web Worker because
|
|
20
|
-
// this uses `localStorage` under the hood,
|
|
21
|
-
// which is not available in a Web Worker.
|
|
22
|
-
const cache = false;
|
|
23
|
-
|
|
24
|
-
const fsMap = await tsvfs.createDefaultMapFromCDN(
|
|
25
|
-
compilerOptions,
|
|
26
|
-
ts.version,
|
|
27
|
-
cache,
|
|
28
|
-
ts,
|
|
29
|
-
);
|
|
30
|
-
const sys: ts.System = tsvfs.createSystem(fsMap);
|
|
31
|
-
|
|
32
|
-
// We'll add files to this later.
|
|
33
|
-
const rootFiles = [];
|
|
34
|
-
|
|
35
|
-
env = tsvfs.createVirtualTypeScriptEnvironment(
|
|
36
|
-
sys,
|
|
37
|
-
rootFiles,
|
|
38
|
-
ts,
|
|
39
|
-
compilerOptions,
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
if (debug) {
|
|
43
|
-
console.log('initializeFileSystem done');
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
const setFile = (tsFileName: string, text: string) => {
|
|
48
|
-
const existingFile = env.getSourceFile(tsFileName);
|
|
49
|
-
if (existingFile === undefined) {
|
|
50
|
-
env.createFile(tsFileName, text);
|
|
51
|
-
} else {
|
|
52
|
-
env.updateFile(tsFileName, text);
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
// This is a promise that resolves when the file system is initialized.
|
|
57
|
-
let fileSystemInitializationPromise = null;
|
|
58
|
-
async function ensureFileSystemInitialized() {
|
|
59
|
-
if (!fileSystemInitializationPromise) {
|
|
60
|
-
fileSystemInitializationPromise =
|
|
61
|
-
initializeFileSystem();
|
|
62
|
-
}
|
|
63
|
-
await fileSystemInitializationPromise;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
onmessage = async ({ data }) => {
|
|
67
|
-
if (debug) {
|
|
68
|
-
console.log('message received');
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Ensure the file system is initialized.
|
|
72
|
-
await ensureFileSystemInitialized();
|
|
73
|
-
|
|
74
|
-
// Sanity check - should never happen.
|
|
75
|
-
if (env === null) {
|
|
76
|
-
throw new Error('File system not initialized');
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
switch (data.event) {
|
|
80
|
-
case 'update-content':
|
|
81
|
-
await handleMessageUpdateContent({
|
|
82
|
-
debug,
|
|
83
|
-
data,
|
|
84
|
-
setFile,
|
|
85
|
-
});
|
|
86
|
-
break;
|
|
87
|
-
|
|
88
|
-
case 'autocomplete-request':
|
|
89
|
-
await handleMessageAutocompleteRequest({
|
|
90
|
-
debug,
|
|
91
|
-
data,
|
|
92
|
-
env,
|
|
93
|
-
setFile,
|
|
94
|
-
});
|
|
95
|
-
break;
|
|
96
|
-
|
|
97
|
-
case 'lint-request':
|
|
98
|
-
await handleMessageLintRequest({
|
|
99
|
-
debug,
|
|
100
|
-
data,
|
|
101
|
-
env,
|
|
102
|
-
setFile,
|
|
103
|
-
});
|
|
104
|
-
break;
|
|
105
|
-
|
|
106
|
-
case 'transpile-request':
|
|
107
|
-
await handleMessageTranspileRequest({ data });
|
|
108
|
-
break;
|
|
109
|
-
}
|
|
110
|
-
};
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import ts from 'typescript';
|
|
2
|
-
|
|
3
|
-
export type AutocompleteRequest = {
|
|
4
|
-
event: 'autocomplete-request';
|
|
5
|
-
fileName: string;
|
|
6
|
-
fileContent: string;
|
|
7
|
-
position: number;
|
|
8
|
-
requestId: string;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export type AutocompleteResponse = {
|
|
12
|
-
event: 'post-completions';
|
|
13
|
-
completions: any;
|
|
14
|
-
requestId: string;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export type LinterRequest = {
|
|
18
|
-
event: 'lint-request';
|
|
19
|
-
fileName: string;
|
|
20
|
-
fileContent: string;
|
|
21
|
-
requestId: string;
|
|
22
|
-
|
|
23
|
-
// If true, linting will not show errors for global variables.
|
|
24
|
-
allowGlobals?: boolean;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export type LinterResponse = {
|
|
28
|
-
event: 'post-error-linter';
|
|
29
|
-
tsErrors: ts.Diagnostic[];
|
|
30
|
-
requestId: string;
|
|
31
|
-
};
|