polen 0.10.0-next.20 → 0.10.0-next.22

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 (96) hide show
  1. package/build/api/builder/builder.d.ts.map +1 -1
  2. package/build/api/builder/builder.js +1 -2
  3. package/build/api/builder/builder.js.map +1 -1
  4. package/build/api/config/configurator.d.ts +62 -11
  5. package/build/api/config/configurator.d.ts.map +1 -1
  6. package/build/api/config/configurator.js +9 -0
  7. package/build/api/config/configurator.js.map +1 -1
  8. package/build/api/config/merge.js +6 -6
  9. package/build/api/content/scan.js +1 -1
  10. package/build/api/content/sidebar.js +4 -4
  11. package/build/api/vite/plugins/build.js +1 -1
  12. package/build/api/vite/plugins/core.d.ts.map +1 -1
  13. package/build/api/vite/plugins/core.js +1 -0
  14. package/build/api/vite/plugins/core.js.map +1 -1
  15. package/build/lib/react-router-aid/get-paths-patterns.js +1 -1
  16. package/build/project-data.d.ts +1 -0
  17. package/build/project-data.d.ts.map +1 -1
  18. package/build/sandbox.js +40 -17
  19. package/build/sandbox.js.map +1 -1
  20. package/build/template/components/CodeBlock.d.ts.map +1 -1
  21. package/build/template/components/CodeBlock.js +3 -5
  22. package/build/template/components/CodeBlock.js.map +1 -1
  23. package/build/template/components/Field.js +1 -1
  24. package/build/template/components/Field.js.map +1 -1
  25. package/build/template/components/GraphQLInteractive/GraphQLInteractive.d.ts +31 -0
  26. package/build/template/components/GraphQLInteractive/GraphQLInteractive.d.ts.map +1 -0
  27. package/build/template/components/GraphQLInteractive/GraphQLInteractive.js +275 -0
  28. package/build/template/components/GraphQLInteractive/GraphQLInteractive.js.map +1 -0
  29. package/build/template/components/GraphQLInteractive/components/GraphQLErrorBoundary.d.ts +39 -0
  30. package/build/template/components/GraphQLInteractive/components/GraphQLErrorBoundary.d.ts.map +1 -0
  31. package/build/template/components/GraphQLInteractive/components/GraphQLErrorBoundary.js +51 -0
  32. package/build/template/components/GraphQLInteractive/components/GraphQLErrorBoundary.js.map +1 -0
  33. package/build/template/components/GraphQLInteractive/components/GraphQLTokenPopover.d.ts +33 -0
  34. package/build/template/components/GraphQLInteractive/components/GraphQLTokenPopover.d.ts.map +1 -0
  35. package/build/template/components/GraphQLInteractive/components/GraphQLTokenPopover.js +242 -0
  36. package/build/template/components/GraphQLInteractive/components/GraphQLTokenPopover.js.map +1 -0
  37. package/build/template/components/GraphQLInteractive/hooks/use-popover-state.d.ts +45 -0
  38. package/build/template/components/GraphQLInteractive/hooks/use-popover-state.d.ts.map +1 -0
  39. package/build/template/components/GraphQLInteractive/hooks/use-popover-state.js +176 -0
  40. package/build/template/components/GraphQLInteractive/hooks/use-popover-state.js.map +1 -0
  41. package/build/template/components/GraphQLInteractive/index.d.ts +2 -0
  42. package/build/template/components/GraphQLInteractive/index.d.ts.map +1 -0
  43. package/build/template/components/GraphQLInteractive/index.js +2 -0
  44. package/build/template/components/GraphQLInteractive/index.js.map +1 -0
  45. package/build/template/components/GraphQLInteractive/lib/graphql-node-types.d.ts +52 -0
  46. package/build/template/components/GraphQLInteractive/lib/graphql-node-types.d.ts.map +1 -0
  47. package/build/template/components/GraphQLInteractive/lib/graphql-node-types.js +34 -0
  48. package/build/template/components/GraphQLInteractive/lib/graphql-node-types.js.map +1 -0
  49. package/build/template/components/GraphQLInteractive/lib/parser.d.ts +71 -0
  50. package/build/template/components/GraphQLInteractive/lib/parser.d.ts.map +1 -0
  51. package/build/template/components/GraphQLInteractive/lib/parser.js +836 -0
  52. package/build/template/components/GraphQLInteractive/lib/parser.js.map +1 -0
  53. package/build/template/components/GraphQLInteractive/lib/semantic-nodes.d.ts +98 -0
  54. package/build/template/components/GraphQLInteractive/lib/semantic-nodes.d.ts.map +1 -0
  55. package/build/template/components/GraphQLInteractive/lib/semantic-nodes.js +31 -0
  56. package/build/template/components/GraphQLInteractive/lib/semantic-nodes.js.map +1 -0
  57. package/build/template/components/content/$$.d.ts +0 -1
  58. package/build/template/components/content/$$.d.ts.map +1 -1
  59. package/build/template/components/content/$$.js +0 -1
  60. package/build/template/components/content/$$.js.map +1 -1
  61. package/package.json +5 -21
  62. package/src/api/builder/builder.ts +1 -2
  63. package/src/api/config/configurator.ts +72 -11
  64. package/src/api/config/merge.ts +6 -6
  65. package/src/api/content/scan.ts +1 -1
  66. package/src/api/content/sidebar.ts +4 -4
  67. package/src/api/vite/plugins/build.ts +1 -1
  68. package/src/api/vite/plugins/core.ts +1 -0
  69. package/src/lib/kit-temp.test.ts +9 -9
  70. package/src/lib/react-router-aid/get-paths-patterns.ts +1 -1
  71. package/src/project-data.ts +1 -0
  72. package/src/sandbox.ts +40 -17
  73. package/src/template/components/CodeBlock.tsx +6 -9
  74. package/src/template/components/Field.tsx +1 -1
  75. package/src/template/components/GraphQLInteractive/GraphQLInteractive.tsx +464 -0
  76. package/src/template/components/GraphQLInteractive/components/GraphQLErrorBoundary.tsx +96 -0
  77. package/src/template/components/GraphQLInteractive/components/GraphQLTokenPopover.tsx +492 -0
  78. package/src/template/components/GraphQLInteractive/hooks/use-popover-state.ts +244 -0
  79. package/src/template/components/GraphQLInteractive/index.ts +1 -0
  80. package/src/template/components/GraphQLInteractive/lib/graphql-node-types.ts +217 -0
  81. package/src/template/components/GraphQLInteractive/lib/parser.ts +1075 -0
  82. package/src/template/components/GraphQLInteractive/lib/semantic-nodes.ts +154 -0
  83. package/src/template/components/GraphQLInteractive/tests/parser-comment.test.ts +33 -0
  84. package/src/template/components/GraphQLInteractive/tests/parser-error-hint.test.ts +102 -0
  85. package/src/template/components/GraphQLInteractive/tests/parser.test.ts +131 -0
  86. package/src/template/components/content/$$.ts +0 -1
  87. package/build/template/components/content/GraphQLDocumentWithSchema.d.ts +0 -8
  88. package/build/template/components/content/GraphQLDocumentWithSchema.d.ts.map +0 -1
  89. package/build/template/components/content/GraphQLDocumentWithSchema.js +0 -13
  90. package/build/template/components/content/GraphQLDocumentWithSchema.js.map +0 -1
  91. package/build/template/components/content/GraphQLDocumentWrapper.d.ts +0 -7
  92. package/build/template/components/content/GraphQLDocumentWrapper.d.ts.map +0 -1
  93. package/build/template/components/content/GraphQLDocumentWrapper.js +0 -48
  94. package/build/template/components/content/GraphQLDocumentWrapper.js.map +0 -1
  95. package/src/template/components/content/GraphQLDocumentWithSchema.tsx +0 -13
  96. package/src/template/components/content/GraphQLDocumentWrapper.tsx +0 -72
