@geenius/tools 0.1.0 → 0.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 (177) hide show
  1. package/package.json +62 -3
  2. package/packages/convex/shared/README.md +1 -1
  3. package/packages/devtools/dist/index.d.ts +204 -0
  4. package/packages/devtools/dist/index.js +186 -0
  5. package/packages/devtools/dist/index.js.map +1 -0
  6. package/packages/devtools/react/README.md +1 -1
  7. package/packages/devtools/solidjs/README.md +1 -1
  8. package/packages/devtools/solidjs/dist/index.js +1830 -0
  9. package/packages/devtools/solidjs/dist/index.js.map +1 -0
  10. package/packages/env/dist/index.d.ts +151 -0
  11. package/packages/env/dist/index.js +93 -0
  12. package/packages/env/dist/index.js.map +1 -0
  13. package/packages/errors/dist/index.d.ts +177 -0
  14. package/packages/errors/dist/index.js +187 -0
  15. package/packages/errors/dist/index.js.map +1 -0
  16. package/packages/errors/react/README.md +1 -1
  17. package/packages/errors/solidjs/README.md +1 -1
  18. package/packages/logger/dist/index.d.ts +171 -0
  19. package/packages/logger/dist/index.js +216 -0
  20. package/packages/logger/dist/index.js.map +1 -0
  21. package/packages/logger/react/README.md +1 -1
  22. package/packages/logger/solidjs/README.md +1 -1
  23. package/packages/perf/dist/index.d.ts +168 -0
  24. package/packages/perf/dist/index.js +265 -0
  25. package/packages/perf/dist/index.js.map +1 -0
  26. package/packages/perf/react/README.md +1 -1
  27. package/packages/perf/solidjs/README.md +1 -1
  28. package/packages/shared/dist/index.d.ts +253 -0
  29. package/packages/shared/dist/index.js +278 -0
  30. package/packages/shared/dist/index.js.map +1 -0
  31. package/.changeset/config.json +0 -11
  32. package/.env.example +0 -2
  33. package/.github/CODEOWNERS +0 -1
  34. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -16
  35. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -11
  36. package/.github/PULL_REQUEST_TEMPLATE.md +0 -10
  37. package/.github/dependabot.yml +0 -11
  38. package/.github/workflows/ci.yml +0 -23
  39. package/.github/workflows/release.yml +0 -29
  40. package/.node-version +0 -1
  41. package/.nvmrc +0 -1
  42. package/.prettierrc +0 -7
  43. package/.project/ACCOUNT.yaml +0 -4
  44. package/.project/IDEAS.yaml +0 -7
  45. package/.project/PROJECT.yaml +0 -11
  46. package/.project/ROADMAP.yaml +0 -15
  47. package/CODE_OF_CONDUCT.md +0 -26
  48. package/CONTRIBUTING.md +0 -69
  49. package/SECURITY.md +0 -18
  50. package/SUPPORT.md +0 -14
  51. package/packages/convex/shared/package.json +0 -42
  52. package/packages/convex/shared/src/audit/index.ts +0 -5
  53. package/packages/convex/shared/src/audit/presets.ts +0 -165
  54. package/packages/convex/shared/src/audit/schema.ts +0 -85
  55. package/packages/convex/shared/src/audit/write.ts +0 -102
  56. package/packages/convex/shared/src/extract.ts +0 -75
  57. package/packages/convex/shared/src/index.ts +0 -41
  58. package/packages/convex/shared/src/messages.ts +0 -45
  59. package/packages/convex/shared/src/security.ts +0 -112
  60. package/packages/convex/shared/src/throw.ts +0 -184
  61. package/packages/convex/shared/src/types.ts +0 -57
  62. package/packages/convex/shared/src/utils.ts +0 -58
  63. package/packages/convex/shared/tsconfig.json +0 -28
  64. package/packages/convex/shared/tsup.config.ts +0 -12
  65. package/packages/devtools/package.json +0 -27
  66. package/packages/devtools/react/package.json +0 -53
  67. package/packages/devtools/react/src/components/DesignPreview.tsx +0 -59
  68. package/packages/devtools/react/src/components/DesignSwitcherDropdown.tsx +0 -99
  69. package/packages/devtools/react/src/components/DevSidebar.tsx +0 -247
  70. package/packages/devtools/react/src/components/DevToolbar.tsx +0 -242
  71. package/packages/devtools/react/src/components/GitHubIssueDialog.tsx +0 -402
  72. package/packages/devtools/react/src/components/InspectorOverlay.tsx +0 -312
  73. package/packages/devtools/react/src/components/PageLoadWaterfall.tsx +0 -144
  74. package/packages/devtools/react/src/components/PerformancePanel.tsx +0 -330
  75. package/packages/devtools/react/src/context/DevModeContext.tsx +0 -226
  76. package/packages/devtools/react/src/context/PerformanceContext.tsx +0 -143
  77. package/packages/devtools/react/src/data/designs.ts +0 -13
  78. package/packages/devtools/react/src/hooks/useGitHubLabels.ts +0 -47
  79. package/packages/devtools/react/src/hooks/useVirtualList.ts +0 -124
  80. package/packages/devtools/react/src/index.ts +0 -77
  81. package/packages/devtools/react/src/panels/ConvexSpy.tsx +0 -130
  82. package/packages/devtools/react/src/panels/DatabaseSeeder.tsx +0 -116
  83. package/packages/devtools/react/src/panels/DevModePhase2.tsx +0 -191
  84. package/packages/devtools/react/src/panels/DevModePhase3.tsx +0 -234
  85. package/packages/devtools/react/src/panels/FeatureFlagsToggle.tsx +0 -104
  86. package/packages/devtools/react/src/panels/QuickRouteJump.tsx +0 -152
  87. package/packages/devtools/react/src/services/github-service.ts +0 -247
  88. package/packages/devtools/react/tsconfig.json +0 -31
  89. package/packages/devtools/react/tsup.config.ts +0 -18
  90. package/packages/devtools/solidjs/package.json +0 -49
  91. package/packages/devtools/solidjs/src/components/DesignPreview.tsx +0 -51
  92. package/packages/devtools/solidjs/src/components/DesignSwitcherDropdown.tsx +0 -95
  93. package/packages/devtools/solidjs/src/components/DevSidebar.tsx +0 -247
  94. package/packages/devtools/solidjs/src/components/DevToolbar.tsx +0 -242
  95. package/packages/devtools/solidjs/src/components/GitHubIssueDialog.tsx +0 -400
  96. package/packages/devtools/solidjs/src/components/InspectorOverlay.tsx +0 -311
  97. package/packages/devtools/solidjs/src/components/PageLoadWaterfall.tsx +0 -144
  98. package/packages/devtools/solidjs/src/components/PerformancePanel.tsx +0 -330
  99. package/packages/devtools/solidjs/src/context/DevModeContext.tsx +0 -216
  100. package/packages/devtools/solidjs/src/context/PerformanceContext.tsx +0 -135
  101. package/packages/devtools/solidjs/src/data/designs.ts +0 -13
  102. package/packages/devtools/solidjs/src/hooks/createGitHubLabels.ts +0 -47
  103. package/packages/devtools/solidjs/src/index.ts +0 -64
  104. package/packages/devtools/solidjs/src/services/github-service.ts +0 -247
  105. package/packages/devtools/solidjs/tsconfig.json +0 -21
  106. package/packages/devtools/src/index.ts +0 -377
  107. package/packages/devtools/tsup.config.ts +0 -12
  108. package/packages/env/package.json +0 -30
  109. package/packages/env/src/index.ts +0 -264
  110. package/packages/env/tsup.config.ts +0 -12
  111. package/packages/errors/package.json +0 -27
  112. package/packages/errors/react/package.json +0 -72
  113. package/packages/errors/react/src/analytics.ts +0 -16
  114. package/packages/errors/react/src/components/ErrorBoundary.tsx +0 -248
  115. package/packages/errors/react/src/components/ErrorDisplay.tsx +0 -328
  116. package/packages/errors/react/src/components/ValidationErrors.tsx +0 -102
  117. package/packages/errors/react/src/config.ts +0 -199
  118. package/packages/errors/react/src/constants.ts +0 -74
  119. package/packages/errors/react/src/hooks/useErrorBoundary.ts +0 -92
  120. package/packages/errors/react/src/hooks/useErrorHandler.ts +0 -87
  121. package/packages/errors/react/src/index.ts +0 -96
  122. package/packages/errors/react/src/types.ts +0 -102
  123. package/packages/errors/react/src/utils/errorMessages.ts +0 -35
  124. package/packages/errors/react/src/utils/errorPolicy.ts +0 -139
  125. package/packages/errors/react/src/utils/extractAppError.ts +0 -174
  126. package/packages/errors/react/src/utils/formatError.ts +0 -112
  127. package/packages/errors/react/tsconfig.json +0 -25
  128. package/packages/errors/react/tsup.config.ts +0 -24
  129. package/packages/errors/solidjs/package.json +0 -46
  130. package/packages/errors/solidjs/src/components/ErrorDisplay.tsx +0 -179
  131. package/packages/errors/solidjs/src/config.ts +0 -98
  132. package/packages/errors/solidjs/src/hooks/createErrorHandler.ts +0 -107
  133. package/packages/errors/solidjs/src/index.ts +0 -61
  134. package/packages/errors/solidjs/src/types.ts +0 -34
  135. package/packages/errors/solidjs/src/utils/errorPolicy.ts +0 -56
  136. package/packages/errors/solidjs/src/utils/extractAppError.ts +0 -94
  137. package/packages/errors/solidjs/src/utils/formatError.ts +0 -33
  138. package/packages/errors/solidjs/tsconfig.json +0 -26
  139. package/packages/errors/solidjs/tsup.config.ts +0 -21
  140. package/packages/errors/src/index.ts +0 -320
  141. package/packages/errors/tsup.config.ts +0 -12
  142. package/packages/logger/package.json +0 -27
  143. package/packages/logger/react/package.json +0 -46
  144. package/packages/logger/react/src/index.ts +0 -4
  145. package/packages/logger/react/src/useMetrics.ts +0 -42
  146. package/packages/logger/react/src/usePerformanceLog.ts +0 -61
  147. package/packages/logger/react/tsconfig.json +0 -31
  148. package/packages/logger/react/tsup.config.ts +0 -12
  149. package/packages/logger/solidjs/package.json +0 -45
  150. package/packages/logger/solidjs/src/createMetrics.ts +0 -37
  151. package/packages/logger/solidjs/src/createPerformanceLog.ts +0 -58
  152. package/packages/logger/solidjs/src/index.ts +0 -4
  153. package/packages/logger/solidjs/tsconfig.json +0 -32
  154. package/packages/logger/solidjs/tsup.config.ts +0 -12
  155. package/packages/logger/src/index.ts +0 -363
  156. package/packages/logger/tsup.config.ts +0 -12
  157. package/packages/perf/package.json +0 -27
  158. package/packages/perf/react/package.json +0 -59
  159. package/packages/perf/react/src/components/PerformanceDashboard.tsx +0 -257
  160. package/packages/perf/react/src/hooks/useMonitoredQuery.ts +0 -89
  161. package/packages/perf/react/src/hooks/usePerformanceMetrics.ts +0 -78
  162. package/packages/perf/react/src/index.ts +0 -33
  163. package/packages/perf/react/src/services/PerformanceMonitor.ts +0 -313
  164. package/packages/perf/react/src/types.ts +0 -77
  165. package/packages/perf/react/tsconfig.json +0 -25
  166. package/packages/perf/react/tsup.config.ts +0 -19
  167. package/packages/perf/solidjs/package.json +0 -41
  168. package/packages/perf/solidjs/src/components/PerformanceDashboard.tsx +0 -207
  169. package/packages/perf/solidjs/src/hooks/createPerformanceMetrics.ts +0 -73
  170. package/packages/perf/solidjs/src/index.ts +0 -31
  171. package/packages/perf/solidjs/src/services/PerformanceMonitor.ts +0 -134
  172. package/packages/perf/solidjs/src/types.ts +0 -78
  173. package/packages/perf/solidjs/tsconfig.json +0 -26
  174. package/packages/perf/solidjs/tsup.config.ts +0 -14
  175. package/packages/perf/src/index.ts +0 -410
  176. package/packages/perf/tsup.config.ts +0 -12
  177. package/pnpm-workspace.yaml +0 -2
