deepspace 0.3.10 → 0.4.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 (120) hide show
  1. package/dist/cli.js +331 -115
  2. package/dist/cli.js.map +1 -1
  3. package/dist/index.d.ts +199 -16
  4. package/dist/index.js +354 -166
  5. package/dist/index.js.map +1 -1
  6. package/dist/server.d.ts +242 -73
  7. package/dist/server.js +985 -374
  8. package/dist/server.js.map +1 -1
  9. package/dist/worker.d.ts +322 -73
  10. package/dist/worker.js +961 -343
  11. package/dist/worker.js.map +1 -1
  12. package/features/admin-page/feature.json +29 -0
  13. package/features/admin-page/src/AdminPage.tsx +292 -0
  14. package/features/admin-page/src/admin-schema.ts +20 -0
  15. package/features/ai-chat/feature.json +41 -0
  16. package/features/ai-chat/src/AiChatPage.tsx +692 -0
  17. package/features/ai-chat/src/ChatPanel.tsx +1098 -0
  18. package/features/ai-chat/src/ai-chat-schema.ts +11 -0
  19. package/features/canvas/feature.json +45 -0
  20. package/features/canvas/src/CanvasEditorPage.tsx +87 -0
  21. package/features/canvas/src/CanvasListPage.tsx +202 -0
  22. package/features/canvas/src/canvas-schema.ts +33 -0
  23. package/features/canvas/src/components/CanvasToolbar.tsx +170 -0
  24. package/features/canvas/src/components/CanvasView.tsx +369 -0
  25. package/features/canvas/src/components/ShapeRenderer.tsx +114 -0
  26. package/features/cron/feature.json +33 -0
  27. package/features/cron/src/CronLogPage.tsx +100 -0
  28. package/features/cron/src/cron.ts +25 -0
  29. package/features/docs/feature.json +96 -0
  30. package/features/docs/src/DocsEditorPage.tsx +1012 -0
  31. package/features/docs/src/DocsListPage.tsx +951 -0
  32. package/features/docs/src/DocsOutlinePanel.tsx +68 -0
  33. package/features/docs/src/DocsPresence.tsx +138 -0
  34. package/features/docs/src/InviteDialog.tsx +336 -0
  35. package/features/docs/src/LibrarySidebar.tsx +464 -0
  36. package/features/docs/src/docs-favorites.ts +18 -0
  37. package/features/docs/src/docs-library-types.ts +15 -0
  38. package/features/docs/src/docs-schema.ts +80 -0
  39. package/features/docs/src/docs-ui.css +309 -0
  40. package/features/docs/src/editor/DocEditorSurface.tsx +257 -0
  41. package/features/docs/src/editor/DocsTiptapToolbar.tsx +560 -0
  42. package/features/docs/src/editor/useDocEditor.ts +206 -0
  43. package/features/docs/src/use-yjs-room-with-awareness.ts +285 -0
  44. package/features/file-attachments/feature.json +42 -0
  45. package/features/file-attachments/src/AttachmentsPage.tsx +864 -0
  46. package/features/file-attachments/src/attachments-constants.ts +9 -0
  47. package/features/file-attachments/src/attachments-schema.ts +45 -0
  48. package/features/file-attachments/src/useFilePreview.ts +471 -0
  49. package/features/file-attachments/src/useMimeTypeDetection.ts +138 -0
  50. package/features/file-manager/feature.json +24 -0
  51. package/features/file-manager/src/FileManagerPage.tsx +330 -0
  52. package/features/integration-test/feature.json +18 -0
  53. package/features/integration-test/src/IntegrationTestPage.tsx +423 -0
  54. package/features/integration-test/src/integration.spec.ts +42 -0
  55. package/features/items/feature.json +33 -0
  56. package/features/items/src/ItemsPage.tsx +325 -0
  57. package/features/items/src/items-constants.ts +10 -0
  58. package/features/items/src/items-schema.ts +27 -0
  59. package/features/kanban/feature.json +18 -0
  60. package/features/kanban/src/Kanban.tsx +283 -0
  61. package/features/landing/feature.json +62 -0
  62. package/features/landing/src/LandingPage.tsx +627 -0
  63. package/features/landing/src/primitives.tsx +389 -0
  64. package/features/landing/src/sections/FAQSection.tsx +110 -0
  65. package/features/landing/src/sections/FeaturesGridSection.tsx +311 -0
  66. package/features/landing/src/sections/HowItWorksSection.tsx +62 -0
  67. package/features/landing/src/sections/LogoCloudSection.tsx +58 -0
  68. package/features/landing/src/sections/ShowcaseSection.tsx +63 -0
  69. package/features/landing/src/sections/StatsSection.tsx +31 -0
  70. package/features/landing/src/sections/TeamSection.tsx +86 -0
  71. package/features/landing/src/sections/TestimonialsSection.tsx +68 -0
  72. package/features/landing/src/sections/VideoSection.tsx +71 -0
  73. package/features/leaderboard/feature.json +33 -0
  74. package/features/leaderboard/src/LeaderboardPage.tsx +372 -0
  75. package/features/leaderboard/src/leaderboard-constants.ts +21 -0
  76. package/features/leaderboard/src/leaderboard-schema.ts +36 -0
  77. package/features/messaging/feature.json +111 -0
  78. package/features/messaging/src/ChatMultiPage.tsx +300 -0
  79. package/features/messaging/src/ChatPage.tsx +75 -0
  80. package/features/messaging/src/components/chat/ChatHeader.tsx +76 -0
  81. package/features/messaging/src/components/chat/MessageActionSheet.tsx +168 -0
  82. package/features/messaging/src/components/chat/MessageInput.tsx +65 -0
  83. package/features/messaging/src/components/chat/MessageItem.tsx +352 -0
  84. package/features/messaging/src/components/chat/MessageList.tsx +248 -0
  85. package/features/messaging/src/components/chat/ReactionPicker.tsx +2 -0
  86. package/features/messaging/src/components/chat/ThreadPanel.tsx +107 -0
  87. package/features/messaging/src/components/chat/UserProfilePopover.tsx +158 -0
  88. package/features/messaging/src/components/chat-multi/AddMemberModal.tsx +188 -0
  89. package/features/messaging/src/components/chat-multi/BrowseGroupsModal.tsx +163 -0
  90. package/features/messaging/src/components/chat-multi/ChannelListItem.tsx +147 -0
  91. package/features/messaging/src/components/chat-multi/ChannelSettingsPanel.tsx +344 -0
  92. package/features/messaging/src/components/chat-multi/ChannelSidebar.tsx +460 -0
  93. package/features/messaging/src/components/chat-multi/CreateGroupModal.tsx +190 -0
  94. package/features/messaging/src/components/chat-multi/InvitationList.tsx +149 -0
  95. package/features/messaging/src/components/chat-multi/NewMessageModal.tsx +159 -0
  96. package/features/messaging/src/hooks/useChatChannel.ts +64 -0
  97. package/features/messaging/src/hooks/useLongPress.ts +74 -0
  98. package/features/messaging/src/hooks/useMultiChannel.ts +142 -0
  99. package/features/messaging/src/messaging-schema.ts +25 -0
  100. package/features/presence-test/feature.json +21 -0
  101. package/features/presence-test/src/PresenceTestPage.tsx +120 -0
  102. package/features/sidebar/feature.json +19 -0
  103. package/features/sidebar/src/AppSidebar.tsx +558 -0
  104. package/features/tasks/feature.json +33 -0
  105. package/features/tasks/src/TasksPage.tsx +598 -0
  106. package/features/tasks/src/tasks-constants.ts +43 -0
  107. package/features/tasks/src/tasks-schema.ts +56 -0
  108. package/features/testing/feature.json +49 -0
  109. package/features/testing/src/TestPage.tsx +145 -0
  110. package/features/testing/src/cpu-burn-action.ts +51 -0
  111. package/features/testing/src/subrequest-burn-action.ts +53 -0
  112. package/features/testing/src/test-schema.ts +23 -0
  113. package/features/topbar/feature.json +18 -0
  114. package/features/topbar/src/Topbar.tsx +353 -0
  115. package/features/tree/feature.json +26 -0
  116. package/features/tree/src/TreeSidebar.tsx +607 -0
  117. package/features/tree/src/tree-constants.ts +68 -0
  118. package/features/tree/src/tree-hooks.ts +258 -0
  119. package/package.json +4 -2
  120. package/scripts/add-feature.cjs +654 -0
