@nocturnium/svelte-ide 1.0.0-rc.1

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 (330) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +251 -0
  3. package/dist/components/agents/AgentActivityPanel.svelte +565 -0
  4. package/dist/components/agents/AgentActivityPanel.svelte.d.ts +24 -0
  5. package/dist/components/agents/AgentAvatar.svelte +417 -0
  6. package/dist/components/agents/AgentAvatar.svelte.d.ts +23 -0
  7. package/dist/components/agents/AgentCursor.svelte +224 -0
  8. package/dist/components/agents/AgentCursor.svelte.d.ts +35 -0
  9. package/dist/components/agents/AgentPresenceBar.svelte +261 -0
  10. package/dist/components/agents/AgentPresenceBar.svelte.d.ts +20 -0
  11. package/dist/components/agents/index.d.ts +4 -0
  12. package/dist/components/agents/index.js +5 -0
  13. package/dist/components/ai/AIConversationList.svelte +524 -0
  14. package/dist/components/ai/AIConversationList.svelte.d.ts +17 -0
  15. package/dist/components/ai/AIEditPreview.svelte +132 -0
  16. package/dist/components/ai/AIEditPreview.svelte.d.ts +8 -0
  17. package/dist/components/ai/AIInlineEdit.svelte +155 -0
  18. package/dist/components/ai/AIInlineEdit.svelte.d.ts +10 -0
  19. package/dist/components/ai/AIMessage.svelte +239 -0
  20. package/dist/components/ai/AIMessage.svelte.d.ts +13 -0
  21. package/dist/components/ai/AIMessageActions.svelte +176 -0
  22. package/dist/components/ai/AIMessageActions.svelte.d.ts +12 -0
  23. package/dist/components/ai/AIMessageContent.svelte +355 -0
  24. package/dist/components/ai/AIMessageContent.svelte.d.ts +7 -0
  25. package/dist/components/ai/AIPanel.svelte +561 -0
  26. package/dist/components/ai/AIPanel.svelte.d.ts +7 -0
  27. package/dist/components/ai/AISuggestionWidget.svelte +132 -0
  28. package/dist/components/ai/AISuggestionWidget.svelte.d.ts +10 -0
  29. package/dist/components/ai/AIToolCallDisplay.svelte +317 -0
  30. package/dist/components/ai/AIToolCallDisplay.svelte.d.ts +12 -0
  31. package/dist/components/ai/index.d.ts +9 -0
  32. package/dist/components/ai/index.js +10 -0
  33. package/dist/components/core/Avatar.svelte +110 -0
  34. package/dist/components/core/Avatar.svelte.d.ts +12 -0
  35. package/dist/components/core/Badge.svelte +98 -0
  36. package/dist/components/core/Badge.svelte.d.ts +11 -0
  37. package/dist/components/core/Button.svelte +175 -0
  38. package/dist/components/core/Button.svelte.d.ts +18 -0
  39. package/dist/components/core/ConnectionStatus.svelte +294 -0
  40. package/dist/components/core/ConnectionStatus.svelte.d.ts +20 -0
  41. package/dist/components/core/ContextMenu.svelte +176 -0
  42. package/dist/components/core/ContextMenu.svelte.d.ts +19 -0
  43. package/dist/components/core/ErrorBoundary.svelte +277 -0
  44. package/dist/components/core/ErrorBoundary.svelte.d.ts +23 -0
  45. package/dist/components/core/Icon.svelte +107 -0
  46. package/dist/components/core/Icon.svelte.d.ts +8 -0
  47. package/dist/components/core/Input.svelte +138 -0
  48. package/dist/components/core/Input.svelte.d.ts +20 -0
  49. package/dist/components/core/Kbd.svelte +34 -0
  50. package/dist/components/core/Kbd.svelte.d.ts +7 -0
  51. package/dist/components/core/ResizeHandle.svelte +200 -0
  52. package/dist/components/core/ResizeHandle.svelte.d.ts +23 -0
  53. package/dist/components/core/Spinner.svelte +35 -0
  54. package/dist/components/core/Spinner.svelte.d.ts +7 -0
  55. package/dist/components/core/Textarea.svelte +112 -0
  56. package/dist/components/core/Textarea.svelte.d.ts +18 -0
  57. package/dist/components/core/Tooltip.svelte +103 -0
  58. package/dist/components/core/Tooltip.svelte.d.ts +11 -0
  59. package/dist/components/core/index.d.ts +13 -0
  60. package/dist/components/core/index.js +14 -0
  61. package/dist/components/editor/AIFocusLayer.svelte +430 -0
  62. package/dist/components/editor/AIFocusLayer.svelte.d.ts +32 -0
  63. package/dist/components/editor/Breadcrumbs.svelte +435 -0
  64. package/dist/components/editor/Breadcrumbs.svelte.d.ts +33 -0
  65. package/dist/components/editor/BreakpointLayer.svelte +642 -0
  66. package/dist/components/editor/BreakpointLayer.svelte.d.ts +20 -0
  67. package/dist/components/editor/CognitiveLoadMeter.svelte +324 -0
  68. package/dist/components/editor/CognitiveLoadMeter.svelte.d.ts +18 -0
  69. package/dist/components/editor/CollaborativeEditor.svelte +218 -0
  70. package/dist/components/editor/CollaborativeEditor.svelte.d.ts +32 -0
  71. package/dist/components/editor/CommandPalette.svelte +434 -0
  72. package/dist/components/editor/CommandPalette.svelte.d.ts +11 -0
  73. package/dist/components/editor/ComplexityLayer.svelte +293 -0
  74. package/dist/components/editor/ComplexityLayer.svelte.d.ts +23 -0
  75. package/dist/components/editor/ConflictZoneLayer.svelte +441 -0
  76. package/dist/components/editor/ConflictZoneLayer.svelte.d.ts +25 -0
  77. package/dist/components/editor/ContextLens.svelte +262 -0
  78. package/dist/components/editor/ContextLens.svelte.d.ts +27 -0
  79. package/dist/components/editor/CustomEditor.svelte +1242 -0
  80. package/dist/components/editor/CustomEditor.svelte.d.ts +37 -0
  81. package/dist/components/editor/DebugConsole.svelte +646 -0
  82. package/dist/components/editor/DebugConsole.svelte.d.ts +41 -0
  83. package/dist/components/editor/EchoCursorLayer.svelte +363 -0
  84. package/dist/components/editor/EchoCursorLayer.svelte.d.ts +24 -0
  85. package/dist/components/editor/Editor.svelte +61 -0
  86. package/dist/components/editor/Editor.svelte.d.ts +22 -0
  87. package/dist/components/editor/EditorGutter.svelte +119 -0
  88. package/dist/components/editor/EditorGutter.svelte.d.ts +19 -0
  89. package/dist/components/editor/EditorLines.svelte +182 -0
  90. package/dist/components/editor/EditorLines.svelte.d.ts +43 -0
  91. package/dist/components/editor/EditorPane.svelte +134 -0
  92. package/dist/components/editor/EditorPane.svelte.d.ts +9 -0
  93. package/dist/components/editor/EditorSelections.svelte +186 -0
  94. package/dist/components/editor/EditorSelections.svelte.d.ts +25 -0
  95. package/dist/components/editor/EditorTabs.svelte +170 -0
  96. package/dist/components/editor/EditorTabs.svelte.d.ts +12 -0
  97. package/dist/components/editor/FileExplorer.svelte +811 -0
  98. package/dist/components/editor/FileExplorer.svelte.d.ts +67 -0
  99. package/dist/components/editor/FileIcon.svelte +110 -0
  100. package/dist/components/editor/FileIcon.svelte.d.ts +10 -0
  101. package/dist/components/editor/FindReplace.svelte +448 -0
  102. package/dist/components/editor/FindReplace.svelte.d.ts +40 -0
  103. package/dist/components/editor/GhostBracketLayer.svelte +391 -0
  104. package/dist/components/editor/GhostBracketLayer.svelte.d.ts +24 -0
  105. package/dist/components/editor/GitBlameLayer.svelte +436 -0
  106. package/dist/components/editor/GitBlameLayer.svelte.d.ts +18 -0
  107. package/dist/components/editor/InlineDiagnosticsLayer.svelte +540 -0
  108. package/dist/components/editor/InlineDiagnosticsLayer.svelte.d.ts +35 -0
  109. package/dist/components/editor/InlineDiffLayer.svelte +337 -0
  110. package/dist/components/editor/InlineDiffLayer.svelte.d.ts +31 -0
  111. package/dist/components/editor/MinimalEditor.svelte +75 -0
  112. package/dist/components/editor/MinimalEditor.svelte.d.ts +6 -0
  113. package/dist/components/editor/MinimalEditor2.svelte +84 -0
  114. package/dist/components/editor/MinimalEditor2.svelte.d.ts +6 -0
  115. package/dist/components/editor/Minimap.svelte +327 -0
  116. package/dist/components/editor/Minimap.svelte.d.ts +34 -0
  117. package/dist/components/editor/PluginPreviewSandbox.svelte +793 -0
  118. package/dist/components/editor/PluginPreviewSandbox.svelte.d.ts +49 -0
  119. package/dist/components/editor/ProblemsPanel.svelte +628 -0
  120. package/dist/components/editor/ProblemsPanel.svelte.d.ts +25 -0
  121. package/dist/components/editor/QuickActionsMenu.svelte +403 -0
  122. package/dist/components/editor/QuickActionsMenu.svelte.d.ts +18 -0
  123. package/dist/components/editor/SnippetPalette.svelte +530 -0
  124. package/dist/components/editor/SnippetPalette.svelte.d.ts +16 -0
  125. package/dist/components/editor/StructureMap.svelte +431 -0
  126. package/dist/components/editor/StructureMap.svelte.d.ts +37 -0
  127. package/dist/components/editor/SymbolOutline.svelte +722 -0
  128. package/dist/components/editor/SymbolOutline.svelte.d.ts +44 -0
  129. package/dist/components/editor/TimelineScrubber.svelte +470 -0
  130. package/dist/components/editor/TimelineScrubber.svelte.d.ts +40 -0
  131. package/dist/components/editor/TokenRenderer.svelte +69 -0
  132. package/dist/components/editor/TokenRenderer.svelte.d.ts +15 -0
  133. package/dist/components/editor/constants.d.ts +32 -0
  134. package/dist/components/editor/constants.js +36 -0
  135. package/dist/components/editor/core/ai-awareness.d.ts +176 -0
  136. package/dist/components/editor/core/ai-awareness.js +210 -0
  137. package/dist/components/editor/core/bracket-healer.d.ts +189 -0
  138. package/dist/components/editor/core/bracket-healer.js +406 -0
  139. package/dist/components/editor/core/breakpoints.d.ts +203 -0
  140. package/dist/components/editor/core/breakpoints.js +414 -0
  141. package/dist/components/editor/core/commands.d.ts +108 -0
  142. package/dist/components/editor/core/commands.js +246 -0
  143. package/dist/components/editor/core/complexity-analyzer.d.ts +123 -0
  144. package/dist/components/editor/core/complexity-analyzer.js +376 -0
  145. package/dist/components/editor/core/conflict-predictor.d.ts +135 -0
  146. package/dist/components/editor/core/conflict-predictor.js +316 -0
  147. package/dist/components/editor/core/crdt-binding.d.ts +118 -0
  148. package/dist/components/editor/core/crdt-binding.js +286 -0
  149. package/dist/components/editor/core/diagnostics.d.ts +210 -0
  150. package/dist/components/editor/core/diagnostics.js +335 -0
  151. package/dist/components/editor/core/echo-cursor.d.ts +201 -0
  152. package/dist/components/editor/core/echo-cursor.js +267 -0
  153. package/dist/components/editor/core/folding.d.ts +124 -0
  154. package/dist/components/editor/core/folding.js +672 -0
  155. package/dist/components/editor/core/ghost-pair.d.ts +122 -0
  156. package/dist/components/editor/core/ghost-pair.js +221 -0
  157. package/dist/components/editor/core/git-blame.d.ts +170 -0
  158. package/dist/components/editor/core/git-blame.js +324 -0
  159. package/dist/components/editor/core/index.d.ts +26 -0
  160. package/dist/components/editor/core/index.js +24 -0
  161. package/dist/components/editor/core/keybindings.d.ts +79 -0
  162. package/dist/components/editor/core/keybindings.js +357 -0
  163. package/dist/components/editor/core/multi-cursor.d.ts +196 -0
  164. package/dist/components/editor/core/multi-cursor.js +521 -0
  165. package/dist/components/editor/core/navigation.d.ts +107 -0
  166. package/dist/components/editor/core/navigation.js +408 -0
  167. package/dist/components/editor/core/quick-actions.d.ts +189 -0
  168. package/dist/components/editor/core/quick-actions.js +427 -0
  169. package/dist/components/editor/core/search.d.ts +88 -0
  170. package/dist/components/editor/core/search.js +192 -0
  171. package/dist/components/editor/core/semantic-analyzer.d.ts +77 -0
  172. package/dist/components/editor/core/semantic-analyzer.js +424 -0
  173. package/dist/components/editor/core/snippet-manager.d.ts +202 -0
  174. package/dist/components/editor/core/snippet-manager.js +565 -0
  175. package/dist/components/editor/core/state.d.ts +367 -0
  176. package/dist/components/editor/core/state.js +900 -0
  177. package/dist/components/editor/core/timeline.d.ts +204 -0
  178. package/dist/components/editor/core/timeline.js +349 -0
  179. package/dist/components/editor/editor-find.d.ts +56 -0
  180. package/dist/components/editor/editor-find.js +148 -0
  181. package/dist/components/editor/editor-input.d.ts +77 -0
  182. package/dist/components/editor/editor-input.js +445 -0
  183. package/dist/components/editor/editor-multicursor.d.ts +21 -0
  184. package/dist/components/editor/editor-multicursor.js +196 -0
  185. package/dist/components/editor/editor-scroll.d.ts +14 -0
  186. package/dist/components/editor/editor-scroll.js +34 -0
  187. package/dist/components/editor/index.d.ts +15 -0
  188. package/dist/components/editor/index.js +21 -0
  189. package/dist/components/editor/languages.d.ts +62 -0
  190. package/dist/components/editor/languages.js +285 -0
  191. package/dist/components/editor/theme.d.ts +88 -0
  192. package/dist/components/editor/theme.js +139 -0
  193. package/dist/components/editor/tokenizer/base.d.ts +40 -0
  194. package/dist/components/editor/tokenizer/base.js +203 -0
  195. package/dist/components/editor/tokenizer/index.d.ts +56 -0
  196. package/dist/components/editor/tokenizer/index.js +215 -0
  197. package/dist/components/editor/tokenizer/languages/css.d.ts +17 -0
  198. package/dist/components/editor/tokenizer/languages/css.js +194 -0
  199. package/dist/components/editor/tokenizer/languages/go.d.ts +17 -0
  200. package/dist/components/editor/tokenizer/languages/go.js +220 -0
  201. package/dist/components/editor/tokenizer/languages/html.d.ts +24 -0
  202. package/dist/components/editor/tokenizer/languages/html.js +145 -0
  203. package/dist/components/editor/tokenizer/languages/javascript.d.ts +56 -0
  204. package/dist/components/editor/tokenizer/languages/javascript.js +452 -0
  205. package/dist/components/editor/tokenizer/languages/json.d.ts +12 -0
  206. package/dist/components/editor/tokenizer/languages/json.js +91 -0
  207. package/dist/components/editor/tokenizer/languages/markdown.d.ts +16 -0
  208. package/dist/components/editor/tokenizer/languages/markdown.js +156 -0
  209. package/dist/components/editor/tokenizer/languages/python.d.ts +20 -0
  210. package/dist/components/editor/tokenizer/languages/python.js +227 -0
  211. package/dist/components/editor/tokenizer/languages/svelte.d.ts +40 -0
  212. package/dist/components/editor/tokenizer/languages/svelte.js +326 -0
  213. package/dist/components/editor/tokenizer/types.d.ts +86 -0
  214. package/dist/components/editor/tokenizer/types.js +4 -0
  215. package/dist/components/layout/IDELayout.svelte +274 -0
  216. package/dist/components/layout/IDELayout.svelte.d.ts +29 -0
  217. package/dist/components/layout/StatusBar.svelte +511 -0
  218. package/dist/components/layout/StatusBar.svelte.d.ts +47 -0
  219. package/dist/components/layout/index.d.ts +2 -0
  220. package/dist/components/layout/index.js +3 -0
  221. package/dist/components/lsp/AutocompleteWidget.svelte +364 -0
  222. package/dist/components/lsp/AutocompleteWidget.svelte.d.ts +33 -0
  223. package/dist/components/lsp/DiagnosticMarker.svelte +166 -0
  224. package/dist/components/lsp/DiagnosticMarker.svelte.d.ts +19 -0
  225. package/dist/components/lsp/DiagnosticsPanel.svelte +388 -0
  226. package/dist/components/lsp/DiagnosticsPanel.svelte.d.ts +21 -0
  227. package/dist/components/lsp/HoverTooltip.svelte +274 -0
  228. package/dist/components/lsp/HoverTooltip.svelte.d.ts +24 -0
  229. package/dist/components/lsp/LSPEditor.svelte +486 -0
  230. package/dist/components/lsp/LSPEditor.svelte.d.ts +39 -0
  231. package/dist/components/lsp/SignatureHelpWidget.svelte +216 -0
  232. package/dist/components/lsp/SignatureHelpWidget.svelte.d.ts +22 -0
  233. package/dist/components/lsp/index.d.ts +6 -0
  234. package/dist/components/lsp/index.js +7 -0
  235. package/dist/components/plugins/PluginCard.svelte +153 -0
  236. package/dist/components/plugins/PluginCard.svelte.d.ts +19 -0
  237. package/dist/components/plugins/PluginPanel.svelte +280 -0
  238. package/dist/components/plugins/PluginPanel.svelte.d.ts +8 -0
  239. package/dist/components/plugins/PluginProposalForm.svelte +250 -0
  240. package/dist/components/plugins/PluginProposalForm.svelte.d.ts +6 -0
  241. package/dist/components/plugins/PluginStatusBadge.svelte +14 -0
  242. package/dist/components/plugins/PluginStatusBadge.svelte.d.ts +8 -0
  243. package/dist/components/plugins/index.d.ts +4 -0
  244. package/dist/components/plugins/index.js +5 -0
  245. package/dist/components/vfs/LockConflictDialog.svelte +705 -0
  246. package/dist/components/vfs/LockConflictDialog.svelte.d.ts +21 -0
  247. package/dist/components/vfs/LockIndicator.svelte +194 -0
  248. package/dist/components/vfs/LockIndicator.svelte.d.ts +29 -0
  249. package/dist/components/vfs/LockOverlay.svelte +344 -0
  250. package/dist/components/vfs/LockOverlay.svelte.d.ts +17 -0
  251. package/dist/components/vfs/VersionConflictDialog.svelte +549 -0
  252. package/dist/components/vfs/VersionConflictDialog.svelte.d.ts +24 -0
  253. package/dist/components/vfs/index.d.ts +4 -0
  254. package/dist/components/vfs/index.js +5 -0
  255. package/dist/crdt/awareness.d.ts +42 -0
  256. package/dist/crdt/awareness.js +109 -0
  257. package/dist/crdt/document.d.ts +101 -0
  258. package/dist/crdt/document.js +187 -0
  259. package/dist/crdt/index.d.ts +9 -0
  260. package/dist/crdt/index.js +8 -0
  261. package/dist/crdt/provider.d.ts +85 -0
  262. package/dist/crdt/provider.js +150 -0
  263. package/dist/crdt/types.d.ts +61 -0
  264. package/dist/crdt/types.js +4 -0
  265. package/dist/crdt/undo.d.ts +34 -0
  266. package/dist/crdt/undo.js +70 -0
  267. package/dist/index.d.ts +277 -0
  268. package/dist/index.js +280 -0
  269. package/dist/plugins/index.d.ts +103 -0
  270. package/dist/plugins/index.js +153 -0
  271. package/dist/services/error-handling.d.ts +95 -0
  272. package/dist/services/error-handling.js +413 -0
  273. package/dist/services/ide-integration.d.ts +83 -0
  274. package/dist/services/ide-integration.js +367 -0
  275. package/dist/services/lsp-client.d.ts +69 -0
  276. package/dist/services/lsp-client.js +667 -0
  277. package/dist/services/mock-ai.d.ts +37 -0
  278. package/dist/services/mock-ai.js +318 -0
  279. package/dist/services/optimistic.d.ts +141 -0
  280. package/dist/services/optimistic.js +367 -0
  281. package/dist/services/vfs-client.d.ts +81 -0
  282. package/dist/services/vfs-client.js +348 -0
  283. package/dist/stores/agents.svelte.d.ts +85 -0
  284. package/dist/stores/agents.svelte.js +459 -0
  285. package/dist/stores/ai-persistence.svelte.d.ts +76 -0
  286. package/dist/stores/ai-persistence.svelte.js +334 -0
  287. package/dist/stores/ai.svelte.d.ts +140 -0
  288. package/dist/stores/ai.svelte.js +383 -0
  289. package/dist/stores/collaboration.svelte.d.ts +164 -0
  290. package/dist/stores/collaboration.svelte.js +334 -0
  291. package/dist/stores/editor.svelte.d.ts +131 -0
  292. package/dist/stores/editor.svelte.js +250 -0
  293. package/dist/stores/index.d.ts +10 -0
  294. package/dist/stores/index.js +29 -0
  295. package/dist/stores/layout.svelte.d.ts +171 -0
  296. package/dist/stores/layout.svelte.js +351 -0
  297. package/dist/stores/plugin.svelte.d.ts +121 -0
  298. package/dist/stores/plugin.svelte.js +410 -0
  299. package/dist/stores/vfs.svelte.d.ts +123 -0
  300. package/dist/stores/vfs.svelte.js +680 -0
  301. package/dist/styles/theme.css +623 -0
  302. package/dist/types/agents.d.ts +127 -0
  303. package/dist/types/agents.js +5 -0
  304. package/dist/types/ai.d.ts +137 -0
  305. package/dist/types/ai.js +4 -0
  306. package/dist/types/crdt.d.ts +222 -0
  307. package/dist/types/crdt.js +5 -0
  308. package/dist/types/editor.d.ts +52 -0
  309. package/dist/types/editor.js +18 -0
  310. package/dist/types/events.d.ts +133 -0
  311. package/dist/types/events.js +4 -0
  312. package/dist/types/filesystem.d.ts +77 -0
  313. package/dist/types/filesystem.js +4 -0
  314. package/dist/types/index.d.ts +9 -0
  315. package/dist/types/index.js +12 -0
  316. package/dist/types/lsp.d.ts +691 -0
  317. package/dist/types/lsp.js +108 -0
  318. package/dist/types/plugin.d.ts +239 -0
  319. package/dist/types/plugin.js +5 -0
  320. package/dist/types/vfs.d.ts +191 -0
  321. package/dist/types/vfs.js +18 -0
  322. package/dist/utils/format.d.ts +55 -0
  323. package/dist/utils/format.js +152 -0
  324. package/dist/utils/index.d.ts +3 -0
  325. package/dist/utils/index.js +4 -0
  326. package/dist/utils/keybindings.d.ts +33 -0
  327. package/dist/utils/keybindings.js +171 -0
  328. package/dist/utils/language.d.ts +27 -0
  329. package/dist/utils/language.js +222 -0
  330. package/package.json +178 -0
