@pyreon/document-primitives 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/lib/index.d.ts CHANGED
@@ -77,10 +77,10 @@ declare const DocButton: import("@pyreon/rocketstyle").RocketStyleComponent<Part
77
77
  }> & import("@pyreon/core").PyreonHTMLAttributes<HTMLElement>, {
78
78
  href?: string;
79
79
  }, {}, {
80
+ padding: string;
80
81
  borderRadius: number;
81
82
  fontSize: number;
82
83
  fontWeight: string;
83
- padding: string;
84
84
  textAlign: string;
85
85
  textDecoration: string;
86
86
  }, {
@@ -114,10 +114,10 @@ declare const DocCode: import("@pyreon/rocketstyle").RocketStyleComponent<Partia
114
114
  language?: string;
115
115
  }, {}, {
116
116
  backgroundColor: string;
117
+ padding: string;
117
118
  borderRadius: number;
118
119
  fontFamily: string;
119
120
  fontSize: number;
120
- padding: string;
121
121
  }, {
122
122
  _documentType: "code";
123
123
  }, {}, {
@@ -419,9 +419,9 @@ declare const DocImage: import("@pyreon/rocketstyle").RocketStyleComponent<Parti
419
419
  beforeContentCss: import("@pyreon/elements").ExtendCss;
420
420
  afterContentCss: import("@pyreon/elements").ExtendCss;
421
421
  }> & import("@pyreon/core").PyreonHTMLAttributes<HTMLElement>, {
422
- height?: number | string;
423
422
  width?: number | string;
424
423
  caption?: string;
424
+ height?: number | string;
425
425
  src?: string;
426
426
  alt?: string;
427
427
  }, {}, {}, {
@@ -696,10 +696,10 @@ declare const DocQuote: import("@pyreon/rocketstyle").RocketStyleComponent<Parti
696
696
  }> & import("@pyreon/core").PyreonHTMLAttributes<HTMLElement>, {
697
697
  borderColor?: string;
698
698
  }, {}, {
699
+ padding: string;
699
700
  borderColor: string;
700
701
  color: string;
701
702
  fontStyle: string;
702
- padding: string;
703
703
  }, {
704
704
  _documentType: "quote";
705
705
  }, {}, {
@@ -757,8 +757,8 @@ declare const DocRow: import("@pyreon/rocketstyle").RocketStyleComponent<Partial
757
757
  afterContentCss: import("@pyreon/elements").ExtendCss;
758
758
  }> & import("@pyreon/core").PyreonHTMLAttributes<HTMLElement>, {
759
759
  tag: string;
760
- direction: "inline";
761
760
  gap: number;
761
+ direction: "inline";
762
762
  _documentProps: {};
763
763
  }, {}, {}, {
764
764
  _documentType: "row";
@@ -928,9 +928,9 @@ declare const DocTable: import("@pyreon/rocketstyle").RocketStyleComponent<Parti
928
928
  beforeContentCss: import("@pyreon/elements").ExtendCss;
929
929
  afterContentCss: import("@pyreon/elements").ExtendCss;
930
930
  }> & import("@pyreon/core").PyreonHTMLAttributes<HTMLElement>, {
931
- columns?: unknown[];
932
931
  caption?: string;
933
932
  rows?: unknown[];
933
+ columns?: unknown[];
934
934
  headerStyle?: Record<string, unknown>;
935
935
  striped?: boolean;
936
936
  bordered?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pyreon/document-primitives",
3
- "version": "0.24.5",
3
+ "version": "0.24.6",
4
4
  "description": "Rocketstyle document components — render in browser, export to 18 formats",
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,25 +40,25 @@
42
40
  "typecheck": "tsc --noEmit"
43
41
  },