@@ -1,330 +0,0 @@
1
- // @geenius-tools/devtools-solidjs — src/components/PerformancePanel.tsx
2
-
3
- import { createMemo, createEffect } from 'solid-js'
4
- import { cn } from '@geenius-ui/solid'
5
- import { X, Trash2, Activity, Zap, Clock, AlertTriangle } from 'lucide-solid'
6
- import { createPerformanceContext } from '../context/PerformanceContext'
7
- import type { PerformanceMetric } from '@geenius-tools/logger'
8
-
9
- function getDurationColor(duration: number | undefined): string {
10
- if (duration === undefined) return 'text-white/40'
11
- if (duration > 100) return 'text-red-400'
12
- if (duration > 50) return 'text-yellow-400'
13
- return 'text-green-400'
14
- }
15
-
16
- function getDurationBgColor(duration: number | undefined): string {
17
- if (duration === undefined) return 'bg-white/20'
18
- if (duration > 100) return 'bg-red-500'
19
- if (duration > 50) return 'bg-yellow-500'
20
- return 'bg-green-500'
21
- }
22
-
23
- function getTypeColor(type: string): string {
24
- switch (type) {
25
- case 'network':
26
- return 'text-blue-400'
27
- case 'query':
28
- return 'text-orange-400'
29
- case 'mutation':
30
- return 'text-red-400'
31
- case 'render':
32
- return 'text-purple-400'
33
- case 'route':
34
- return 'text-green-400'
35
- case 'component':
36
- return 'text-cyan-400'
37
- case 'effect':
38
- return 'text-teal-400'
39
- default:
40
- return 'text-white/60'
41
- }
42
- }
43
-
44
- function getTypeIcon(type: string) {
45
- switch (type) {
46
- case 'network':
47
- return '🌐'
48
- case 'query':
49
- return '🔍'
50
- case 'mutation':
51
- return '✏️'
52
- case 'render':
53
- return '🎨'
54
- case 'route':
55
- return '🧭'
56
- case 'component':
57
- return '📦'
58
- case 'effect':
59
- return '⚡'
60
- default:
61
- return '📝'
62
- }
63
- }
64
-
65
- const MiniBar = memo(function MiniBar({
66
- height,
67
- color,
68
- label,
69
- }: {
70
- height: number
71
- color: string
72
- label: string
73
- }) {
74
- return (
75
- <div class="flex flex-col items-center gap-0.5 flex-1 min-w-0">
76
- <div class="w-full h-12 flex items-end">
77
- <div
78
- class={cn('w-full rounded-t-sm transition-all duration-300', color)}
79
- style={{ height: `${Math.min(height, 100)}%` }}
80
- title={label}
81
- />
82
- </div>
83
- </div>
84
- )
85
- })
86
-
87
- const MetricRow = memo(function MetricRow({
88
- metric,
89
- }: {
90
- metric: PerformanceMetric
91
- }) {
92
- const duration = metric.duration
93
- const durationStr = duration ? `${duration.toFixed(1)}ms` : 'pending...'
94
-
95
- return (
96
- <div
97
- class={cn(
98
- 'flex items-center gap-3 px-3 py-2 rounded-lg',
99
- 'bg-white/5 hover:bg-white/10 transition-colors',
100
- )}
101
- >
102
- <span class="text-sm">{getTypeIcon(metric.type)}</span>
103
- <div class="flex-1 min-w-0">
104
- <div class={cn('text-xs font-medium truncate', getTypeColor(metric.type))}>
105
- {metric.name}
106
- </div>
107
- </div>
108
- <div
109
- class={cn(
110
- 'text-xs font-mono font-bold',
111
- getDurationColor(duration),
112
- )}
113
- >
114
- {durationStr}
115
- </div>
116
- </div>
117
- )
118
- })
119
-
120
- const StatCard = memo(function StatCard({
121
- icon: Icon,
122
- label,
123
- value,
124
- color = 'text-white',
125
- }: {
126
- icon: React.ElementType
127
- label: string
128
- value: string | number
129
- color?: string
130
- }) {
131
- return (
132
- <div class="flex items-center gap-2 px-3 py-2 rounded-lg bg-white/5">
133
- <Icon class={cn('w-4 h-4', color)} />
134
- <div class="flex flex-col">
135
- <span class="text-[10px] text-white/50 uppercase">{label}</span>
136
- <span class="text-sm font-bold text-white">{value}</span>
137
- </div>
138
- </div>
139
- )
140
- })
141
-
142
- const FilterToggle = memo(function FilterToggle({
143
- label,
144
- active,
145
- color,
146
- onClick,
147
- }: {
148
- label: string
149
- active: boolean
150
- color: string
151
- onClick: () => void
152
- }) {
153
- return (
154
- <button
155
- onClick={onClick}
156
- class={cn(
157
- 'px-2 py-1 rounded text-xs font-medium transition-all',
158
- active
159
- ? `${color} text-white`
160
- : 'bg-white/10 text-white/50 hover:bg-white/20',
161
- )}
162
- >
163
- {label}
164
- </button>
165
- )
166
- })
167
-
168
- export const PerformancePanel = memo(function PerformancePanel() {
169
- const {
170
- isPerformancePanelOpen,
171
- metrics,
172
- filters,
173
- stats,
174
- togglePerformancePanel,
175
- clearMetrics,
176
- toggleFilter,
177
- } = createPerformanceContext()
178
-
179
- let listRef: HTMLDivElement | undefined
180
-
181
- const filteredMetrics = createMemo(() => {
182
- return metrics.filter((m) => {
183
- if (m.type === 'network' && !filters.network) return false
184
- if (m.type === 'query' && !filters.query) return false
185
- if (m.type === 'mutation' && !filters.mutation) return false
186
- if (m.type === 'render' && !filters.render) return false
187
- if (m.type === 'route' && !filters.route) return false
188
- return true
189
- })
190
- })
191
-
192
- const chartMetrics = createMemo(() => {
193
- return filteredMetrics.filter((m) => m.duration !== undefined).slice(-20)
194
- })
195
-
196
- const maxDuration = createMemo(() => {
197
- if (chartMetrics.length === 0) return 100
198
- const max = Math.max(...chartMetrics.map((m) => m.duration || 0))
199
- return Math.max(max, 100)
200
- })
201
-
202
- createEffect(() => {
203
- if (listRef) {
204
- listRef.scrollTop = listRef.scrollHeight
205
- }
206
- }, [filteredMetrics.length])
207
-
208
- if (!isPerformancePanelOpen) return null
209
-
210
- return (
211
- <div
212
- data-dev-tool="true"
213
- class={cn(
214
- 'fixed bottom-20 left-1/2 -translate-x-1/2 z-50',
215
- 'w-[440px] max-h-[400px]',
216
- 'rounded-2xl border border-white/10',
217
- 'bg-gradient-to-b from-slate-900/95 via-slate-800/95 to-slate-900/95',
218
- 'backdrop-blur-xl shadow-2xl shadow-black/50',
219
- 'flex flex-col overflow-hidden',
220
- 'animate-in slide-in-from-bottom-4 fade-in duration-300',
221
- )}
222
- >
223
- {/* Header */}
224
- <div class="flex items-center justify-between px-4 py-3 border-b border-white/10">
225
- <div class="flex items-center gap-2">
226
- <Activity class="w-4 h-4 text-primary" />
227
- <span class="text-sm font-bold text-white">Performance</span>
228
- <span class="text-xs text-white/40">
229
- ({filteredMetrics.length} events)
230
- </span>
231
- </div>
232
- <div class="flex items-center gap-1">
233
- <button
234
- onClick={clearMetrics}
235
- class="p-1.5 text-white/40 hover:text-white hover:bg-white/10 rounded-lg transition-colors"
236
- title="Clear metrics"
237
- >
238
- <Trash2 class="w-3.5 h-3.5" />
239
- </button>
240
- <button
241
- onClick={togglePerformancePanel}
242
- class="p-1.5 text-white/40 hover:text-white hover:bg-white/10 rounded-lg transition-colors"
243
- title="Close panel"
244
- >
245
- <X class="w-4 h-4" />
246
- </button>
247
- </div>
248
- </div>
249
-
250
- {/* Stats Bar */}
251
- <div class="flex gap-2 px-4 py-3 border-b border-white/10 overflow-x-auto">
252
- <StatCard
253
- icon={Activity}
254
- label="Requests"
255
- value={stats.totalRequests}
256
- color="text-blue-400"
257
- />
258
- <StatCard
259
- icon={Clock}
260
- label="Avg"
261
- value={`${stats.avgDuration}ms`}
262
- color={
263
- stats.avgDuration > 100
264
- ? 'text-red-400'
265
- : stats.avgDuration > 50
266
- ? 'text-yellow-400'
267
- : 'text-green-400'
268
- }
269
- />
270
- <StatCard
271
- icon={Zap}
272
- label="Fast"
273
- value={stats.fastRequests}
274
- color="text-green-400"
275
- />
276
- <StatCard
277
- icon={AlertTriangle}
278
- label="Slow"
279
- value={stats.slowRequests}
280
- color={stats.slowRequests > 0 ? 'text-red-400' : 'text-white/50'}
281
- />
282
- </div>
283
-
284
- {/* Mini Chart */}
285
- {chartMetrics.length > 0 && (
286
- <div class="px-4 py-3 border-b border-white/10">
287
- <div class="flex items-end gap-1 h-16">
288
- {chartMetrics.map((metric) => (
289
- <MiniBar
290
- key={metric.id}
291
- height={((metric.duration || 0) / maxDuration) * 100}
292
- color={getDurationBgColor(metric.duration)}
293
- label={`${metric.name}: ${metric.duration?.toFixed(1)}ms`}
294
- />
295
- ))}
296
- </div>
297
- <div class="flex justify-between mt-1 text-xs text-white/40">
298
- <span>Recent requests</span>
299
- <span>0-{maxDuration.toFixed(0)}ms</span>
300
- </div>
301
- </div>
302
- )}
303
-
304
- {/* Filters */}
305
- <div class="flex gap-1 px-4 py-2 border-b border-white/10">
306
- <FilterToggle label="Network" active={filters.network} color="bg-blue-500" onClick={() => toggleFilter('network')} />
307
- <FilterToggle label="Query" active={filters.query} color="bg-orange-500" onClick={() => toggleFilter('query')} />
308
- <FilterToggle label="Mutation" active={filters.mutation} color="bg-red-500" onClick={() => toggleFilter('mutation')} />
309
- <FilterToggle label="Render" active={filters.render} color="bg-purple-500" onClick={() => toggleFilter('render')} />
310
- <FilterToggle label="Route" active={filters.route} color="bg-green-500" onClick={() => toggleFilter('route')} />
311
- </div>
312
-
313
- {/* Metrics List */}
314
- <div
315
- ref={listRef}
316
- class="flex-1 overflow-y-auto px-3 py-2 space-y-1 min-h-[100px] max-h-[180px]"
317
- >
318
- {filteredMetrics.length === 0 ? (
319
- <div class="flex items-center justify-center py-8 text-sm text-white/30">
320
- No metrics recorded yet
321
- </div>
322
- ) : (
323
- filteredMetrics.map((metric) => (
324
- <MetricRow key={metric.id} metric={metric} />
325
- ))
326
- )}
327
- </div>
328
- </div>
329
- )
330
- })
@@ -1,216 +0,0 @@
1
- // @geenius-tools/devtools-solidjs — src/context/DevModeContext.tsx
2
-
3
- import { createContext, useContext, createSignal, createEffect, type JSX } from 'solid-js'
4
-
5
- const DEV_MODE_STORAGE_KEY = 'geenius-dev-mode-state'
6
-
7
- export interface ComponentDetails {
8
- name: string
9
- file?: string
10
- selector: string
11
- key?: string
12
- props?: Record<string, unknown>
13
- }
14
-
15
- interface DevModeState {
16
- isDevMode: boolean
17
- isSidebarOpen: boolean
18
- isInspectorMode: boolean
19
- issueDialog: {
20
- isOpen: boolean
21
- type: 'bug' | 'feature'
22
- initialDescription?: string
23
- componentDetails?: ComponentDetails[]
24
- }
25
- }
26
-
27
- export interface DevModeContextValue extends DevModeState {
28
- toggleDevMode: () => void
29
- toggleSidebar: () => void
30
- toggleInspector: () => void
31
- setDevMode: (enabled: boolean) => void
32
- setSidebarOpen: (open: boolean) => void
33
- setInspectorMode: (enabled: boolean) => void
34
- openIssueDialog: (
35
- type: 'bug' | 'feature',
36
- description?: string,
37
- componentDetails?: ComponentDetails[],
38
- ) => void
39
- closeIssueDialog: () => void
40
- }
41
-
42
- const defaultState: DevModeState = {
43
- isDevMode: false,
44
- isSidebarOpen: false,
45
- isInspectorMode: false,
46
- issueDialog: {
47
- isOpen: false,
48
- type: 'bug',
49
- initialDescription: '',
50
- },
51
- }
52
-
53
- const DevModeContext = createContext<DevModeContextValue | undefined>(undefined)
54
-
55
- export function createDevMode() {
56
- const context = useContext(DevModeContext)
57
- if (!context) {
58
- throw new Error('createDevMode must be used within a DevModeProvider')
59
- }
60
- return context
61
- }
62
-
63
- export function createDevModeOptional(): DevModeContextValue | null {
64
- return useContext(DevModeContext) ?? null
65
- }
66
-
67
- export interface DevModeProviderProps {
68
- children: JSX.Element
69
- /** Whether dev tools are allowed. Default: checks import.meta.env.DEV */
70
- isAllowed?: boolean
71
- }
72
-
73
- export const DevModeProvider = memo(function DevModeProvider({
74
- children,
75
- isAllowed,
76
- }: DevModeProviderProps) {
77
- const resolvedAllowed = isAllowed ?? resolveDevAllowed()
78
-
79
- const [state, setState] = createSignal<DevModeState>(() => {
80
- if (!resolvedAllowed || typeof window === 'undefined') return defaultState
81
-
82
- try {
83
- const stored = localStorage.getItem(DEV_MODE_STORAGE_KEY)
84
- if (stored) {
85
- const parsed = JSON.parse(stored) as Partial<DevModeState>
86
- return {
87
- isDevMode: parsed.isDevMode ?? false,
88
- isSidebarOpen: false,
89
- isInspectorMode: false,
90
- issueDialog: defaultState.issueDialog,
91
- }
92
- }
93
- } catch {
94
- // Ignore parse errors
95
- }
96
- return defaultState
97
- })
98
-
99
- createEffect(() => {
100
- if (!resolvedAllowed || typeof window === 'undefined') return
101
-
102
- try {
103
- localStorage.setItem(
104
- DEV_MODE_STORAGE_KEY,
105
- JSON.stringify({ isDevMode: state.isDevMode }),
106
- )
107
- } catch {
108
- // Ignore storage errors
109
- }
110
- }, [state.isDevMode, resolvedAllowed])
111
-
112
- const toggleDevMode = () => {
113
- setState((prev) => ({
114
- ...prev,
115
- isDevMode: !prev.isDevMode,
116
- isSidebarOpen: prev.isDevMode ? false : prev.isSidebarOpen,
117
- isInspectorMode: prev.isDevMode ? false : prev.isInspectorMode,
118
- }))
119
- }
120
-
121
- const toggleSidebar = () => {
122
- setState((prev) => ({ ...prev, isSidebarOpen: !prev.isSidebarOpen }))
123
- }
124
-
125
- const toggleInspector = () => {
126
- setState((prev) => ({
127
- ...prev,
128
- isInspectorMode: !prev.isInspectorMode,
129
- }))
130
- }
131
-
132
- const setDevMode = (enabled: boolean) => {
133
- setState((prev) => ({
134
- ...prev,
135
- isDevMode: enabled,
136
- isSidebarOpen: enabled ? prev.isSidebarOpen : false,
137
- isInspectorMode: enabled ? prev.isInspectorMode : false,
138
- }))
139
- }
140
-
141
- const setSidebarOpen = (open: boolean) => {
142
- setState((prev) => ({ ...prev, isSidebarOpen: open }))
143
- }
144
-
145
- const setInspectorMode = (enabled: boolean) => {
146
- setState((prev) => ({ ...prev, isInspectorMode: enabled }))
147
- }
148
-
149
- const openIssueDialog = (
150
- type: 'bug' | 'feature',
151
- description?: string,
152
- componentDetails?: ComponentDetails[],
153
- ) => {
154
- setState((prev) => ({
155
- ...prev,
156
- issueDialog: {
157
- isOpen: true,
158
- type,
159
- initialDescription: description,
160
- componentDetails,
161
- },
162
- }))
163
- },
164
- []
165
-
166
- const closeIssueDialog = () => {
167
- setState((prev) => ({
168
- ...prev,
169
- issueDialog: { ...prev.issueDialog, isOpen: false },
170
- }))
171
- }
172
-
173
- if (!resolvedAllowed) {
174
- return <>{children}</>
175
- }
176
-
177
- return (
178
- <DevModeContext.Provider
179
- value={{
180
- ...state,
181
- toggleDevMode,
182
- toggleSidebar,
183
- toggleInspector,
184
- setDevMode,
185
- setSidebarOpen,
186
- setInspectorMode,
187
- openIssueDialog,
188
- closeIssueDialog,
189
- }}
190
- >
191
- {children}
192
- </DevModeContext.Provider>
193
- )
194
- })
195
-
196
- export function createIsDevToolsVisible(): boolean {
197
- const context = createDevModeOptional()
198
- if (!context) return false
199
- return context.isDevMode
200
- }
201
-
202
- export function createIsDevAllowed(isAllowed?: boolean): boolean {
203
- return isAllowed ?? resolveDevAllowed()
204
- }
205
-
206
- function resolveDevAllowed(): boolean {
207
- try {
208
- // @ts-expect-error — Vite env
209
- if (import.meta?.env?.VITE_CONVEX_IS_DEV === 'true') return true
210
- // @ts-expect-error — Vite env
211
- if (import.meta?.env?.DEV) return true
212
- } catch {
213
- // Not in Vite
214
- }
215
- return false
216
- }
@@ -1,135 +0,0 @@
1
- // @geenius-tools/devtools-solidjs — src/context/PerformanceContext.tsx
2
-
3
- import { createContext, useContext, createSignal, createEffect, type JSX } from 'solid-js'
4
- import { metricsStore, type PerformanceMetric } from '@geenius-tools/logger'
5
-
6
- const MAX_METRICS = 100
7
-
8
- interface PerformanceContextValue {
9
- isPerformancePanelOpen: boolean
10
- metrics: PerformanceMetric[]
11
- filters: {
12
- network: boolean
13
- query: boolean
14
- mutation: boolean
15
- render: boolean
16
- route: boolean
17
- }
18
- stats: {
19
- totalRequests: number
20
- avgDuration: number
21
- slowRequests: number
22
- fastRequests: number
23
- }
24
- togglePerformancePanel: () => void
25
- clearMetrics: () => void
26
- toggleFilter: (filter: keyof PerformanceContextValue['filters']) => void
27
- }
28
-
29
- const PerformanceContext = createContext<PerformanceContextValue | undefined>(
30
- undefined,
31
- )
32
-
33
- export function createPerformanceContext() {
34
- const context = useContext(PerformanceContext)
35
- if (!context) {
36
- throw new Error(
37
- 'createPerformanceContext must be used within PerformanceProvider',
38
- )
39
- }
40
- return context
41
- }
42
-
43
- export function createPerformanceContextOptional(): PerformanceContextValue | null {
44
- return useContext(PerformanceContext) ?? null
45
- }
46
-
47
- interface PerformanceProviderProps {
48
- children: JSX.Element
49
- }
50
-
51
- export const PerformanceProvider = memo(function PerformanceProvider({
52
- children,
53
- }: PerformanceProviderProps) {
54
- const [isPerformancePanelOpen, setIsPerformancePanelOpen] = createSignal(false)
55
- const [metrics, setMetrics] = createSignal<PerformanceMetric[]>([])
56
- const [filters, setFilters] = createSignal({
57
- network: true,
58
- query: true,
59
- mutation: true,
60
- render: true,
61
- route: true,
62
- })
63
-
64
- createEffect(() => {
65
- const unsubscribe = metricsStore.subscribe((newMetrics) => {
66
- setMetrics((prev) => {
67
- const combined = [...prev, ...newMetrics]
68
- if (combined.length > MAX_METRICS) {
69
- return combined.slice(-MAX_METRICS)
70
- }
71
- return combined
72
- })
73
- })
74
-
75
- return () => unsubscribe()
76
- })
77
-
78
- const stats = () => {
79
- const filtered = metrics.filter((m) => m.duration !== undefined)
80
- const total = filtered.length
81
-
82
- if (total === 0) {
83
- return {
84
- totalRequests: 0,
85
- avgDuration: 0,
86
- slowRequests: 0,
87
- fastRequests: 0,
88
- }
89
- }
90
-
91
- const durations = filtered.map((m) => m.duration!)
92
- const avg = durations.reduce((a, b) => a + b, 0) / total
93
- const slow = durations.filter((d) => d > 100).length
94
- const fast = durations.filter((d) => d < 50).length
95
-
96
- return {
97
- totalRequests: total,
98
- avgDuration: Math.round(avg * 100) / 100,
99
- slowRequests: slow,
100
- fastRequests: fast,
101
- }
102
- }
103
-
104
- const togglePerformancePanel = () => {
105
- setIsPerformancePanelOpen((prev) => !prev)
106
- }
107
-
108
- const clearMetrics = () => {
109
- setMetrics([])
110
- metricsStore.clear()
111
- }
112
-
113
- const toggleFilter = (filter: keyof typeof filters) => {
114
- setFilters((prev) => ({
115
- ...prev,
116
- [filter]: !prev[filter],
117
- }))
118
- }
119
-
120
- return (
121
- <PerformanceContext.Provider
122
- value={{
123
- isPerformancePanelOpen,
124
- metrics,
125
- filters,
126
- stats: stats(),
127
- togglePerformancePanel,
128
- clearMetrics,
129
- toggleFilter,
130
- }}
131
- >
132
- {children}
133
- </PerformanceContext.Provider>
134
- )
135
- })
@@ -1,13 +0,0 @@
1
- // @geenius-tools/devtools — data/designs.ts
2
-
3
- export interface Design {
4
- id: string
5
- name: string
6
- path: string
7
- }
8
-
9
- export const designs: Design[] = Array.from({ length: 21 }, (_, i) => ({
10
- id: String(i + 1),
11
- name: `Design ${i + 1}`,
12
- path: `/dev/design/${i + 1}`,
13
- }))