@@ -0,0 +1,367 @@
1
+ /**
2
+ * Optimistic Update Service
3
+ *
4
+ * Provides utilities for optimistic UI updates with automatic rollback on failure.
5
+ * Implements a queue-based system for managing pending operations.
6
+ */
7
+ // ============================================================================
8
+ // Operation Queue
9
+ // ============================================================================
10
+ const operationQueue = new Map();
11
+ const rollbackFunctions = new Map();
12
+ // ============================================================================
13
+ // Core Functions
14
+ // ============================================================================
15
+ /**
16
+ * Execute an optimistic update with automatic rollback on failure
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * const result = await optimisticUpdate({
21
+ * type: 'file_save',
22
+ * payload: { path: '/src/main.ts', content: '...' },
23
+ * apply: () => {
24
+ * // Apply change locally immediately
25
+ * updateLocalFile(path, content);
26
+ * },
27
+ * rollback: () => {
28
+ * // Revert to previous state
29
+ * updateLocalFile(path, previousContent);
30
+ * },
31
+ * commit: async () => {
32
+ * // Persist to server
33
+ * return await vfsClient.writeFile(workspaceId, path, content);
34
+ * }
35
+ * });
36
+ * ```
37
+ */
38
+ export async function optimisticUpdate(options) {
39
+ const { type, payload, apply, rollback, commit, config = {} } = options;
40
+ const { maxRetries = 3, retryDelay = 1000, onCommit, onRollback, onRetry } = config;
41
+ const operation = {
42
+ id: crypto.randomUUID(),
43
+ type,
44
+ payload,
45
+ timestamp: Date.now(),
46
+ status: 'pending',
47
+ retryCount: 0,
48
+ maxRetries
49
+ };
50
+ // Store operation and rollback
51
+ operationQueue.set(operation.id, operation);
52
+ rollbackFunctions.set(operation.id, rollback);
53
+ // Apply optimistically
54
+ try {
55
+ apply();
56
+ }
57
+ catch (applyError) {
58
+ // If apply fails, don't even try to commit
59
+ operation.status = 'failed';
60
+ operationQueue.delete(operation.id);
61
+ rollbackFunctions.delete(operation.id);
62
+ return {
63
+ success: false,
64
+ error: applyError instanceof Error ? applyError : new Error(String(applyError)),
65
+ operation: operation
66
+ };
67
+ }
68
+ // Try to commit with retries
69
+ let lastError;
70
+ while (operation.retryCount <= maxRetries) {
71
+ try {
72
+ const result = await commit();
73
+ operation.status = 'committed';
74
+ operationQueue.delete(operation.id);
75
+ rollbackFunctions.delete(operation.id);
76
+ onCommit?.(operation);
77
+ return {
78
+ success: true,
79
+ data: result,
80
+ operation: operation
81
+ };
82
+ }
83
+ catch (commitError) {
84
+ lastError = commitError instanceof Error ? commitError : new Error(String(commitError));
85
+ operation.retryCount++;
86
+ if (operation.retryCount <= maxRetries) {
87
+ onRetry?.(operation, operation.retryCount);
88
+ await delay(retryDelay * operation.retryCount); // Exponential backoff
89
+ }
90
+ }
91
+ }
92
+ // All retries failed - rollback
93
+ operation.status = 'failed';
94
+ try {
95
+ await rollback();
96
+ operation.status = 'rolledback';
97
+ onRollback?.(operation, lastError);
98
+ }
99
+ catch (rollbackError) {
100
+ console.error('Rollback failed:', rollbackError);
101
+ }
102
+ operationQueue.delete(operation.id);
103
+ rollbackFunctions.delete(operation.id);
104
+ return {
105
+ success: false,
106
+ error: lastError,
107
+ operation: operation
108
+ };
109
+ }
110
+ /**
111
+ * Create an optimistic state manager for a specific resource
112
+ */
113
+ export function createOptimisticState(initialValue) {
114
+ let currentValue = initialValue;
115
+ let pendingValue = null;
116
+ let isPending = false;
117
+ return {
118
+ get value() {
119
+ return pendingValue ?? currentValue;
120
+ },
121
+ get isPending() {
122
+ return isPending;
123
+ },
124
+ get confirmedValue() {
125
+ return currentValue;
126
+ },
127
+ /**
128
+ * Apply an optimistic update
129
+ */
130
+ async update(newValue, commit, config) {
131
+ const previousValue = currentValue;
132
+ pendingValue = newValue;
133
+ isPending = true;
134
+ const result = await optimisticUpdate({
135
+ type: 'state_update',
136
+ payload: newValue,
137
+ apply: () => {
138
+ // Already set pendingValue above
139
+ },
140
+ rollback: () => {
141
+ pendingValue = null;
142
+ isPending = false;
143
+ },
144
+ commit: async () => {
145
+ const confirmed = await commit();
146
+ currentValue = confirmed;
147
+ pendingValue = null;
148
+ isPending = false;
149
+ return confirmed;
150
+ },
151
+ config
152
+ });
153
+ if (!result.success) {
154
+ pendingValue = null;
155
+ isPending = false;
156
+ currentValue = previousValue;
157
+ }
158
+ return result;
159
+ },
160
+ /**
161
+ * Confirm a pending value (e.g., from server response)
162
+ */
163
+ confirm(value) {
164
+ currentValue = value;
165
+ pendingValue = null;
166
+ isPending = false;
167
+ },
168
+ /**
169
+ * Reset to initial value
170
+ */
171
+ reset() {
172
+ currentValue = initialValue;
173
+ pendingValue = null;
174
+ isPending = false;
175
+ }
176
+ };
177
+ }
178
+ /**
179
+ * Batch multiple optimistic operations
180
+ */
181
+ export async function batchOptimisticUpdates(operations, config) {
182
+ const results = [];
183
+ let failedCount = 0;
184
+ // Apply all optimistically first
185
+ const appliedOps = [];
186
+ for (const op of operations) {
187
+ try {
188
+ op.apply();
189
+ appliedOps.push({ op, rollback: op.rollback });
190
+ }
191
+ catch {
192
+ // If any apply fails, rollback all previous
193
+ for (const applied of appliedOps.reverse()) {
194
+ try {
195
+ await applied.rollback();
196
+ }
197
+ catch (rollbackError) {
198
+ console.error('Batch rollback failed:', rollbackError);
199
+ }
200
+ }
201
+ return {
202
+ success: false,
203
+ results: [],
204
+ failedCount: operations.length
205
+ };
206
+ }
207
+ }
208
+ // Commit all
209
+ for (const { op, rollback } of appliedOps) {
210
+ const result = await optimisticUpdate({
211
+ ...op,
212
+ apply: () => { }, // Already applied
213
+ rollback,
214
+ config
215
+ });
216
+ results.push(result);
217
+ if (!result.success)
218
+ failedCount++;
219
+ }
220
+ return {
221
+ success: failedCount === 0,
222
+ results,
223
+ failedCount
224
+ };
225
+ }
226
+ // ============================================================================
227
+ // Queue Management
228
+ // ============================================================================
229
+ /**
230
+ * Get all pending operations
231
+ */
232
+ export function getPendingOperations() {
233
+ return Array.from(operationQueue.values()).filter((op) => op.status === 'pending');
234
+ }
235
+ /**
236
+ * Get operation by ID
237
+ */
238
+ export function getOperation(id) {
239
+ return operationQueue.get(id);
240
+ }
241
+ /**
242
+ * Cancel a pending operation
243
+ */
244
+ export async function cancelOperation(id) {
245
+ const operation = operationQueue.get(id);
246
+ if (!operation || operation.status !== 'pending') {
247
+ return false;
248
+ }
249
+ const rollback = rollbackFunctions.get(id);
250
+ if (rollback) {
251
+ try {
252
+ await rollback();
253
+ operation.status = 'rolledback';
254
+ }
255
+ catch (error) {
256
+ console.error('Cancel rollback failed:', error);
257
+ return false;
258
+ }
259
+ }
260
+ operationQueue.delete(id);
261
+ rollbackFunctions.delete(id);
262
+ return true;
263
+ }
264
+ /**
265
+ * Cancel all pending operations
266
+ */
267
+ export async function cancelAllOperations() {
268
+ const pending = getPendingOperations();
269
+ for (const op of pending) {
270
+ await cancelOperation(op.id);
271
+ }
272
+ }
273
+ /**
274
+ * Check if an error indicates a conflict
275
+ */
276
+ export function isConflictError(error) {
277
+ const message = error.message.toLowerCase();
278
+ if (message.includes('version') || message.includes('conflict') || message.includes('stale')) {
279
+ return {
280
+ type: 'version',
281
+ timestamp: Date.now()
282
+ };
283
+ }
284
+ if (message.includes('lock') || message.includes('locked')) {
285
+ return {
286
+ type: 'lock',
287
+ timestamp: Date.now()
288
+ };
289
+ }
290
+ if (message.includes('concurrent') || message.includes('modified')) {
291
+ return {
292
+ type: 'concurrent',
293
+ timestamp: Date.now()
294
+ };
295
+ }
296
+ return null;
297
+ }
298
+ /**
299
+ * Parse conflict details from error
300
+ */
301
+ export function parseConflictDetails(error) {
302
+ // This would parse structured error responses from the server
303
+ // For now, return null as a placeholder
304
+ try {
305
+ const data = JSON.parse(error.message);
306
+ return {
307
+ localContent: data.localContent,
308
+ serverContent: data.serverContent,
309
+ baseContent: data.baseContent
310
+ };
311
+ }
312
+ catch {
313
+ return null;
314
+ }
315
+ }
316
+ // ============================================================================
317
+ // Utilities
318
+ // ============================================================================
319
+ function delay(ms) {
320
+ return new Promise((resolve) => setTimeout(resolve, ms));
321
+ }
322
+ /**
323
+ * Create a debounced optimistic updater
324
+ */
325
+ export function createDebouncedOptimistic(commitFn, delayMs = 500) {
326
+ let timeoutId = null;
327
+ let pendingValue = null;
328
+ let pendingResolve = null;
329
+ return {
330
+ update(value, apply, rollback) {
331
+ // Apply immediately
332
+ apply();
333
+ pendingValue = value;
334
+ // Clear previous timeout
335
+ if (timeoutId) {
336
+ clearTimeout(timeoutId);
337
+ }
338
+ return new Promise((resolve) => {
339
+ pendingResolve = resolve;
340
+ timeoutId = setTimeout(async () => {
341
+ if (pendingValue === null)
342
+ return;
343
+ const result = await optimisticUpdate({
344
+ type: 'debounced_update',
345
+ payload: pendingValue,
346
+ apply: () => { }, // Already applied
347
+ rollback,
348
+ commit: () => commitFn(pendingValue)
349
+ });
350
+ pendingValue = null;
351
+ timeoutId = null;
352
+ pendingResolve?.(result);
353
+ pendingResolve = null;
354
+ }, delayMs);
355
+ });
356
+ },
357
+ flush() {
358
+ if (timeoutId) {
359
+ clearTimeout(timeoutId);
360
+ timeoutId = null;
361
+ }
362
+ },
363
+ get isPending() {
364
+ return pendingValue !== null;
365
+ }
366
+ };
367
+ }
@@ -0,0 +1,81 @@
1
+ /**
2
+ * VFS Client Service
3
+ * Handles all HTTP interactions with a virtual filesystem (VFS) backend
4
+ */
5
+ import { type VFSFile, type VFSFileInfo, type VFSDirectory, type VFSWorkspace, type VFSTransaction, type VFSTransactionResult, type VFSOperation, type VFSFileLock, type VFSLockAcquisitionOptions, type VFSClientConfig } from '../types';
6
+ export declare function configure(newConfig: Partial<VFSClientConfig>): void;
7
+ export declare function getConfig(): VFSClientConfig;
8
+ export declare function getWorkspace(workspaceId: string): Promise<VFSWorkspace>;
9
+ export declare function updateWorkspace(workspaceId: string, updates: Partial<VFSWorkspace>): Promise<VFSWorkspace>;
10
+ export declare function listWorkspaces(): Promise<VFSWorkspace[]>;
11
+ export declare function readFile(workspaceId: string, path: string): Promise<VFSFile>;
12
+ export declare function writeFile(workspaceId: string, path: string, content: string, version?: number): Promise<VFSFileInfo>;
13
+ export declare function deleteFile(workspaceId: string, path: string, version?: number): Promise<void>;
14
+ export declare function renameFile(workspaceId: string, oldPath: string, newPath: string, version?: number): Promise<VFSFileInfo>;
15
+ export declare function getFileInfo(workspaceId: string, path: string): Promise<VFSFileInfo>;
16
+ export declare function copyFile(workspaceId: string, sourcePath: string, destPath: string): Promise<VFSFileInfo>;
17
+ export declare function readDirectory(workspaceId: string, path: string): Promise<VFSDirectory>;
18
+ export declare function createDirectory(workspaceId: string, path: string): Promise<VFSFileInfo>;
19
+ export declare function deleteDirectory(workspaceId: string, path: string, recursive?: boolean): Promise<void>;
20
+ export declare function quickWriteFile(workspaceId: string, path: string, content: string): Promise<VFSFileInfo>;
21
+ export declare function quickDeleteFile(workspaceId: string, path: string): Promise<void>;
22
+ export declare function beginTransaction(workspaceId: string): Promise<string>;
23
+ export declare function commitTransaction(transactionId: string, operations: VFSOperation[]): Promise<VFSTransactionResult>;
24
+ export declare function rollbackTransaction(transactionId: string): Promise<void>;
25
+ export declare function getTransaction(transactionId: string): Promise<VFSTransaction>;
26
+ /**
27
+ * Execute multiple operations in a transaction
28
+ * Auto-commits on success, auto-rollbacks on failure
29
+ */
30
+ export declare function executeTransaction(workspaceId: string, operations: VFSOperation[]): Promise<VFSTransactionResult>;
31
+ export declare function acquireLock(workspaceId: string, path: string, holder: string, options?: VFSLockAcquisitionOptions): Promise<VFSFileLock>;
32
+ export declare function releaseLock(workspaceId: string, path: string, holder: string): Promise<void>;
33
+ export declare function refreshLock(workspaceId: string, path: string, holder: string): Promise<VFSFileLock>;
34
+ export declare function getLockInfo(workspaceId: string, path: string): Promise<VFSFileLock | null>;
35
+ export declare function listLocks(workspaceId: string): Promise<VFSFileLock[]>;
36
+ export declare function forceReleaseLock(workspaceId: string, path: string, adminId: string): Promise<void>;
37
+ /**
38
+ * Execute a function with a file lock
39
+ * Automatically acquires, executes, and releases
40
+ */
41
+ export declare function withLock<T>(workspaceId: string, path: string, holder: string, fn: () => Promise<T>, options?: VFSLockAcquisitionOptions): Promise<T>;
42
+ /**
43
+ * Batch file operations with automatic locking and transaction
44
+ */
45
+ export declare function batchUpdate(workspaceId: string, holder: string, updates: Array<{
46
+ path: string;
47
+ content: string;
48
+ version?: number;
49
+ }>): Promise<VFSTransactionResult>;
50
+ /**
51
+ * Read file with automatic version tracking
52
+ */
53
+ export declare function readFileWithVersion(workspaceId: string, path: string): Promise<{
54
+ content: string;
55
+ version: number;
56
+ }>;
57
+ /**
58
+ * Write file with version conflict detection
59
+ */
60
+ export declare function safeWriteFile(workspaceId: string, path: string, content: string, expectedVersion: number): Promise<VFSFileInfo>;
61
+ export interface VFSSearchOptions {
62
+ pattern: string;
63
+ caseSensitive?: boolean;
64
+ regex?: boolean;
65
+ includeHidden?: boolean;
66
+ maxResults?: number;
67
+ filePatterns?: string[];
68
+ }
69
+ export interface VFSSearchResult {
70
+ path: string;
71
+ line: number;
72
+ column: number;
73
+ content: string;
74
+ matchStart: number;
75
+ matchEnd: number;
76
+ }
77
+ export declare function searchFiles(workspaceId: string, options: VFSSearchOptions): Promise<VFSSearchResult[]>;
78
+ export declare function healthCheck(): Promise<{
79
+ status: 'ok' | 'error';
80
+ latency: number;
81
+ }>;