@wix/zero-config-implementation 1.5.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 (78) hide show
  1. package/README.md +72 -0
  2. package/dist/component-loader.d.ts +42 -0
  3. package/dist/component-renderer.d.ts +31 -0
  4. package/dist/converters/data-item-builder.d.ts +15 -0
  5. package/dist/converters/index.d.ts +1 -0
  6. package/dist/converters/to-editor-component.d.ts +3 -0
  7. package/dist/converters/utils.d.ts +16 -0
  8. package/dist/errors.d.ts +230 -0
  9. package/dist/index.d.ts +42 -0
  10. package/dist/index.js +51978 -0
  11. package/dist/information-extractors/css/index.d.ts +3 -0
  12. package/dist/information-extractors/css/parse.d.ts +7 -0
  13. package/dist/information-extractors/css/selector-matcher.d.ts +3 -0
  14. package/dist/information-extractors/css/types.d.ts +49 -0
  15. package/dist/information-extractors/react/extractors/core/index.d.ts +6 -0
  16. package/dist/information-extractors/react/extractors/core/runner.d.ts +19 -0
  17. package/dist/information-extractors/react/extractors/core/store.d.ts +17 -0
  18. package/dist/information-extractors/react/extractors/core/tree-builder.d.ts +15 -0
  19. package/dist/information-extractors/react/extractors/core/types.d.ts +40 -0
  20. package/dist/information-extractors/react/extractors/css-properties.d.ts +20 -0
  21. package/dist/information-extractors/react/extractors/index.d.ts +11 -0
  22. package/dist/information-extractors/react/extractors/prop-tracker.d.ts +24 -0
  23. package/dist/information-extractors/react/index.d.ts +9 -0
  24. package/dist/information-extractors/react/types.d.ts +51 -0
  25. package/dist/information-extractors/react/utils/mock-generator.d.ts +9 -0
  26. package/dist/information-extractors/react/utils/prop-spy.d.ts +10 -0
  27. package/dist/information-extractors/ts/components.d.ts +9 -0
  28. package/dist/information-extractors/ts/css-imports.d.ts +2 -0
  29. package/dist/information-extractors/ts/index.d.ts +3 -0
  30. package/dist/information-extractors/ts/types.d.ts +47 -0
  31. package/dist/information-extractors/ts/utils/semantic-type-resolver.d.ts +3 -0
  32. package/dist/jsx-runtime-interceptor.d.ts +42 -0
  33. package/dist/jsx-runtime-interceptor.js +63 -0
  34. package/dist/jsx-runtime-loader.d.ts +23 -0
  35. package/dist/jsx-runtime-loader.js +7 -0
  36. package/dist/manifest-pipeline.d.ts +33 -0
  37. package/dist/schema.d.ts +167 -0
  38. package/dist/ts-compiler.d.ts +13 -0
  39. package/package.json +81 -0
  40. package/src/component-loader.test.ts +277 -0
  41. package/src/component-loader.ts +256 -0
  42. package/src/component-renderer.ts +192 -0
  43. package/src/converters/data-item-builder.ts +354 -0
  44. package/src/converters/index.ts +1 -0
  45. package/src/converters/to-editor-component.ts +167 -0
  46. package/src/converters/utils.ts +21 -0
  47. package/src/errors.ts +103 -0
  48. package/src/index.ts +223 -0
  49. package/src/information-extractors/css/README.md +3 -0
  50. package/src/information-extractors/css/index.ts +3 -0
  51. package/src/information-extractors/css/parse.ts +450 -0
  52. package/src/information-extractors/css/selector-matcher.ts +88 -0
  53. package/src/information-extractors/css/types.ts +56 -0
  54. package/src/information-extractors/react/extractors/core/index.ts +6 -0
  55. package/src/information-extractors/react/extractors/core/runner.ts +89 -0
  56. package/src/information-extractors/react/extractors/core/store.ts +36 -0
  57. package/src/information-extractors/react/extractors/core/tree-builder.ts +273 -0
  58. package/src/information-extractors/react/extractors/core/types.ts +48 -0
  59. package/src/information-extractors/react/extractors/css-properties.ts +214 -0
  60. package/src/information-extractors/react/extractors/index.ts +27 -0
  61. package/src/information-extractors/react/extractors/prop-tracker.ts +132 -0
  62. package/src/information-extractors/react/index.ts +53 -0
  63. package/src/information-extractors/react/types.ts +70 -0
  64. package/src/information-extractors/react/utils/mock-generator.ts +331 -0
  65. package/src/information-extractors/react/utils/prop-spy.ts +168 -0
  66. package/src/information-extractors/ts/components.ts +300 -0
  67. package/src/information-extractors/ts/css-imports.ts +26 -0
  68. package/src/information-extractors/ts/index.ts +3 -0
  69. package/src/information-extractors/ts/types.ts +56 -0
  70. package/src/information-extractors/ts/utils/semantic-type-resolver.ts +377 -0
  71. package/src/jsx-runtime-interceptor.ts +146 -0
  72. package/src/jsx-runtime-loader.ts +38 -0
  73. package/src/manifest-pipeline.ts +362 -0
  74. package/src/schema.ts +174 -0
  75. package/src/ts-compiler.ts +41 -0
  76. package/tsconfig.json +17 -0
  77. package/typedoc.json +18 -0
  78. package/vite.config.ts +45 -0