@@ -0,0 +1,258 @@
1
+ /**
2
+ * Tree Sidebar - Hooks
3
+ *
4
+ * Drag and drop hooks for reordering items in a tree structure.
5
+ */
6
+
7
+ import React, { useState, useCallback, useRef } from 'react'
8
+
9
+ interface DragItem {
10
+ id: string
11
+ [key: string]: unknown
12
+ }
13
+
14
+ interface DragDropState {
15
+ dragging: DragItem | null
16
+ over: DragItem | null
17
+ }
18
+
19
+ interface DragHandlers {
20
+ onDragStart: (e: React.DragEvent, item: DragItem) => void
21
+ onDragOver: (e: React.DragEvent, item: DragItem) => void
22
+ onDragLeave: (e: React.DragEvent) => void
23
+ onDrop: (e: React.DragEvent, item: DragItem) => void
24
+ onDragEnd: () => void
25
+ }
26
+
27
+ /**
28
+ * Hook for drag-and-drop reordering of items.
29
+ * Supports multi-select drag when selectedIds is provided.
30
+ */
31
+ export function useDragDrop<T extends DragItem>(
32
+ items: T[],
33
+ setItems: (items: T[]) => void,
34
+ onReorder?: () => void,
35
+ selectedIds: string[] = []
36
+ ): {
37
+ draggedItem: DragItem | null
38
+ dragOverItem: DragItem | null
39
+ handlers: DragHandlers
40
+ } {
41
+ const [dragState, setDragState] = useState<DragDropState>({ dragging: null, over: null })
42
+ const dragRef = useRef<DragDropState>({ dragging: null, over: null })
43
+
44
+ const handleDragStart = useCallback((e: React.DragEvent, item: DragItem) => {
45
+ dragRef.current.dragging = item
46
+ setDragState(prev => ({ ...prev, dragging: item }))
47
+
48
+ e.dataTransfer.effectAllowed = 'move'
49
+ e.dataTransfer.setData('text/plain', item.id)
50
+ e.dataTransfer.setData('application/x-item', item.id)
51
+
52
+ const isMultiDrag = selectedIds.includes(item.id) && selectedIds.length > 1
53
+ const dragCount = isMultiDrag ? selectedIds.length : 1
54
+
55
+ const ghost = document.createElement('div')
56
+ ghost.style.cssText = `
57
+ position: fixed;
58
+ top: -1000px;
59
+ left: -1000px;
60
+ padding: 8px 12px;
61
+ background: var(--color-primary);
62
+ color: var(--color-primary-foreground);
63
+ border-radius: 8px;
64
+ font: 13px -apple-system, system-ui, sans-serif;
65
+ font-weight: 500;
66
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
67
+ pointer-events: none;
68
+ white-space: nowrap;
69
+ `
70
+
71
+ if (isMultiDrag) {
72
+ ghost.textContent = `${dragCount} items`
73
+ } else {
74
+ ghost.textContent = ((item as Record<string, unknown>).title as string || 'Item').slice(0, 25)
75
+ }
76
+
77
+ document.body.appendChild(ghost)
78
+ e.dataTransfer.setDragImage(ghost, 0, 0)
79
+
80
+ setTimeout(() => {
81
+ if (ghost.parentNode) ghost.parentNode.removeChild(ghost)
82
+ }, 0)
83
+ }, [selectedIds])
84
+
85
+ const handleDragOver = useCallback((e: React.DragEvent, item: DragItem) => {
86
+ e.preventDefault()
87
+ e.dataTransfer.dropEffect = 'move'
88
+
89
+ if (dragRef.current.over?.id !== item.id && dragRef.current.dragging?.id !== item.id) {
90
+ dragRef.current.over = item
91
+ setDragState(prev => ({ ...prev, over: item }))
92
+ }
93
+ }, [])
94
+
95
+ const handleDragLeave = useCallback(() => {
96
+ dragRef.current.over = null
97
+ setDragState(prev => ({ ...prev, over: null }))
98
+ }, [])
99
+
100
+ const handleDrop = useCallback((e: React.DragEvent, dropTarget: DragItem) => {
101
+ e.preventDefault()
102
+
103
+ const draggedItem = dragRef.current.dragging
104
+
105
+ dragRef.current = { dragging: null, over: null }
106
+ setDragState({ dragging: null, over: null })
107
+
108
+ if (!draggedItem || !dropTarget || draggedItem.id === dropTarget.id) {
109
+ return
110
+ }
111
+
112
+ const list = [...(items || [])]
113
+ const fromIndex = list.findIndex(t => t.id === draggedItem.id)
114
+ const toIndex = list.findIndex(t => t.id === dropTarget.id)
115
+
116
+ if (fromIndex !== -1 && toIndex !== -1) {
117
+ const [moved] = list.splice(fromIndex, 1)
118
+ list.splice(toIndex, 0, moved)
119
+ const reordered = list.map((item, i) => ({ ...item, order: i }))
120
+ setItems(reordered as T[])
121
+ if (onReorder) onReorder()
122
+ }
123
+ }, [items, setItems, onReorder])
124
+
125
+ const handleDragEnd = useCallback(() => {
126
+ dragRef.current = { dragging: null, over: null }
127
+ setDragState({ dragging: null, over: null })
128
+ }, [])
129
+
130
+ return {
131
+ draggedItem: dragState.dragging,
132
+ dragOverItem: dragState.over,
133
+ handlers: {
134
+ onDragStart: handleDragStart,
135
+ onDragOver: handleDragOver,
136
+ onDragLeave: handleDragLeave,
137
+ onDrop: handleDrop,
138
+ onDragEnd: handleDragEnd,
139
+ },
140
+ }
141
+ }
142
+
143
+ /**
144
+ * Hook for hierarchical drag-and-drop with before/after/inside positions.
145
+ * Used for tree structures like project hierarchies.
146
+ */
147
+ export function useTreeDragDrop(
148
+ onReorder?: (draggedId: string, targetId: string | null, position: 'before' | 'after' | 'inside') => void
149
+ ) {
150
+ const [dragState, setDragState] = useState<{
151
+ draggingId: string | null
152
+ dropTargetId: string | null
153
+ dropPosition: 'before' | 'after' | 'inside' | null
154
+ }>({
155
+ draggingId: null,
156
+ dropTargetId: null,
157
+ dropPosition: null,
158
+ })
159
+
160
+ const handleDragStart = useCallback((e: React.DragEvent, node: { id: string; title?: string; color?: string }) => {
161
+ e.dataTransfer.effectAllowed = 'move'
162
+ e.dataTransfer.setData('text/plain', node.id)
163
+ setDragState(prev => ({ ...prev, draggingId: node.id }))
164
+
165
+ const ghost = document.createElement('div')
166
+ ghost.textContent = (node.title || 'Item').slice(0, 30)
167
+ ghost.style.cssText = `
168
+ position: fixed;
169
+ top: -1000px;
170
+ left: -1000px;
171
+ padding: 6px 10px;
172
+ background: ${node.color || '#007AFF'};
173
+ color: white;
174
+ border-radius: 6px;
175
+ font: 13px -apple-system, system-ui, sans-serif;
176
+ font-weight: 500;
177
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
178
+ pointer-events: none;
179
+ white-space: nowrap;
180
+ `
181
+ document.body.appendChild(ghost)
182
+ e.dataTransfer.setDragImage(ghost, 0, 0)
183
+
184
+ setTimeout(() => {
185
+ if (ghost.parentNode) ghost.parentNode.removeChild(ghost)
186
+ }, 0)
187
+ }, [])
188
+
189
+ const handleDragOver = useCallback((e: React.DragEvent, targetId: string) => {
190
+ e.preventDefault()
191
+ e.stopPropagation()
192
+
193
+ if (!dragState.draggingId || dragState.draggingId === targetId) return
194
+
195
+ const rect = e.currentTarget.getBoundingClientRect()
196
+ const y = e.clientY - rect.top
197
+ const height = rect.height
198
+
199
+ let position: 'before' | 'after' | 'inside'
200
+ if (y < height * 0.25) {
201
+ position = 'before'
202
+ } else if (y > height * 0.75) {
203
+ position = 'after'
204
+ } else {
205
+ position = 'inside'
206
+ }
207
+
208
+ setDragState(prev => ({ ...prev, dropTargetId: targetId, dropPosition: position }))
209
+ }, [dragState.draggingId])
210
+
211
+ const handleDragLeave = useCallback((e: React.DragEvent) => {
212
+ if (!e.currentTarget.contains(e.relatedTarget as Node)) {
213
+ setDragState(prev => ({ ...prev, dropTargetId: null, dropPosition: null }))
214
+ }
215
+ }, [])
216
+
217
+ const handleDrop = useCallback((e: React.DragEvent, targetId: string) => {
218
+ e.preventDefault()
219
+ e.stopPropagation()
220
+
221
+ const { draggingId, dropPosition } = dragState
222
+ if (!draggingId || !targetId || draggingId === targetId || !dropPosition) {
223
+ setDragState({ draggingId: null, dropTargetId: null, dropPosition: null })
224
+ return
225
+ }
226
+
227
+ if (onReorder) {
228
+ onReorder(draggingId, targetId, dropPosition)
229
+ }
230
+
231
+ setDragState({ draggingId: null, dropTargetId: null, dropPosition: null })
232
+ }, [dragState, onReorder])
233
+
234
+ const handleDragEnd = useCallback(() => {
235
+ setDragState({ draggingId: null, dropTargetId: null, dropPosition: null })
236
+ }, [])
237
+
238
+ const handleRootDrop = useCallback((e: React.DragEvent) => {
239
+ e.preventDefault()
240
+ const { draggingId } = dragState
241
+ if (draggingId && onReorder) {
242
+ onReorder(draggingId, null, 'inside')
243
+ }
244
+ setDragState({ draggingId: null, dropTargetId: null, dropPosition: null })
245
+ }, [dragState, onReorder])
246
+
247
+ return {
248
+ dragState,
249
+ handlers: {
250
+ onDragStart: handleDragStart,
251
+ onDragOver: handleDragOver,
252
+ onDragLeave: handleDragLeave,
253
+ onDrop: handleDrop,
254
+ onDragEnd: handleDragEnd,
255
+ onRootDrop: handleRootDrop,
256
+ },
257
+ }
258
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepspace",
3
- "version": "0.3.10",
3
+ "version": "0.4.0",
4
4
  "description": "DeepSpace SDK — build real-time collaborative apps on Cloudflare Workers",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -27,7 +27,9 @@
27
27
  }
28
28
  },
29
29
  "files": [
30
- "dist"
30
+ "dist",
31
+ "features",
32
+ "scripts"
31
33
  ],
32
34
  "scripts": {
33
35
  "build": "tsup --clean",