@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
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Create an immutable tag registry from tag definitions.
3
+ *
4
+ * The registry provides type-safe access to tag definitions and their
5
+ * Zod schemas for attribute validation.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { z } from 'zod';
10
+ * import { createRegistry } from '@aura/xml-render';
11
+ *
12
+ * const registry = createRegistry({
13
+ * chart: {
14
+ * schema: z.object({
15
+ * type: z.enum(['bar', 'line', 'pie']),
16
+ * title: z.string().optional(),
17
+ * }),
18
+ * hasContent: true,
19
+ * },
20
+ * image: {
21
+ * schema: z.object({
22
+ * src: z.string(),
23
+ * alt: z.string().optional(),
24
+ * }),
25
+ * selfClosing: true,
26
+ * hasContent: false,
27
+ * },
28
+ * });
29
+ *
30
+ * // TypeScript knows the exact tag names
31
+ * registry.tagNames; // ['chart', 'image']
32
+ *
33
+ * // Attribute types are inferred from Zod schemas
34
+ * type ChartAttrs = InferAttributes<typeof registry.definitions.chart>;
35
+ * // { type: 'bar' | 'line' | 'pie'; title?: string }
36
+ * ```
37
+ *
38
+ * @param definitions - Record of tag names to their definitions
39
+ * @returns An immutable registry instance
40
+ */
41
+ export function createRegistry(definitions) {
42
+ // Freeze the definitions to make the registry immutable
43
+ const frozenDefs = Object.freeze(Object.fromEntries(Object.entries(definitions).map(([name, def]) => [
44
+ name,
45
+ Object.freeze({
46
+ ...def,
47
+ hasContent: def.hasContent ?? true,
48
+ selfClosing: def.selfClosing ?? false,
49
+ }),
50
+ ])));
51
+ const tagNames = Object.freeze(Object.keys(frozenDefs));
52
+ const tagNameSet = new Set(tagNames);
53
+ const registry = {
54
+ tagNames,
55
+ definitions: frozenDefs,
56
+ getTag(name) {
57
+ return frozenDefs[name];
58
+ },
59
+ hasTag(name) {
60
+ return tagNameSet.has(name);
61
+ },
62
+ getSchema(name) {
63
+ return frozenDefs[name]?.schema;
64
+ },
65
+ validateAttributes(name, attributes) {
66
+ const schema = frozenDefs[name]?.schema;
67
+ if (!schema) {
68
+ return {
69
+ success: false,
70
+ error: new Error(`Unknown tag: ${String(name)}`),
71
+ };
72
+ }
73
+ // Use Zod's safeParse and normalize the result
74
+ const result = schema.safeParse(attributes);
75
+ if (result.success) {
76
+ return {
77
+ success: true,
78
+ data: result.data,
79
+ };
80
+ }
81
+ return { success: false, error: result.error };
82
+ },
83
+ isSelfClosing(name) {
84
+ return frozenDefs[name]?.selfClosing ?? false;
85
+ },
86
+ hasContent(name) {
87
+ return frozenDefs[name]?.hasContent ?? true;
88
+ },
89
+ };
90
+ // Freeze the registry itself
91
+ return Object.freeze(registry);
92
+ }
93
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAqEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,UAAU,cAAc,CAC5B,WAAkB;IAElB,wDAAwD;IACxD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAC9B,MAAM,CAAC,WAAW,CAChB,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC;QAC/C,IAAI;QACJ,MAAM,CAAC,MAAM,CAAC;YACZ,GAAG,GAAG;YACN,UAAU,EAAE,GAAG,CAAC,UAAU,IAAI,IAAI;YAClC,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,KAAK;SACtC,CAAC;KACH,CAAC,CACH,CACiB,CAAC;IAErB,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAErD,CAAC;IAEF,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IAErC,MAAM,QAAQ,GAAoB;QAChC,QAAQ;QACR,WAAW,EAAE,UAAU;QAEvB,MAAM,CAAwB,IAAO;YACnC,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;QAED,MAAM,CAAC,IAAY;YACjB,OAAO,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAED,SAAS,CAAwB,IAAO;YACtC,OAAO,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAClC,CAAC;QAED,kBAAkB,CAChB,IAAO,EACP,UAAmB;YAEnB,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;YACxC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,IAAI,KAAK,CAAC,gBAAgB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;iBACjD,CAAC;YACJ,CAAC;YACD,+CAA+C;YAC/C,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;YAC5C,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,IAAI,EAAE,MAAM,CAAC,IAAiC;iBAC/C,CAAC;YACJ,CAAC;YACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;QACjD,CAAC;QAED,aAAa,CAAwB,IAAO;YAC1C,OAAO,UAAU,CAAC,IAAI,CAAC,EAAE,WAAW,IAAI,KAAK,CAAC;QAChD,CAAC;QAED,UAAU,CAAwB,IAAO;YACvC,OAAO,UAAU,CAAC,IAAI,CAAC,EAAE,UAAU,IAAI,IAAI,CAAC;QAC9C,CAAC;KACF,CAAC;IAEF,6BAA6B;IAC7B,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,436 @@
1
+ /**
2
+ * @aura/xml-render - TypeScript Type Definitions
3
+ *
4
+ * This file consolidates all public TypeScript types for the xml-render library.
5
+ * Import types from here for the best developer experience and autocomplete support.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ import type { ZodType, infer as ZodInfer } from "zod";
10
+ import type { ComponentType, ReactNode } from "react";
11
+ /**
12
+ * Definition for a single XML tag in the registry.
13
+ *
14
+ * @typeParam TSchema - The Zod schema type for attribute validation
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import { z } from 'zod';
19
+ * import type { TagDefinition } from '@aura/xml-render';
20
+ *
21
+ * const chartDefinition: TagDefinition<typeof chartSchema> = {
22
+ * schema: z.object({ type: z.enum(['bar', 'line', 'pie']) }),
23
+ * hasContent: true,
24
+ * selfClosing: false,
25
+ * };
26
+ * ```
27
+ */
28
+ export interface TagDefinition<TSchema extends ZodType = ZodType> {
29
+ /** Zod schema for validating and typing tag attributes */
30
+ schema: TSchema;
31
+ /** Whether the tag contains inner content (default: true) */
32
+ hasContent?: boolean;
33
+ /** Whether the tag is self-closing like `<image />` (default: false) */
34
+ selfClosing?: boolean;
35
+ }
36
+ /**
37
+ * Input type for createRegistry - a record of tag names to their definitions.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * import type { TagDefinitions } from '@aura/xml-render';
42
+ *
43
+ * const definitions: TagDefinitions = {
44
+ * chart: { schema: chartSchema, hasContent: true },
45
+ * image: { schema: imageSchema, selfClosing: true },
46
+ * };
47
+ * ```
48
+ */
49
+ export type TagDefinitions = Record<string, TagDefinition>;
50
+ /**
51
+ * Infer the TypeScript type of tag attributes from a TagDefinition's Zod schema.
52
+ *
53
+ * This is a key utility type that allows you to extract the attribute types
54
+ * that TypeScript will use for a given tag definition.
55
+ *
56
+ * @typeParam T - The TagDefinition to infer attributes from
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * import { z } from 'zod';
61
+ * import type { TagDefinition, InferAttributes } from '@aura/xml-render';
62
+ *
63
+ * const chartDef = {
64
+ * schema: z.object({
65
+ * type: z.enum(['bar', 'line', 'pie']),
66
+ * title: z.string().optional(),
67
+ * }),
68
+ * } satisfies TagDefinition;
69
+ *
70
+ * // ChartAttrs = { type: 'bar' | 'line' | 'pie'; title?: string }
71
+ * type ChartAttrs = InferAttributes<typeof chartDef>;
72
+ * ```
73
+ */
74
+ export type InferAttributes<T extends TagDefinition> = ZodInfer<T["schema"]>;
75
+ /**
76
+ * Safe parse result type for attribute validation.
77
+ *
78
+ * This is a normalized result type that doesn't depend on specific Zod versions,
79
+ * ensuring compatibility across Zod v3 and v4.
80
+ *
81
+ * @typeParam T - The expected data type on success
82
+ */
83
+ export type SafeParseResult<T> = {
84
+ success: true;
85
+ data: T;
86
+ } | {
87
+ success: false;
88
+ error: unknown;
89
+ };
90
+ /**
91
+ * The immutable registry interface returned by createRegistry.
92
+ *
93
+ * The registry provides type-safe access to tag definitions and their
94
+ * Zod schemas for attribute validation. All methods preserve type inference.
95
+ *
96
+ * @typeParam TDefs - The tag definitions record type
97
+ */
98
+ export interface Registry<TDefs extends TagDefinitions> {
99
+ /** Get all registered tag names as a readonly array */
100
+ readonly tagNames: ReadonlyArray<keyof TDefs & string>;
101
+ /** Get the definition for a specific tag */
102
+ getTag<K extends keyof TDefs>(name: K): Readonly<TDefs[K]> | undefined;
103
+ /** Check if a tag name is registered (acts as type guard) */
104
+ hasTag(name: string): name is keyof TDefs & string;
105
+ /** Get the Zod schema for a tag's attributes */
106
+ getSchema<K extends keyof TDefs>(name: K): TDefs[K]["schema"] | undefined;
107
+ /** Validate attributes for a tag using its Zod schema */
108
+ validateAttributes<K extends keyof TDefs>(name: K, attributes: unknown): SafeParseResult<InferAttributes<TDefs[K]>>;
109
+ /** Check if a tag is self-closing (e.g., `<image />`) */
110
+ isSelfClosing<K extends keyof TDefs>(name: K): boolean;
111
+ /** Check if a tag has content (can contain inner text/elements) */
112
+ hasContent<K extends keyof TDefs>(name: K): boolean;
113
+ /** The raw definitions (frozen for immutability) */
114
+ readonly definitions: Readonly<TDefs>;
115
+ }
116
+ /**
117
+ * A parsed segment representing either plain text or a recognized tag.
118
+ *
119
+ * This is the core output type from the parser. Each segment contains:
120
+ * - `type`: Either 'text' for plain content or a registered tag name
121
+ * - `content`: The inner content of the tag or the text content
122
+ * - `attributes`: Typed attributes (only for tag segments, undefined for text)
123
+ *
124
+ * @typeParam TDefs - The tag definitions from the registry
125
+ * @typeParam TType - The specific segment type (defaults to union of all types)
126
+ *
127
+ * @example
128
+ * ```ts
129
+ * // After parsing "<callout type="info">Hello</callout>"
130
+ * const segment: ParsedSegment<MyRegistry, 'callout'> = {
131
+ * type: 'callout',
132
+ * content: 'Hello',
133
+ * attributes: { type: 'info' }, // TypeScript knows the exact shape!
134
+ * };
135
+ * ```
136
+ */
137
+ export interface ParsedSegment<TDefs extends TagDefinitions = TagDefinitions, TType extends keyof TDefs | "text" = keyof TDefs | "text"> {
138
+ /** The segment type: 'text' or a registered tag name */
139
+ type: TType;
140
+ /** The content inside the tag, or the text content for 'text' segments */
141
+ content: string;
142
+ /** Attributes parsed from the tag (undefined for 'text' segments) */
143
+ attributes?: TType extends keyof TDefs ? InferAttributes<TDefs[TType]> : undefined;
144
+ }
145
+ /**
146
+ * Union type of all valid segment types for a given registry.
147
+ *
148
+ * This includes all registered tag names plus the 'text' type for plain content.
149
+ *
150
+ * @typeParam TDefs - The tag definitions from the registry
151
+ *
152
+ * @example
153
+ * ```ts
154
+ * type MyTypes = SegmentType<typeof registry.definitions>;
155
+ * // 'text' | 'callout' | 'chart' | 'image' | ...
156
+ * ```
157
+ */
158
+ export type SegmentType<TDefs extends TagDefinitions> = keyof TDefs | "text";
159
+ /**
160
+ * An array of parsed segments that can contain any valid segment type.
161
+ *
162
+ * This is the return type of `parser.parse()` and represents the complete
163
+ * parsed output of an XML-containing text string.
164
+ *
165
+ * @typeParam TDefs - The tag definitions from the registry
166
+ */
167
+ export type Segments<TDefs extends TagDefinitions> = Array<ParsedSegment<TDefs, keyof TDefs | "text">>;
168
+ /**
169
+ * Parser state for handling incomplete/streaming content.
170
+ *
171
+ * This state object is passed between `parseChunk` calls to track:
172
+ * - Buffered content that might be part of an incomplete tag
173
+ * - Whether we're currently inside an opened component tag
174
+ * - The tag being processed and its attributes
175
+ *
176
+ * Create initial state with `parser.createState()`.
177
+ */
178
+ export interface ParserState {
179
+ /** Accumulated text buffer */
180
+ buffer: string;
181
+ /** Whether we're currently inside an unclosed component tag */
182
+ inComponent: boolean;
183
+ /** The tag name being processed, if any */
184
+ currentTag: string | null;
185
+ /** Attributes string for the current tag */
186
+ currentAttrs: string;
187
+ /** Index in buffer where current tag started */
188
+ tagStartIndex: number;
189
+ }
190
+ /**
191
+ * Result of parsing a streaming chunk.
192
+ *
193
+ * Contains the segments that are complete and ready to render,
194
+ * plus the updated state for the next chunk.
195
+ *
196
+ * @typeParam TDefs - The tag definitions from the registry
197
+ */
198
+ export interface StreamingParseResult<TDefs extends TagDefinitions> {
199
+ /** Segments that are complete and can be rendered */
200
+ segments: Segments<TDefs>;
201
+ /** Updated parser state for next chunk */
202
+ state: ParserState;
203
+ /** Whether we're currently buffering (waiting for more data) */
204
+ isBuffering: boolean;
205
+ /** The type of tag being buffered, if any (useful for showing loading states) */
206
+ bufferingTag: keyof TDefs | null;
207
+ }
208
+ /**
209
+ * The parser interface returned by createParser.
210
+ *
211
+ * Provides methods for both complete text parsing and streaming parsing.
212
+ *
213
+ * @typeParam TDefs - The tag definitions from the registry
214
+ */
215
+ export interface Parser<TDefs extends TagDefinitions> {
216
+ /**
217
+ * Parse a complete text string into segments.
218
+ * This is the main entry point for non-streaming use cases.
219
+ *
220
+ * @param text - The complete text to parse
221
+ * @returns Array of parsed segments in order
222
+ */
223
+ parse(text: string): Segments<TDefs>;
224
+ /**
225
+ * Create initial parser state for streaming parsing.
226
+ *
227
+ * @returns Fresh parser state
228
+ */
229
+ createState(): ParserState;
230
+ /**
231
+ * Parse a chunk of streaming text.
232
+ * Handles incomplete tags by buffering until complete.
233
+ *
234
+ * @param chunk - New text chunk to process
235
+ * @param state - Current parser state
236
+ * @returns Parse result with complete segments and updated state
237
+ */
238
+ parseChunk(chunk: string, state: ParserState): StreamingParseResult<TDefs>;
239
+ /**
240
+ * Finalize parsing, returning any remaining buffered content as text.
241
+ * Call this when streaming is complete.
242
+ *
243
+ * @param state - Current parser state
244
+ * @returns Final segments including any buffered content
245
+ */
246
+ finalize(state: ParserState): Segments<TDefs>;
247
+ /** The registry used by this parser */
248
+ readonly registry: Registry<TDefs>;
249
+ }
250
+ /**
251
+ * Props passed to segment renderer components.
252
+ *
253
+ * Your custom renderer components receive these props to render each segment.
254
+ *
255
+ * @typeParam TDefs - The tag definitions from the registry
256
+ * @typeParam TType - The specific segment type this component renders
257
+ *
258
+ * @example
259
+ * ```tsx
260
+ * import type { SegmentProps } from '@aura/xml-render/react';
261
+ *
262
+ * function CalloutRenderer({ segment, index }: SegmentProps<MyRegistry, 'callout'>) {
263
+ * // segment.attributes is fully typed: { type: 'info' | 'warning' | 'error' }
264
+ * return <div className={`callout-${segment.attributes?.type}`}>{segment.content}</div>;
265
+ * }
266
+ * ```
267
+ */
268
+ export interface SegmentProps<TDefs extends TagDefinitions, TType extends keyof TDefs | "text"> {
269
+ /** The segment being rendered */
270
+ segment: ParsedSegment<TDefs, TType>;
271
+ /** Index of this segment in the segments array */
272
+ index: number;
273
+ }
274
+ /**
275
+ * Props for the text segment renderer.
276
+ *
277
+ * @typeParam TDefs - The tag definitions from the registry
278
+ */
279
+ export interface TextSegmentProps<TDefs extends TagDefinitions> {
280
+ /** The text segment to render */
281
+ segment: ParsedSegment<TDefs, "text">;
282
+ /** Index of this segment in the segments array */
283
+ index: number;
284
+ }
285
+ /**
286
+ * A React component that renders a specific segment type.
287
+ *
288
+ * @typeParam TDefs - The tag definitions from the registry
289
+ * @typeParam TType - The segment type this renderer handles
290
+ */
291
+ export type SegmentRenderer<TDefs extends TagDefinitions, TType extends keyof TDefs> = ComponentType<SegmentProps<TDefs, TType>>;
292
+ /**
293
+ * A React component that renders text segments.
294
+ *
295
+ * @typeParam TDefs - The tag definitions from the registry
296
+ */
297
+ export type TextRenderer<TDefs extends TagDefinitions> = ComponentType<TextSegmentProps<TDefs>>;
298
+ /**
299
+ * Component definitions for the catalog - maps tag names to renderer components.
300
+ *
301
+ * @typeParam TDefs - The tag definitions from the registry
302
+ */
303
+ export type CatalogComponents<TDefs extends TagDefinitions> = {
304
+ [K in keyof TDefs]: SegmentRenderer<TDefs, K>;
305
+ };
306
+ /**
307
+ * Options for creating a component catalog.
308
+ *
309
+ * @typeParam TDefs - The tag definitions from the registry
310
+ */
311
+ export interface CatalogOptions<TDefs extends TagDefinitions> {
312
+ /** Component renderers for each tag type (can be partial) */
313
+ components: Partial<CatalogComponents<TDefs>>;
314
+ /** Optional text segment renderer (default renders plain text) */
315
+ textRenderer?: TextRenderer<TDefs>;
316
+ }
317
+ /**
318
+ * The catalog interface returned by createCatalog.
319
+ *
320
+ * Maps segment types to their renderer components with full type safety.
321
+ *
322
+ * @typeParam TDefs - The tag definitions from the registry
323
+ */
324
+ export interface Catalog<TDefs extends TagDefinitions> {
325
+ /** Get the renderer component for a specific segment type */
326
+ getRenderer<K extends keyof TDefs>(type: K): SegmentRenderer<TDefs, K> | undefined;
327
+ /** Get the text segment renderer */
328
+ getTextRenderer(): TextRenderer<TDefs> | undefined;
329
+ /** Check if a renderer exists for a segment type */
330
+ hasRenderer(type: keyof TDefs | "text"): boolean;
331
+ /** The registry this catalog is based on */
332
+ readonly registry: Registry<TDefs>;
333
+ /** All registered component renderers */
334
+ readonly components: Readonly<Partial<CatalogComponents<TDefs>>>;
335
+ }
336
+ /**
337
+ * Props for the XmlRenderProvider component.
338
+ *
339
+ * @typeParam TDefs - The tag definitions from the registry
340
+ */
341
+ export interface XmlRenderProviderProps<TDefs extends TagDefinitions> {
342
+ /** The component catalog to provide to the tree */
343
+ catalog: Catalog<TDefs>;
344
+ /** Child components that can use XmlRender */
345
+ children: ReactNode;
346
+ }
347
+ /**
348
+ * Props for the XmlRender component.
349
+ *
350
+ * @typeParam TDefs - The tag definitions from the registry
351
+ */
352
+ export interface XmlRenderProps<TDefs extends TagDefinitions> {
353
+ /** Array of parsed segments to render */
354
+ segments: Segments<TDefs>;
355
+ /** Optional fallback renderer for unknown segment types */
356
+ fallback?: (segment: ParsedSegment<TDefs>, index: number) => ReactNode;
357
+ /** Optional catalog override (uses context catalog if not provided) */
358
+ catalog?: Catalog<TDefs>;
359
+ /** Optional custom error fallback renderer */
360
+ errorFallback?: (error: Error, segmentType: string) => ReactNode;
361
+ }
362
+ /**
363
+ * Props for the ErrorBoundary component.
364
+ */
365
+ export interface ErrorBoundaryProps {
366
+ /** The child components to render */
367
+ children: ReactNode;
368
+ /** The segment type being rendered (for error messages) */
369
+ segmentType: string;
370
+ /** Optional custom fallback renderer for errors */
371
+ fallback?: (error: Error, segmentType: string) => ReactNode;
372
+ }
373
+ /**
374
+ * Extract the tag definitions type from a Registry instance.
375
+ *
376
+ * Useful when you have a registry and need to reference its definitions type.
377
+ *
378
+ * @typeParam R - The Registry type
379
+ *
380
+ * @example
381
+ * ```ts
382
+ * const registry = createRegistry({ ... });
383
+ * type MyDefs = ExtractRegistryDefs<typeof registry>;
384
+ * ```
385
+ */
386
+ export type ExtractRegistryDefs<R> = R extends Registry<infer TDefs> ? TDefs : never;
387
+ /**
388
+ * Extract the parser's tag definitions type from a Parser instance.
389
+ *
390
+ * @typeParam P - The Parser type
391
+ */
392
+ export type ExtractParserDefs<P> = P extends Parser<infer TDefs> ? TDefs : never;
393
+ /**
394
+ * Extract the catalog's tag definitions type from a Catalog instance.
395
+ *
396
+ * @typeParam C - The Catalog type
397
+ */
398
+ export type ExtractCatalogDefs<C> = C extends Catalog<infer TDefs> ? TDefs : never;
399
+ /**
400
+ * Get the attribute type for a specific tag from a registry's definitions.
401
+ *
402
+ * @typeParam TDefs - The tag definitions type
403
+ * @typeParam K - The tag name
404
+ *
405
+ * @example
406
+ * ```ts
407
+ * type ChartAttrs = TagAttributes<MyDefs, 'chart'>;
408
+ * // { type: 'bar' | 'line' | 'pie'; title?: string }
409
+ * ```
410
+ */
411
+ export type TagAttributes<TDefs extends TagDefinitions, K extends keyof TDefs> = InferAttributes<TDefs[K]>;
412
+ /**
413
+ * Get a typed ParsedSegment for a specific tag from a registry.
414
+ *
415
+ * @typeParam TDefs - The tag definitions type
416
+ * @typeParam K - The tag name
417
+ */
418
+ export type TypedSegment<TDefs extends TagDefinitions, K extends keyof TDefs | "text"> = ParsedSegment<TDefs, K>;
419
+ /**
420
+ * Type guard helper to check if a segment is of a specific type.
421
+ *
422
+ * @param segment - The segment to check
423
+ * @param type - The type to check for
424
+ * @returns Type predicate indicating if segment is of the specified type
425
+ *
426
+ * @example
427
+ * ```ts
428
+ * const segment: ParsedSegment<MyDefs> = ...;
429
+ * if (isSegmentType(segment, 'chart')) {
430
+ * // TypeScript now knows segment.attributes has chart's attribute type
431
+ * console.log(segment.attributes?.type); // 'bar' | 'line' | 'pie'
432
+ * }
433
+ * ```
434
+ */
435
+ export declare function isSegmentType<TDefs extends TagDefinitions, K extends keyof TDefs | "text">(segment: ParsedSegment<TDefs>, type: K): segment is ParsedSegment<TDefs, K>;
436
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @aura/xml-render - TypeScript Type Definitions
3
+ *
4
+ * This file consolidates all public TypeScript types for the xml-render library.
5
+ * Import types from here for the best developer experience and autocomplete support.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ /**
10
+ * Type guard helper to check if a segment is of a specific type.
11
+ *
12
+ * @param segment - The segment to check
13
+ * @param type - The type to check for
14
+ * @returns Type predicate indicating if segment is of the specified type
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * const segment: ParsedSegment<MyDefs> = ...;
19
+ * if (isSegmentType(segment, 'chart')) {
20
+ * // TypeScript now knows segment.attributes has chart's attribute type
21
+ * console.log(segment.attributes?.type); // 'bar' | 'line' | 'pie'
22
+ * }
23
+ * ```
24
+ */
25
+ export function isSegmentType(segment, type) {
26
+ return segment.type === type;
27
+ }
28
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAkfH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,aAAa,CAI3B,OAA6B,EAC7B,IAAO;IAEP,OAAO,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC;AAC/B,CAAC"}
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@khairold/xml-render",
3
+ "version": "0.1.0",
4
+ "description": "A type-safe XML-like tag parser and renderer framework for React and React Native",
5
+ "keywords": [
6
+ "xml",
7
+ "parser",
8
+ "react",
9
+ "react-native",
10
+ "streaming",
11
+ "llm",
12
+ "ai",
13
+ "render",
14
+ "zod",
15
+ "typescript"
16
+ ],
17
+ "author": "Khairul Kamarudin",
18
+ "license": "MIT",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/khairold/aura.git",
22
+ "directory": "packages/xml-render"
23
+ },
24
+ "main": "./dist/index.js",
25
+ "types": "./dist/index.d.ts",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "default": "./dist/index.js"
30
+ },
31
+ "./react": {
32
+ "types": "./dist/react/index.d.ts",
33
+ "default": "./dist/react/index.js"
34
+ },
35
+ "./react-native": {
36
+ "types": "./dist/react-native/index.d.ts",
37
+ "default": "./dist/react-native/index.js"
38
+ }
39
+ },
40
+ "files": [
41
+ "dist",
42
+ "README.md"
43
+ ],
44
+ "scripts": {
45
+ "build": "tsc -p tsconfig.build.json"
46
+ },
47
+ "peerDependencies": {
48
+ "react": ">=18.0.0",
49
+ "react-native": ">=0.70.0",
50
+ "zod": ">=3.0.0"
51
+ },
52
+ "peerDependenciesMeta": {
53
+ "react": {
54
+ "optional": true
55
+ },
56
+ "react-native": {
57
+ "optional": true
58
+ }
59
+ }
60
+ }