@khairold/xml-render 0.1.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 (58) hide show
  1. package/README.md +372 -0
  2. package/dist/index.d.ts +33 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +41 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/parser.d.ts +129 -0
  7. package/dist/parser.d.ts.map +1 -0
  8. package/dist/parser.js +321 -0
  9. package/dist/parser.js.map +1 -0
  10. package/dist/react/ErrorBoundary.d.ts +56 -0
  11. package/dist/react/ErrorBoundary.d.ts.map +1 -0
  12. package/dist/react/ErrorBoundary.js +69 -0
  13. package/dist/react/ErrorBoundary.js.map +1 -0
  14. package/dist/react/XmlRender.d.ts +62 -0
  15. package/dist/react/XmlRender.d.ts.map +1 -0
  16. package/dist/react/XmlRender.js +90 -0
  17. package/dist/react/XmlRender.js.map +1 -0
  18. package/dist/react/catalog.d.ts +99 -0
  19. package/dist/react/catalog.d.ts.map +1 -0
  20. package/dist/react/catalog.js +55 -0
  21. package/dist/react/catalog.js.map +1 -0
  22. package/dist/react/context.d.ts +66 -0
  23. package/dist/react/context.d.ts.map +1 -0
  24. package/dist/react/context.js +63 -0
  25. package/dist/react/context.js.map +1 -0
  26. package/dist/react/index.d.ts +35 -0
  27. package/dist/react/index.d.ts.map +1 -0
  28. package/dist/react/index.js +41 -0
  29. package/dist/react/index.js.map +1 -0
  30. package/dist/react-native/ErrorBoundary.d.ts +60 -0
  31. package/dist/react-native/ErrorBoundary.d.ts.map +1 -0
  32. package/dist/react-native/ErrorBoundary.js +84 -0
  33. package/dist/react-native/ErrorBoundary.js.map +1 -0
  34. package/dist/react-native/XmlRender.d.ts +62 -0
  35. package/dist/react-native/XmlRender.d.ts.map +1 -0
  36. package/dist/react-native/XmlRender.js +91 -0
  37. package/dist/react-native/XmlRender.js.map +1 -0
  38. package/dist/react-native/catalog.d.ts +100 -0
  39. package/dist/react-native/catalog.d.ts.map +1 -0
  40. package/dist/react-native/catalog.js +56 -0
  41. package/dist/react-native/catalog.js.map +1 -0
  42. package/dist/react-native/context.d.ts +66 -0
  43. package/dist/react-native/context.d.ts.map +1 -0
  44. package/dist/react-native/context.js +63 -0
  45. package/dist/react-native/context.js.map +1 -0
  46. package/dist/react-native/index.d.ts +35 -0
  47. package/dist/react-native/index.d.ts.map +1 -0
  48. package/dist/react-native/index.js +41 -0
  49. package/dist/react-native/index.js.map +1 -0
  50. package/dist/registry.d.ts +99 -0
  51. package/dist/registry.d.ts.map +1 -0
  52. package/dist/registry.js +93 -0
  53. package/dist/registry.js.map +1 -0
  54. package/dist/types.d.ts +436 -0
  55. package/dist/types.d.ts.map +1 -0
  56. package/dist/types.js +28 -0
  57. package/dist/types.js.map +1 -0
  58. package/package.json +60 -0