@@ -0,0 +1,214 @@
1
+ /**
2
+ * CSS Properties Extractor
3
+ *
4
+ * Determines which CSS properties are relevant to each element
5
+ * based on its tag, role, and whether it has text content.
6
+ */
7
+
8
+ import type { CreateElementEvent, ReactExtractor } from './core/types'
9
+
10
+ // ─────────────────────────────────────────────────────────────────────────────
11
+ // Types
12
+ // ─────────────────────────────────────────────────────────────────────────────
13
+
14
+ export interface CssPropertiesData {
15
+ relevant: string[]
16
+ }
17
+
18
+ // ─────────────────────────────────────────────────────────────────────────────
19
+ // Element Categories
20
+ // ─────────────────────────────────────────────────────────────────────────────
21
+
22
+ /**
23
+ * Layout Containers - structural boxes focused on spacing and positioning
24
+ */
25
+ const LAYOUT_CONTAINER_TAGS = new Set(['div', 'section', 'article', 'header', 'footer', 'main', 'nav', 'aside'])
26
+
27
+ /**
28
+ * Text & Typography - elements where readability and hierarchy are primary
29
+ */
30
+ const TEXT_TAGS = new Set([
31
+ 'h1',
32
+ 'h2',
33
+ 'h3',
34
+ 'h4',
35
+ 'h5',
36
+ 'h6',
37
+ 'p',
38
+ 'span',
39
+ 'li',
40
+ 'a',
41
+ 'label',
42
+ 'strong',
43
+ 'em',
44
+ 'b',
45
+ 'i',
46
+ ])
47
+
48
+ /**
49
+ * Media & Visuals - elements requiring aspect ratio control (excluding svg)
50
+ */
51
+ const MEDIA_TAGS = new Set(['img', 'video', 'canvas', 'picture'])
52
+
53
+ /**
54
+ * Form Inputs & Interactive Elements - require state-based styling
55
+ */
56
+ const INTERACTIVE_TAGS = new Set(['button', 'input', 'textarea', 'select'])
57
+
58
+ // ─────────────────────────────────────────────────────────────────────────────
59
+ // CSS Property Sets (using logical properties)
60
+ // ─────────────────────────────────────────────────────────────────────────────
61
+
62
+ /**
63
+ * CSS properties for Layout Containers and Interactive Elements
64
+ */
65
+ const CONTAINER_CSS_PROPERTIES = [
66
+ 'background',
67
+ 'border-block-start',
68
+ 'border-block-end',
69
+ 'border-inline-start',
70
+ 'border-inline-end',
71
+ 'padding-block-start',
72
+ 'padding-block-end',
73
+ 'padding-inline-start',
74
+ 'padding-inline-end',
75
+ 'border-start-start-radius',
76
+ 'border-start-end-radius',
77
+ 'border-end-start-radius',
78
+ 'border-end-end-radius',
79
+ 'box-shadow',
80
+ ]
81
+
82
+ /**
83
+ * CSS properties for Text elements and leaf elements with textContent
84
+ */
85
+ const TEXT_CSS_PROPERTIES = ['font', 'line-height', 'letter-spacing', 'text-decoration']
86
+
87
+ /**
88
+ * CSS properties for Media elements (excluding svg)
89
+ */
90
+ const MEDIA_CSS_PROPERTIES = [
91
+ 'border-block-start',
92
+ 'border-block-end',
93
+ 'border-inline-start',
94
+ 'border-inline-end',
95
+ 'border-start-start-radius',
96
+ 'border-start-end-radius',
97
+ 'border-end-start-radius',
98
+ 'border-end-end-radius',
99
+ 'box-shadow',
100
+ ]
101
+
102
+ // ─────────────────────────────────────────────────────────────────────────────
103
+ // Category Detection
104
+ // ─────────────────────────────────────────────────────────────────────────────
105
+
106
+ type ElementCategory = 'layout' | 'text' | 'media' | 'interactive' | 'unknown'
107
+
108
+ /**
109
+ * Determines the category of an element based on its tag and role
110
+ */
111
+ function getElementCategory(tag: string, role?: string): ElementCategory {
112
+ const normalizedTag = tag.toLowerCase()
113
+
114
+ // Check role-based overrides first
115
+ if (role) {
116
+ const normalizedRole = role.toLowerCase()
117
+ if (normalizedRole === 'button' || normalizedRole === 'textbox') {
118
+ return 'interactive'
119
+ }
120
+ if (normalizedRole === 'heading' || normalizedRole === 'paragraph') {
121
+ return 'text'
122
+ }
123
+ if (normalizedRole === 'img' || normalizedRole === 'figure') {
124
+ return 'media'
125
+ }
126
+ }
127
+
128
+ // Check tag-based categories
129
+ if (INTERACTIVE_TAGS.has(normalizedTag)) {
130
+ return 'interactive'
131
+ }
132
+ if (TEXT_TAGS.has(normalizedTag)) {
133
+ return 'text'
134
+ }
135
+ if (MEDIA_TAGS.has(normalizedTag)) {
136
+ return 'media'
137
+ }
138
+ if (LAYOUT_CONTAINER_TAGS.has(normalizedTag)) {
139
+ return 'layout'
140
+ }
141
+
142
+ return 'unknown'
143
+ }
144
+
145
+ /**
146
+ * Gets CSS properties relevant to an element based on tag and role.
147
+ * Note: hasTextContent determination is deferred to tree building since
148
+ * we can't know during createElement if a child will have text content.
149
+ */
150
+ export function getCssPropertiesForTag(tag: string, role?: string): string[] {
151
+ const category = getElementCategory(tag, role)
152
+ const properties: string[] = []
153
+
154
+ switch (category) {
155
+ case 'layout':
156
+ case 'interactive':
157
+ properties.push(...CONTAINER_CSS_PROPERTIES)
158
+ break
159
+
160
+ case 'text':
161
+ properties.push(...TEXT_CSS_PROPERTIES)
162
+ break
163
+
164
+ case 'media':
165
+ properties.push(...MEDIA_CSS_PROPERTIES)
166
+ break
167
+
168
+ case 'unknown':
169
+ // For unknown elements, default to container properties
170
+ // (can be refined during tree building based on children)
171
+ properties.push(...CONTAINER_CSS_PROPERTIES)
172
+ break
173
+ }
174
+
175
+ return properties
176
+ }
177
+
178
+ /**
179
+ * Adds text CSS properties to an existing property list without duplicates.
180
+ * Called during tree building when we know an element has text content.
181
+ */
182
+ export function addTextProperties(existing: string[]): string[] {
183
+ const result = [...existing]
184
+ for (const prop of TEXT_CSS_PROPERTIES) {
185
+ if (!result.includes(prop)) {
186
+ result.push(prop)
187
+ }
188
+ }
189
+ return result
190
+ }
191
+
192
+ // ─────────────────────────────────────────────────────────────────────────────
193
+ // Factory
194
+ // ─────────────────────────────────────────────────────────────────────────────
195
+
196
+ /**
197
+ * Creates a CSS properties extractor that determines relevant CSS properties
198
+ * for each element based on its tag and role.
199
+ */
200
+ export function createCssPropertiesExtractor(): ReactExtractor {
201
+ return {
202
+ name: 'css-properties',
203
+
204
+ onCreateElement(event: CreateElementEvent): void {
205
+ const { tag, props, traceId, store } = event
206
+ const role = props.role as string | undefined
207
+
208
+ const relevant = getCssPropertiesForTag(tag, role)
209
+ const data: CssPropertiesData = { relevant }
210
+
211
+ store.set(traceId, 'css-properties', data)
212
+ },
213
+ }
214
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * React Extractors
3
+ *
4
+ * Core infrastructure and pluggable extractors for the React information extraction system.
5
+ */
6
+
7
+ // Core infrastructure
8
+ export {
9
+ ExtractorStore,
10
+ runExtractors,
11
+ buildElementTree,
12
+ } from './core'
13
+ export type {
14
+ ExtractionResult,
15
+ ExtractedElement,
16
+ ReactExtractor,
17
+ RenderContext,
18
+ CreateElementEvent,
19
+ RenderCompleteEvent,
20
+ } from './core'
21
+
22
+ // Extractors
23
+ export { createPropTrackerExtractor } from './prop-tracker'
24
+ export type { PropTrackerData, PropTrackerExtractorState } from './prop-tracker'
25
+
26
+ export { createCssPropertiesExtractor } from './css-properties'
27
+ export type { CssPropertiesData } from './css-properties'
@@ -0,0 +1,132 @@
1
+ /**
2
+ * PropTracker Extractor
3
+ *
4
+ * Tracks how props flow into DOM elements during render.
5
+ * Detects spy markers in element attributes and records prop→DOM bindings.
6
+ */
7
+
8
+ import type { HTMLAttributes } from 'react'
9
+ import { TRACE_ATTR } from '../../../component-renderer'
10
+ import type { PropSpyMeta, TrackingStores } from '../types'
11
+ import { type PropSpyContext, createPropSpyContext } from '../utils/prop-spy'
12
+ import type { CreateElementEvent, ReactExtractor, RenderContext } from './core/types'
13
+
14
+ // ─────────────────────────────────────────────────────────────────────────────
15
+ // Types
16
+ // ─────────────────────────────────────────────────────────────────────────────
17
+
18
+ const SPY_REGEX = /__spy_\d+__/g
19
+
20
+ export type GetSpyMetadataFn = (id: string) => PropSpyMeta | null
21
+
22
+ export interface PropTrackerData {
23
+ tag: string
24
+ role?: string
25
+ boundProps: string[]
26
+ concatenatedAttrs: Map<string, string> // attrName → propName (for concatenated values)
27
+ }
28
+
29
+ export interface PropTrackerExtractorState {
30
+ stores: TrackingStores
31
+ spyContext: PropSpyContext
32
+ }
33
+
34
+ // ─────────────────────────────────────────────────────────────────────────────
35
+ // Factory
36
+ // ─────────────────────────────────────────────────────────────────────────────
37
+
38
+ /**
39
+ * Creates a prop tracker extractor that:
40
+ * 1. Wraps props with spy proxies during beforeRender
41
+ * 2. Detects spy markers in element props during onCreateElement
42
+ * 3. Writes tracking data to the store namespaced by 'prop-tracker'
43
+ */
44
+ export function createPropTrackerExtractor(): {
45
+ extractor: ReactExtractor
46
+ state: PropTrackerExtractorState
47
+ } {
48
+ const spyContext = createPropSpyContext()
49
+ const stores: TrackingStores = {
50
+ reads: new Map(),
51
+ writes: new Map(),
52
+ }
53
+
54
+ const extractSpies = (value: unknown, seen = new WeakSet<object>()): { propName: string; path: string }[] => {
55
+ if (typeof value === 'string') {
56
+ return (value.match(SPY_REGEX) ?? [])
57
+ .map((id) => {
58
+ const meta = spyContext.getSpyMetadataByUniqueId(id)
59
+ return meta ? { propName: meta.propName, path: meta.path } : null
60
+ })
61
+ .filter(Boolean) as { propName: string; path: string }[]
62
+ }
63
+ if (value && typeof value === 'object') {
64
+ // Prevent infinite recursion from circular references
65
+ if (seen.has(value as object)) {
66
+ return []
67
+ }
68
+ seen.add(value as object)
69
+ // Skip React elements (have $$typeof symbol) - they have circular refs
70
+ if ('$$typeof' in value) {
71
+ return []
72
+ }
73
+ return Object.values(value).flatMap((v) => extractSpies(v, seen))
74
+ }
75
+ return []
76
+ }
77
+
78
+ const extractor: ReactExtractor = {
79
+ name: 'prop-tracker',
80
+
81
+ onBeforeRender(context: RenderContext): void {
82
+ // Wrap props with spy proxies to track access
83
+ context.props = spyContext.createAuditedProps(context.props, stores, () => context.componentInfo.componentName)
84
+ },
85
+
86
+ onCreateElement(event: CreateElementEvent): void {
87
+ const { tag, props, traceId, store } = event
88
+ const htmlProps = props as HTMLAttributes<unknown>
89
+
90
+ const boundProps = new Set<string>()
91
+ const concatenatedAttrs = new Map<string, string>()
92
+
93
+ Object.entries(props).forEach(([key, value]) => {
94
+ if (key.startsWith('__') || key === TRACE_ATTR) return
95
+
96
+ const spies = extractSpies(value)
97
+
98
+ spies.forEach((spy) => {
99
+ boundProps.add(spy.propName)
100
+ const path = spy.path
101
+ const entry = stores.writes.get(path) ?? { elements: new Map(), attributes: new Map() }
102
+
103
+ if (!stores.writes.has(path)) {
104
+ stores.writes.set(path, entry)
105
+ }
106
+
107
+ entry.elements.set(traceId, { tag, elementId: traceId })
108
+ entry.attributes.set(`${traceId}:${key}`, { attr: key, concatenated: spies.length > 1 })
109
+
110
+ // Track concatenated attributes
111
+ if (spies.length > 1) {
112
+ concatenatedAttrs.set(key, spy.propName)
113
+ }
114
+ })
115
+ })
116
+
117
+ // Write to store
118
+ const data: PropTrackerData = {
119
+ tag,
120
+ role: htmlProps.role,
121
+ boundProps: [...boundProps],
122
+ concatenatedAttrs,
123
+ }
124
+ store.set(traceId, 'prop-tracker', data)
125
+ },
126
+ }
127
+
128
+ return {
129
+ extractor,
130
+ state: { stores, spyContext },
131
+ }
132
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * React Information Extraction
3
+ *
4
+ * API: runExtractors() with pluggable extractors
5
+ */
6
+
7
+ // ─────────────────────────────────────────────────────────────────────────────
8
+ // Core API - Re-export from extractors module
9
+ // ─────────────────────────────────────────────────────────────────────────────
10
+
11
+ export {
12
+ // Core
13
+ ExtractorStore,
14
+ runExtractors,
15
+ buildElementTree,
16
+ // Extractors
17
+ createPropTrackerExtractor,
18
+ createCssPropertiesExtractor,
19
+ } from './extractors'
20
+
21
+ export type {
22
+ // Core types
23
+ ExtractionResult,
24
+ ExtractedElement,
25
+ ReactExtractor,
26
+ RenderContext,
27
+ CreateElementEvent,
28
+ RenderCompleteEvent,
29
+ // Extractor types
30
+ PropTrackerData,
31
+ PropTrackerExtractorState,
32
+ CssPropertiesData,
33
+ } from './extractors'
34
+
35
+ // ─────────────────────────────────────────────────────────────────────────────
36
+ // Type Exports
37
+ // ─────────────────────────────────────────────────────────────────────────────
38
+
39
+ export type {
40
+ CoupledComponentInfo,
41
+ CoupledProp,
42
+ TrackingStores,
43
+ DOMBinding,
44
+ PropReadInfo,
45
+ PropWriteInfo,
46
+ PropSpyMeta,
47
+ } from './types'
48
+
49
+ // ─────────────────────────────────────────────────────────────────────────────
50
+ // Utility Exports
51
+ // ─────────────────────────────────────────────────────────────────────────────
52
+
53
+ export type { PropSpyContext } from './utils/prop-spy'
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Types for React Information Extraction
3
+ */
4
+
5
+ import type { PropInfo } from '../ts/types'
6
+ import type { ExtractedElement } from './extractors/core/tree-builder'
7
+
8
+ // ─────────────────────────────────────────────────────────────────────────────
9
+ // Prop Spy (for tracking prop access)
10
+ // ─────────────────────────────────────────────────────────────────────────────
11
+
12
+ export const PROP_SPY_SYMBOL = Symbol.for('__prop_spy__')
13
+
14
+ export interface PropSpyMeta {
15
+ path: string
16
+ propName: string
17
+ uniqueId: string
18
+ originalValue: unknown
19
+ }
20
+
21
+ export interface PropSpy<T = unknown> {
22
+ [PROP_SPY_SYMBOL]: true
23
+ __meta: PropSpyMeta
24
+ valueOf: () => T
25
+ toString: () => string
26
+ toJSON: () => T
27
+ [Symbol.toPrimitive]?: (hint: string) => T | string | number
28
+ }
29
+
30
+ // ─────────────────────────────────────────────────────────────────────────────
31
+ // Tracking Stores
32
+ // ─────────────────────────────────────────────────────────────────────────────
33
+
34
+ export interface PropReadInfo {
35
+ components: Set<string>
36
+ value: unknown
37
+ }
38
+
39
+ export interface PropWriteInfo {
40
+ elements: Map<string, { tag: string; elementId: string }>
41
+ attributes: Map<string, { attr: string; concatenated: boolean }>
42
+ }
43
+
44
+ export interface TrackingStores {
45
+ reads: Map<string, PropReadInfo>
46
+ writes: Map<string, PropWriteInfo>
47
+ }
48
+
49
+ // ─────────────────────────────────────────────────────────────────────────────
50
+ // Output Types
51
+ // ─────────────────────────────────────────────────────────────────────────────
52
+
53
+ export interface DOMBinding {
54
+ element: string
55
+ attribute: string
56
+ concatenated: boolean
57
+ elementId: string
58
+ }
59
+
60
+ export interface CoupledProp extends PropInfo {
61
+ bindings: DOMBinding[]
62
+ logicOnly: boolean
63
+ }
64
+
65
+ export interface CoupledComponentInfo {
66
+ componentName: string
67
+ props: Record<string, CoupledProp>
68
+ elements: ExtractedElement[]
69
+ innerElementProps?: Map<string, Record<string, CoupledProp>>
70
+ }