44
42
  "dependencies": {
45
- "@pyreon/connector-document": "^0.24.5",
46
- "@pyreon/core": "^0.24.5",
47
- "@pyreon/document": "^0.24.5",
48
- "@pyreon/elements": "^0.24.5",
49
- "@pyreon/rocketstyle": "^0.24.5",
50
- "@pyreon/styler": "^0.24.5",
51
- "@pyreon/ui-core": "^0.24.5"
43
+ "@pyreon/connector-document": "^0.24.6",
44
+ "@pyreon/core": "^0.24.6",
45
+ "@pyreon/document": "^0.24.6",
46
+ "@pyreon/elements": "^0.24.6",
47
+ "@pyreon/rocketstyle": "^0.24.6",
48
+ "@pyreon/styler": "^0.24.6",
49
+ "@pyreon/ui-core": "^0.24.6"
52
50
  },
53
51
  "devDependencies": {
54
- "@pyreon/core": "^0.24.5",
55
- "@pyreon/elements": "^0.24.5",
52
+ "@pyreon/core": "^0.24.6",
53
+ "@pyreon/elements": "^0.24.6",
56
54
  "@pyreon/manifest": "0.13.1",
57
- "@pyreon/reactivity": "^0.24.5",
58
- "@pyreon/rocketstyle": "^0.24.5",
59
- "@pyreon/runtime-dom": "^0.24.5",
60
- "@pyreon/styler": "^0.24.5",
55
+ "@pyreon/reactivity": "^0.24.6",
56
+ "@pyreon/rocketstyle": "^0.24.6",
57
+ "@pyreon/runtime-dom": "^0.24.6",
58
+ "@pyreon/styler": "^0.24.6",
61
59
  "@pyreon/test-utils": "^0.13.11",
62
- "@pyreon/typescript": "^0.24.5",
63
- "@pyreon/ui-core": "^0.24.5",
60
+ "@pyreon/typescript": "^0.24.6",
61
+ "@pyreon/ui-core": "^0.24.6",
64
62
  "@vitest/browser-playwright": "^4.1.4",
65
63
  "@vitus-labs/tools-rolldown": "^2.4.0"
66
64
  },
