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,153 +0,0 @@
1
- import { useContext, useState } from 'react';
2
- import ShareDBClient from 'sharedb-client-browser/dist/sharedb-client-umd.cjs';
3
- import { json1Presence } from '../../ot';
4
- import { Username } from '../../types';
5
- // @ts-ignore
6
- import PrettierWorker from '../usePrettier/worker?worker';
7
- // @ts-ignore
8
- import {
9
- LiveKitRoom,
10
- RoomAudioRenderer,
11
- } from '@livekit/components-react';
12
- import { v4 } from 'uuid';
13
- import { SplitPaneResizeProvider } from '../SplitPaneResizeContext';
14
- import {
15
- VZCodeContext,
16
- VZCodeProvider,
17
- } from '../VZCodeContext';
18
- import { VZLeft } from '../VZLeft';
19
- import { VZMiddle } from '../VZMiddle';
20
- import { VZResizer } from '../VZResizer';
21
- import { VZRight } from '../VZRight';
22
- import {
23
- useInitialUsername,
24
- usePersistUsername,
25
- } from '../usernameLocalStorage';
26
- import './style.scss';
27
- import { useShareDB } from './useShareDB';
28
- import { useESLint } from '../useESLint';
29
-
30
- // Instantiate the Prettier worker.
31
- const prettierWorker = new PrettierWorker();
32
-
33
- // Register our custom JSON1 OT type that supports presence.
34
- // See https://github.com/vizhub-core/json1-presence
35
- ShareDBClient.types.register(json1Presence.type);
36
-
37
- // Establish the singleton ShareDB connection over WebSockets.
38
- // TODO consider using reconnecting WebSocket
39
- const { Connection } = ShareDBClient;
40
- const wsProtocol =
41
- window.location.protocol === 'https:'
42
- ? 'wss://'
43
- : 'ws://';
44
- const socket = new WebSocket(
45
- wsProtocol + window.location.host + '/ws',
46
- );
47
- const connection = new Connection(socket);
48
-
49
- // Stores the username to local storage.
50
- // TODO consider if there's a cleaner pattern for this.
51
- // This makes sense in VZCode itself, but for an app with
52
- // authentication that wraps VZCode, it is not required.
53
- const PersistUsername = () => {
54
- const { username } = useContext(VZCodeContext);
55
- usePersistUsername(username);
56
- return null;
57
- };
58
-
59
- function App() {
60
- const {
61
- shareDBDoc,
62
- content,
63
- localPresence,
64
- docPresence,
65
- submitOperation,
66
- connected,
67
- pending,
68
- } = useShareDB({
69
- connection,
70
- });
71
-
72
- //state for the voice channel
73
- const [liveKitToken, setLiveKitToken] =
74
- useState(undefined);
75
- const [liveKitRoomName, setLiveKitRoomName] =
76
- useState(v4()); //default room name will be an arbitrary uuid
77
- const [liveKitConnection, setLiveKitConnection] =
78
- useState(false);
79
- const { esLintSource } = useESLint();
80
- // Get the initial username from localStorage.
81
- const initialUsername: Username = useInitialUsername();
82
-
83
- //@ts-ignore
84
- const serverUrl = import.meta.env.VITE_LIVEKIT_URL; //Vite only parses VITE_ prefixed environment variables
85
-
86
- // Feature flag for enabling the right-side panel.
87
- // Useful for debugging dual split pane functionality.
88
- // We may want to add this as an actual VZCode feature,
89
- // for running the code that the VZCode user is developing
90
- // in the same browser window as the VZCode editor,
91
- // so that multiple browser windows are not required.
92
- const enableRightPanel = true;
93
-
94
- // TODO: enable this when the AI copilot is ready
95
- // Currently it's glitchy and frustrating to use.
96
- // It appears to be bugs in the upstream CodeMirror copilot code.
97
- // Ghost text appears after just moving the cursor, not typing.
98
- // It's hard to figure out how to dismiss it.
99
- // Clicking on it accepts it but should not.
100
- const enableCopilot = false;
101
-
102
- return (
103
- <SplitPaneResizeProvider>
104
- <VZCodeProvider
105
- content={content}
106
- shareDBDoc={shareDBDoc}
107
- submitOperation={submitOperation}
108
- localPresence={localPresence}
109
- docPresence={docPresence}
110
- prettierWorker={prettierWorker}
111
- initialUsername={initialUsername}
112
- connected={connected}
113
- pending={pending}
114
- liveKitRoomName={liveKitRoomName}
115
- setLiveKitRoom={setLiveKitRoomName}
116
- liveKitToken={liveKitToken}
117
- setLiveKitToken={setLiveKitToken}
118
- liveKitConnection={liveKitConnection}
119
- setLiveKitConnection={setLiveKitConnection}
120
- aiChatEndpoint="/ai-chat-message"
121
- aiChatUndoEndpoint="/ai-chat-undo"
122
- aiChatOptions={{}}
123
- >
124
- <LiveKitRoom
125
- audio={true}
126
- token={liveKitToken}
127
- serverUrl={serverUrl}
128
- connect={liveKitConnection}
129
- style={{ height: '100%' }}
130
- >
131
- <div className="app">
132
- <VZLeft />
133
- <VZMiddle
134
- aiCopilotEndpoint={
135
- enableCopilot ? '/ai-copilot' : null
136
- }
137
- esLintSource={esLintSource}
138
- />
139
- {enableRightPanel ? <VZRight /> : null}
140
- <VZResizer side="left" />
141
- {enableRightPanel ? (
142
- <VZResizer side="right" />
143
- ) : null}
144
- </div>
145
- <PersistUsername />
146
- <RoomAudioRenderer />
147
- </LiveKitRoom>
148
- </VZCodeProvider>
149
- </SplitPaneResizeProvider>
150
- );
151
- }
152
-
153
- export default App;
@@ -1,82 +0,0 @@
1
- @import url('https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap');
2
- @import url('https://fonts.googleapis.com/css2?family=Inconsolata:wght@200..900&display=swap');
3
- @import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro:ital,wght@0,200..900;1,200..900&display=swap');
4
- @import url('https://fonts.googleapis.com/css2?family=Ubuntu+Mono:ital,wght@0,400;0,700;1,400;1,700&display=swap');
5
- @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap');
6
- @import url('https://fonts.googleapis.com/css2?family=Fira+Code:wght@300..700&display=swap');
7
- :root {
8
- // --vzcode-font-family: ui-monospace, SFMono-Regular,
9
- // 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace !important;
10
-
11
- --vzcode-font-family: 'Roboto Mono', monospace !important;
12
- --vzcode-font-size: 16px;
13
-
14
- /* Variable for the background color */
15
- --vz-bg-color: rgb(
16
- 41,
17
- 44,
18
- 52
19
- ); /* Variable for the background color */
20
- }
21
-
22
- /* Scrollbar Styles */
23
- ::-webkit-scrollbar {
24
- width: 16px;
25
- height: 16px;
26
- }
27
-
28
- // ::-webkit-scrollbar-track {
29
- // background: rgb(255, 255, 255, 0.1);
30
- // }
31
-
32
- ::-webkit-scrollbar-thumb {
33
- background: rgb(255, 255, 255, 0.3);
34
- }
35
-
36
- ::-webkit-scrollbar-thumb:hover {
37
- background: #555;
38
- }
39
-
40
- /* Layout Styles */
41
- html,
42
- body,
43
- #root,
44
- .app {
45
- height: 100%;
46
- }
47
-
48
- .app {
49
- background-color: var(--vz-bg-color);
50
- // font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI',
51
- // 'Noto Sans', Helvetica, Arial, sans-serif,
52
- // 'Apple Color Emoji', 'Segoe UI Emoji';
53
- display: flex;
54
-
55
- /* To support Resizer, which is position: absolute */
56
- position: relative;
57
-
58
- .left,
59
- .middle {
60
- display: flex;
61
-
62
- /* To suport PrettierErrorOverlay, which is position: absolute */
63
- position: relative;
64
- }
65
-
66
- .middle {
67
- // flex: 1;
68
- flex-direction: column;
69
- min-width: 0;
70
- }
71
-
72
- .right {
73
- display: flex;
74
- flex: 1;
75
- background-color: white;
76
-
77
- iframe {
78
- flex: 1;
79
- border: none;
80
- }
81
- }
82
- }
@@ -1,51 +0,0 @@
1
- import {
2
- useState,
3
- useEffect,
4
- useCallback,
5
- useRef,
6
- } from 'react';
7
- import { ShareDBDoc } from '../../types';
8
- import { VizContent } from '@vizhub/viz-types';
9
-
10
- // import { runDelay } from '../constants';
11
- // TODO understand what this part is for
12
- const runDelay = 1000;
13
-
14
- export const usePending = (
15
- shareDBDoc: ShareDBDoc<VizContent>,
16
- ) => {
17
- const lastOpTimerRef = useRef<NodeJS.Timeout>();
18
-
19
- // TODO rename this to isPending,
20
- // and also rename connected to isConnected.
21
- const [pending, setPending] = useState<boolean>(false);
22
-
23
- const resetOnNoPending = useCallback(() => {
24
- if (!shareDBDoc) return;
25
-
26
- // This happens AFTER the changes have been
27
- // acknowledged by the server.
28
- shareDBDoc.whenNothingPending(() => {
29
- setPending(false);
30
- });
31
- }, [shareDBDoc, setPending]);
32
-
33
- useEffect(() => {
34
- if (!shareDBDoc) return;
35
-
36
- // This happens when you type, but BEFORE
37
- // the changes are sent to the server.
38
- shareDBDoc.on('before op', () => {
39
- setPending(true);
40
-
41
- clearTimeout(lastOpTimerRef.current);
42
-
43
- lastOpTimerRef.current = setTimeout(() => {
44
- // should be triggered only once, cause upcoming ops unschedule previous resetOnNoPending
45
- resetOnNoPending();
46
- }, runDelay);
47
- });
48
- }, [shareDBDoc, resetOnNoPending]);
49
-
50
- return pending;
51
- };
@@ -1,161 +0,0 @@
1
- import { useEffect, useState, useRef } from 'react';
2
- import { randomId } from '../../randomId';
3
- import { ShareDBDoc } from '../../types';
4
- import { VizContent } from '@vizhub/viz-types';
5
- import { useSubmitOperation } from '../useSubmitOperation';
6
- import { usePending } from './usePending';
7
-
8
- // Set up the connection to ShareDB.
9
- export const useShareDB = ({
10
- connection,
11
- }: {
12
- connection: any;
13
- }) => {
14
- // The ShareDB document.
15
- const [shareDBDoc, setShareDBDoc] =
16
- useState<ShareDBDoc<VizContent> | null>(null);
17
-
18
- // Local ShareDB presence, for broadcasting our cursor position
19
- // so other clients can see it.
20
- // See https://share.github.io/sharedb/api/local-presence
21
- const [localPresence, setLocalPresence] = useState(null);
22
-
23
- // The document-level presence object, which emits
24
- // changes in remote presence.
25
- const [docPresence, setDocPresence] = useState(null);
26
-
27
- // The `doc.data` part of the ShareDB document,
28
- // updated on each change to decouple rendering from ShareDB.
29
- // Starts out as `null` until the document is loaded.
30
- const [content, setContent] = useState<VizContent | null>(
31
- null,
32
- );
33
-
34
- const [connected, setConnected] =
35
- useState<boolean>(false);
36
-
37
- // const [isSaving, setIsSaving] = useState<boolean>(false);
38
- // const [isSaved, setIsSaved] = useState<boolean>(false);
39
-
40
- // const debounceTimeoutRef = useRef<ReturnType<
41
- // typeof setTimeout
42
- // > | null>(null);
43
-
44
- useEffect(() => {
45
- // Listen for connection state changes
46
- connection.on('connected', () => {
47
- setConnected(true);
48
- });
49
-
50
- connection.on('disconnected', () => {
51
- setConnected(false);
52
- });
53
-
54
- // Since there is only ever a single document,
55
- // these things are pretty arbitrary.
56
- // * `collection` - the ShareDB collection to use
57
- // * `id` - the id of the ShareDB document to use
58
- const collection = 'documents';
59
- const id = '1';
60
-
61
- // Initialize the ShareDB document.
62
- const shareDBDoc = connection.get(collection, id);
63
-
64
- // Subscribe to the document to get updates.
65
- // This callback gets called once only.
66
- shareDBDoc.subscribe(() => {
67
- // Expose ShareDB doc to downstream logic.
68
- setShareDBDoc(shareDBDoc);
69
-
70
- // Set initial data.
71
- setContent(shareDBDoc.data);
72
-
73
- // Listen for all changes and update `data`.
74
- // This decouples rendering logic from ShareDB.
75
- // This callback gets called on each change.
76
- shareDBDoc.on('op', () => {
77
- // TODO consider excluding file contents from this,
78
- // because currently we are re-rendering the entire
79
- // document on each file change (each keystroke while editing).
80
- // This is not required, because no part of the app outside
81
- // of the CodeMirror integration uses those file contents.
82
- // The Sidebar only needs to know file names, not contents.
83
- // Start saving process when there’s an operation.
84
- // setIsSaving(true);
85
- // setIsSaved(false);
86
-
87
- setContent(shareDBDoc.data);
88
-
89
- // // Simulate a saving process and switch status to "saved"
90
- // if (debounceTimeoutRef.current) {
91
- // clearTimeout(debounceTimeoutRef.current);
92
- // }
93
-
94
- // // Set up a debounce timer to switch from "saving" to "saved" after 2 seconds of inactivity.
95
- // debounceTimeoutRef.current = setTimeout(() => {
96
- // setIsSaving(false);
97
- // setIsSaved(true); // Only set isSaved to true after 2 seconds of inactivity
98
-
99
- // const resetSavedTimeout = setTimeout(() => {
100
- // setIsSaved(false);
101
- // }, 1000); // 1 second delay after `isSaved` becomes true.
102
-
103
- // return () => clearTimeout(resetSavedTimeout);
104
- // }, 1800); // 1.8-second delay for detecting inactivity
105
- });
106
-
107
- // Set up presence.
108
- // See https://github.com/share/sharedb/blob/master/examples/rich-text-presence/client.js#L53
109
- const docPresence = connection.getDocPresence(
110
- collection,
111
- id,
112
- );
113
-
114
- // Subscribe to receive remote presence updates.
115
- docPresence.subscribe(function (error) {
116
- if (error) throw error;
117
- });
118
-
119
- // Set up our local presence for broadcasting this client's presence.
120
- const generateTimestampedId = () => {
121
- const timestamp = Date.now().toString(36);
122
- const randomPart = randomId();
123
- return `${timestamp}-${randomPart}`;
124
- };
125
- setLocalPresence(
126
- docPresence.create(generateTimestampedId()),
127
- );
128
-
129
- // Store docPresence so child components can listen for changes.
130
- setDocPresence(docPresence);
131
- });
132
-
133
- // TODO unsubscribe from presence
134
- // TODO unsubscribe from doc
135
- return () => {
136
- // if (debounceTimeoutRef.current)
137
- // clearTimeout(debounceTimeoutRef.current);
138
- // shareDBDoc.destroy();
139
- // docPresence.destroy();
140
- };
141
- }, []);
142
-
143
- // True for "Saving..."
144
- // False for "Saved"
145
- const pending = usePending(shareDBDoc);
146
-
147
- // A convenience function for mutating the ShareDB document
148
- // based submitting OT ops generated by diffing the JSON.
149
- const submitOperation =
150
- useSubmitOperation<VizContent>(shareDBDoc);
151
-
152
- return {
153
- shareDBDoc,
154
- content,
155
- localPresence,
156
- docPresence,
157
- submitOperation,
158
- connected,
159
- pending,
160
- };
161
- };
@@ -1,74 +0,0 @@
1
- import { inlineCopilot } from 'codemirror-copilot';
2
-
3
- const defaultAICopilotEndpoint = '/ai-copilot';
4
-
5
- const DEBUG = false;
6
-
7
- // If the endpoint is broken, we don't want to keep sending requests
8
- // to it. This flag will be set to true if we get an error from the
9
- // server.
10
- let isEndpointBroken = false;
11
-
12
- export const copilot = ({
13
- aiCopilotEndpoint = defaultAICopilotEndpoint,
14
- }: {
15
- aiCopilotEndpoint: string;
16
- }) => {
17
- return inlineCopilot(async (prefix, suffix) => {
18
- DEBUG &&
19
- console.log('[copilot] Executing AI completion...');
20
- if (isEndpointBroken) {
21
- DEBUG &&
22
- console.log(
23
- '[copilot] Endpoint is broken, not sending request',
24
- );
25
- return '';
26
- }
27
-
28
- DEBUG &&
29
- console.log('[copilot] Sending request to server...');
30
- const response = await fetch(aiCopilotEndpoint, {
31
- method: 'POST',
32
- headers: { 'Content-Type': 'application/json' },
33
- body: JSON.stringify({ prefix, suffix }),
34
- });
35
-
36
- if (!response.ok) {
37
- DEBUG &&
38
- console.error(
39
- '[copilot] Error from server:',
40
- response.statusText,
41
- );
42
- DEBUG &&
43
- console.error(
44
- '[copilot] Disabling future requests to the server',
45
- );
46
- isEndpointBroken = true;
47
- return '';
48
- }
49
-
50
- const responseJson = await response.json();
51
-
52
- DEBUG &&
53
- console.log(
54
- '[copilot] Response from server:',
55
- response,
56
- );
57
-
58
- if (responseJson.error) {
59
- DEBUG &&
60
- console.error(
61
- '[copilot] error from server:',
62
- responseJson.error,
63
- );
64
- DEBUG &&
65
- console.error(
66
- '[copilot] Disabling future requests to the server',
67
- );
68
- isEndpointBroken = true;
69
- return '';
70
- }
71
-
72
- return responseJson.text;
73
- });
74
- };
@@ -1,12 +0,0 @@
1
- import { InteractRule } from '@replit/codemirror-interact';
2
- export const boolTogglerRegex = /true|false/g;
3
- export const boolToggler = (
4
- onInteract?: () => void,
5
- ): InteractRule => ({
6
- regexp: boolTogglerRegex,
7
- cursor: 'pointer',
8
- onClick: (text, setText) => {
9
- setText(text === 'true' ? 'false' : 'true');
10
- if (onInteract) onInteract();
11
- },
12
- });
@@ -1,68 +0,0 @@
1
- import { InteractRule } from '@replit/codemirror-interact';
2
-
3
- // Regular expression for hex colors.
4
- export const colorPickerRegex = /#[0-9A-Fa-f]{6}/g;
5
-
6
- // hex color picker
7
- // Inspired by https://github.com/replit/codemirror-interact/blob/master/dev/index.ts#L71
8
- // Works without quotes to support CSS.
9
- export const colorPicker = (
10
- onInteract?: () => void,
11
- ): InteractRule => ({
12
- regexp: colorPickerRegex,
13
- cursor: 'pointer',
14
- onClick(
15
- text: string,
16
- setText: (newText: string) => void,
17
- event: MouseEvent,
18
- ) {
19
- const startingColor: string = text;
20
-
21
- const sel: HTMLInputElement =
22
- document.createElement('input');
23
- sel.type = 'color';
24
- sel.value = startingColor.toLowerCase();
25
-
26
- // `valueIsUpper` maintains the style of the user's code.
27
- // It keeps the case of a-f the same case as the original.
28
- const valueIsUpper: boolean =
29
- startingColor.toUpperCase() === startingColor;
30
-
31
- const updateHex = (e: Event) => {
32
- const el: HTMLInputElement =
33
- e.target as HTMLInputElement;
34
- if (el.value) {
35
- setText(
36
- valueIsUpper ? el.value.toUpperCase() : el.value,
37
- );
38
- }
39
- if (onInteract) onInteract();
40
- };
41
- sel.addEventListener('input', updateHex);
42
-
43
- // Position the color input at the mouse cursor
44
- sel.style.position = 'absolute';
45
- sel.style.left = `${event.clientX}px`;
46
- sel.style.top = `${event.clientY}px`;
47
-
48
- // Make it invisible
49
- sel.style.opacity = '0';
50
- sel.style.height = '0';
51
- sel.style.width = '0';
52
- sel.style.border = 'none';
53
- sel.style.padding = '0';
54
- sel.style.margin = '0';
55
- document.body.appendChild(sel);
56
-
57
- // Click the input after a delay, so that
58
- // it gets the correct position
59
- setTimeout(() => {
60
- sel.click();
61
- }, 10);
62
-
63
- // Remove the input after interaction
64
- sel.addEventListener('blur', () => {
65
- document.body.removeChild(sel);
66
- });
67
- },
68
- });