vzcode 0.42.0 → 0.44.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-7MNYa9sP.css +1 -0
- package/dist/assets/{index-EvjpKQwB.js → index-f4vqBOE4.js} +45 -45
- package/dist/assets/{worker-5MYmBNqK.js → worker-VwMsqrhy.js} +82 -82
- package/dist/assets/worker-fboacSft.js +234 -0
- package/dist/index.html +2 -2
- package/package.json +24 -11
- package/src/client/CodeEditor/getOrCreateEditor.ts +14 -1
- package/src/client/CodeEditor/widgets.ts +39 -22
- package/src/client/VZCodeContext.tsx +5 -2
- package/src/client/VZLeft.tsx +2 -1
- package/src/client/VZMiddle.tsx +2 -2
- package/src/client/index.ts +1 -0
- package/src/client/usePrettier/index.ts +98 -30
- package/src/client/useTypeScript/worker.ts +20 -0
- package/src/index.ts +1 -0
- package/src/server/computeInitialDocument.js +133 -13
- package/dist/assets/index-vD_kE3p2.css +0 -1
- package/dist/assets/worker-pzCcKLRg.js +0 -237
package/dist/index.html
CHANGED
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
href="https://unpkg.com/boxicons@2.0.7/css/boxicons.min.css"
|
|
25
25
|
rel="stylesheet"
|
|
26
26
|
/>
|
|
27
|
-
<script type="module" crossorigin src="/assets/index-
|
|
28
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
27
|
+
<script type="module" crossorigin src="/assets/index-f4vqBOE4.js"></script>
|
|
28
|
+
<link rel="stylesheet" crossorigin href="/assets/index-7MNYa9sP.css">
|
|
29
29
|
</head>
|
|
30
30
|
<body>
|
|
31
31
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vzcode",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.44.0",
|
|
4
4
|
"description": "Multiplayer code editor system",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -43,6 +43,18 @@
|
|
|
43
43
|
{
|
|
44
44
|
"name": "Anooj Pai",
|
|
45
45
|
"url": "https://github.com/Anooj-Pai"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "Jack Hankin",
|
|
49
|
+
"url": "https://github.com/Darmin-Geek"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"name": "Amanda Ruan",
|
|
53
|
+
"url": "https://github.com/aruan20"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "Evan Whymark",
|
|
57
|
+
"url": "https://github.com/EvWhymark"
|
|
46
58
|
}
|
|
47
59
|
],
|
|
48
60
|
"license": "MIT",
|
|
@@ -59,11 +71,11 @@
|
|
|
59
71
|
"@codemirror/lang-markdown": "^6.2.3",
|
|
60
72
|
"@codemirror/state": "^6.3.3",
|
|
61
73
|
"@codemirror/theme-one-dark": "^6.1.2",
|
|
62
|
-
"@codemirror/view": "^6.22.
|
|
74
|
+
"@codemirror/view": "^6.22.3",
|
|
63
75
|
"@lezer/highlight": "^1.2.0",
|
|
64
76
|
"@replit/codemirror-indentation-markers": "^6.5.0",
|
|
65
77
|
"@replit/codemirror-interact": "^6.3.0",
|
|
66
|
-
"@replit/codemirror-minimap": "^0.5.
|
|
78
|
+
"@replit/codemirror-minimap": "^0.5.2",
|
|
67
79
|
"@replit/codemirror-vscode-keymap": "^6.0.2",
|
|
68
80
|
"@teamwork/websocket-json-stream": "^2.0.0",
|
|
69
81
|
"@typescript/vfs": "^1.5.0",
|
|
@@ -84,26 +96,27 @@
|
|
|
84
96
|
"diff-match-patch": "^1.0.5",
|
|
85
97
|
"dotenv": "^16.3.1",
|
|
86
98
|
"express": "^4.18.2",
|
|
99
|
+
"ignore": "^5.3.0",
|
|
87
100
|
"json0-ot-diff": "^1.1.2",
|
|
88
101
|
"ngrok": "^4.3.3",
|
|
89
102
|
"open": "^9.1.0",
|
|
90
|
-
"openai": "^4.
|
|
103
|
+
"openai": "^4.23.0",
|
|
91
104
|
"react": "^18.2.0",
|
|
92
105
|
"react-bootstrap": "^2.9.1",
|
|
93
106
|
"react-dom": "^18.2.0",
|
|
94
107
|
"sharedb": "^4.1.2",
|
|
95
108
|
"sharedb-client-browser": "^4.4.0",
|
|
96
|
-
"vizhub-ui": "^3.
|
|
97
|
-
"ws": "^8.
|
|
109
|
+
"vizhub-ui": "^3.13.0",
|
|
110
|
+
"ws": "^8.15.1"
|
|
98
111
|
},
|
|
99
112
|
"devDependencies": {
|
|
100
|
-
"@types/react": "^18.2.
|
|
101
|
-
"@types/react-dom": "^18.2.
|
|
113
|
+
"@types/react": "^18.2.45",
|
|
114
|
+
"@types/react-dom": "^18.2.18",
|
|
102
115
|
"@vitejs/plugin-react": "^4.2.1",
|
|
103
|
-
"prettier": "^3.1.
|
|
116
|
+
"prettier": "^3.1.1",
|
|
104
117
|
"sass": "^1.69.5",
|
|
105
118
|
"typescript": "^5.3.3",
|
|
106
|
-
"vite": "^5.0.
|
|
107
|
-
"vitest": "^1.0.
|
|
119
|
+
"vite": "^5.0.10",
|
|
120
|
+
"vitest": "^1.0.4"
|
|
108
121
|
}
|
|
109
122
|
}
|
|
@@ -294,7 +294,20 @@ export const getOrCreateEditor = ({
|
|
|
294
294
|
|
|
295
295
|
// VSCode keybindings
|
|
296
296
|
// See https://github.com/replit/codemirror-vscode-keymap#usage
|
|
297
|
-
extensions.push(keymap.of(vscodeKeymap));
|
|
297
|
+
// extensions.push(keymap.of(vscodeKeymap));
|
|
298
|
+
extensions.push(
|
|
299
|
+
keymap.of(
|
|
300
|
+
vscodeKeymap.map((binding) => {
|
|
301
|
+
// Here we override the Shift+Enter behavior specifically,
|
|
302
|
+
// as that can be used to trigger a manual save/Prettier,
|
|
303
|
+
// and the default behavior from the keymap interferes.
|
|
304
|
+
if (binding.key === 'Enter') {
|
|
305
|
+
delete binding.shift;
|
|
306
|
+
}
|
|
307
|
+
return binding;
|
|
308
|
+
}),
|
|
309
|
+
),
|
|
310
|
+
);
|
|
298
311
|
|
|
299
312
|
const editor = new EditorView({
|
|
300
313
|
state: EditorState.create({
|
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
ViewPlugin,
|
|
5
5
|
Decoration,
|
|
6
6
|
WidgetType,
|
|
7
|
-
keymap,
|
|
8
7
|
} from '@codemirror/view';
|
|
9
8
|
import {
|
|
10
9
|
Annotation,
|
|
@@ -30,15 +29,17 @@ export const widgets = ({
|
|
|
30
29
|
rules: [
|
|
31
30
|
// hex color picker
|
|
32
31
|
// Inspired by https://github.com/replit/codemirror-interact/blob/master/dev/index.ts#L71
|
|
32
|
+
// Extended to support single and double quotes
|
|
33
33
|
{
|
|
34
|
-
regexp:
|
|
34
|
+
regexp: /["']\#([0-9]|[A-F]|[a-f]){6}["']/g,
|
|
35
35
|
cursor: 'pointer',
|
|
36
36
|
onClick(text, setText, e) {
|
|
37
37
|
const res =
|
|
38
|
-
|
|
38
|
+
/(?<quote>["'])(?<hex>\#([0-9]|[A-F]|[a-f]){6})\k<quote>/.exec(
|
|
39
39
|
text,
|
|
40
40
|
);
|
|
41
41
|
const startingColor = res.groups?.hex;
|
|
42
|
+
const quoteType = res.groups?.quote;
|
|
42
43
|
|
|
43
44
|
const sel = document.createElement('input');
|
|
44
45
|
sel.type = 'color';
|
|
@@ -54,11 +55,11 @@ export const widgets = ({
|
|
|
54
55
|
if (onInteract) onInteract();
|
|
55
56
|
if (el.value) {
|
|
56
57
|
setText(
|
|
57
|
-
|
|
58
|
+
`${quoteType}${
|
|
58
59
|
valueIsUpper
|
|
59
60
|
? el.value.toUpperCase()
|
|
60
61
|
: el.value
|
|
61
|
-
}
|
|
62
|
+
}${quoteType}`,
|
|
62
63
|
);
|
|
63
64
|
}
|
|
64
65
|
};
|
|
@@ -210,11 +211,12 @@ const rgb2Hex = (r: number, g: number, b: number): string =>
|
|
|
210
211
|
'#' + r.toString(16) + g.toString(16) + b.toString(16);
|
|
211
212
|
|
|
212
213
|
const colorCircleTheme = EditorView.baseTheme({
|
|
213
|
-
'.color-circle-parent': {
|
|
214
|
+
'.color-circle-parent': {
|
|
215
|
+
display: 'inline-block',
|
|
216
|
+
cursor: 'inherit',
|
|
217
|
+
},
|
|
214
218
|
});
|
|
215
219
|
|
|
216
|
-
const colorCircleAnnotation = Annotation.define();
|
|
217
|
-
|
|
218
220
|
export const colorsInTextPlugin: Extension = [
|
|
219
221
|
ViewPlugin.fromClass(
|
|
220
222
|
class {
|
|
@@ -232,7 +234,8 @@ export const colorsInTextPlugin: Extension = [
|
|
|
232
234
|
const lines = v.view.state.doc.iter();
|
|
233
235
|
let line = lines.next();
|
|
234
236
|
|
|
235
|
-
//Offset is the number of characters before the hex
|
|
237
|
+
// Offset is the number of characters before the hex
|
|
238
|
+
// so the circle can be placed properly.
|
|
236
239
|
let offset = 0;
|
|
237
240
|
while (!line.done) {
|
|
238
241
|
if (line.value === '\n') {
|
|
@@ -240,15 +243,16 @@ export const colorsInTextPlugin: Extension = [
|
|
|
240
243
|
line = lines.next();
|
|
241
244
|
continue;
|
|
242
245
|
}
|
|
243
|
-
const
|
|
244
|
-
/\"\#([0-9]|[A-F]|[a-f]){6}\"/g,
|
|
246
|
+
const hexColorOccurences = line.value.matchAll(
|
|
247
|
+
// /\"\#([0-9]|[A-F]|[a-f]){6}\"/g,
|
|
248
|
+
/["']\#([0-9]|[A-F]|[a-f]){6}["']/g,
|
|
245
249
|
);
|
|
246
|
-
let hexOccurance =
|
|
250
|
+
let hexOccurance = hexColorOccurences.next();
|
|
247
251
|
while (!hexOccurance.done) {
|
|
248
252
|
const offsetColorInfo = hexOccurance.value;
|
|
249
253
|
offsetColorInfo.index += offset;
|
|
250
254
|
colorInfos.push(offsetColorInfo);
|
|
251
|
-
hexOccurance =
|
|
255
|
+
hexOccurance = hexColorOccurences.next();
|
|
252
256
|
}
|
|
253
257
|
offset += line.value.length;
|
|
254
258
|
line = lines.next();
|
|
@@ -257,7 +261,7 @@ export const colorsInTextPlugin: Extension = [
|
|
|
257
261
|
return Decoration.set(
|
|
258
262
|
colorInfos.map((colorInfo) => {
|
|
259
263
|
return {
|
|
260
|
-
//9 is the length of the hex color string including quotation marks
|
|
264
|
+
// 9 is the length of the hex color string including quotation marks
|
|
261
265
|
from: colorInfo.index + 9,
|
|
262
266
|
to: colorInfo.index + 9,
|
|
263
267
|
value: Decoration.widget({
|
|
@@ -287,8 +291,13 @@ class ColorWidget extends WidgetType {
|
|
|
287
291
|
|
|
288
292
|
toDOM(view: EditorView): HTMLElement {
|
|
289
293
|
const parent = document.createElement('div');
|
|
294
|
+
const size = 20;
|
|
295
|
+
const innerSize = 16;
|
|
290
296
|
|
|
291
|
-
parent.setAttribute(
|
|
297
|
+
parent.setAttribute(
|
|
298
|
+
'style',
|
|
299
|
+
`width:${size}px;height:${size}px`,
|
|
300
|
+
);
|
|
292
301
|
parent.className = 'color-circle-parent';
|
|
293
302
|
const svg = document.createElementNS(
|
|
294
303
|
'http://www.w3.org/2000/svg',
|
|
@@ -301,15 +310,23 @@ class ColorWidget extends WidgetType {
|
|
|
301
310
|
colorCircle.setAttributeNS(
|
|
302
311
|
null,
|
|
303
312
|
'fill',
|
|
304
|
-
this.color.replace(
|
|
313
|
+
this.color.replace(/["']/g, ''),
|
|
314
|
+
);
|
|
315
|
+
colorCircle.setAttributeNS(null, 'stroke', 'black');
|
|
316
|
+
colorCircle.setAttributeNS(
|
|
317
|
+
null,
|
|
318
|
+
'r',
|
|
319
|
+
'' + innerSize / 2,
|
|
320
|
+
);
|
|
321
|
+
colorCircle.setAttributeNS(null, 'cx', '' + size / 2);
|
|
322
|
+
colorCircle.setAttributeNS(
|
|
323
|
+
null,
|
|
324
|
+
'cy',
|
|
325
|
+
'' + (size / 2 - 1),
|
|
305
326
|
);
|
|
306
|
-
colorCircle.setAttributeNS(null, 'r', '5');
|
|
307
|
-
colorCircle.setAttributeNS(null, 'cx', '5');
|
|
308
|
-
colorCircle.setAttributeNS(null, 'cy', '5');
|
|
309
327
|
|
|
310
|
-
svg.setAttributeNS(null, '
|
|
311
|
-
svg.setAttributeNS(null, '
|
|
312
|
-
svg.setAttributeNS(null, 'height', '10');
|
|
328
|
+
svg.setAttributeNS(null, 'width', '' + size);
|
|
329
|
+
svg.setAttributeNS(null, 'height', '' + size);
|
|
313
330
|
|
|
314
331
|
svg.appendChild(colorCircle);
|
|
315
332
|
|
|
@@ -94,6 +94,7 @@ export const VZCodeProvider = ({
|
|
|
94
94
|
initialUsername,
|
|
95
95
|
children,
|
|
96
96
|
codeError = null,
|
|
97
|
+
enableManualPretter = false,
|
|
97
98
|
}: {
|
|
98
99
|
content: VZCodeContent;
|
|
99
100
|
shareDBDoc: ShareDBDoc<VZCodeContent>;
|
|
@@ -107,17 +108,19 @@ export const VZCodeProvider = ({
|
|
|
107
108
|
initialUsername: Username;
|
|
108
109
|
children: React.ReactNode;
|
|
109
110
|
codeError?: string | null;
|
|
111
|
+
enableManualPretter?: boolean;
|
|
110
112
|
}) => {
|
|
111
113
|
// Auto-run Pretter after local changes.
|
|
112
114
|
const {
|
|
113
115
|
prettierError,
|
|
114
116
|
}: {
|
|
115
117
|
prettierError: string | null;
|
|
116
|
-
} = usePrettier(
|
|
118
|
+
} = usePrettier({
|
|
117
119
|
shareDBDoc,
|
|
118
120
|
submitOperation,
|
|
119
121
|
prettierWorker,
|
|
120
|
-
|
|
122
|
+
enableManualPretter,
|
|
123
|
+
});
|
|
121
124
|
|
|
122
125
|
// The error message shows either:
|
|
123
126
|
// * `prettierError` - errors from Prettier, client-side only
|
package/src/client/VZLeft.tsx
CHANGED
|
@@ -6,7 +6,7 @@ import { VZCodeContext } from './VZCodeContext';
|
|
|
6
6
|
// The middle portion of the VZCode environment, containing:
|
|
7
7
|
// * The sidebar
|
|
8
8
|
// * The settings modal
|
|
9
|
-
export const VZLeft = () => {
|
|
9
|
+
export const VZLeft = ({ enableUsernameField = true }) => {
|
|
10
10
|
// TODO leverage this context in deeper levels of the component tree.
|
|
11
11
|
const {
|
|
12
12
|
files,
|
|
@@ -50,6 +50,7 @@ export const VZLeft = () => {
|
|
|
50
50
|
setTheme={setTheme}
|
|
51
51
|
username={username}
|
|
52
52
|
setUsername={setUsername}
|
|
53
|
+
enableUsernameField={enableUsernameField}
|
|
53
54
|
/>
|
|
54
55
|
</div>
|
|
55
56
|
);
|
package/src/client/VZMiddle.tsx
CHANGED
|
@@ -13,7 +13,7 @@ import { VZCodeContext } from './VZCodeContext';
|
|
|
13
13
|
// * The code error overlay
|
|
14
14
|
// * The presence notifications
|
|
15
15
|
// * The UI for AI Assist
|
|
16
|
-
export const VZMiddle = () => {
|
|
16
|
+
export const VZMiddle = ({ enableAIAssist = true }) => {
|
|
17
17
|
const { codeEditorWidth } = useContext(
|
|
18
18
|
SplitPaneResizeContext,
|
|
19
19
|
);
|
|
@@ -78,7 +78,7 @@ export const VZMiddle = () => {
|
|
|
78
78
|
docPresence={docPresence}
|
|
79
79
|
localPresence={localPresence}
|
|
80
80
|
/>
|
|
81
|
-
{content && activeFileId ? (
|
|
81
|
+
{enableAIAssist && content && activeFileId ? (
|
|
82
82
|
<AIAssistWidget
|
|
83
83
|
activeFileId={activeFileId}
|
|
84
84
|
shareDBDoc={shareDBDoc}
|
package/src/client/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { JSONOp } from 'ot
|
|
1
|
+
import { JSONOp } from '../../ot';
|
|
2
2
|
import {
|
|
3
3
|
FileId,
|
|
4
4
|
ShareDBDoc,
|
|
@@ -20,16 +20,58 @@ const extension = (fileName: string) => {
|
|
|
20
20
|
}
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
export const
|
|
24
|
-
|
|
23
|
+
// export const shouldTriggerRun = (event: KeyboardEvent) => {
|
|
24
|
+
// if(event.ctrlKey && event.key === 's') {
|
|
25
|
+
// return true;
|
|
26
|
+
// }
|
|
27
|
+
// }
|
|
28
|
+
|
|
29
|
+
export const shouldTriggerRun = (event: KeyboardEvent) => {
|
|
30
|
+
const isMac = /Mac|iMac|MacBook/i.test(
|
|
31
|
+
navigator.userAgent,
|
|
32
|
+
);
|
|
33
|
+
const ctrlOrCmd = isMac ? event.metaKey : event.ctrlKey;
|
|
34
|
+
|
|
35
|
+
if (ctrlOrCmd && event.key === 's') {
|
|
36
|
+
// Save
|
|
37
|
+
return true;
|
|
38
|
+
} else if (
|
|
39
|
+
event.key === 'F5' || // Run (F5)
|
|
40
|
+
(ctrlOrCmd && event.key === 'Enter') || // Ctrl+Enter or Cmd+Enter
|
|
41
|
+
(event.shiftKey && event.key === 'Enter') || // Shift+Enter
|
|
42
|
+
// Let's not override the browser's default behavior for refresh page.
|
|
43
|
+
// (ctrlOrCmd && event.key === 'r') || // Ctrl+R or Cmd+R
|
|
44
|
+
|
|
45
|
+
(event.altKey && event.key === 'Enter') || // Alt+Enter
|
|
46
|
+
(ctrlOrCmd &&
|
|
47
|
+
event.shiftKey &&
|
|
48
|
+
(event.key === 'B' || event.key === 'b')) || // Ctrl+Shift+B or Cmd+Shift+B
|
|
49
|
+
(ctrlOrCmd && event.shiftKey && event.key === 'F10') || // Ctrl+Shift+F10 or Cmd+Shift+F10
|
|
50
|
+
event.key === 'F8' ||
|
|
51
|
+
event.key === 'F9'
|
|
52
|
+
) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const usePrettier = ({
|
|
59
|
+
shareDBDoc,
|
|
60
|
+
submitOperation,
|
|
61
|
+
prettierWorker,
|
|
62
|
+
enableManualPretter,
|
|
63
|
+
}: {
|
|
64
|
+
shareDBDoc: ShareDBDoc<VZCodeContent> | null;
|
|
25
65
|
submitOperation: (
|
|
26
66
|
next: (content: VZCodeContent) => VZCodeContent,
|
|
27
|
-
) => void
|
|
28
|
-
prettierWorker: Worker
|
|
29
|
-
|
|
67
|
+
) => void;
|
|
68
|
+
prettierWorker: Worker;
|
|
69
|
+
enableManualPretter: boolean;
|
|
70
|
+
}) => {
|
|
30
71
|
// The set of files that have been modified
|
|
31
72
|
// since the last Prettier run.
|
|
32
|
-
const dirtyFiles: Set<FileId> = new Set<FileId>();
|
|
73
|
+
// const dirtyFiles: Set<FileId> = new Set<FileId>();
|
|
74
|
+
const dirtyFilesRef = useRef<Set<FileId>>(new Set());
|
|
33
75
|
|
|
34
76
|
// State to hold the error from Prettier
|
|
35
77
|
// `null` means no errors
|
|
@@ -95,6 +137,9 @@ export const usePrettier = (
|
|
|
95
137
|
// Get the files
|
|
96
138
|
const files = content.files;
|
|
97
139
|
|
|
140
|
+
// Get the set of dirty files
|
|
141
|
+
const dirtyFiles = dirtyFilesRef.current;
|
|
142
|
+
|
|
98
143
|
// Get the dirty files
|
|
99
144
|
const dirtyFileIds = Array.from(dirtyFiles);
|
|
100
145
|
|
|
@@ -118,20 +163,35 @@ export const usePrettier = (
|
|
|
118
163
|
}
|
|
119
164
|
};
|
|
120
165
|
|
|
121
|
-
|
|
166
|
+
let debouncePrettier;
|
|
122
167
|
let debounceTimeout;
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
168
|
+
let handleKeyDown;
|
|
169
|
+
if (enableManualPretter) {
|
|
170
|
+
handleKeyDown = (event: KeyboardEvent) => {
|
|
171
|
+
if (shouldTriggerRun(event)) {
|
|
172
|
+
event.preventDefault();
|
|
173
|
+
runPrettier();
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
document.addEventListener('keydown', handleKeyDown);
|
|
177
|
+
} else {
|
|
178
|
+
// Function to debounce running Prettier
|
|
179
|
+
|
|
180
|
+
debouncePrettier = () => {
|
|
181
|
+
clearTimeout(debounceTimeout);
|
|
182
|
+
debounceTimeout = setTimeout(
|
|
183
|
+
runPrettier,
|
|
184
|
+
autoPrettierDebounceTimeMS,
|
|
185
|
+
);
|
|
186
|
+
};
|
|
187
|
+
//Stops prettier from running when you perform a mouse move or a keydown
|
|
188
|
+
window.addEventListener(
|
|
189
|
+
'mousemove',
|
|
190
|
+
debouncePrettier,
|
|
128
191
|
);
|
|
192
|
+
window.addEventListener('keydown', debouncePrettier);
|
|
129
193
|
}
|
|
130
194
|
|
|
131
|
-
//Stops prettier from running when you perform a mouse move or a keydown
|
|
132
|
-
window.addEventListener('mousemove', debouncePrettier);
|
|
133
|
-
window.addEventListener('keydown', debouncePrettier);
|
|
134
|
-
|
|
135
195
|
// Listen for changes
|
|
136
196
|
shareDBDoc.on(
|
|
137
197
|
'op batch',
|
|
@@ -170,11 +230,12 @@ export const usePrettier = (
|
|
|
170
230
|
const fileId: FileId = op[1];
|
|
171
231
|
|
|
172
232
|
// Add the file id to the set of dirty files
|
|
173
|
-
|
|
233
|
+
dirtyFilesRef.current.add(fileId);
|
|
174
234
|
|
|
175
235
|
// Debounce running Prettier
|
|
176
|
-
|
|
177
|
-
|
|
236
|
+
if (!enableManualPretter) {
|
|
237
|
+
debouncePrettier();
|
|
238
|
+
}
|
|
178
239
|
// console.log('Op is for file', fileId);
|
|
179
240
|
}
|
|
180
241
|
} else {
|
|
@@ -190,17 +251,24 @@ export const usePrettier = (
|
|
|
190
251
|
'message',
|
|
191
252
|
handleMessage,
|
|
192
253
|
);
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
254
|
+
if (enableManualPretter) {
|
|
255
|
+
document.removeEventListener(
|
|
256
|
+
'keydown',
|
|
257
|
+
handleKeyDown,
|
|
258
|
+
);
|
|
259
|
+
} else {
|
|
260
|
+
window.removeEventListener(
|
|
261
|
+
'keydown',
|
|
262
|
+
debouncePrettier,
|
|
263
|
+
);
|
|
264
|
+
window.removeEventListener(
|
|
265
|
+
'mousemove',
|
|
266
|
+
debouncePrettier,
|
|
267
|
+
);
|
|
201
268
|
|
|
202
|
-
|
|
203
|
-
|
|
269
|
+
// Clear the timeout
|
|
270
|
+
clearTimeout(debounceTimeout);
|
|
271
|
+
}
|
|
204
272
|
};
|
|
205
273
|
}, [shareDBDoc]);
|
|
206
274
|
return { prettierError }; // Return the errors for use in other files
|
|
@@ -244,4 +244,24 @@ onmessage = async ({ data }) => {
|
|
|
244
244
|
};
|
|
245
245
|
postMessage(linterResponse);
|
|
246
246
|
}
|
|
247
|
+
|
|
248
|
+
// Handle the transpile-request event, which
|
|
249
|
+
// transpiles TypeScript to JavaScript.
|
|
250
|
+
if (data.event === 'transpile-request') {
|
|
251
|
+
const tsCode = data.tsCode;
|
|
252
|
+
|
|
253
|
+
const compilerOptions = {
|
|
254
|
+
jsx: ts.JsxEmit.React,
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
const jsCode = ts.transpileModule(tsCode, {
|
|
258
|
+
compilerOptions,
|
|
259
|
+
}).outputText;
|
|
260
|
+
|
|
261
|
+
postMessage({
|
|
262
|
+
event: 'transpile-response',
|
|
263
|
+
jsCode,
|
|
264
|
+
fileId: data.fileId,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
247
267
|
};
|