@@ -1,48 +0,0 @@
1
- import { Element } from '@pyreon/elements'
2
- import rocketstyle from '@pyreon/rocketstyle'
3
-
4
- const DocumentPreview = rocketstyle({
5
- dimensions: {
6
- sizes: 'size',
7
- },
8
- useBooleans: true,
9
- })({ name: 'DocumentPreview', component: Element })
10
- .theme({
11
- backgroundColor: '#f5f5f5',
12
- padding: 40,
13
- })
14
- .sizes({
15
- A4: { width: '210mm', minHeight: '297mm' },
16
- A3: { width: '297mm', minHeight: '420mm' },
17
- A5: { width: '148mm', minHeight: '210mm' },
18
- letter: { width: '8.5in', minHeight: '11in' },
19
- legal: { width: '8.5in', minHeight: '14in' },
20
- })
21
- .styles(
22
- (css: any) => css`
23
- display: flex;
24
- flex-direction: column;
25
- align-items: center;
26
- min-height: 100vh;
27
-
28
- & > * {
29
- background: white;
30
- padding: 25mm;
31
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
32
- margin: 20px 0;
33
- }
34
- `,
35
- )
36
- .statics({ _documentType: 'document' as const })
37
- .attrs<{
38
- size?: string
39
- showPageBreaks?: boolean
40
- }>((props) => ({
41
- tag: 'div',
42
- _documentProps: {
43
- ...(props.size ? { size: props.size } : { size: 'A4' }),
44
- ...(props.showPageBreaks ? { showPageBreaks: props.showPageBreaks } : {}),
45
- },
46
- }))
47
-
48
- export default DocumentPreview
@@ -1,253 +0,0 @@
1
- import { h } from '@pyreon/core'
2
- import { extractDocumentTree } from '@pyreon/connector-document'
3
- import { signal } from '@pyreon/reactivity'
4
- import { mountInBrowser } from '@pyreon/test-utils/browser'
5
- import { afterEach, describe, expect, it } from 'vitest'
6
- import DocCode from '../primitives/DocCode'
7
- import DocDocument from '../primitives/DocDocument'
8
- import DocHeading from '../primitives/DocHeading'
9
- import DocImage from '../primitives/DocImage'
10
- import DocLink from '../primitives/DocLink'
11
- import DocList from '../primitives/DocList'
12
- import DocListItem from '../primitives/DocListItem'
13
- import DocSection from '../primitives/DocSection'
14
- import DocTable from '../primitives/DocTable'
15
- import DocText from '../primitives/DocText'
16
-
17
- // Real-browser smoke suite for @pyreon/document-primitives.
18
- //
19
- // The contract under test here is the one PR #197 fixed: when you pass a real
20
- // rocketstyle-wrapped primitive (not a hand-constructed mock vnode) through
21
- // `extractDocumentTree`, the extractor must invoke the component to reach the
22
- // post-attrs vnode where `_documentProps` actually lives. Before PR #197,
23
- // every real primitive silently dropped its metadata during export.
24
- //
25
- // The existing unit tests in `connector-document/src/__tests__/` use a
26
- // hand-constructed `DocDocLike` function. This suite closes the gap by
27
- // using the ACTUAL `DocDocument` primitive with real rocketstyle runtime,
28
- // in a real browser.
29
-
30
- describe('document-primitives in real browser', () => {
31
- afterEach(() => {
32
- // Each test cleans up its own mount; extract-only tests have nothing to do.
33
- })
34
-
35
- it('extracts title + author from a real DocDocument vnode (PR #197 regression)', () => {
36
- const vnode = h(DocDocument, { title: 'Resume', author: 'Alice' })
37
- const tree = extractDocumentTree(vnode)
38
-
39
- expect(tree.type).toBe('document')
40
- expect(tree.props.title).toBe('Resume')
41
- expect(tree.props.author).toBe('Alice')
42
- })
43
-
44
- it('resolves reactive accessor props at extraction time (live signal reads)', () => {
45
- const name = signal('Alice')
46
- const vnode = h(DocDocument, {
47
- title: () => `${name()} — Resume`,
48
- author: () => name(),
49
- })
50
-
51
- const first = extractDocumentTree(vnode)
52
- expect(first.props.title).toBe('Alice — Resume')
53
- expect(first.props.author).toBe('Alice')
54
-
55
- name.set('Bob')
56
- const second = extractDocumentTree(vnode)
57
- expect(second.props.title).toBe('Bob — Resume')
58
- expect(second.props.author).toBe('Bob')
59
- })
60
-
61
- it('renders a nested DocDocument tree to real DOM and extracts the same tree', () => {
62
- const vnode = h(
63
- DocDocument,
64
- { title: 'Report' },
65
- h(DocHeading, { level: 'h1' }, 'Q1 Results'),
66
- h(DocText, null, 'Revenue grew 12%.'),
67
- )
68
-
69
- const { container, unmount } = mountInBrowser(vnode)
70
- // Real browser renders the rocketstyle-wrapped elements.
71
- expect(container.textContent).toContain('Q1 Results')
72
- expect(container.textContent).toContain('Revenue grew 12%.')
73
-
74
- // Same vnode drives the export path.
75
- const tree = extractDocumentTree(vnode)
76
- expect(tree.type).toBe('document')
77
- expect(tree.props.title).toBe('Report')
78
- expect(tree.children.length).toBeGreaterThanOrEqual(2)
79
- const nodeChildren = tree.children.filter(
80
- (c): c is Exclude<typeof c, string> => typeof c !== 'string',
81
- )
82
- expect(nodeChildren.some((c) => c.type === 'heading')).toBe(true)
83
- expect(nodeChildren.some((c) => c.type === 'text')).toBe(true)
84
-
85
- unmount()
86
- })
87
-
88
- it('extracts heading level from real DocHeading primitive', () => {
89
- const tree = extractDocumentTree(
90
- h(DocDocument, { title: 't' }, h(DocHeading, { level: 'h2' }, 'Section')),
91
- )
92
- const heading = (tree.children.find((c) => typeof c !== 'string' && c.type === 'heading') ??
93
- null) as { type: string; props: { level?: number } } | null
94
- expect(heading).not.toBeNull()
95
- // DocHeading converts the 'h2' level prop into a numeric `level: 2`.
96
- expect(heading?.props.level).toBe(2)
97
- })
98
-
99
- it('extracts href from real DocLink primitive', () => {
100
- const tree = extractDocumentTree(
101
- h(
102
- DocDocument,
103
- { title: 't' },
104
- h(DocLink, { href: 'https://example.com' }, 'click me'),
105
- ),
106
- )
107
- const link = (tree.children.find((c) => typeof c !== 'string' && c.type === 'link') ??
108
- null) as { type: string; props: { href?: string } } | null
109
- expect(link).not.toBeNull()
110
- expect(link?.props.href).toBe('https://example.com')
111
- })
112
-
113
- it('extracts ordered flag from real DocList primitive', () => {
114
- const tree = extractDocumentTree(
115
- h(
116
- DocDocument,
117
- { title: 't' },
118
- h(
119
- DocList,
120
- { ordered: true },
121
- h(DocListItem, null, 'one'),
122
- h(DocListItem, null, 'two'),
123
- ),
124
- ),
125
- )
126
- const list = (tree.children.find((c) => typeof c !== 'string' && c.type === 'list') ??
127
- null) as { type: string; props: { ordered?: boolean }; children: unknown[] } | null
128
- expect(list).not.toBeNull()
129
- expect(list?.props.ordered).toBe(true)
130
- expect(list?.children.length).toBe(2)
131
- })
132
-
133
- it('extracts language from real DocCode primitive', () => {
134
- const tree = extractDocumentTree(
135
- h(
136
- DocDocument,
137
- { title: 't' },
138
- h(DocCode, { language: 'typescript' }, 'const x = 1'),
139
- ),
140
- )
141
- const code = (tree.children.find((c) => typeof c !== 'string' && c.type === 'code') ??
142
- null) as { type: string; props: { language?: string } } | null
143
- expect(code).not.toBeNull()
144
- expect(code?.props.language).toBe('typescript')
145
- })
146
-
147
- it('extracts src + alt from real DocImage primitive (no DOM forwarding crash)', () => {
148
- // Image element has read-only `naturalWidth`/`naturalHeight` properties —
149
- // a clean test that DocImage doesn't try to set them via property assignment.
150
- const tree = extractDocumentTree(
151
- h(
152
- DocDocument,
153
- { title: 't' },
154
- h(DocImage, { src: 'https://example.com/x.png', alt: 'logo' }),
155
- ),
156
- )
157
- const img = (tree.children.find((c) => typeof c !== 'string' && c.type === 'image') ??
158
- null) as { type: string; props: { src?: string; alt?: string } } | null
159
- expect(img).not.toBeNull()
160
- expect(img?.props.src).toBe('https://example.com/x.png')
161
- expect(img?.props.alt).toBe('logo')
162
- })
163
-
164
- it('extracts table rows + columns without read-only-property crash', () => {
165
- // DocTable uses `.attrs(callback, { filter: ['rows', 'columns', ...] })`
166
- // to strip export-only props before they reach the DOM, because
167
- // HTMLTableElement.rows is a read-only HTMLCollection getter — assigning
168
- // to it would crash. This test exercises that filter path.
169
- const tree = extractDocumentTree(
170
- h(
171
- DocDocument,
172
- { title: 't' },
173
- h(DocTable, {
174
- rows: [
175
- ['a1', 'b1'],
176
- ['a2', 'b2'],
177
- ],
178
- columns: ['col-a', 'col-b'],
179
- }),
180
- ),
181
- )
182
- const table = (tree.children.find((c) => typeof c !== 'string' && c.type === 'table') ??
183
- null) as
184
- | {
185
- type: string
186
- props: {
187
- rows?: unknown[]
188
- columns?: unknown[]
189
- }
190
- }
191
- | null
192
- expect(table).not.toBeNull()
193
- expect(Array.isArray(table?.props.rows)).toBe(true)
194
- expect(table?.props.rows).toHaveLength(2)
195
- expect(table?.props.columns).toEqual(['col-a', 'col-b'])
196
- })
197
-
198
- it('extracts deeply nested tree (DocSection wrapping multiple primitives)', () => {
199
- const tree = extractDocumentTree(
200
- h(
201
- DocDocument,
202
- { title: 'Report' },
203
- h(
204
- DocSection,
205
- null,
206
- h(DocHeading, { level: 'h1' }, 'Intro'),
207
- h(DocText, null, 'paragraph'),
208
- h(DocSection, null, h(DocText, null, 'nested-paragraph')),
209
- ),
210
- ),
211
- )
212
- expect(tree.type).toBe('document')
213
-
214
- // The traversal into nested sections should preserve depth.
215
- const findByType = (node: unknown, type: string): unknown => {
216
- if (typeof node !== 'object' || !node) return null
217
- const n = node as { type?: string; children?: unknown[] }
218
- if (n.type === type) return n
219
- for (const c of n.children ?? []) {
220
- const found = findByType(c, type)
221
- if (found) return found
222
- }
223
- return null
224
- }
225
- const heading = findByType(tree, 'heading')
226
- expect(heading).not.toBeNull()
227
- // 'nested-paragraph' should appear as a text node anywhere in the tree.
228
- const treeStr = JSON.stringify(tree)
229
- expect(treeStr).toContain('nested-paragraph')
230
- })
231
-
232
- it('handles primitives that have NO _documentProps cleanly (DocText)', () => {
233
- // DocText has `_documentProps: {}` — empty object. Confirms the
234
- // extractor doesn't choke on absent metadata.
235
- const tree = extractDocumentTree(
236
- h(DocDocument, { title: 't' }, h(DocText, null, 'just text')),
237
- )
238
- const text = (tree.children.find((c) => typeof c !== 'string' && c.type === 'text') ??
239
- null) as { type: string; children?: unknown[] } | null
240
- expect(text).not.toBeNull()
241
- expect(JSON.stringify(text)).toContain('just text')
242
- })
243
-
244
- it('handles undefined / nullish optional metadata (omits, does not emit `key: undefined`)', () => {
245
- // DocDocument explicitly only sets keys when non-null. Verify by
246
- // omitting all optional props.
247
- const tree = extractDocumentTree(h(DocDocument, {}))
248
- expect(tree.type).toBe('document')
249
- expect(tree.props).not.toHaveProperty('title')
250
- expect(tree.props).not.toHaveProperty('author')
251
- expect(tree.props).not.toHaveProperty('subject')
252
- })
253
- })
@@ -1,45 +0,0 @@
1
- import {
2
- renderApiReferenceEntries,
3
- renderLlmsFullSection,
4
- renderLlmsTxtLine,
5
- } from '@pyreon/manifest'
6
- import manifest from '../manifest'
7
-
8
- describe('gen-docs — document-primitives snapshot', () => {
9
- it('renders a llms.txt bullet starting with the package prefix', () => {
10
- const line = renderLlmsTxtLine(manifest)
11
- expect(line.startsWith('- @pyreon/document-primitives —')).toBe(true)
12
- })
13
-
14
- it('renders a llms-full.txt section with the right header', () => {
15
- const section = renderLlmsFullSection(manifest)
16
- expect(section.startsWith('## @pyreon/document-primitives —')).toBe(true)
17
- expect(section).toContain('```typescript')
18
- })
19
-
20
- it('renders MCP api-reference entries for every api[] item', () => {
21
- const record = renderApiReferenceEntries(manifest)
22
- expect(Object.keys(record).sort()).toEqual([
23
- 'document-primitives/DocButton',
24
- 'document-primitives/DocCode',
25
- 'document-primitives/DocColumn',
26
- 'document-primitives/DocDivider',
27
- 'document-primitives/DocDocument',
28
- 'document-primitives/DocHeading',
29
- 'document-primitives/DocImage',
30
- 'document-primitives/DocLink',
31
- 'document-primitives/DocList',
32
- 'document-primitives/DocListItem',
33
- 'document-primitives/DocPage',
34
- 'document-primitives/DocPageBreak',
35
- 'document-primitives/DocQuote',
36
- 'document-primitives/DocRow',
37
- 'document-primitives/DocSection',
38
- 'document-primitives/DocSpacer',
39
- 'document-primitives/DocTable',
40
- 'document-primitives/DocText',
41
- 'document-primitives/createDocumentExport',
42
- 'document-primitives/extractDocNode',
43
- ])
44
- })
45
- })