@@ -0,0 +1,244 @@
1
+ /**
2
+ * State management for GraphQL token popovers
3
+ *
4
+ * Handles hover delays, pinning, and multiple popover coordination
5
+ */
6
+
7
+ import { React as ReactHooks } from '#dep/react/index'
8
+
9
+ export interface PopoverState {
10
+ /** Currently visible popover (via hover) */
11
+ hoveredId: string | null
12
+ /** Set of pinned popover IDs */
13
+ pinnedIds: Set<string>
14
+ /** ID pending show (waiting for delay) */
15
+ pendingShowId: string | null
16
+ /** ID pending hide (waiting for grace period) */
17
+ pendingHideId: string | null
18
+ }
19
+
20
+ export interface UsePopoverStateOptions {
21
+ /** Delay before showing popover on hover (ms) */
22
+ showDelay?: number
23
+ /** Delay before hiding popover on mouse leave (ms) */
24
+ hideDelay?: number
25
+ /** Whether to allow multiple pinned popovers */
26
+ allowMultiplePins?: boolean
27
+ }
28
+
29
+ export interface UsePopoverStateReturn {
30
+ /** Check if a popover should be visible */
31
+ isOpen: (id: string) => boolean
32
+ /** Check if a popover is pinned */
33
+ isPinned: (id: string) => boolean
34
+ /** Handle hover start */
35
+ onHoverStart: (id: string) => void
36
+ /** Handle hover end */
37
+ onHoverEnd: (id: string) => void
38
+ /** Handle click (toggle pin) */
39
+ onTogglePin: (id: string) => void
40
+ /** Handle popover content hover (cancels hide) */
41
+ onPopoverHover: (id: string) => void
42
+ /** Handle popover content leave (starts hide timer) */
43
+ onPopoverLeave: (id: string) => void
44
+ /** Unpin a specific popover */
45
+ unpin: (id: string) => void
46
+ /** Unpin all popovers */
47
+ unpinAll: () => void
48
+ }
49
+
50
+ export const usePopoverState = (options: UsePopoverStateOptions = {}): UsePopoverStateReturn => {
51
+ const {
52
+ showDelay = 300,
53
+ hideDelay = 200,
54
+ allowMultiplePins = true,
55
+ } = options
56
+
57
+ const [hoveredId, setHoveredId] = ReactHooks.useState<string | null>(null)
58
+ const [pinnedIds, setPinnedIds] = ReactHooks.useState<Set<string>>(new Set())
59
+ const [pendingShowId, setPendingShowId] = ReactHooks.useState<string | null>(null)
60
+ const [pendingHideId, setPendingHideId] = ReactHooks.useState<string | null>(null)
61
+
62
+ // Timer refs
63
+ const showTimerRef = ReactHooks.useRef<NodeJS.Timeout | null>(null)
64
+ const hideTimerRef = ReactHooks.useRef<NodeJS.Timeout | null>(null)
65
+
66
+ // Clear any pending timers
67
+ const clearTimers = ReactHooks.useCallback(() => {
68
+ if (showTimerRef.current) {
69
+ clearTimeout(showTimerRef.current)
70
+ showTimerRef.current = null
71
+ }
72
+ if (hideTimerRef.current) {
73
+ clearTimeout(hideTimerRef.current)
74
+ hideTimerRef.current = null
75
+ }
76
+ setPendingShowId(null)
77
+ setPendingHideId(null)
78
+ }, [])
79
+
80
+ // Check if popover should be visible
81
+ const isOpen = ReactHooks.useCallback((id: string): boolean => {
82
+ return hoveredId === id || pinnedIds.has(id)
83
+ }, [hoveredId, pinnedIds])
84
+
85
+ // Check if popover is pinned
86
+ const isPinned = ReactHooks.useCallback((id: string): boolean => {
87
+ return pinnedIds.has(id)
88
+ }, [pinnedIds])
89
+
90
+ // Handle hover start
91
+ const onHoverStart = ReactHooks.useCallback((id: string) => {
92
+ // Don't show if already pinned
93
+ if (pinnedIds.has(id)) return
94
+
95
+ // Cancel any pending hide for this ID
96
+ if (pendingHideId === id) {
97
+ clearTimeout(hideTimerRef.current!)
98
+ hideTimerRef.current = null
99
+ setPendingHideId(null)
100
+ return
101
+ }
102
+
103
+ // Clear any existing timers
104
+ clearTimers()
105
+
106
+ // Set pending show
107
+ setPendingShowId(id)
108
+
109
+ // Start show timer
110
+ showTimerRef.current = setTimeout(() => {
111
+ setHoveredId(id)
112
+ setPendingShowId(null)
113
+ showTimerRef.current = null
114
+ }, showDelay)
115
+ }, [pinnedIds, pendingHideId, clearTimers, showDelay])
116
+
117
+ // Handle hover end
118
+ const onHoverEnd = ReactHooks.useCallback((id: string) => {
119
+ // Don't hide if pinned
120
+ if (pinnedIds.has(id)) return
121
+
122
+ // Cancel any pending show
123
+ if (pendingShowId === id) {
124
+ clearTimeout(showTimerRef.current!)
125
+ showTimerRef.current = null
126
+ setPendingShowId(null)
127
+ return
128
+ }
129
+
130
+ // Only hide if currently hovered
131
+ if (hoveredId === id) {
132
+ setPendingHideId(id)
133
+
134
+ hideTimerRef.current = setTimeout(() => {
135
+ setHoveredId(null)
136
+ setPendingHideId(null)
137
+ hideTimerRef.current = null
138
+ }, hideDelay)
139
+ }
140
+ }, [pinnedIds, pendingShowId, hoveredId, hideDelay])
141
+
142
+ // Handle popover content hover (cancels hide)
143
+ const onPopoverHover = ReactHooks.useCallback((id: string) => {
144
+ if (pendingHideId === id) {
145
+ clearTimeout(hideTimerRef.current!)
146
+ hideTimerRef.current = null
147
+ setPendingHideId(null)
148
+ }
149
+ }, [pendingHideId])
150
+
151
+ // Handle popover content leave (starts hide timer)
152
+ const onPopoverLeave = ReactHooks.useCallback((id: string) => {
153
+ // Don't hide if pinned
154
+ if (pinnedIds.has(id)) return
155
+
156
+ // Only hide if currently hovered
157
+ if (hoveredId === id) {
158
+ setPendingHideId(id)
159
+
160
+ hideTimerRef.current = setTimeout(() => {
161
+ setHoveredId(null)
162
+ setPendingHideId(null)
163
+ hideTimerRef.current = null
164
+ }, hideDelay)
165
+ }
166
+ }, [pinnedIds, hoveredId, hideDelay])
167
+
168
+ // Toggle pin state
169
+ const onTogglePin = ReactHooks.useCallback((id: string) => {
170
+ setPinnedIds(prev => {
171
+ const next = new Set(prev)
172
+
173
+ if (next.has(id)) {
174
+ // Unpin
175
+ next.delete(id)
176
+ } else {
177
+ // Pin
178
+ if (!allowMultiplePins) {
179
+ // Clear other pins if multiple not allowed
180
+ next.clear()
181
+ }
182
+ next.add(id)
183
+
184
+ // Clear any hover state for this ID
185
+ if (hoveredId === id) {
186
+ setHoveredId(null)
187
+ }
188
+
189
+ // Clear any pending operations
190
+ if (pendingShowId === id) {
191
+ clearTimeout(showTimerRef.current!)
192
+ showTimerRef.current = null
193
+ setPendingShowId(null)
194
+ }
195
+ if (pendingHideId === id) {
196
+ clearTimeout(hideTimerRef.current!)
197
+ hideTimerRef.current = null
198
+ setPendingHideId(null)
199
+ }
200
+ }
201
+
202
+ return next
203
+ })
204
+ }, [allowMultiplePins, hoveredId, pendingShowId, pendingHideId])
205
+
206
+ // Unpin specific popover
207
+ const unpin = ReactHooks.useCallback((id: string) => {
208
+ setPinnedIds(prev => {
209
+ const next = new Set(prev)
210
+ next.delete(id)
211
+ return next
212
+ })
213
+ }, [])
214
+
215
+ // Unpin all popovers
216
+ const unpinAll = ReactHooks.useCallback(() => {
217
+ setPinnedIds(new Set())
218
+ }, [])
219
+
220
+ // Cleanup timers on unmount and when dependencies change
221
+ ReactHooks.useEffect(() => {
222
+ return () => {
223
+ if (showTimerRef.current) clearTimeout(showTimerRef.current)
224
+ if (hideTimerRef.current) clearTimeout(hideTimerRef.current)
225
+ }
226
+ }, [])
227
+
228
+ // Clear timers when delay options change to prevent stale timers
229
+ ReactHooks.useEffect(() => {
230
+ clearTimers()
231
+ }, [showDelay, hideDelay, clearTimers])
232
+
233
+ return {
234
+ isOpen,
235
+ isPinned,
236
+ onHoverStart,
237
+ onHoverEnd,
238
+ onTogglePin,
239
+ onPopoverHover,
240
+ onPopoverLeave,
241
+ unpin,
242
+ unpinAll,
243
+ }
244
+ }
@@ -0,0 +1 @@
1
+ export { GraphQLInteractive } from './GraphQLInteractive.js'
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Tree-sitter GraphQL Grammar Node Types
3
+ *
4
+ * This file defines all possible node types from the tree-sitter-graphql grammar.
5
+ * These types are used by the tree-sitter parser when parsing GraphQL documents.
6
+ *
7
+ * Source: https://github.com/bkegley/tree-sitter-graphql
8
+ *
9
+ * Having these as a TypeScript union type enables:
10
+ * - Type-safe node.type checking
11
+ * - IntelliSense/autocomplete in IDEs
12
+ * - Compile-time verification of node type strings
13
+ * - Better code maintainability and refactoring
14
+ */
15
+
16
+ /**
17
+ * All possible node types that can be returned by tree-sitter-graphql
18
+ * when parsing GraphQL documents.
19
+ */
20
+ export type TreeSitterGraphQLNodeType =
21
+ // Structure
22
+ | 'document'
23
+ | 'definition'
24
+ | 'executable_definition'
25
+ | 'type_system_definition'
26
+ | 'type_system_extension'
27
+ | 'source_file'
28
+ // Operations
29
+ | 'operation_definition'
30
+ | 'selection_set'
31
+ | 'selection'
32
+ | 'field'
33
+ | 'alias'
34
+ // Fragments
35
+ | 'fragment_definition'
36
+ | 'fragment_spread'
37
+ | 'inline_fragment'
38
+ | 'fragment_name'
39
+ | 'type_condition'
40
+ // Arguments and Variables
41
+ | 'arguments'
42
+ | 'argument'
43
+ | 'variable'
44
+ | 'variable_definition'
45
+ | 'variable_definitions'
46
+ | 'default_value'
47
+ // Types
48
+ | 'type'
49
+ | 'named_type'
50
+ | 'list_type'
51
+ | 'non_null_type'
52
+ // Type Definitions
53
+ | 'type_definition'
54
+ | 'scalar_type_definition'
55
+ | 'object_type_definition'
56
+ | 'interface_type_definition'
57
+ | 'union_type_definition'
58
+ | 'enum_type_definition'
59
+ | 'input_object_type_definition'
60
+ // Type Extensions
61
+ | 'type_extension'
62
+ | 'scalar_type_extension'
63
+ | 'object_type_extension'
64
+ | 'interface_type_extension'
65
+ | 'union_type_extension'
66
+ | 'enum_type_extension'
67
+ | 'input_object_type_extension'
68
+ // Schema
69
+ | 'schema_definition'
70
+ | 'schema_extension'
71
+ | 'root_operation_type_definition'
72
+ // Field Definitions
73
+ | 'fields_definition'
74
+ | 'field_definition'
75
+ | 'arguments_definition'
76
+ | 'input_value_definition'
77
+ | 'input_fields_definition'
78
+ // Directives
79
+ | 'directives'
80
+ | 'directive'
81
+ | 'directive_definition'
82
+ | 'directive_locations'
83
+ | 'directive_location'
84
+ // Enum
85
+ | 'enum_values_definition'
86
+ | 'enum_value_definition'
87
+ | 'enum_value'
88
+ // Other Type System
89
+ | 'implements_interfaces'
90
+ | 'union_member_types'
91
+ | 'description'
92
+ // Values
93
+ | 'value'
94
+ | 'string_value'
95
+ | 'int_value'
96
+ | 'float_value'
97
+ | 'boolean_value'
98
+ | 'null_value'
99
+ | 'list_value'
100
+ | 'object_value'
101
+ | 'object_field'
102
+ // Basic tokens
103
+ | 'name'
104
+ | 'comment'
105
+ | 'comma'
106
+ // Punctuation tokens (anonymous nodes in the grammar)
107
+ | '{'
108
+ | '}'
109
+ | '('
110
+ | ')'
111
+ | '['
112
+ | ']'
113
+ | ':'
114
+ | '='
115
+ | ','
116
+ | '!'
117
+ | '|'
118
+ | '&'
119
+ | '@'
120
+ | '...'
121
+ | '$'
122
+ // GraphQL Keywords (these are also node types)
123
+ | 'query'
124
+ | 'mutation'
125
+ | 'subscription'
126
+ | 'fragment'
127
+ | 'on'
128
+ | 'type'
129
+ | 'interface'
130
+ | 'enum'
131
+ | 'scalar'
132
+ | 'union'
133
+ | 'input'
134
+ | 'schema'
135
+ | 'directive'
136
+ | 'implements'
137
+ | 'extend'
138
+ | 'true'
139
+ | 'false'
140
+ | 'null'
141
+ // Custom synthetic nodes
142
+ | 'error_hint'
143
+ | 'whitespace'
144
+
145
+ /**
146
+ * Subset of node types that are interactive in Polen's GraphQL viewer
147
+ */
148
+ export type InteractiveNodeParentType =
149
+ | 'named_type' // Type references like "Pokemon", "ID"
150
+ | 'field' // Field selections like "name", "abilities"
151
+
152
+ /**
153
+ * Subset of node types that are non-interactive user-defined names
154
+ */
155
+ export type NonInteractiveNodeParentType =
156
+ | 'operation_definition' // Operation names like "GetPokemon"
157
+ | 'fragment_definition' // Fragment names like "PokemonDetails"
158
+ | 'variable_definition' // Variable definitions (though the 'variable' node itself represents the usage)
159
+ | 'argument' // Argument names
160
+
161
+ /**
162
+ * Node types that represent keywords in GraphQL
163
+ */
164
+ export type KeywordNodeType = 'query' | 'mutation' | 'subscription' | 'fragment' | 'on'
165
+
166
+ /**
167
+ * Node types that represent literal values
168
+ */
169
+ export type LiteralNodeType =
170
+ | 'string_value'
171
+ | 'int_value'
172
+ | 'float_value'
173
+ | 'boolean_value'
174
+ | 'null_value'
175
+ | 'enum_value'
176
+
177
+ /**
178
+ * Node types that represent punctuation
179
+ */
180
+ export type PunctuationNodeType =
181
+ | '{'
182
+ | '}'
183
+ | '('
184
+ | ')'
185
+ | '['
186
+ | ']'
187
+ | ':'
188
+ | '='
189
+ | ','
190
+ | '!'
191
+ | '|'
192
+ | '&'
193
+ | '@'
194
+ | '...'
195
+ | '$'
196
+
197
+ /**
198
+ * Helper function to check if a node type is a keyword
199
+ */
200
+ export function isKeywordNodeType(type: string): type is KeywordNodeType {
201
+ return type === 'query' || type === 'mutation' || type === 'subscription' || type === 'fragment' || type === 'on'
202
+ }
203
+
204
+ /**
205
+ * Helper function to check if a node type is a literal
206
+ */
207
+ export function isLiteralNodeType(type: string): type is LiteralNodeType {
208
+ return type === 'string_value' || type === 'int_value' || type === 'float_value'
209
+ || type === 'boolean_value' || type === 'null_value' || type === 'enum_value'
210
+ }
211
+
212
+ /**
213
+ * Helper function to check if a node type is punctuation
214
+ */
215
+ export function isPunctuationNodeType(type: string): type is PunctuationNodeType {
216
+ return ['{', '}', '(', ')', '[', ']', ':', '=', ',', '!', '|', '&', '@', '...', '$'].includes(type)
217
+ }