vzcode 2.2.0 → 2.3.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.
Files changed (220) hide show
  1. package/dist/assets/{buildWorker-Dsx6rOdK.js → buildWorker-wLkQ0yz1.js} +64 -64
  2. package/dist/assets/{index-BM8tDh6M.css → index-BoFeK4GL.css} +1 -1
  3. package/dist/assets/{index-CpxqGhXj.js → index-DuUjtrt6.js} +150 -150
  4. package/dist/assets/{worker-BeBZGG1n.js → worker-DHxSPM7N.js} +78 -78
  5. package/dist/cli.js +113 -0
  6. package/dist/index.html +2 -2
  7. package/{src/ot.ts → dist/ot.js} +2 -14
  8. package/{src/randomId.ts → dist/randomId.js} +5 -6
  9. package/dist/runCode.js +20 -0
  10. package/dist/server/aiChatHandler/aiEditing.js +89 -0
  11. package/dist/server/aiChatHandler/chatOperations.js +360 -0
  12. package/dist/server/aiChatHandler/errorHandling.js +49 -0
  13. package/dist/server/aiChatHandler/index.js +112 -0
  14. package/dist/server/aiChatHandler/llmStreaming.js +284 -0
  15. package/dist/server/aiChatHandler/validation.js +19 -0
  16. package/dist/server/computeInitialDocument.js +146 -0
  17. package/{src/server/config.ts → dist/server/config.js} +4 -7
  18. package/{src/server/featureFlags.ts → dist/server/featureFlags.js} +0 -3
  19. package/dist/server/generateAIResponse.js +129 -0
  20. package/dist/server/handleAIAssist.js +39 -0
  21. package/dist/server/handleAICopilot.js +81 -0
  22. package/dist/server/index.js +297 -0
  23. package/dist/server/livekit.js +17 -0
  24. package/dist/server/prettier.js +90 -0
  25. package/{src/server/setupEnv.ts → dist/server/setupEnv.js} +1 -2
  26. package/dist/submitOperation.js +14 -0
  27. package/dist/types.js +1 -0
  28. package/dist/utils/fileDiff.js +66 -0
  29. package/package.json +22 -22
  30. package/src/client/AIAssist/AIAssistCodeMirrorKeyMap.ts +0 -42
  31. package/src/client/AIAssist/AIAssistWidget/index.tsx +0 -135
  32. package/src/client/AIAssist/AIAssistWidget/style.scss +0 -47
  33. package/src/client/AIAssist/Spinner.jsx +0 -76
  34. package/src/client/AIAssist/formatFile.ts +0 -27
  35. package/src/client/AIAssist/generateFilesContext.ts +0 -25
  36. package/src/client/AIAssist/index.ts +0 -2
  37. package/src/client/AIAssist/startAIAssist.ts +0 -95
  38. package/src/client/App/index.tsx +0 -153
  39. package/src/client/App/style.scss +0 -82
  40. package/src/client/App/usePending.ts +0 -51
  41. package/src/client/App/useShareDB.ts +0 -161
  42. package/src/client/CodeEditor/Copilot/index.ts +0 -74
  43. package/src/client/CodeEditor/InteractiveWidgets/boolToggler.ts +0 -12
  44. package/src/client/CodeEditor/InteractiveWidgets/colorPicker.ts +0 -68
  45. package/src/client/CodeEditor/InteractiveWidgets/colorsInTextPlugin.ts +0 -174
  46. package/src/client/CodeEditor/InteractiveWidgets/highlightWidgets.ts +0 -79
  47. package/src/client/CodeEditor/InteractiveWidgets/index.ts +0 -44
  48. package/src/client/CodeEditor/InteractiveWidgets/markdownCheckboxToggler.ts +0 -12
  49. package/src/client/CodeEditor/InteractiveWidgets/numberDragger.ts +0 -20
  50. package/src/client/CodeEditor/InteractiveWidgets/rotateWidget.ts +0 -143
  51. package/src/client/CodeEditor/InteractiveWidgets/urlClicker.test.ts +0 -48
  52. package/src/client/CodeEditor/InteractiveWidgets/urlClicker.ts +0 -12
  53. package/src/client/CodeEditor/InteractiveWidgets/vec2Slider.ts +0 -25
  54. package/src/client/CodeEditor/basicSetup.ts +0 -73
  55. package/src/client/CodeEditor/getOrCreateEditor.tsx +0 -615
  56. package/src/client/CodeEditor/index.tsx +0 -202
  57. package/src/client/CodeEditor/json1PresenceBroadcast.ts +0 -41
  58. package/src/client/CodeEditor/json1PresenceDisplay.ts +0 -350
  59. package/src/client/CodeEditor/rainbowBrackets.ts +0 -122
  60. package/src/client/CodeEditor/style.scss +0 -156
  61. package/src/client/CodeEditor/typescriptExtension/worker.ts +0 -32
  62. package/src/client/CodeErrorOverlay/index.tsx +0 -77
  63. package/src/client/CodeErrorOverlay/style.scss +0 -33
  64. package/src/client/Fonts/fonts.ts +0 -8
  65. package/src/client/Icons/AdjustmentSVG.tsx +0 -19
  66. package/src/client/Icons/BugSVG.tsx +0 -20
  67. package/src/client/Icons/CloseSVG.tsx +0 -19
  68. package/src/client/Icons/CssSVG.tsx +0 -16
  69. package/src/client/Icons/DirectoryArrowSVG.tsx +0 -19
  70. package/src/client/Icons/EditSVG.tsx +0 -19
  71. package/src/client/Icons/FileSVG.tsx +0 -19
  72. package/src/client/Icons/FolderSVG.tsx +0 -20
  73. package/src/client/Icons/GearSVG.tsx +0 -16
  74. package/src/client/Icons/HtmlSVG.tsx +0 -16
  75. package/src/client/Icons/JavaScriptSVG.tsx +0 -16
  76. package/src/client/Icons/JsonSVG.tsx +0 -16
  77. package/src/client/Icons/MarkdownSVG.tsx +0 -16
  78. package/src/client/Icons/MicOffSVG.tsx +0 -35
  79. package/src/client/Icons/MicSVG.tsx +0 -25
  80. package/src/client/Icons/NewSVG.tsx +0 -19
  81. package/src/client/Icons/PinSVG.tsx +0 -14
  82. package/src/client/Icons/PlaySVG.tsx +0 -16
  83. package/src/client/Icons/QuestionMarkSVG.tsx +0 -18
  84. package/src/client/Icons/ReactSVG.tsx +0 -16
  85. package/src/client/Icons/SearchSVG.tsx +0 -20
  86. package/src/client/Icons/SparklesSVG.tsx +0 -23
  87. package/src/client/Icons/SplitEditorSVG.tsx +0 -34
  88. package/src/client/Icons/StopSVG.tsx +0 -15
  89. package/src/client/Icons/SvelteSVG.tsx +0 -16
  90. package/src/client/Icons/TrashSVG.tsx +0 -19
  91. package/src/client/Icons/TypeScriptSVG.tsx +0 -16
  92. package/src/client/Icons/index.tsx +0 -26
  93. package/src/client/ImageViewer/index.tsx +0 -91
  94. package/src/client/ImageViewer/style.scss +0 -41
  95. package/src/client/PresenceNotifications/PresenceNotifications.test.ts +0 -134
  96. package/src/client/PresenceNotifications/index.tsx +0 -158
  97. package/src/client/PresenceNotifications/style.scss +0 -17
  98. package/src/client/RunCodeWidget/index.tsx +0 -117
  99. package/src/client/RunCodeWidget/style.scss +0 -24
  100. package/src/client/SplitPaneResizeContext.tsx +0 -159
  101. package/src/client/TabList/Tab.tsx +0 -73
  102. package/src/client/TabList/index.tsx +0 -35
  103. package/src/client/TabList/style.scss +0 -51
  104. package/src/client/VZCodeContext/index.tsx +0 -29
  105. package/src/client/VZCodeContext/types.ts +0 -249
  106. package/src/client/VZCodeContext/useVZCodeState.ts +0 -584
  107. package/src/client/VZKeyboardShortcutsDoc.tsx +0 -148
  108. package/src/client/VZLeft.tsx +0 -28
  109. package/src/client/VZMiddle.tsx +0 -172
  110. package/src/client/VZResizer/index.tsx +0 -128
  111. package/src/client/VZResizer/styles.scss +0 -33
  112. package/src/client/VZRight.tsx +0 -113
  113. package/src/client/VZSettings.tsx +0 -275
  114. package/src/client/VZSidebar/AIChat/ChatInput.tsx +0 -239
  115. package/src/client/VZSidebar/AIChat/DiffView.scss +0 -136
  116. package/src/client/VZSidebar/AIChat/DiffView.tsx +0 -176
  117. package/src/client/VZSidebar/AIChat/Message.tsx +0 -143
  118. package/src/client/VZSidebar/AIChat/MessageList.tsx +0 -205
  119. package/src/client/VZSidebar/AIChat/StreamingMessage.tsx +0 -35
  120. package/src/client/VZSidebar/AIChat/ThinkingScratchpad.tsx +0 -156
  121. package/src/client/VZSidebar/AIChat/TypingIndicator.tsx +0 -19
  122. package/src/client/VZSidebar/AIChat/index.tsx +0 -273
  123. package/src/client/VZSidebar/AIChat/styles.scss +0 -627
  124. package/src/client/VZSidebar/AIChat/useSpeechRecognition.ts +0 -117
  125. package/src/client/VZSidebar/CreateDirModal.tsx +0 -111
  126. package/src/client/VZSidebar/CreateFileModal.tsx +0 -111
  127. package/src/client/VZSidebar/DeleteConfirmationModal.tsx +0 -76
  128. package/src/client/VZSidebar/DirectoryListing.tsx +0 -89
  129. package/src/client/VZSidebar/EmptyState.tsx +0 -11
  130. package/src/client/VZSidebar/FileListing.tsx +0 -91
  131. package/src/client/VZSidebar/FileTypeIcon.tsx +0 -49
  132. package/src/client/VZSidebar/Item.tsx +0 -237
  133. package/src/client/VZSidebar/Listing.tsx +0 -47
  134. package/src/client/VZSidebar/Search.tsx +0 -527
  135. package/src/client/VZSidebar/VisualEditor.tsx +0 -282
  136. package/src/client/VZSidebar/VoiceChatModal.tsx +0 -121
  137. package/src/client/VZSidebar/aiCopyPaste.ts +0 -199
  138. package/src/client/VZSidebar/index.tsx +0 -728
  139. package/src/client/VZSidebar/styles.scss +0 -612
  140. package/src/client/VZSidebar/useDragAndDrop.tsx +0 -408
  141. package/src/client/bootstrap.ts +0 -26
  142. package/src/client/buildWorker.ts +0 -3
  143. package/src/client/featureFlags.ts +0 -8
  144. package/src/client/generateRequestId.ts +0 -6
  145. package/src/client/getFileTree.ts +0 -53
  146. package/src/client/index.ts +0 -19
  147. package/src/client/main.jsx +0 -10
  148. package/src/client/presenceColor.ts +0 -8
  149. package/src/client/shouldTriggerRun.ts +0 -31
  150. package/src/client/sortFileTree.ts +0 -21
  151. package/src/client/tabsSearchParameters.test.ts +0 -79
  152. package/src/client/tabsSearchParameters.ts +0 -137
  153. package/src/client/themes/index.ts +0 -7
  154. package/src/client/themes/themes.ts +0 -77
  155. package/src/client/themes/uiwImports.ts +0 -32
  156. package/src/client/themes/useDynamicTheme.ts +0 -29
  157. package/src/client/themes/vizhubTheme/colors.ts +0 -80
  158. package/src/client/themes/vizhubTheme/index.ts +0 -193
  159. package/src/client/useActions.ts +0 -288
  160. package/src/client/useESLint/index.ts +0 -72
  161. package/src/client/useESLint/worker.ts +0 -113
  162. package/src/client/useEditorCache.ts +0 -35
  163. package/src/client/useFileCRUD.ts +0 -228
  164. package/src/client/useKeyboardShortcuts.ts +0 -451
  165. package/src/client/useOpenDirectories.ts +0 -99
  166. package/src/client/usePresenceAutoFollow.ts +0 -85
  167. package/src/client/usePrettier/index.ts +0 -178
  168. package/src/client/usePrettier/worker.ts +0 -109
  169. package/src/client/useRunCode.tsx +0 -15
  170. package/src/client/useRuntimeError.ts +0 -32
  171. package/src/client/useSubmitOperation.ts +0 -15
  172. package/src/client/useURLSync.ts +0 -137
  173. package/src/client/usernameLocalStorage.ts +0 -43
  174. package/src/client/utils/fileExtension.ts +0 -10
  175. package/src/client/utils/isImageFile.ts +0 -12
  176. package/src/client/vzReducer/aiChatReducer.ts +0 -44
  177. package/src/client/vzReducer/closeTabReducer.test.ts +0 -205
  178. package/src/client/vzReducer/closeTabsReducer.ts +0 -96
  179. package/src/client/vzReducer/createInitialState.ts +0 -38
  180. package/src/client/vzReducer/editorNoLongerWantsFocusReducer.ts +0 -9
  181. package/src/client/vzReducer/findPane.ts +0 -19
  182. package/src/client/vzReducer/index.ts +0 -250
  183. package/src/client/vzReducer/openTabReducer.test.ts +0 -127
  184. package/src/client/vzReducer/openTabReducer.ts +0 -74
  185. package/src/client/vzReducer/searchReducer.test.ts +0 -292
  186. package/src/client/vzReducer/searchReducer.ts +0 -181
  187. package/src/client/vzReducer/setActiveFileIdReducer.ts +0 -28
  188. package/src/client/vzReducer/setActiveFileLeftRightReducer.ts +0 -76
  189. package/src/client/vzReducer/setIsDocOpenReducer.ts +0 -9
  190. package/src/client/vzReducer/setIsSettingsOpenReducer.ts +0 -9
  191. package/src/client/vzReducer/setThemeReducer.ts +0 -9
  192. package/src/client/vzReducer/setUsernameReducer.ts +0 -9
  193. package/src/client/vzReducer/splitCurrentPaneReducer.ts +0 -66
  194. package/src/client/vzReducer/toggleAutoFollowReducer.ts +0 -12
  195. package/src/client/vzReducer/updatePane.ts +0 -40
  196. package/src/client/vzReducer/updatePresenceIndicatorReducer.ts +0 -30
  197. package/src/client/vzReducer/visualEditorReducer.ts +0 -9
  198. package/src/reactRouterExports.ts +0 -15
  199. package/src/runCode.ts +0 -27
  200. package/src/server/aiChatHandler/aiEditing.ts +0 -152
  201. package/src/server/aiChatHandler/chatOperations.ts +0 -510
  202. package/src/server/aiChatHandler/errorHandling.ts +0 -66
  203. package/src/server/aiChatHandler/index.ts +0 -200
  204. package/src/server/aiChatHandler/llmStreaming.ts +0 -419
  205. package/src/server/aiChatHandler/undoHandler.ts +0 -97
  206. package/src/server/aiChatHandler/validation.ts +0 -24
  207. package/src/server/computeInitialDocument.ts +0 -220
  208. package/src/server/generateAIResponse.ts +0 -188
  209. package/src/server/handleAIAssist.ts +0 -53
  210. package/src/server/handleAIChatUndo.ts +0 -2
  211. package/src/server/handleAICopilot.ts +0 -97
  212. package/src/server/index.ts +0 -388
  213. package/src/server/livekit.ts +0 -24
  214. package/src/server/prettier.ts +0 -115
  215. package/src/submitOperation.ts +0 -25
  216. package/src/types.ts +0 -205
  217. package/src/utils/fileDiff.ts +0 -117
  218. package/src/vite-env.d.ts +0 -10
  219. /package/{src/server/handleAIChatMessage.ts → dist/server/handleAIChatMessage.js} +0 -0
  220. /package/{src/server/isDirectory.ts → dist/server/isDirectory.js} +0 -0
