vzcode 0.81.0 → 0.82.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/index.html CHANGED
@@ -20,7 +20,7 @@
20
20
  href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap"
21
21
  rel="stylesheet"
22
22
  />
23
- <script type="module" crossorigin src="/assets/index-CnwdGSLW.js"></script>
23
+ <script type="module" crossorigin src="/assets/index-BKQfM_WG.js"></script>
24
24
  <link rel="stylesheet" crossorigin href="/assets/index-J8-kRnnE.css">
25
25
  </head>
26
26
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vzcode",
3
- "version": "0.81.0",
3
+ "version": "0.82.0",
4
4
  "description": "Multiplayer code editor system",
5
5
  "main": "src/index.ts",
6
6
  "type": "module",
@@ -74,7 +74,7 @@
74
74
  "@codemirror/view": "^6.26.0",
75
75
  "@lezer/highlight": "^1.2.0",
76
76
  "@replit/codemirror-indentation-markers": "^6.5.1",
77
- "@replit/codemirror-interact": "^6.3.0",
77
+ "@replit/codemirror-interact": "^6.3.1",
78
78
  "@replit/codemirror-lang-svelte": "^6.0.0",
79
79
  "@replit/codemirror-vscode-keymap": "^6.0.2",
80
80
  "@teamwork/websocket-json-stream": "^2.0.0",
@@ -112,7 +112,7 @@
112
112
  "ws": "^8.16.0"
113
113
  },
