@wireweave/core 3.0.0 → 3.0.1-beta.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.
- package/README.md +105 -104
- package/dist/index.cjs +10564 -10520
- package/dist/index.js +10564 -10520
- package/dist/parser.cjs +4 -3
- package/dist/parser.js +4 -3
- package/dist/renderer.cjs +10427 -10477
- package/dist/renderer.js +10427 -10477
- package/package.json +17 -1
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ yarn add @wireweave/core
|
|
|
19
19
|
## Quick Start
|
|
20
20
|
|
|
21
21
|
```typescript
|
|
22
|
-
import { parse, render, renderToSvg, renderToHtml } from '@wireweave/core'
|
|
22
|
+
import { parse, render, renderToSvg, renderToHtml } from '@wireweave/core'
|
|
23
23
|
|
|
24
24
|
const source = `
|
|
25
25
|
page "Hello" {
|
|
@@ -29,19 +29,19 @@ const source = `
|
|
|
29
29
|
button "Get Started" primary
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
-
|
|
32
|
+
`
|
|
33
33
|
|
|
34
34
|
// Parse DSL to AST
|
|
35
|
-
const doc = parse(source)
|
|
35
|
+
const doc = parse(source)
|
|
36
36
|
|
|
37
37
|
// Render to HTML + CSS
|
|
38
|
-
const { html, css } = render(doc)
|
|
38
|
+
const { html, css } = render(doc)
|
|
39
39
|
|
|
40
40
|
// Render to complete HTML document
|
|
41
|
-
const fullHtml = renderToHtml(doc)
|
|
41
|
+
const fullHtml = renderToHtml(doc)
|
|
42
42
|
|
|
43
43
|
// Render to SVG
|
|
44
|
-
const { svg, width, height } = renderToSvg(doc)
|
|
44
|
+
const { svg, width, height } = renderToSvg(doc)
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
## API Reference
|
|
@@ -53,10 +53,10 @@ const { svg, width, height } = renderToSvg(doc);
|
|
|
53
53
|
Parses wireframe DSL source code into an AST (Abstract Syntax Tree).
|
|
54
54
|
|
|
55
55
|
```typescript
|
|
56
|
-
import { parse } from '@wireweave/core'
|
|
56
|
+
import { parse } from '@wireweave/core'
|
|
57
57
|
|
|
58
|
-
const doc = parse('page { text "Hello" }')
|
|
59
|
-
console.log(doc.children[0].type)
|
|
58
|
+
const doc = parse('page { text "Hello" }')
|
|
59
|
+
console.log(doc.children[0].type) // 'Page'
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
**Throws**: `ParseError` if the source contains syntax errors.
|
|
@@ -68,10 +68,10 @@ console.log(doc.children[0].type); // 'Page'
|
|
|
68
68
|
Renders the AST to HTML and CSS.
|
|
69
69
|
|
|
70
70
|
```typescript
|
|
71
|
-
import { parse, render } from '@wireweave/core'
|
|
71
|
+
import { parse, render } from '@wireweave/core'
|
|
72
72
|
|
|
73
|
-
const doc = parse('page { card { text "Hello" } }')
|
|
74
|
-
const { html, css } = render(doc)
|
|
73
|
+
const doc = parse('page { card { text "Hello" } }')
|
|
74
|
+
const { html, css } = render(doc)
|
|
75
75
|
```
|
|
76
76
|
|
|
77
77
|
**Options**:
|
|
@@ -86,10 +86,10 @@ const { html, css } = render(doc);
|
|
|
86
86
|
Renders the AST to a complete HTML document with embedded CSS.
|
|
87
87
|
|
|
88
88
|
```typescript
|
|
89
|
-
import { parse, renderToHtml } from '@wireweave/core'
|
|
89
|
+
import { parse, renderToHtml } from '@wireweave/core'
|
|
90
90
|
|
|
91
|
-
const doc = parse('page "Test" { text "Hello" }')
|
|
92
|
-
const html = renderToHtml(doc, { theme: 'dark' })
|
|
91
|
+
const doc = parse('page "Test" { text "Hello" }')
|
|
92
|
+
const html = renderToHtml(doc, { theme: 'dark' })
|
|
93
93
|
// Returns: <!DOCTYPE html><html>...</html>
|
|
94
94
|
```
|
|
95
95
|
|
|
@@ -100,13 +100,13 @@ const html = renderToHtml(doc, { theme: 'dark' });
|
|
|
100
100
|
Renders the AST to SVG format.
|
|
101
101
|
|
|
102
102
|
```typescript
|
|
103
|
-
import { parse, renderToSvg } from '@wireweave/core'
|
|
103
|
+
import { parse, renderToSvg } from '@wireweave/core'
|
|
104
104
|
|
|
105
|
-
const doc = parse('page { button "Click" primary }')
|
|
105
|
+
const doc = parse('page { button "Click" primary }')
|
|
106
106
|
const { svg, width, height } = renderToSvg(doc, {
|
|
107
107
|
width: 800,
|
|
108
|
-
padding: 20
|
|
109
|
-
})
|
|
108
|
+
padding: 20,
|
|
109
|
+
})
|
|
110
110
|
```
|
|
111
111
|
|
|
112
112
|
**Options**:
|
|
@@ -125,21 +125,21 @@ const { svg, width, height } = renderToSvg(doc, {
|
|
|
125
125
|
Analyzes a wireframe document and returns comprehensive statistics.
|
|
126
126
|
|
|
127
127
|
```typescript
|
|
128
|
-
import { parse, analyze } from '@wireweave/core'
|
|
128
|
+
import { parse, analyze } from '@wireweave/core'
|
|
129
129
|
|
|
130
|
-
const doc = parse('page { card { text "Hello" button "Click" } }')
|
|
131
|
-
const result = analyze(doc)
|
|
130
|
+
const doc = parse('page { card { text "Hello" button "Click" } }')
|
|
131
|
+
const result = analyze(doc)
|
|
132
132
|
|
|
133
|
-
console.log(result.summary)
|
|
133
|
+
console.log(result.summary)
|
|
134
134
|
// { totalComponents: 4, uniqueTypes: 4, mostUsedType: 'Page', ... }
|
|
135
135
|
|
|
136
|
-
console.log(result.tree)
|
|
136
|
+
console.log(result.tree)
|
|
137
137
|
// { totalNodes: 4, maxDepth: 3, avgDepth: 2, ... }
|
|
138
138
|
|
|
139
|
-
console.log(result.accessibility)
|
|
139
|
+
console.log(result.accessibility)
|
|
140
140
|
// { score: 100, imagesWithAlt: 0, inputsWithLabels: 0, ... }
|
|
141
141
|
|
|
142
|
-
console.log(result.complexity)
|
|
142
|
+
console.log(result.complexity)
|
|
143
143
|
// { score: 2, level: 'simple', interactiveElements: 1, ... }
|
|
144
144
|
```
|
|
145
145
|
|
|
@@ -159,16 +159,16 @@ console.log(result.complexity);
|
|
|
159
159
|
Compares two wireframe documents and returns detailed differences.
|
|
160
160
|
|
|
161
161
|
```typescript
|
|
162
|
-
import { parse, diff } from '@wireweave/core'
|
|
162
|
+
import { parse, diff } from '@wireweave/core'
|
|
163
163
|
|
|
164
|
-
const oldDoc = parse('page { text "Hello" }')
|
|
165
|
-
const newDoc = parse('page { text "Hello" button "Click" }')
|
|
164
|
+
const oldDoc = parse('page { text "Hello" }')
|
|
165
|
+
const newDoc = parse('page { text "Hello" button "Click" }')
|
|
166
166
|
|
|
167
|
-
const result = diff(oldDoc, newDoc)
|
|
167
|
+
const result = diff(oldDoc, newDoc)
|
|
168
168
|
|
|
169
|
-
console.log(result.identical)
|
|
170
|
-
console.log(result.description)
|
|
171
|
-
console.log(result.summary)
|
|
169
|
+
console.log(result.identical) // false
|
|
170
|
+
console.log(result.description) // "Added 1 component(s): Button."
|
|
171
|
+
console.log(result.summary)
|
|
172
172
|
// { addedCount: 1, removedCount: 0, changedCount: 0, ... }
|
|
173
173
|
```
|
|
174
174
|
|
|
@@ -177,12 +177,12 @@ console.log(result.summary);
|
|
|
177
177
|
Quick check if two documents are identical.
|
|
178
178
|
|
|
179
179
|
```typescript
|
|
180
|
-
import { parse, areIdentical } from '@wireweave/core'
|
|
180
|
+
import { parse, areIdentical } from '@wireweave/core'
|
|
181
181
|
|
|
182
|
-
const doc1 = parse('page { text "Hello" }')
|
|
183
|
-
const doc2 = parse('page { text "Hello" }')
|
|
182
|
+
const doc1 = parse('page { text "Hello" }')
|
|
183
|
+
const doc2 = parse('page { text "Hello" }')
|
|
184
184
|
|
|
185
|
-
console.log(areIdentical(doc1, doc2))
|
|
185
|
+
console.log(areIdentical(doc1, doc2)) // true
|
|
186
186
|
```
|
|
187
187
|
|
|
188
188
|
#### `getChangeSummary(oldDoc: WireframeDocument, newDoc: WireframeDocument): string`
|
|
@@ -190,12 +190,12 @@ console.log(areIdentical(doc1, doc2)); // true
|
|
|
190
190
|
Returns a human-readable summary of changes.
|
|
191
191
|
|
|
192
192
|
```typescript
|
|
193
|
-
import { parse, getChangeSummary } from '@wireweave/core'
|
|
193
|
+
import { parse, getChangeSummary } from '@wireweave/core'
|
|
194
194
|
|
|
195
|
-
const oldDoc = parse('page { text "A" }')
|
|
196
|
-
const newDoc = parse('page { text "B" }')
|
|
195
|
+
const oldDoc = parse('page { text "A" }')
|
|
196
|
+
const newDoc = parse('page { text "B" }')
|
|
197
197
|
|
|
198
|
-
console.log(getChangeSummary(oldDoc, newDoc))
|
|
198
|
+
console.log(getChangeSummary(oldDoc, newDoc))
|
|
199
199
|
// "Modified 1 component(s)."
|
|
200
200
|
```
|
|
201
201
|
|
|
@@ -206,14 +206,14 @@ console.log(getChangeSummary(oldDoc, newDoc));
|
|
|
206
206
|
Exports wireframe to JSON format.
|
|
207
207
|
|
|
208
208
|
```typescript
|
|
209
|
-
import { parse, exportToJson } from '@wireweave/core'
|
|
209
|
+
import { parse, exportToJson } from '@wireweave/core'
|
|
210
210
|
|
|
211
|
-
const doc = parse('page { card { text "Hello" } }')
|
|
212
|
-
const result = exportToJson(doc)
|
|
211
|
+
const doc = parse('page { card { text "Hello" } }')
|
|
212
|
+
const result = exportToJson(doc)
|
|
213
213
|
|
|
214
|
-
console.log(result.version)
|
|
215
|
-
console.log(result.pages)
|
|
216
|
-
console.log(result.metadata)
|
|
214
|
+
console.log(result.version) // "1.0.0"
|
|
215
|
+
console.log(result.pages) // [{ type: 'page', children: [...] }]
|
|
216
|
+
console.log(result.metadata)
|
|
217
217
|
// { exportedAt: '...', nodeCount: 3, componentTypes: ['card', 'page', 'text'] }
|
|
218
218
|
```
|
|
219
219
|
|
|
@@ -222,10 +222,10 @@ console.log(result.metadata);
|
|
|
222
222
|
Exports wireframe to JSON string.
|
|
223
223
|
|
|
224
224
|
```typescript
|
|
225
|
-
import { parse, exportToJsonString } from '@wireweave/core'
|
|
225
|
+
import { parse, exportToJsonString } from '@wireweave/core'
|
|
226
226
|
|
|
227
|
-
const doc = parse('page { text "Hello" }')
|
|
228
|
-
const json = exportToJsonString(doc, { prettyPrint: true })
|
|
227
|
+
const doc = parse('page { text "Hello" }')
|
|
228
|
+
const json = exportToJsonString(doc, { prettyPrint: true })
|
|
229
229
|
```
|
|
230
230
|
|
|
231
231
|
#### `exportToFigma(doc: WireframeDocument): FigmaExportResult`
|
|
@@ -233,13 +233,13 @@ const json = exportToJsonString(doc, { prettyPrint: true });
|
|
|
233
233
|
Exports wireframe to Figma-compatible format.
|
|
234
234
|
|
|
235
235
|
```typescript
|
|
236
|
-
import { parse, exportToFigma } from '@wireweave/core'
|
|
236
|
+
import { parse, exportToFigma } from '@wireweave/core'
|
|
237
237
|
|
|
238
|
-
const doc = parse('page { card { text "Hello" } }')
|
|
239
|
-
const result = exportToFigma(doc)
|
|
238
|
+
const doc = parse('page { card { text "Hello" } }')
|
|
239
|
+
const result = exportToFigma(doc)
|
|
240
240
|
|
|
241
|
-
console.log(result.document)
|
|
242
|
-
console.log(result.componentMappings)
|
|
241
|
+
console.log(result.document) // Figma-compatible node tree
|
|
242
|
+
console.log(result.componentMappings)
|
|
243
243
|
// { page: 'CANVAS', card: 'FRAME', text: 'TEXT' }
|
|
244
244
|
```
|
|
245
245
|
|
|
@@ -250,13 +250,13 @@ console.log(result.componentMappings);
|
|
|
250
250
|
Traverses the AST tree depth-first.
|
|
251
251
|
|
|
252
252
|
```typescript
|
|
253
|
-
import { parse } from '@wireweave/core'
|
|
254
|
-
import { walk } from '@wireweave/core/ast'
|
|
253
|
+
import { parse } from '@wireweave/core'
|
|
254
|
+
import { walk } from '@wireweave/core/ast'
|
|
255
255
|
|
|
256
|
-
const doc = parse('page { card { text "A" text "B" } }')
|
|
256
|
+
const doc = parse('page { card { text "A" text "B" } }')
|
|
257
257
|
walk(doc.children[0], (node, parent, depth) => {
|
|
258
|
-
console.log(`${node.type} at depth ${depth}`)
|
|
259
|
-
})
|
|
258
|
+
console.log(`${node.type} at depth ${depth}`)
|
|
259
|
+
})
|
|
260
260
|
```
|
|
261
261
|
|
|
262
262
|
#### `find(node: ASTNode, predicate: (n: ASTNode) => boolean): ASTNode | undefined`
|
|
@@ -264,9 +264,9 @@ walk(doc.children[0], (node, parent, depth) => {
|
|
|
264
264
|
Finds the first node matching the predicate.
|
|
265
265
|
|
|
266
266
|
```typescript
|
|
267
|
-
import { find } from '@wireweave/core/ast'
|
|
267
|
+
import { find } from '@wireweave/core/ast'
|
|
268
268
|
|
|
269
|
-
const button = find(doc.children[0], n => n.type === 'Button')
|
|
269
|
+
const button = find(doc.children[0], (n) => n.type === 'Button')
|
|
270
270
|
```
|
|
271
271
|
|
|
272
272
|
#### `findAll(node: ASTNode, predicate: (n: ASTNode) => boolean): ASTNode[]`
|
|
@@ -274,9 +274,9 @@ const button = find(doc.children[0], n => n.type === 'Button');
|
|
|
274
274
|
Finds all nodes matching the predicate.
|
|
275
275
|
|
|
276
276
|
```typescript
|
|
277
|
-
import { findAll } from '@wireweave/core/ast'
|
|
277
|
+
import { findAll } from '@wireweave/core/ast'
|
|
278
278
|
|
|
279
|
-
const buttons = findAll(doc.children[0], n => n.type === 'Button')
|
|
279
|
+
const buttons = findAll(doc.children[0], (n) => n.type === 'Button')
|
|
280
280
|
```
|
|
281
281
|
|
|
282
282
|
#### `findByType<T>(node: ASTNode, type: string): T[]`
|
|
@@ -284,10 +284,10 @@ const buttons = findAll(doc.children[0], n => n.type === 'Button');
|
|
|
284
284
|
Finds all nodes of a specific type.
|
|
285
285
|
|
|
286
286
|
```typescript
|
|
287
|
-
import { findByType } from '@wireweave/core/ast'
|
|
288
|
-
import type { ButtonNode } from '@wireweave/core'
|
|
287
|
+
import { findByType } from '@wireweave/core/ast'
|
|
288
|
+
import type { ButtonNode } from '@wireweave/core'
|
|
289
289
|
|
|
290
|
-
const buttons = findByType<ButtonNode>(doc.children[0], 'Button')
|
|
290
|
+
const buttons = findByType<ButtonNode>(doc.children[0], 'Button')
|
|
291
291
|
```
|
|
292
292
|
|
|
293
293
|
#### `countNodes(node: ASTNode): number`
|
|
@@ -308,8 +308,8 @@ Creates a deep copy of a node.
|
|
|
308
308
|
|
|
309
309
|
```typescript
|
|
310
310
|
interface WireframeDocument {
|
|
311
|
-
type: 'Document'
|
|
312
|
-
children: PageNode[]
|
|
311
|
+
type: 'Document'
|
|
312
|
+
children: PageNode[]
|
|
313
313
|
}
|
|
314
314
|
```
|
|
315
315
|
|
|
@@ -317,9 +317,9 @@ interface WireframeDocument {
|
|
|
317
317
|
|
|
318
318
|
```typescript
|
|
319
319
|
interface PageNode {
|
|
320
|
-
type: 'Page'
|
|
321
|
-
title?: string
|
|
322
|
-
children: ASTNode[]
|
|
320
|
+
type: 'Page'
|
|
321
|
+
title?: string
|
|
322
|
+
children: ASTNode[]
|
|
323
323
|
// ... spacing attributes
|
|
324
324
|
}
|
|
325
325
|
```
|
|
@@ -327,6 +327,7 @@ interface PageNode {
|
|
|
327
327
|
### Common Node Properties
|
|
328
328
|
|
|
329
329
|
All nodes include:
|
|
330
|
+
|
|
330
331
|
- `type: string` - Node type (e.g., 'Button', 'Card')
|
|
331
332
|
- `location?: Location` - Source location info
|
|
332
333
|
- Spacing: `p`, `px`, `py`, `pt`, `pr`, `pb`, `pl`, `m`, `mx`, `my`, `mt`, `mr`, `mb`, `ml`
|
|
@@ -337,42 +338,42 @@ All nodes include:
|
|
|
337
338
|
```typescript
|
|
338
339
|
// Button
|
|
339
340
|
interface ButtonNode {
|
|
340
|
-
type: 'Button'
|
|
341
|
-
content: string
|
|
342
|
-
primary?: boolean
|
|
343
|
-
secondary?: boolean
|
|
344
|
-
outline?: boolean
|
|
345
|
-
ghost?: boolean
|
|
346
|
-
danger?: boolean
|
|
347
|
-
disabled?: boolean
|
|
341
|
+
type: 'Button'
|
|
342
|
+
content: string
|
|
343
|
+
primary?: boolean
|
|
344
|
+
secondary?: boolean
|
|
345
|
+
outline?: boolean
|
|
346
|
+
ghost?: boolean
|
|
347
|
+
danger?: boolean
|
|
348
|
+
disabled?: boolean
|
|
348
349
|
}
|
|
349
350
|
|
|
350
351
|
// Input
|
|
351
352
|
interface InputNode {
|
|
352
|
-
type: 'Input'
|
|
353
|
-
label?: string
|
|
354
|
-
placeholder?: string
|
|
355
|
-
inputType?: 'text' | 'email' | 'password' | 'search' | 'tel' | 'url' | 'number'
|
|
356
|
-
required?: boolean
|
|
357
|
-
disabled?: boolean
|
|
353
|
+
type: 'Input'
|
|
354
|
+
label?: string
|
|
355
|
+
placeholder?: string
|
|
356
|
+
inputType?: 'text' | 'email' | 'password' | 'search' | 'tel' | 'url' | 'number'
|
|
357
|
+
required?: boolean
|
|
358
|
+
disabled?: boolean
|
|
358
359
|
}
|
|
359
360
|
|
|
360
361
|
// Card
|
|
361
362
|
interface CardNode {
|
|
362
|
-
type: 'Card'
|
|
363
|
-
title?: string
|
|
364
|
-
children: ASTNode[]
|
|
363
|
+
type: 'Card'
|
|
364
|
+
title?: string
|
|
365
|
+
children: ASTNode[]
|
|
365
366
|
}
|
|
366
367
|
|
|
367
368
|
// Col
|
|
368
369
|
interface ColNode {
|
|
369
|
-
type: 'Col'
|
|
370
|
-
span?: number
|
|
371
|
-
sm?: number
|
|
372
|
-
md?: number
|
|
373
|
-
lg?: number
|
|
374
|
-
xl?: number
|
|
375
|
-
children: ASTNode[]
|
|
370
|
+
type: 'Col'
|
|
371
|
+
span?: number
|
|
372
|
+
sm?: number
|
|
373
|
+
md?: number
|
|
374
|
+
lg?: number
|
|
375
|
+
xl?: number
|
|
376
|
+
children: ASTNode[]
|
|
376
377
|
}
|
|
377
378
|
```
|
|
378
379
|
|
|
@@ -442,15 +443,15 @@ page {
|
|
|
442
443
|
## Error Handling
|
|
443
444
|
|
|
444
445
|
```typescript
|
|
445
|
-
import { parse } from '@wireweave/core'
|
|
446
|
+
import { parse } from '@wireweave/core'
|
|
446
447
|
|
|
447
448
|
try {
|
|
448
|
-
const doc = parse('page { invalid }')
|
|
449
|
+
const doc = parse('page { invalid }')
|
|
449
450
|
} catch (error) {
|
|
450
451
|
if (error.name === 'ParseError') {
|
|
451
|
-
console.log(error.message)
|
|
452
|
+
console.log(error.message)
|
|
452
453
|
// "Syntax error at line 1, column 8: ..."
|
|
453
|
-
console.log(error.location)
|
|
454
|
+
console.log(error.location)
|
|
454
455
|
// { start: { line: 1, column: 8 }, end: { ... } }
|
|
455
456
|
}
|
|
456
457
|
}
|
|
@@ -462,12 +463,12 @@ The core library works in both Node.js and browser environments. For browser usa
|
|
|
462
463
|
|
|
463
464
|
```html
|
|
464
465
|
<script type="module">
|
|
465
|
-
import { parse, render } from '@wireweave/core'
|
|
466
|
+
import { parse, render } from '@wireweave/core'
|
|
466
467
|
|
|
467
|
-
const doc = parse('page { text "Hello" }')
|
|
468
|
-
const { html, css } = render(doc)
|
|
468
|
+
const doc = parse('page { text "Hello" }')
|
|
469
|
+
const { html, css } = render(doc)
|
|
469
470
|
|
|
470
|
-
document.body.innerHTML = `<style>${css}</style>${html}
|
|
471
|
+
document.body.innerHTML = `<style>${css}</style>${html}`
|
|
471
472
|
</script>
|
|
472
473
|
```
|
|
473
474
|
|