@@ -1,388 +0,0 @@
1
- #!/usr/bin/env node
2
- import WebSocketJSONStream from '@teamwork/websocket-json-stream';
3
- import bodyParser from 'body-parser';
4
- import express from 'express';
5
- import fs from 'fs';
6
- import http from 'http';
7
- import open from 'open';
8
- import path from 'path';
9
- import ShareDB from 'sharedb';
10
- import { fileURLToPath } from 'url';
11
- import { WebSocketServer } from 'ws';
12
- import { json1Presence } from '../ot.js';
13
- import { computeInitialDocument } from './computeInitialDocument.js';
14
- import { handleAIAssist } from './handleAIAssist.js';
15
- import { handleAICopilot } from './handleAICopilot.js';
16
- import { handleAIChatMessage } from './handleAIChatMessage.js';
17
- import { handleAIChatUndo } from './handleAIChatUndo.js';
18
- import { isDirectory } from './isDirectory.js';
19
- import { createToken } from './livekit.js';
20
- import './setupEnv.js';
21
-
22
- // Import the image file utility
23
- const isImageFile = (fileName) => {
24
- return (
25
- fileName.match(
26
- /\.(png|jpg|jpeg|gif|bmp|svg|webp)$/i,
27
- ) !== null
28
- );
29
- };
30
-
31
- // The time in milliseconds by which auto-saving is debounced.
32
- const autoSaveDebounceTimeMS = 800;
33
-
34
- // The time in milliseconds by which auto-saving is throttled
35
- // when the user is interacting with the widgets in the editor.
36
- const throttleTimeMS = 100;
37
-
38
- // Helper function to get the port from command line arguments or use default.
39
- function getPortFromArgs(defaultPort = 3030) {
40
- const portArg = process.argv.find((arg) =>
41
- arg.startsWith('--port='),
42
- );
43
- if (portArg) {
44
- return parseInt(portArg.split('=')[1], 10);
45
- }
46
- return defaultPort;
47
- }
48
-
49
- // Server port.
50
- const port = getPortFromArgs();
51
-
52
- const initialDocument = computeInitialDocument({
53
- // Use the current working directory to look for files.
54
- fullPath: process.cwd(),
55
- });
56
-
57
- // Register our custom OT type,
58
- // because it does not ship with ShareDB.
59
- ShareDB.types.register(json1Presence.type);
60
-
61
- const app = express();
62
-
63
- // Use ShareDB over WebSocket
64
- const shareDBBackend = new ShareDB({
65
- // Enable presence
66
- // See https://github.com/share/sharedb/blob/master/examples/rich-text-presence/server.js#L9
67
- presence: true,
68
- doNotForwardSendPresenceErrorsToClient: true,
69
- });
70
- const server = http.createServer(app);
71
- const wss = new WebSocketServer({ server });
72
- wss.on('connection', (ws) => {
73
- const clientStream = new WebSocketJSONStream(ws);
74
- shareDBBackend.listen(clientStream);
75
-
76
- // Prevent server crashes on errors.
77
- clientStream.on('error', (error) => {
78
- console.log('clientStream error: ' + error.message);
79
- });
80
-
81
- // Handle errors
82
- ws.on('error', (error) => {
83
- console.log('ws error: ' + error.message);
84
- });
85
-
86
- // Handle disconnections
87
- ws.on('close', () => {
88
- clientStream.end();
89
- });
90
- });
91
-
92
- // Serve static files
93
- const filename = fileURLToPath(import.meta.url);
94
- const dirname = path.dirname(filename);
95
- const dir = path.join(dirname, '..', '..', 'dist');
96
- app.use(express.static(dir));
97
-
98
- // Create the initial "document",
99
- // which is a representation of files on disk.
100
- const shareDBConnection = shareDBBackend.connect();
101
- const shareDBDoc = shareDBConnection.get('documents', '1');
102
-
103
- // Set up presence for AI editing following the same pattern as useShareDB.ts
104
- const docPresence = shareDBConnection.getDocPresence(
105
- 'documents',
106
- '1',
107
- );
108
-
109
- // Create local presence for AI editing with a unique ID
110
- const generateAIEditId = () => {
111
- const timestamp = Date.now().toString(36);
112
- return `ai-edit-${timestamp}`;
113
- };
114
-
115
- const createAIEditLocalPresence = () =>
116
- docPresence.create(generateAIEditId());
117
-
118
- shareDBDoc.create(initialDocument, json1Presence.type.uri);
119
-
120
- // Handle AI Assist requests.
121
- app.post(
122
- '/ai-assist',
123
- bodyParser.json(),
124
- handleAIAssist(shareDBDoc),
125
- );
126
-
127
- // Handle AI Copilot requests.
128
- app.post(
129
- '/ai-copilot',
130
- bodyParser.json(),
131
- handleAICopilot(),
132
- );
133
-
134
- // Handle AI Chat Message requests.
135
- app.post(
136
- '/ai-chat-message',
137
- bodyParser.json(),
138
- handleAIChatMessage({
139
- shareDBDoc,
140
- createAIEditLocalPresence,
141
- onCreditDeduction: undefined,
142
- }),
143
- );
144
-
145
- // Handle AI Chat Undo requests.
146
- app.post(
147
- '/ai-chat-undo',
148
- bodyParser.json(),
149
- handleAIChatUndo({
150
- shareDBDoc,
151
- }),
152
- );
153
-
154
- // Livekit Token Generator
155
- app.get('/livekit-token', async (req, res) => {
156
- const { room, username } = req.query;
157
- res.send(await createToken(room, username));
158
- });
159
-
160
- // The state of the document when files were last auto-saved.
161
- let previousDocument = initialDocument;
162
-
163
- // Saves the files that changed.
164
- const save = () => {
165
- const currentDocument = shareDBDoc.data;
166
-
167
- // Take a look at each file (key) previously and currently.
168
- const allKeys = Object.keys({
169
- ...currentDocument.files,
170
- ...previousDocument.files,
171
- });
172
-
173
- const directoriesToDelete = [];
174
-
175
- for (const key of allKeys) {
176
- const previous = previousDocument.files[key];
177
- const current = currentDocument.files[key];
178
-
179
- // If this file was neither created nor deleted...
180
- if (previous && current) {
181
- // Handle changing of text content.
182
- if (previous.text !== current.text) {
183
- if (isImageFile(current.name)) {
184
- // Write image files as binary from base64
185
- const buffer = Buffer.from(
186
- current.text,
187
- 'base64',
188
- );
189
- fs.writeFileSync(current.name, buffer);
190
- } else {
191
- // Write non-image files as text
192
- fs.writeFileSync(current.name, current.text);
193
- }
194
- }
195
-
196
- // // Handle renaming files.
197
- // if (previous.name !== current.name) {
198
-
199
- // const previousPath = previous.name.split('/');
200
- // const currentPath = current.name.split('/');
201
-
202
- // // - If the path is length 1 for previous and current,
203
- // // then this should be true.
204
- // // - If the path length is the sane for previous and current,
205
- // // AND all the entries leading up to the last one are the same
206
- // // between previous and current, AND the last entry in the arrays
207
- // // (the file name itself) is different between previous and current
208
- // const onlyFileNameChanged =
209
- // (previousPath.length === 1 &&
210
- // currentPath.length === 1) ||
211
- // (previousPath.length === currentPath.length &&
212
- // previousPath
213
- // .slice(0, -1)
214
- // .every(
215
- // (val, index) => val === currentPath[index],
216
- // ) &&
217
- // previousPath.at(-1) !== currentPath.at(-1));
218
-
219
- // // This logic works if only the file name itself changes.
220
- // if (onlyFileNameChanged) {
221
- // fs.renameSync(previous.name, current.name);
222
- // }
223
- // {
224
- // // If we get here, then the directory may have been renamed,
225
- // // or the file has been moved between directories.
226
- // // If we get here, then the directory may have been renamed,
227
- // // or the file has been moved between directories.
228
- // const newDir = path.dirname(current.name);
229
-
230
- // // Check if the new directory exists, if not, create it
231
- // if (!fs.existsSync(newDir)) {
232
- // fs.mkdirSync(newDir, { recursive: true });
233
- // }
234
-
235
- // // Move the file to the new directory
236
- // fs.renameSync(previous.name, current.name);
237
- // }
238
- // }
239
- // Handle renaming files.
240
- if (previous.name !== current.name) {
241
- if (isDirectory(previous.name)) {
242
- // If the directory itself is being renamed,
243
- // Phase I: Ignore it, and get the files moved
244
- // Phase II: Keep track of these, and delete them after
245
- // all the files moved.
246
- // directoriesToDelete.push(previous.name)
247
- directoriesToDelete.push(previous.name);
248
- } else {
249
- const newDir = path.dirname(current.name);
250
-
251
- // Check if the new directory exists, if not, create it
252
- if (!fs.existsSync(newDir)) {
253
- fs.mkdirSync(newDir, { recursive: true });
254
- }
255
-
256
- // Move the file to the new directory
257
- fs.renameSync(previous.name, current.name);
258
- }
259
- }
260
- }
261
-
262
- // handle deleting files and directories.
263
- if (previous && !current) {
264
- let stats = fs.statSync(previous.name);
265
- //Check if the file path we are trying to delete is a directory
266
- if (!stats.isDirectory()) {
267
- fs.unlinkSync(previous.name);
268
- } else {
269
- //Performs directory deletion.
270
- fs.rm(
271
- previous.name,
272
- {
273
- recursive: true, //Makes sure that all files in directory are deleted.
274
- },
275
- (error) => {
276
- if (error) {
277
- console.log(error);
278
- }
279
- },
280
- );
281
- }
282
- }
283
-
284
- // Handle creating files and Directories.
285
- if (!previous && current) {
286
- //File Creation
287
- if (!isDirectory(current.name)) {
288
- if (isImageFile(current.name)) {
289
- // Write image files as binary from base64
290
- const buffer = Buffer.from(
291
- current.text,
292
- 'base64',
293
- );
294
- fs.writeFileSync(current.name, buffer);
295
- } else {
296
- // Write non-image files as text
297
- fs.writeFileSync(current.name, current.text);
298
- }
299
- } else {
300
- fs.mkdirSync(current.name, { recursive: true });
301
- }
302
- }
303
- }
304
- // TODO deleted all directories under directoriesToDelete
305
-
306
- for (const dir of directoriesToDelete) {
307
- //Performs directory deletion.
308
- fs.rm(
309
- dir,
310
- {
311
- recursive: true, //Makes sure that all files in directory are deleted.
312
- },
313
- (error) => {
314
- if (error) {
315
- console.log(error);
316
- }
317
- },
318
- );
319
- }
320
-
321
- previousDocument = currentDocument;
322
- };
323
-
324
- // // Listen for when users modify files.
325
- // // Files get written to disk after `autoSaveDebounceTimeMS`
326
- // // milliseconds of inactivity.
327
- // let timeout;
328
- // shareDBDoc.subscribe(() => {
329
- // shareDBDoc.on('op', () => {
330
- // // console.log(shareDBDoc.data.isInteracting);
331
- // clearTimeout(timeout);
332
- // timeout = setTimeout(save, autoSaveDebounceTimeMS);
333
- // });
334
- // });
335
-
336
- let lastExecutedTime = Date.now();
337
- let lastChangeTimeout; // This timeout ensures the last change is saved
338
-
339
- // Function to throttle the saving
340
- function throttleSave() {
341
- const now = Date.now();
342
- const timeSinceLastExecution = now - lastExecutedTime;
343
-
344
- if (timeSinceLastExecution > throttleTimeMS) {
345
- save();
346
- lastExecutedTime = now;
347
- } else {
348
- // Clear the previous timeout and set a new one to save the last change
349
- clearTimeout(lastChangeTimeout);
350
- lastChangeTimeout = setTimeout(() => {
351
- save();
352
- lastExecutedTime = now;
353
- }, throttleTimeMS - timeSinceLastExecution);
354
- }
355
- }
356
-
357
- // Function to debounce the saving
358
- let debounceTimeout;
359
- function debounceSave() {
360
- clearTimeout(debounceTimeout);
361
- debounceTimeout = setTimeout(
362
- save,
363
- autoSaveDebounceTimeMS,
364
- );
365
- }
366
-
367
- // Subscribe to listen for modifications
368
- shareDBDoc.subscribe(() => {
369
- shareDBDoc.on('op', () => {
370
- if (shareDBDoc.data.isInteracting) {
371
- throttleSave();
372
- } else {
373
- debounceSave();
374
- }
375
- });
376
- });
377
-
378
- server.listen(port, async () => {
379
- // Note: ngrok support can be added when the package is properly installed
380
- // Sets the port to the one specified in the environment
381
- // variable (for development) or the default port.
382
- let livePort = process.env.EDITOR_PORT || port;
383
- console.log(`EDITOR_PORT: ${process.env.EDITOR_PORT}`);
384
- console.log(
385
- `Editor is live at http://localhost:${livePort}`,
386
- );
387
- open(`http://localhost:${livePort}`);
388
- });
@@ -1,24 +0,0 @@
1
- import { AccessToken } from 'livekit-server-sdk';
2
-
3
- const { LIVEKIT_API_KEY, LIVEKIT_API_SECRET } = process.env;
4
-
5
- export const createToken = async (roomName, username) => {
6
- // If this room doesn't exist, it'll be automatically created when the first
7
- // client joins
8
- // Identifier to be used for participant.
9
- // It's available as LocalParticipant.identity with livekit-client SDK
10
- // console.log(username);
11
- const participantName = `${username}`;
12
-
13
- const at = new AccessToken(
14
- LIVEKIT_API_KEY,
15
- LIVEKIT_API_SECRET,
16
- {
17
- identity: participantName,
18
- // Token to expire after 10 minutes
19
- ttl: '10m',
20
- },
21
- );
22
- at.addGrant({ roomJoin: true, room: roomName });
23
- return await at.toJwt();
24
- };
@@ -1,115 +0,0 @@
1
- import { format } from 'prettier/standalone';
2
- import * as prettierPluginBabel from 'prettier/plugins/babel';
3
- import * as prettierPluginEstree from 'prettier/plugins/estree';
4
- import * as prettierPluginHtml from 'prettier/plugins/html';
5
- import * as prettierPluginMarkdown from 'prettier/plugins/markdown';
6
- import * as prettierPluginCSS from 'prettier/plugins/postcss';
7
- import * as prettierPluginTypescript from 'prettier/plugins/typescript';
8
- import { VizFiles, VizFileId } from '@vizhub/viz-types';
9
-
10
- // Parser mappings - matches client-side implementation
11
- const parsers = {
12
- js: 'babel',
13
- jsx: 'babel',
14
- mjs: 'babel',
15
- cjs: 'babel',
16
- ts: 'typescript',
17
- tsx: 'typescript',
18
- css: 'css',
19
- html: 'html',
20
- json: 'json',
21
- json5: 'json5',
22
- md: 'markdown',
23
- markdown: 'markdown',
24
- } as const;
25
-
26
- // Prettier plugins - matches client-side implementation
27
- const plugins = [
28
- prettierPluginBabel,
29
- prettierPluginEstree,
30
- prettierPluginHtml,
31
- prettierPluginMarkdown,
32
- prettierPluginTypescript,
33
- prettierPluginCSS,
34
- ] as any;
35
-
36
- // Prettier options - matches client-side implementation and .prettierrc
37
- const prettierOptions = {
38
- proseWrap: 'always' as const,
39
- singleQuote: true,
40
- printWidth: 60,
41
- };
42
-
43
- /**
44
- * Extracts file extension from filename
45
- * Example: 'foo.js' => 'js'
46
- */
47
- const getFileExtension = (fileName: string): string => {
48
- const match = fileName.match(/\.([^.]+)$/);
49
- return match ? match[1] : '';
50
- };
51
-
52
- /**
53
- * Formats a single file using Prettier
54
- */
55
- export const formatFile = async (
56
- fileText: string,
57
- fileName: string,
58
- ): Promise<string | null> => {
59
- const fileExtension = getFileExtension(fileName);
60
- const parser =
61
- parsers[fileExtension as keyof typeof parsers];
62
-
63
- // If no parser is found, return null (no formatting)
64
- if (!parser) {
65
- return null;
66
- }
67
-
68
- try {
69
- const formatted = await format(fileText, {
70
- parser,
71
- plugins,
72
- ...prettierOptions,
73
- });
74
- return formatted;
75
- } catch (error) {
76
- // Log error but don't throw - return original text
77
- console.error(
78
- `Prettier formatting error for ${fileName}:`,
79
- error,
80
- );
81
- return null;
82
- }
83
- };
84
-
85
- /**
86
- * Formats multiple files using Prettier
87
- * Only formats files that have supported extensions
88
- * Returns a map of fileId -> formatted text for successfully formatted files
89
- */
90
- export const formatFiles = async (
91
- files: VizFiles,
92
- fileIds?: VizFileId[],
93
- ): Promise<{ [fileId: VizFileId]: string }> => {
94
- const results: { [fileId: VizFileId]: string } = {};
95
- const targetFileIds = fileIds || Object.keys(files);
96
-
97
- // Process files in parallel for better performance
98
- const formatPromises = targetFileIds.map(
99
- async (fileId) => {
100
- const file = files[fileId];
101
- if (!file) return;
102
-
103
- const formatted = await formatFile(
104
- file.text,
105
- file.name,
106
- );
107
- if (formatted !== null && formatted !== file.text) {
108
- results[fileId] = formatted;
109
- }
110
- },
111
- );
112
-
113
- await Promise.all(formatPromises);
114
- return results;
115
- };
@@ -1,25 +0,0 @@
1
- import { diff } from './ot.js';
2
-
3
- /**
4
- * Creates a submitOperation function that can be used to submit diff-based operations to ShareDB.
5
- * This is the core logic extracted from useSubmitOperation for reuse across client and server.
6
- */
7
- export const createSubmitOperation = <T>(shareDBDoc: {
8
- data: T;
9
- submitOp: (op: any) => void;
10
- }): ((next: (data: T) => T) => void) => {
11
- return (next) => {
12
- const data: T = shareDBDoc.data;
13
- const op = diff(data, next(data));
14
- if (op && shareDBDoc) {
15
- shareDBDoc.submitOp(op);
16
- }
17
- };
18
- };
19
-
20
- /**
21
- * Type definition for the submitOperation function
22
- */
23
- export type SubmitOperationFunction<T> = (
24
- next: (data: T) => T,
25
- ) => void;