114
114
  "devDependencies": {
115
- "@types/react": "^18.2.71",
115
+ "@types/react": "^18.2.72",
116
116
  "@types/react-dom": "^18.2.22",
117
117
  "@vitejs/plugin-react": "^4.2.1",
118
118
  "concurrently": "^8.2.2",
@@ -55,6 +55,17 @@ export const AIAssistWidget = ({
55
55
  aiAssistOptions,
56
56
  });
57
57
 
58
+ // Introduce a delay before running Prettier
59
+ // and the code, to give the ShareDB ops a chance
60
+ // to be applied and to propagate via WebSockets
61
+ // to the client. This is necessary because sometimes
62
+ // the ShareDB ops from the AI assist actually don't
63
+ // reach the client until AFTER the response comes back
64
+ // from `await startAIAssist`.
65
+ await new Promise((resolve) =>
66
+ setTimeout(resolve, 1000),
67
+ );
68
+
58
69
  // Trigger a Prettier run after the AI Assist.
59
70
  const runPrettier = runPrettierRef.current;
60
71
  if (runPrettier !== null) {
@@ -69,7 +80,7 @@ export const AIAssistWidget = ({
69
80
 
70
81
  // Handles the case that the user has started,
71
82
  // stopped, and started again before the first request
72
- // has finished, bu comparing the current stream ID
83
+ // has finished, by comparing the current stream ID
73
84
  // with the stream ID that was active when the request
74
85
  // was started.
75
86
  setAiStreamId((currentAIStreamId) =>
@@ -91,6 +91,7 @@ export const getOrCreateEditor = ({
91
91
  usernameRef,
92
92
  typeScriptWorker,
93
93
  customInteractRules,
94
+ allowGlobals,
94
95
  }: {
95
96
  fileId: FileId;
96
97
 
@@ -119,6 +120,7 @@ export const getOrCreateEditor = ({
119
120
  aiAssistEndpoint?: string;
120
121
  typeScriptWorker: Worker;
121
122
  customInteractRules?: Array<InteractRule>;
123
+ allowGlobals: boolean;
122
124
  }): EditorCacheValue => {
123
125
  // Cache hit
124
126
  if (editorCache.has(fileId)) {
@@ -276,6 +278,7 @@ export const getOrCreateEditor = ({
276
278
  fileName: name,
277
279
  shareDBDoc,
278
280
  fileId,
281
+ allowGlobals,
279
282
  }) as unknown as () => Diagnostic[],
280
283
  //Needs the unknown because we are returning a Promise<Diagnostic>
281
284
  ),
@@ -9,16 +9,18 @@ import { Username } from '../../types';
9
9
  import { EditorCacheValue } from '../useEditorCache';
10
10
  import { getOrCreateEditor } from './getOrCreateEditor';
11
11
  import { VZCodeContext } from '../VZCodeContext';
12
- import './style.scss';
13
12
  import { InteractRule } from '@replit/codemirror-interact';
13
+ import './style.scss';
14
14
 
15
15
  // The path in the ShareDB document where the files live.
16
16
  const filesPath = ['files'];
17
17
 
18
18
  export const CodeEditor = ({
19
19
  customInteractRules,
20
+ allowGlobals,
20
21
  }: {
21
22
  customInteractRules?: Array<InteractRule>;
23
+ allowGlobals: boolean;
22
24
  }) => {
23
25
  const {
24
26
  activeFileId,
@@ -85,6 +87,7 @@ export const CodeEditor = ({
85
87
  usernameRef,
86
88
  typeScriptWorker,
87
89
  customInteractRules,
90
+ allowGlobals,
88
91
  }),
89
92
  [
90
93
  activeFileId,
@@ -10,6 +10,7 @@ export const typeScriptLinter = ({
10
10
  fileName,
11
11
  shareDBDoc,
12
12
  fileId,
13
+ allowGlobals,
13
14
  }) => {
14
15
  return async () => {
15
16
  const requestId = generateRequestId();
@@ -20,6 +21,7 @@ export const typeScriptLinter = ({
20
21
  fileName,
21
22
  fileContent,
22
23
  requestId,
24
+ allowGlobals,
23
25
  };
24
26
  typeScriptWorker.postMessage(linterRequest);
25
27
 
@@ -1,9 +1,11 @@
1
1
  // TODO move back to this way of importing when this PR is merged:
2
2
  // https://github.com/replit/codemirror-interact/pull/19/files
3
- // import interact from '@replit/codemirror-interact';
4
3
  import interact, {
5
4
  InteractRule,
6
- } from './codemirror-interact';
5
+ } from '@replit/codemirror-interact';
6
+ // import interact, {
7
+ // InteractRule,
8
+ // } from './codemirror-interact';
7
9
 
8
10
  import {
9
11
  ViewPlugin,
@@ -22,6 +22,7 @@ export const VZMiddle = ({
22
22
  aiAssistTooltipText,
23
23
  aiAssistClickOverride,
24
24
  customInteractRules,
25
+ allowGlobals = false,
25
26
  }: {
26
27
  enableAIAssist?: boolean;
27
28
  aiAssistEndpoint?: string;
@@ -29,6 +30,7 @@ export const VZMiddle = ({
29
30
  aiAssistTooltipText?: string;
30
31
  aiAssistClickOverride?: () => void;
31
32
  customInteractRules?: Array<InteractRule>;
33
+ allowGlobals?: boolean;
32
34
  }) => {
33
35
  const { codeEditorWidth } = useContext(
34
36
  SplitPaneResizeContext,
@@ -58,6 +60,7 @@ export const VZMiddle = ({
58
60
  {isClient && content && activeFileId && (
59
61
  <CodeEditor
60
62
  customInteractRules={customInteractRules}
63
+ allowGlobals={allowGlobals}
61
64
  />
62
65
  )}
63
66
  {isClient &&
@@ -64,9 +64,6 @@ export const VZSettings = ({
64
64
  }, [selectedFont]);
65
65
 
66
66
  useEffect(() => {
67
- // const fontSize = event.target.value;
68
- // const root = document.documentElement;
69
- // root.style.setProperty('--vzcode-font-size', fontSize);
70
67
  document.body.style.setProperty(
71
68
  '--vzcode-font-size',
72
69
  selectedFontSize,
@@ -109,7 +106,6 @@ export const VZSettings = ({
109
106
 
110
107
  <Form.Group className="mb-3" controlId="formFork">
111
108
  <Form.Label>Theme</Form.Label>
112
-
113
109
  <select
114
110
  className="form-select"
115
111
  value={theme}
@@ -121,7 +117,6 @@ export const VZSettings = ({
121
117
  </option>
122
118
  ))}
123
119
  </select>
124
-
125
120
  <Form.Text className="text-muted">
126
121
  Select a color theme for the editor
127
122
  </Form.Text>
@@ -129,7 +124,6 @@ export const VZSettings = ({
129
124
 
130
125
  <Form.Group className="mb-3" controlId="formFork">
131
126
  <Form.Label>Font</Form.Label>
132
-
133
127
  <select
134
128
  className="form-select"
135
129
  onChange={handleFontChange}
@@ -141,7 +135,6 @@ export const VZSettings = ({
141
135
  </option>
142
136
  ))}
143
137
  </select>
144
-
145
138
  <Form.Text className="text-muted">
146
139
  Select font for the editor
147
140
  </Form.Text>
@@ -149,7 +142,6 @@ export const VZSettings = ({
149
142
 
150
143
  <Form.Group className="mb-3" controlId="formFork">
151
144
  <Form.Label>Font Size</Form.Label>
152
-
153
145
  <select
154
146
  className="form-select"
155
147
  onChange={handleFontSizeChange}
@@ -161,11 +153,53 @@ export const VZSettings = ({
161
153
  </option>
162
154
  ))}
163
155
  </select>
164
-
165
156
  <Form.Text className="text-muted">
166
157
  Select a font size for the editor
167
158
  </Form.Text>
168
159
  </Form.Group>
160
+
161
+ {/* Keyboard Shortcuts Documentation */}
162
+ <Form.Group className="mb-3" controlId="formFork">
163
+ <Form.Label>Keyboard Shortcuts</Form.Label>
164
+ <ul>
165
+ <li>
166
+ <strong>Alt-w</strong> <span>⌥W</span>
167
+ <br />
168
+ <span>Close the current tab</span>
169
+ </li>
170
+ <li>
171
+ <strong>Alt-n</strong> <span>⌥N</span>
172
+ <br />
173
+ <span>Open the create file modal</span>
174
+ </li>
175
+ <li>
176
+ <strong>Alt-PageUp</strong> <span>⌥⇞</span>
177
+ <br />
178
+ <span>
179
+ Change the active tab to the previous one
180
+ </span>
181
+ </li>
182
+ <li>
183
+ <strong>Alt-PageDown</strong> <span>⌥⇟</span>
184
+ <br />
185
+ <span>
186
+ Change the active tab to the next one
187
+ </span>
188
+ </li>
189
+ <li>
190
+ <strong>Ctrl-s</strong> or{' '}
191
+ <strong>Shift-Enter</strong> <span>⌘S</span>{' '}
192
+ or <span>⇧↩</span>
193
+ <br />
194
+ <span>
195
+ Run the code and format it with Prettier
196
+ </span>
197
+ </li>
198
+ </ul>
199
+ <Form.Text className="text-muted">
200
+ Keyboard shortcuts for quick actions
201
+ </Form.Text>
202
+ </Form.Group>
169
203
  </Modal.Body>
170
204
  <Modal.Footer>
171
205
  <Button variant="primary" onClick={closeSettings}>
@@ -20,6 +20,9 @@ export type LinterRequest = {
20
20
  fileName: string;
21
21
  fileContent: string;
22
22
  requestId: string;
23
+
24
+ // If true, linting will not show errors for global variables.
25
+ allowGlobals?: boolean;
23
26
  };
24
27
 
25
28
  export type LinterResponse = {
@@ -217,8 +217,12 @@ onmessage = async ({ data }) => {
217
217
  console.log('Lint Request');
218
218
  }
219
219
  const linterRequest: LinterRequest = data;
220
- const { fileName, fileContent, requestId } =
221
- linterRequest;
220
+ const {
221
+ fileName,
222
+ fileContent,
223
+ requestId,
224
+ allowGlobals,
225
+ } = linterRequest;
222
226
 
223
227
  const tsFileName = getTSFileName(fileName);
224
228
  let tsErrors = [];
@@ -271,6 +275,9 @@ onmessage = async ({ data }) => {
271
275
  // is not assignable to parameter of type 'never'.
272
276
  const LINT_ERROR_CODE_ASSIGNABLE_TO_NEVER = 2345;
273
277
 
278
+ // Cannot find name 'd3'.
279
+ const LINT_ERROR_CODE_CANNOT_FIND_NAME = 2304;
280
+
274
281
  if (debug) {
275
282
  console.log('tsErrors');
276
283
  console.log(tsErrors);
@@ -286,7 +293,13 @@ onmessage = async ({ data }) => {
286
293
  LINT_ERROR_CODE_NON_EXISTENT_PROPERTY &&
287
294
  error.code !== LINT_ERROR_CODE_ITERATED_THROUGH &&
288
295
  error.code !==
289
- LINT_ERROR_CODE_ASSIGNABLE_TO_NEVER,
296
+ LINT_ERROR_CODE_ASSIGNABLE_TO_NEVER &&
297
+ // If allowGlobals is true, we will allow
298
+ // global variables to be used without error.
299
+ allowGlobals
300
+ ? error.code !==
301
+ LINT_ERROR_CODE_CANNOT_FIND_NAME
302
+ : true,
290
303
  );
291
304
  // }
292
305
  tsErrors = convertToCodeMirrorDiagnostic(tsErrors);