package/README.md ADDED
@@ -0,0 +1,372 @@
1
+ # @khairold/xml-render
2
+
3
+ A type-safe XML-like tag parser and renderer framework for React and React Native. Parse structured content from text streams and render with custom components.
4
+
5
+ ## Features
6
+
7
+ - **Type-safe parsing** - Define tags with Zod schemas, get full TypeScript inference
8
+ - **Streaming support** - Parse content progressively as it streams in
9
+ - **Platform agnostic** - Separate entry points for React and React Native
10
+ - **Error boundaries** - Individual segment errors don't crash the entire UI
11
+ - **Immutable by design** - All registry and catalog instances are frozen
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install @khairold/xml-render zod
17
+ # or
18
+ bun add @khairold/xml-render zod
19
+ ```
20
+
21
+ Peer dependencies:
22
+ - `zod` ^3.0.0 (for attribute schemas)
23
+ - `react` ^18.0.0
24
+ - `react-native` (optional, for React Native renderer)
25
+
26
+ ## Quick Start
27
+
28
+ ```tsx
29
+ import { z } from 'zod';
30
+ import { createRegistry, createParser } from '@khairold/xml-render';
31
+ import { createCatalog, XmlRender } from '@khairold/xml-render/react';
32
+
33
+ // 1. Define your tags with Zod schemas
34
+ const registry = createRegistry({
35
+ callout: {
36
+ schema: z.object({ type: z.enum(['info', 'warning', 'error']) }),
37
+ hasContent: true,
38
+ },
39
+ image: {
40
+ schema: z.object({ src: z.string(), alt: z.string().optional() }),
41
+ selfClosing: true,
42
+ },
43
+ });
44
+
45
+ // 2. Create a parser
46
+ const parser = createParser(registry);
47
+
48
+ // 3. Create a component catalog
49
+ const catalog = createCatalog(registry, {
50
+ components: {
51
+ callout: ({ segment }) => (
52
+ <div className={`callout callout-${segment.attributes?.type}`}>
53
+ {segment.content}
54
+ </div>
55
+ ),
56
+ image: ({ segment }) => (
57
+ <img src={segment.attributes?.src} alt={segment.attributes?.alt} />
58
+ ),
59
+ },
60
+ textRenderer: ({ segment }) => <span>{segment.content}</span>,
61
+ });
62
+
63
+ // 4. Parse and render
64
+ const text = 'Hello <callout type="info">Important message!</callout> World';
65
+ const segments = parser.parse(text);
66
+
67
+ function App() {
68
+ return <XmlRender segments={segments} catalog={catalog} />;
69
+ }
70
+ ```
71
+
72
+ ## API Reference
73
+
74
+ ### Core Functions
75
+
76
+ #### `createRegistry(definitions)`
77
+
78
+ Creates an immutable tag registry from tag definitions.
79
+
80
+ ```ts
81
+ import { z } from 'zod';
82
+ import { createRegistry } from '@khairold/xml-render';
83
+
84
+ const registry = createRegistry({
85
+ chart: {
86
+ schema: z.object({
87
+ type: z.enum(['bar', 'line', 'pie']),
88
+ title: z.string().optional(),
89
+ }),
90
+ hasContent: true, // Tag contains inner content (default: true)
91
+ selfClosing: false, // Tag must have closing tag (default: false)
92
+ },
93
+ image: {
94
+ schema: z.object({
95
+ src: z.string(),
96
+ alt: z.string().optional(),
97
+ }),
98
+ selfClosing: true, // Self-closing tag like <image />
99
+ hasContent: false,
100
+ },
101
+ });
102
+ ```
103
+
104
+ **Registry methods:**
105
+ - `registry.tagNames` - Array of all registered tag names
106
+ - `registry.hasTag(name)` - Check if a tag is registered
107
+ - `registry.getTag(name)` - Get the definition for a tag
108
+ - `registry.validateAttributes(name, attrs)` - Validate attributes with Zod schema
109
+ - `registry.isSelfClosing(name)` - Check if tag is self-closing
110
+ - `registry.hasContent(name)` - Check if tag has content
111
+
112
+ #### `createParser(registry)`
113
+
114
+ Creates a parser instance bound to a registry.
115
+
116
+ ```ts
117
+ import { createParser } from '@khairold/xml-render';
118
+
119
+ const parser = createParser(registry);
120
+
121
+ // Parse complete text
122
+ const segments = parser.parse('Hello <callout type="info">World</callout>');
123
+ // [
124
+ // { type: 'text', content: 'Hello ' },
125
+ // { type: 'callout', content: 'World', attributes: { type: 'info' } },
126
+ // ]
127
+ ```
128
+
129
+ **Parser methods:**
130
+ - `parser.parse(text)` - Parse complete text into segments
131
+ - `parser.createState()` - Create initial state for streaming
132
+ - `parser.parseChunk(chunk, state)` - Parse streaming chunk
133
+ - `parser.finalize(state)` - Flush remaining buffer at stream end
134
+
135
+ ### Streaming Usage
136
+
137
+ For real-time content streaming (e.g., LLM responses):
138
+
139
+ ```ts
140
+ import { createParser, type ParserState } from '@khairold/xml-render';
141
+
142
+ const parser = createParser(registry);
143
+
144
+ // Initialize streaming state
145
+ let state = parser.createState();
146
+ let allSegments: Segments<typeof registry.definitions> = [];
147
+
148
+ // Process each chunk as it arrives
149
+ function onChunk(chunk: string) {
150
+ const result = parser.parseChunk(chunk, state);
151
+
152
+ // Update state for next chunk (immutable pattern)
153
+ state = result.state;
154
+
155
+ // Append complete segments
156
+ allSegments = [...allSegments, ...result.segments];
157
+
158
+ // Check if currently buffering a tag
159
+ if (result.isBuffering && result.bufferingTag) {
160
+ // Show loading placeholder for the buffering tag type
161
+ showPlaceholder(result.bufferingTag);
162
+ }
163
+ }
164
+
165
+ // When stream ends, finalize to flush any remaining content
166
+ function onStreamEnd() {
167
+ const finalSegments = parser.finalize(state);
168
+ allSegments = [...allSegments, ...finalSegments];
169
+ }
170
+ ```
171
+
172
+ ### React Renderer
173
+
174
+ ```tsx
175
+ import { createCatalog, XmlRender, XmlRenderProvider } from '@khairold/xml-render/react';
176
+ ```
177
+
178
+ #### `createCatalog(registry, options)`
179
+
180
+ Creates a component catalog mapping tag types to renderers.
181
+
182
+ ```tsx
183
+ const catalog = createCatalog(registry, {
184
+ components: {
185
+ // Each component receives { segment, index } props
186
+ callout: ({ segment }) => (
187
+ <div className={`callout-${segment.attributes?.type}`}>
188
+ {segment.content}
189
+ </div>
190
+ ),
191
+ chart: ({ segment }) => (
192
+ <ChartComponent
193
+ type={segment.attributes?.type}
194
+ title={segment.attributes?.title}
195
+ data={JSON.parse(segment.content)}
196
+ />
197
+ ),
198
+ },
199
+ // Optional: custom text renderer (default: <span>{content}</span>)
200
+ textRenderer: ({ segment }) => <MarkdownText>{segment.content}</MarkdownText>,
201
+ });
202
+ ```
203
+
204
+ #### `<XmlRender>` Component
205
+
206
+ Renders an array of segments using the catalog.
207
+
208
+ ```tsx
209
+ // Option 1: Pass catalog directly
210
+ <XmlRender segments={segments} catalog={catalog} />
211
+
212
+ // Option 2: Use context provider
213
+ <XmlRenderProvider catalog={catalog}>
214
+ <XmlRender segments={segments} />
215
+ </XmlRenderProvider>
216
+
217
+ // With custom fallback for unknown segment types
218
+ <XmlRender
219
+ segments={segments}
220
+ catalog={catalog}
221
+ fallback={(segment, index) => (
222
+ <div>Unknown: {segment.type}</div>
223
+ )}
224
+ />
225
+
226
+ // With custom error fallback
227
+ <XmlRender
228
+ segments={segments}
229
+ catalog={catalog}
230
+ errorFallback={(error, segmentType) => (
231
+ <div>Error rendering {segmentType}: {error.message}</div>
232
+ )}
233
+ />
234
+ ```
235
+
236
+ ### React Native Renderer
237
+
238
+ ```tsx
239
+ import { createCatalog, XmlRender, XmlRenderProvider } from '@khairold/xml-render/react-native';
240
+ ```
241
+
242
+ The React Native API is identical to React. The only differences are:
243
+ - Default text renderer uses `<Text>` instead of `<span>`
244
+ - Container uses `<View>` instead of `<div>`
245
+ - Error boundary styles use React Native `StyleSheet`
246
+
247
+ ### Type Utilities
248
+
249
+ ```ts
250
+ import {
251
+ type ParsedSegment,
252
+ type Segments,
253
+ type SegmentType,
254
+ type ParserState,
255
+ type InferAttributes,
256
+ isSegmentType,
257
+ } from '@khairold/xml-render';
258
+
259
+ // Get attribute type for a specific tag
260
+ type ChartAttrs = InferAttributes<typeof registry.definitions.chart>;
261
+ // { type: 'bar' | 'line' | 'pie'; title?: string }
262
+
263
+ // Type-safe segment type checking
264
+ const segment: ParsedSegment<typeof registry.definitions> = /* ... */;
265
+ if (isSegmentType(segment, 'chart', registry)) {
266
+ // segment.attributes is typed as ChartAttrs
267
+ console.log(segment.attributes.type);
268
+ }
269
+ ```
270
+
271
+ ## Example: Tag Definitions
272
+
273
+ ### Callout (notification box)
274
+
275
+ ```ts
276
+ const calloutDef = {
277
+ callout: {
278
+ schema: z.object({
279
+ type: z.enum(['info', 'warning', 'error']).default('info'),
280
+ }),
281
+ hasContent: true,
282
+ },
283
+ };
284
+ // Usage: <callout type="warning">Watch out!</callout>
285
+ ```
286
+
287
+ ### Table (markdown table)
288
+
289
+ ```ts
290
+ const tableDef = {
291
+ table: {
292
+ schema: z.object({}),
293
+ hasContent: true,
294
+ },
295
+ };
296
+ // Usage: <table>| Col1 | Col2 |\n|---|---|\n| A | B |</table>
297
+ ```
298
+
299
+ ### Chart (data visualization)
300
+
301
+ ```ts
302
+ const chartDef = {
303
+ chart: {
304
+ schema: z.object({
305
+ type: z.enum(['bar', 'line', 'pie']).default('bar'),
306
+ title: z.string().optional(),
307
+ }),
308
+ hasContent: true,
309
+ },
310
+ };
311
+ // Usage: <chart type="pie" title="Sales">{"labels":["Q1","Q2"],"data":[100,200]}</chart>
312
+ ```
313
+
314
+ ### Image (self-closing)
315
+
316
+ ```ts
317
+ const imageDef = {
318
+ image: {
319
+ schema: z.object({
320
+ src: z.string(),
321
+ alt: z.string().optional(),
322
+ }),
323
+ selfClosing: true,
324
+ hasContent: false,
325
+ },
326
+ };
327
+ // Usage: <image src="photo.jpg" alt="A photo" />
328
+ ```
329
+
330
+ ## Platform-Specific Imports
331
+
332
+ ```ts
333
+ // Core (parser + registry) - platform agnostic
334
+ import { createRegistry, createParser } from '@khairold/xml-render';
335
+
336
+ // React (web)
337
+ import { createCatalog, XmlRender } from '@khairold/xml-render/react';
338
+
339
+ // React Native (mobile)
340
+ import { createCatalog, XmlRender } from '@khairold/xml-render/react-native';
341
+ ```
342
+
343
+ ## Parsing Behavior
344
+
345
+ - **Unknown tags** pass through as literal text (not parsed)
346
+ - **Malformed/unclosed tags** fall back to text segments
347
+ - **XML entities** are decoded: `&lt;` `&gt;` `&amp;` `&quot;`
348
+ - **Attribute parsing** supports both single and double quotes
349
+ - **Case insensitive** tag matching
350
+
351
+ ## Error Handling
352
+
353
+ Each segment is wrapped in an ErrorBoundary. If a component throws:
354
+ - **Development**: Shows error message with segment type
355
+ - **Production**: Renders a hidden/minimal fallback
356
+
357
+ ```tsx
358
+ // Custom error handling
359
+ <XmlRender
360
+ segments={segments}
361
+ catalog={catalog}
362
+ errorFallback={(error, segmentType) => (
363
+ <div className="render-error">
364
+ Failed to render {segmentType}
365
+ </div>
366
+ )}
367
+ />
368
+ ```
369
+
370
+ ## License
371
+
372
+ MIT
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @aura/xml-render - Core XML Parsing Library
3
+ *
4
+ * A type-safe XML-like tag parser and renderer framework.
5
+ * Supports both complete text parsing and streaming for real-time content.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { z } from 'zod';
10
+ * import { createRegistry, createParser } from '@aura/xml-render';
11
+ *
12
+ * // Define your tags with Zod schemas
13
+ * const registry = createRegistry({
14
+ * callout: {
15
+ * schema: z.object({ type: z.enum(['info', 'warning', 'error']) }),
16
+ * hasContent: true,
17
+ * },
18
+ * });
19
+ *
20
+ * // Create a parser and parse content
21
+ * const parser = createParser(registry);
22
+ * const segments = parser.parse('Hello <callout type="info">Important!</callout>');
23
+ * ```
24
+ *
25
+ * @packageDocumentation
26
+ */
27
+ export { createRegistry } from "./registry";
28
+ export { createParser } from "./parser";
29
+ export * from "./types";
30
+ export { isSegmentType } from "./types";
31
+ export type { TagDefinition, TagDefinitions, Registry, InferAttributes, SafeParseResult, } from "./registry";
32
+ export type { Parser, ParsedSegment, SegmentType, Segments, ParserState, StreamingParseResult, } from "./parser";
33
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAOH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAG5C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAOxC,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAOxC,YAAY,EACV,aAAa,EACb,cAAc,EACd,QAAQ,EACR,eAAe,EACf,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,MAAM,EACN,aAAa,EACb,WAAW,EACX,QAAQ,EACR,WAAW,EACX,oBAAoB,GACrB,MAAM,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @aura/xml-render - Core XML Parsing Library
3
+ *
4
+ * A type-safe XML-like tag parser and renderer framework.
5
+ * Supports both complete text parsing and streaming for real-time content.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { z } from 'zod';
10
+ * import { createRegistry, createParser } from '@aura/xml-render';
11
+ *
12
+ * // Define your tags with Zod schemas
13
+ * const registry = createRegistry({
14
+ * callout: {
15
+ * schema: z.object({ type: z.enum(['info', 'warning', 'error']) }),
16
+ * hasContent: true,
17
+ * },
18
+ * });
19
+ *
20
+ * // Create a parser and parse content
21
+ * const parser = createParser(registry);
22
+ * const segments = parser.parse('Hello <callout type="info">Important!</callout>');
23
+ * ```
24
+ *
25
+ * @packageDocumentation
26
+ */
27
+ // ============================================================================
28
+ // Core Functions
29
+ // ============================================================================
30
+ // Registry - Define your XML tags
31
+ export { createRegistry } from "./registry";
32
+ // Parser - Parse text into segments
33
+ export { createParser } from "./parser";
34
+ // ============================================================================
35
+ // Type Exports - Import from here for best DX
36
+ // ============================================================================
37
+ // Consolidated types file - preferred import location for types
38
+ export * from "./types";
39
+ // Re-export type guard helper
40
+ export { isSegmentType } from "./types";
41
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E,kCAAkC;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,oCAAoC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,+EAA+E;AAC/E,8CAA8C;AAC9C,+EAA+E;AAE/E,gEAAgE;AAChE,cAAc,SAAS,CAAC;AAExB,8BAA8B;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * XML Parser for xml-render
3
+ *
4
+ * Creates a registry-aware parser that converts text containing XML-like tags
5
+ * into typed segments. Supports complete text parsing and streaming.
6
+ */
7
+ import type { Registry, TagDefinitions, InferAttributes } from "./registry";
8
+ /**
9
+ * A parsed segment representing either plain text or a recognized tag
10
+ */
11
+ export interface ParsedSegment<TDefs extends TagDefinitions = TagDefinitions, TType extends keyof TDefs | "text" = keyof TDefs | "text"> {
12
+ /** The segment type: 'text' or a registered tag name */
13
+ type: TType;
14
+ /** The content inside the tag, or the text content for 'text' segments */
15
+ content: string;
16
+ /** Attributes parsed from the tag (undefined for 'text' segments) */
17
+ attributes?: TType extends keyof TDefs ? InferAttributes<TDefs[TType]> : undefined;
18
+ }
19
+ /**
20
+ * Union of all segment types for a given registry
21
+ */
22
+ export type SegmentType<TDefs extends TagDefinitions> = keyof TDefs | "text";
23
+ /**
24
+ * A segment array that can contain any valid segment for the registry
25
+ */
26
+ export type Segments<TDefs extends TagDefinitions> = Array<ParsedSegment<TDefs, keyof TDefs | "text">>;
27
+ /**
28
+ * Parser state for handling incomplete/streaming content
29
+ */
30
+ export interface ParserState {
31
+ /** Accumulated text buffer */
32
+ buffer: string;
33
+ /** Whether we're currently inside an unclosed component tag */
34
+ inComponent: boolean;
35
+ /** The tag name being processed, if any */
36
+ currentTag: string | null;
37
+ /** Attributes string for the current tag */
38
+ currentAttrs: string;
39
+ /** Index in buffer where current tag started */
40
+ tagStartIndex: number;
41
+ }
42
+ /**
43
+ * Result of parsing a streaming chunk
44
+ */
45
+ export interface StreamingParseResult<TDefs extends TagDefinitions> {
46
+ /** Segments that are complete and can be rendered */
47
+ segments: Segments<TDefs>;
48
+ /** Updated parser state for next chunk */
49
+ state: ParserState;
50
+ /** Whether we're currently buffering (waiting for more data) */
51
+ isBuffering: boolean;
52
+ /** The type of tag being buffered, if any */
53
+ bufferingTag: keyof TDefs | null;
54
+ }
55
+ /**
56
+ * Parser interface returned by createParser
57
+ */
58
+ export interface Parser<TDefs extends TagDefinitions> {
59
+ /**
60
+ * Parse a complete text string into segments.
61
+ * This is the main entry point for non-streaming use cases.
62
+ *
63
+ * @param text - The complete text to parse
64
+ * @returns Array of parsed segments in order
65
+ */
66
+ parse(text: string): Segments<TDefs>;
67
+ /**
68
+ * Create initial parser state for streaming parsing.
69
+ *
70
+ * @returns Fresh parser state
71
+ */
72
+ createState(): ParserState;
73
+ /**
74
+ * Parse a chunk of streaming text.
75
+ * Handles incomplete tags by buffering until complete.
76
+ *
77
+ * @param chunk - New text chunk to process
78
+ * @param state - Current parser state
79
+ * @returns Parse result with complete segments and updated state
80
+ */
81
+ parseChunk(chunk: string, state: ParserState): StreamingParseResult<TDefs>;
82
+ /**
83
+ * Finalize parsing, returning any remaining buffered content as text.
84
+ * Call this when streaming is complete.
85
+ *
86
+ * @param state - Current parser state
87
+ * @returns Final segments including any buffered content
88
+ */
89
+ finalize(state: ParserState): Segments<TDefs>;
90
+ /** The registry used by this parser */
91
+ readonly registry: Registry<TDefs>;
92
+ }
93
+ /**
94
+ * Create a parser instance bound to a registry.
95
+ *
96
+ * The parser recognizes tags defined in the registry and converts them
97
+ * into typed segments. Unknown tags are treated as literal text.
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * import { z } from 'zod';
102
+ * import { createRegistry, createParser } from '@aura/xml-render';
103
+ *
104
+ * const registry = createRegistry({
105
+ * callout: {
106
+ * schema: z.object({ type: z.enum(['info', 'warning', 'error']) }),
107
+ * hasContent: true,
108
+ * },
109
+ * image: {
110
+ * schema: z.object({ src: z.string(), alt: z.string().optional() }),
111
+ * selfClosing: true,
112
+ * },
113
+ * });
114
+ *
115
+ * const parser = createParser(registry);
116
+ *
117
+ * const segments = parser.parse('Hello <callout type="info">Important!</callout> World');
118
+ * // [
119
+ * // { type: 'text', content: 'Hello ' },
120
+ * // { type: 'callout', content: 'Important!', attributes: { type: 'info' } },
121
+ * // { type: 'text', content: ' World' },
122
+ * // ]
123
+ * ```
124
+ *
125
+ * @param registry - The tag registry to use for parsing
126
+ * @returns A parser instance
127
+ */
128
+ export declare function createParser<TDefs extends TagDefinitions>(registry: Registry<TDefs>): Parser<TDefs>;
129
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE5E;;GAEG;AACH,MAAM,WAAW,aAAa,CAC5B,KAAK,SAAS,cAAc,GAAG,cAAc,EAC7C,KAAK,SAAS,MAAM,KAAK,GAAG,MAAM,GAAG,MAAM,KAAK,GAAG,MAAM;IAEzD,wDAAwD;IACxD,IAAI,EAAE,KAAK,CAAC;IACZ,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,UAAU,CAAC,EAAE,KAAK,SAAS,MAAM,KAAK,GAClC,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAC7B,SAAS,CAAC;CACf;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,CAAC,KAAK,SAAS,cAAc,IAAI,MAAM,KAAK,GAAG,MAAM,CAAC;AAE7E;;GAEG;AACH,MAAM,MAAM,QAAQ,CAAC,KAAK,SAAS,cAAc,IAAI,KAAK,CACxD,aAAa,CAAC,KAAK,EAAE,MAAM,KAAK,GAAG,MAAM,CAAC,CAC3C,CAAC;AA8BF;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,WAAW,EAAE,OAAO,CAAC;IACrB,2CAA2C;IAC3C,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,4CAA4C;IAC5C,YAAY,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB,CAAC,KAAK,SAAS,cAAc;IAChE,qDAAqD;IACrD,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1B,0CAA0C;IAC1C,KAAK,EAAE,WAAW,CAAC;IACnB,gEAAgE;IAChE,WAAW,EAAE,OAAO,CAAC;IACrB,6CAA6C;IAC7C,YAAY,EAAE,MAAM,KAAK,GAAG,IAAI,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,MAAM,CAAC,KAAK,SAAS,cAAc;IAClD;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAErC;;;;OAIG;IACH,WAAW,IAAI,WAAW,CAAC;IAE3B;;;;;;;OAOG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAE3E;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE9C,uCAAuC;IACvC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;CACpC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,YAAY,CAAC,KAAK,SAAS,cAAc,EACvD,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,GACxB,MAAM,CAAC,KAAK,CAAC,CA+Tf"}