@pyreon/connector-document 0.24.5 → 0.24.6
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/package.json +8 -10
- package/src/__tests__/connector-document.browser.test.tsx +0 -146
- package/src/__tests__/cssValueParser.test.ts +0 -136
- package/src/__tests__/extractDocumentTree.test.ts +0 -548
- package/src/__tests__/resolveStyles.test.ts +0 -124
- package/src/cssValueParser.ts +0 -110
- package/src/extractDocumentTree.ts +0 -280
- package/src/index.ts +0 -10
- package/src/resolveStyles.ts +0 -101
- package/src/types.ts +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pyreon/connector-document",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.6",
|
|
4
4
|
"description": "Bridge between @pyreon/pyreon styled components and @pyreon/document rendering",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -13,8 +13,7 @@
|
|
|
13
13
|
"!lib/**/*.map",
|
|
14
14
|
"!lib/analysis",
|
|
15
15
|
"README.md",
|
|
16
|
-
"LICENSE"
|
|
17
|
-
"src"
|
|
16
|
+
"LICENSE"
|
|
18
17
|
],
|
|
19
18
|
"type": "module",
|
|
20
19
|
"sideEffects": false,
|
|
@@ -22,7 +21,6 @@
|
|
|
22
21
|
"types": "./lib/index.d.ts",
|
|
23
22
|
"exports": {
|
|
24
23
|
".": {
|
|
25
|
-
"bun": "./src/index.ts",
|
|
26
24
|
"import": "./lib/index.js",
|
|
27
25
|
"types": "./lib/index.d.ts"
|
|
28
26
|
}
|
|
@@ -42,11 +40,11 @@
|
|
|
42
40
|
"typecheck": "tsc --noEmit"
|
|
43
41
|
},
|
|
44
42
|
"devDependencies": {
|
|
45
|
-
"@pyreon/core": "^0.24.
|
|
46
|
-
"@pyreon/document": "^0.24.
|
|
47
|
-
"@pyreon/reactivity": "^0.24.
|
|
43
|
+
"@pyreon/core": "^0.24.6",
|
|
44
|
+
"@pyreon/document": "^0.24.6",
|
|
45
|
+
"@pyreon/reactivity": "^0.24.6",
|
|
48
46
|
"@pyreon/test-utils": "^0.13.11",
|
|
49
|
-
"@pyreon/typescript": "^0.24.
|
|
47
|
+
"@pyreon/typescript": "^0.24.6",
|
|
50
48
|
"@vitest/browser-playwright": "^4.1.4",
|
|
51
49
|
"@vitus-labs/tools-rolldown": "^2.4.0"
|
|
52
50
|
},
|
|
@@ -54,7 +52,7 @@
|
|
|
54
52
|
"node": ">= 22"
|
|
55
53
|
},
|
|
56
54
|
"dependencies": {
|
|
57
|
-
"@pyreon/core": "^0.24.
|
|
58
|
-
"@pyreon/document": "^0.24.
|
|
55
|
+
"@pyreon/core": "^0.24.6",
|
|
56
|
+
"@pyreon/document": "^0.24.6"
|
|
59
57
|
}
|
|
60
58
|
}
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
/** @jsxImportSource @pyreon/core */
|
|
2
|
-
import { h } from '@pyreon/core'
|
|
3
|
-
import { signal } from '@pyreon/reactivity'
|
|
4
|
-
import { afterEach, describe, expect, it } from 'vitest'
|
|
5
|
-
import { extractDocumentTree } from '../extractDocumentTree'
|
|
6
|
-
import { resolveStyles } from '../resolveStyles'
|
|
7
|
-
|
|
8
|
-
// Real-Chromium smoke for @pyreon/connector-document.
|
|
9
|
-
//
|
|
10
|
-
// The pre-existing unit tests construct mock vnode objects by hand
|
|
11
|
-
// (`{ type, props, children }`) — fast but they bypass the real
|
|
12
|
-
// `@pyreon/core` `h()` runtime. PR #197 fixed a class of bug that
|
|
13
|
-
// hand-mock tests can't catch: `_documentProps` only appears on a
|
|
14
|
-
// vnode AFTER rocketstyle's `.attrs()` HOC runs, so the JSX
|
|
15
|
-
// vnode (what `h()` returns) only carries USER-provided props.
|
|
16
|
-
//
|
|
17
|
-
// This suite builds vnodes with the real `h()` runtime and verifies:
|
|
18
|
-
// 1. Path A: a documentType component with `_documentProps` already
|
|
19
|
-
// set on the JSX vnode extracts cleanly.
|
|
20
|
-
// 2. Path B: `extractDocumentTree` invokes the component and reads
|
|
21
|
-
// `_documentProps` from the post-call vnode (the rocketstyle
|
|
22
|
-
// attrs-style path) — proving the workaround documented in the
|
|
23
|
-
// source still functions in a real browser.
|
|
24
|
-
// 3. Function-valued `_documentProps` (reactive accessors) are
|
|
25
|
-
// resolved to LIVE values at extraction time — covers the
|
|
26
|
-
// "metadata reads current signal" path used by document-primitives.
|
|
27
|
-
// 4. resolveStyles converts rocketstyle theme objects to plain
|
|
28
|
-
// style records in the browser bundle (no Node-only dep leaks).
|
|
29
|
-
|
|
30
|
-
describe('@pyreon/connector-document in real browser', () => {
|
|
31
|
-
afterEach(() => {
|
|
32
|
-
// No globals to reset — extractDocumentTree is pure.
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
it('Path A — reads _documentProps off the JSX vnode WITHOUT invoking the component', () => {
|
|
36
|
-
// Strict Path A: the component function itself must NEVER touch
|
|
37
|
-
// `_documentProps` — `_documentProps` is supplied directly on the
|
|
38
|
-
// JSX vnode props. To prove the extractor takes the fast path and
|
|
39
|
-
// doesn't call the component, we install a throwing body: if
|
|
40
|
-
// extractNode falls through to Path B (invoking the component),
|
|
41
|
-
// the test fails with the throw. Passing proves Path A is taken.
|
|
42
|
-
const Heading = (_props: any) => {
|
|
43
|
-
throw new Error('Path A must not invoke the component')
|
|
44
|
-
}
|
|
45
|
-
;(Heading as any)._documentType = 'heading'
|
|
46
|
-
|
|
47
|
-
const tree = h(
|
|
48
|
-
Heading,
|
|
49
|
-
{ _documentProps: { level: 1 }, $rocketstyle: { color: '#000' } },
|
|
50
|
-
'Hi',
|
|
51
|
-
)
|
|
52
|
-
const result = extractDocumentTree(tree)
|
|
53
|
-
|
|
54
|
-
expect(result.type).toBe('heading')
|
|
55
|
-
expect(result.props).toEqual({ level: 1 })
|
|
56
|
-
expect(result.children[0]).toBe('Hi')
|
|
57
|
-
expect(result.styles?.color).toBe('#000')
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
it('Path B — invokes the component to recover _documentProps from the post-call vnode', () => {
|
|
61
|
-
// Simulates the rocketstyle attrs-HOC pattern: USER passes
|
|
62
|
-
// `{ title, author }` as JSX props; the component itself
|
|
63
|
-
// injects `_documentProps` into its return vnode via h().
|
|
64
|
-
const DocDocument = (props: any) =>
|
|
65
|
-
h(
|
|
66
|
-
'div',
|
|
67
|
-
{
|
|
68
|
-
// Post-attrs props — never visible on the JSX vnode itself.
|
|
69
|
-
_documentProps: {
|
|
70
|
-
title: props.title,
|
|
71
|
-
author: props.author,
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
|
-
props.children,
|
|
75
|
-
)
|
|
76
|
-
;(DocDocument as any)._documentType = 'document'
|
|
77
|
-
|
|
78
|
-
const tree = h(DocDocument, { title: 'Manual', author: 'Vít' }, 'body')
|
|
79
|
-
const result = extractDocumentTree(tree)
|
|
80
|
-
|
|
81
|
-
expect(result.type).toBe('document')
|
|
82
|
-
expect(result.props).toEqual({ title: 'Manual', author: 'Vít' })
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
it('resolves function-valued _documentProps to LIVE values at extraction time', () => {
|
|
86
|
-
const titleSig = signal('Initial')
|
|
87
|
-
const DocDocument = (props: any) =>
|
|
88
|
-
h(
|
|
89
|
-
'div',
|
|
90
|
-
{
|
|
91
|
-
_documentProps: {
|
|
92
|
-
// Accessor — extractor must call this to read the live signal.
|
|
93
|
-
title: props.title,
|
|
94
|
-
},
|
|
95
|
-
},
|
|
96
|
-
props.children,
|
|
97
|
-
)
|
|
98
|
-
;(DocDocument as any)._documentType = 'document'
|
|
99
|
-
|
|
100
|
-
const tree = h(DocDocument, { title: () => titleSig() }, 'x')
|
|
101
|
-
|
|
102
|
-
const before = extractDocumentTree(tree)
|
|
103
|
-
expect(before.props).toEqual({ title: 'Initial' })
|
|
104
|
-
|
|
105
|
-
titleSig.set('Updated')
|
|
106
|
-
const after = extractDocumentTree(tree)
|
|
107
|
-
// Same vnode, same accessor — but it now reads the new signal value.
|
|
108
|
-
expect(after.props).toEqual({ title: 'Updated' })
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
it('flattens transparent (non-documentType) wrappers built with h()', () => {
|
|
112
|
-
const Section = (props: any) => h('div', props, props.children)
|
|
113
|
-
;(Section as any)._documentType = 'section'
|
|
114
|
-
const Text = (props: any) => h('span', props, props.children)
|
|
115
|
-
;(Text as any)._documentType = 'text'
|
|
116
|
-
|
|
117
|
-
const tree = h(
|
|
118
|
-
Section,
|
|
119
|
-
null,
|
|
120
|
-
// Plain `h('div')` wrapper has no _documentType — should be
|
|
121
|
-
// flattened, leaving the inner Text directly under Section.
|
|
122
|
-
h('div', null, h(Text, null, 'inner')),
|
|
123
|
-
)
|
|
124
|
-
const result = extractDocumentTree(tree)
|
|
125
|
-
expect(result.type).toBe('section')
|
|
126
|
-
expect(result.children).toHaveLength(1)
|
|
127
|
-
expect((result.children[0] as any).type).toBe('text')
|
|
128
|
-
expect((result.children[0] as any).children[0]).toBe('inner')
|
|
129
|
-
})
|
|
130
|
-
|
|
131
|
-
it('resolveStyles produces a plain style record in the browser bundle', () => {
|
|
132
|
-
const styles = resolveStyles(
|
|
133
|
-
{
|
|
134
|
-
color: '#fff',
|
|
135
|
-
backgroundColor: '#0070f3',
|
|
136
|
-
fontSize: 24,
|
|
137
|
-
padding: '8px 16px',
|
|
138
|
-
},
|
|
139
|
-
16,
|
|
140
|
-
)
|
|
141
|
-
expect(styles.color).toBe('#fff')
|
|
142
|
-
expect(styles.backgroundColor).toBe('#0070f3')
|
|
143
|
-
expect(styles.fontSize).toBe(24)
|
|
144
|
-
expect(styles.padding).toEqual([8, 16])
|
|
145
|
-
})
|
|
146
|
-
})
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import {
|
|
3
|
-
parseBoxModel,
|
|
4
|
-
parseCssDimension,
|
|
5
|
-
parseFontWeight,
|
|
6
|
-
parseLineHeight,
|
|
7
|
-
} from '../cssValueParser'
|
|
8
|
-
|
|
9
|
-
describe('parseCssDimension', () => {
|
|
10
|
-
it('passes through numbers', () => {
|
|
11
|
-
expect(parseCssDimension(14)).toBe(14)
|
|
12
|
-
expect(parseCssDimension(0)).toBe(0)
|
|
13
|
-
expect(parseCssDimension(-5)).toBe(-5)
|
|
14
|
-
expect(parseCssDimension(1.5)).toBe(1.5)
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
it('parses px values', () => {
|
|
18
|
-
expect(parseCssDimension('14px')).toBe(14)
|
|
19
|
-
expect(parseCssDimension('0px')).toBe(0)
|
|
20
|
-
expect(parseCssDimension('-5px')).toBe(-5)
|
|
21
|
-
expect(parseCssDimension('1.5px')).toBe(1.5)
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
it('parses rem values', () => {
|
|
25
|
-
expect(parseCssDimension('1rem')).toBe(16)
|
|
26
|
-
expect(parseCssDimension('1.5rem')).toBe(24)
|
|
27
|
-
expect(parseCssDimension('0.5rem')).toBe(8)
|
|
28
|
-
expect(parseCssDimension('2rem', 20)).toBe(40)
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
it('parses em values', () => {
|
|
32
|
-
expect(parseCssDimension('1em')).toBe(16)
|
|
33
|
-
expect(parseCssDimension('2em')).toBe(32)
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
it('parses pt values', () => {
|
|
37
|
-
expect(parseCssDimension('12pt')).toBeCloseTo(16)
|
|
38
|
-
expect(parseCssDimension('9pt')).toBeCloseTo(12)
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
it('parses bare number strings', () => {
|
|
42
|
-
expect(parseCssDimension('14')).toBe(14)
|
|
43
|
-
expect(parseCssDimension('0')).toBe(0)
|
|
44
|
-
expect(parseCssDimension('-5')).toBe(-5)
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
it('returns undefined for unresolvable values', () => {
|
|
48
|
-
expect(parseCssDimension('auto')).toBeUndefined()
|
|
49
|
-
expect(parseCssDimension('100%')).toBeUndefined()
|
|
50
|
-
expect(parseCssDimension('calc(100% - 20px)')).toBeUndefined()
|
|
51
|
-
expect(parseCssDimension('var(--spacing)')).toBeUndefined()
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
it('trims whitespace', () => {
|
|
55
|
-
expect(parseCssDimension(' 14px ')).toBe(14)
|
|
56
|
-
expect(parseCssDimension(' 1rem ')).toBe(16)
|
|
57
|
-
})
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
describe('parseBoxModel', () => {
|
|
61
|
-
it('returns undefined for null/undefined', () => {
|
|
62
|
-
expect(parseBoxModel(undefined)).toBeUndefined()
|
|
63
|
-
expect(parseBoxModel(null as any)).toBeUndefined()
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
it('passes through numbers', () => {
|
|
67
|
-
expect(parseBoxModel(8)).toBe(8)
|
|
68
|
-
expect(parseBoxModel(0)).toBe(0)
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
it('parses single value', () => {
|
|
72
|
-
expect(parseBoxModel('8px')).toBe(8)
|
|
73
|
-
expect(parseBoxModel('1rem')).toBe(16)
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
it('parses two values (vertical horizontal)', () => {
|
|
77
|
-
expect(parseBoxModel('8px 16px')).toEqual([8, 16])
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
it('parses three values (top horizontal bottom)', () => {
|
|
81
|
-
expect(parseBoxModel('8px 16px 12px')).toEqual([8, 16, 12, 16])
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
it('parses four values', () => {
|
|
85
|
-
expect(parseBoxModel('8px 16px 12px 4px')).toEqual([8, 16, 12, 4])
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
it('returns undefined when any part is unresolvable', () => {
|
|
89
|
-
expect(parseBoxModel('8px auto')).toBeUndefined()
|
|
90
|
-
expect(parseBoxModel('8px 16px auto 4px')).toBeUndefined()
|
|
91
|
-
})
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
describe('parseFontWeight', () => {
|
|
95
|
-
it('passes through numbers', () => {
|
|
96
|
-
expect(parseFontWeight(400)).toBe(400)
|
|
97
|
-
expect(parseFontWeight(700)).toBe(700)
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
it('handles string keywords', () => {
|
|
101
|
-
expect(parseFontWeight('normal')).toBe('normal')
|
|
102
|
-
expect(parseFontWeight('bold')).toBe('bold')
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
it('parses numeric strings', () => {
|
|
106
|
-
expect(parseFontWeight('400')).toBe(400)
|
|
107
|
-
expect(parseFontWeight('700')).toBe(700)
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
it('returns undefined for null/undefined', () => {
|
|
111
|
-
expect(parseFontWeight(undefined)).toBeUndefined()
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
it('returns undefined for unrecognized values', () => {
|
|
115
|
-
expect(parseFontWeight('lighter')).toBeUndefined()
|
|
116
|
-
})
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
describe('parseLineHeight', () => {
|
|
120
|
-
it('passes through numbers (unitless)', () => {
|
|
121
|
-
expect(parseLineHeight(1.5)).toBe(1.5)
|
|
122
|
-
expect(parseLineHeight(2)).toBe(2)
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
it('parses px values', () => {
|
|
126
|
-
expect(parseLineHeight('24px')).toBe(24)
|
|
127
|
-
})
|
|
128
|
-
|
|
129
|
-
it("returns undefined for 'normal'", () => {
|
|
130
|
-
expect(parseLineHeight('normal')).toBeUndefined()
|
|
131
|
-
})
|
|
132
|
-
|
|
133
|
-
it('returns undefined for null/undefined', () => {
|
|
134
|
-
expect(parseLineHeight(undefined)).toBeUndefined()
|
|
135
|
-
})
|
|
136
|
-
})
|