jsx-object 0.0.0-stage → 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Guilherme Chaguri
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,307 @@
1
- # Temporary Holding Version
1
+ # jsx-object
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ [![npm version](https://img.shields.io/npm/v/jsx-object)](https://www.npmjs.com/package/jsx-object)
4
+ [![bundle size](https://img.shields.io/bundlephobia/minzip/jsx-object)](https://bundlephobia.com/package/jsx-object)
5
+ [![license](https://img.shields.io/npm/l/jsx-object)](./LICENSE)
6
+
7
+ A tiny, dependency-free JSX runtime that turns JSX into plain JavaScript objects.
8
+
9
+ ```tsx
10
+ // Write React-like components that return an object
11
+ const Post = (props: PostProps) => {
12
+ return { type: 'post', title: props.title };
13
+ }
14
+
15
+ // Use JSX to build the object
16
+ console.log(<Post title="Hello World!" />)
17
+ // { type: 'post', title: 'Hello World!' }
18
+ ```
19
+
20
+ There is no virtual DOM, no rendering step and no reconciliation: a JSX expression evaluates directly to whatever your components return.
21
+
22
+ - [Why?](#why)
23
+ - [Getting Started](#getting-started)
24
+ - [Examples](#examples)
25
+ - [TypeScript](#typescript)
26
+ - [Behavior Notes](#behavior-notes)
27
+ - [Compatibility](#compatibility)
28
+ - [Contributing](#contributing)
29
+
30
+ ## Why?
31
+
32
+ JSX is a great syntax for describing trees, and trees aren't only HTML. Use jsx-object when you want to build structured data with composable components, for example:
33
+
34
+ - **Server-driven UI**: build the JSON payloads your mobile or web clients render.
35
+ - **CMS and JSON templates**: assemble documents from reusable, typed pieces.
36
+ - **Configuration DSLs**: describe pipelines, forms or workflows declaratively.
37
+
38
+ Compared to similar tools:
39
+
40
+ - **React** renders elements into a UI. jsx-object has no rendering step: the result *is* the data.
41
+ - **[Kita Html](https://html.kitajs.org/)** turns JSX into HTML strings. jsx-object turns JSX into objects.
42
+
43
+ ## Getting Started
44
+
45
+ First, install the library:
46
+
47
+ ```shell
48
+ npm install jsx-object
49
+ ```
50
+
51
+ Then add the following JSX configuration to your `tsconfig.json`:
52
+
53
+ ```json
54
+ {
55
+ "compilerOptions": {
56
+ "jsx": "react-jsx",
57
+ "jsxImportSource": "jsx-object"
58
+ }
59
+ }
60
+ ```
61
+
62
+ ### Other build tools
63
+
64
+ Tools that read `tsconfig.json`, such as Vite, esbuild, tsx and Bun, pick this up automatically. Otherwise, configure the automatic JSX runtime with `jsx-object` as the import source:
65
+
66
+ <details>
67
+ <summary>esbuild</summary>
68
+
69
+ ```shell
70
+ esbuild app.tsx --jsx=automatic --jsx-import-source=jsx-object
71
+ ```
72
+
73
+ </details>
74
+
75
+ <details>
76
+ <summary>Babel</summary>
77
+
78
+ ```json
79
+ {
80
+ "plugins": [
81
+ ["@babel/plugin-transform-react-jsx", { "runtime": "automatic", "importSource": "jsx-object" }]
82
+ ]
83
+ }
84
+ ```
85
+
86
+ </details>
87
+
88
+ <details>
89
+ <summary>SWC</summary>
90
+
91
+ ```json
92
+ {
93
+ "jsc": {
94
+ "transform": {
95
+ "react": { "runtime": "automatic", "importSource": "jsx-object" }
96
+ }
97
+ }
98
+ }
99
+ ```
100
+
101
+ </details>
102
+
103
+ To use jsx-object in only some files, add this comment to the top of each file instead:
104
+
105
+ ```tsx
106
+ /** @jsxImportSource jsx-object */
107
+ ```
108
+
109
+ > [!NOTE]
110
+ > jsx-object declares a global `JSX` namespace, so it can't share a TypeScript project with other libraries that also declare one, such as `@types/react` 18.
111
+
112
+ ## Examples
113
+
114
+ ### Components
115
+
116
+ Compose any number of components together.
117
+
118
+ ```tsx
119
+ const Paragraph = (props: ParagraphProps) => {
120
+ return { type: 'paragraph', content: props.children, variant: props.variant };
121
+ }
122
+
123
+ const Card = (props: CardProps) => {
124
+ return { type: 'card', paragraphs: props.children };
125
+ }
126
+
127
+ const Post = (props: PostProps) => {
128
+ return (
129
+ <Card>
130
+ <Paragraph variant="h1">{props.title}</Paragraph>
131
+ <Paragraph>{props.description}</Paragraph>
132
+ <Paragraph>Share</Paragraph>
133
+ </Card>
134
+ );
135
+ }
136
+
137
+ console.log(<Post title="Hello World!" description="Lorem Ipsum" />);
138
+ // {
139
+ // type: 'card',
140
+ // paragraphs: [
141
+ // { type: 'paragraph', content: 'Hello World!', variant: 'h1' },
142
+ // { type: 'paragraph', content: 'Lorem Ipsum', variant: undefined },
143
+ // { type: 'paragraph', content: 'Share', variant: undefined },
144
+ // ]
145
+ // }
146
+ ```
147
+
148
+ ### Async Components
149
+
150
+ Components can be async. If any component in the tree is async, the whole result becomes a Promise.
151
+
152
+ ```tsx
153
+ const Product = async (props: { id: number }) => {
154
+ const product = await fetchProduct(props.id);
155
+
156
+ return <Paragraph>{product.name}</Paragraph>;
157
+ };
158
+
159
+ // The await is necessary here
160
+ console.log(await <Product id={32} />)
161
+ ```
162
+
163
+ Async siblings are resolved in parallel, and the result keeps their original order.
164
+
165
+ Mapped lists of async components are awaited too, wherever they appear among the children:
166
+
167
+ ```tsx
168
+ <List>
169
+ <Paragraph>Products</Paragraph>
170
+ {ids.map((id) => <Product id={id} />)}
171
+ </List>
172
+ ```
173
+
174
+ ### Children
175
+
176
+ Children can be either a single object or an array of objects.
177
+
178
+ ```tsx
179
+ const data = (
180
+ <Paragraph>Hello</Paragraph>
181
+ )
182
+
183
+ console.log(data);
184
+ // { type: 'paragraph', content: 'Hello', variant: undefined }
185
+ ```
186
+
187
+ Use a fragment (`<>...</>`) to return several objects as an array:
188
+
189
+ ```tsx
190
+ const data = (
191
+ <>
192
+ <Paragraph>Hello</Paragraph>
193
+ <Paragraph>World</Paragraph>
194
+ </>
195
+ )
196
+
197
+ console.log(data);
198
+ // [
199
+ // { type: 'paragraph', content: 'Hello', variant: undefined },
200
+ // { type: 'paragraph', content: 'World', variant: undefined },
201
+ // ]
202
+ ```
203
+
204
+ ## TypeScript
205
+
206
+ jsx-object exports a few helper types:
207
+
208
+ ```tsx
209
+ import type { Children, Component, PropsWithChildren } from 'jsx-object';
210
+
211
+ // Children: anything that can be passed as children, including promises and arrays
212
+ interface CardProps {
213
+ title: string;
214
+ children?: Children;
215
+ }
216
+
217
+ // PropsWithChildren<T>: adds an optional `children` prop to T
218
+ type SectionProps = PropsWithChildren<{ title: string }>;
219
+
220
+ // Component<T>: a component function that receives T plus children
221
+ const Section: Component<{ title: string }> = (props) => {
222
+ return { type: 'section', title: props.title, content: props.children };
223
+ };
224
+ ```
225
+
226
+ ### Typing results
227
+
228
+ TypeScript can't infer what a component returns from a JSX expression: every JSX expression has the type `JSX.Element`, which is `JSX.ComponentObject | Promise<JSX.ComponentObject>`. `JSX.ComponentObject` is a loose object type whose properties are all `any`, so reading properties from a result compiles without type checking, typos included. Cast the result to the type you expect:
229
+
230
+ ```tsx
231
+ interface PostObject {
232
+ type: 'post';
233
+ title: string;
234
+ }
235
+
236
+ const post = <Post title="Hello World!" /> as PostObject;
237
+
238
+ // For async trees, await first
239
+ const product = (await <Product id={32} />) as ProductObject;
240
+ ```
241
+
242
+ ### Extending the JSX types
243
+
244
+ The `JSX` namespace is global, so `JSX.Element` and `JSX.ComponentObject` are available without an import. Extend it with a `declare global` block from any module file in your project:
245
+
246
+ ```tsx
247
+ export {};
248
+
249
+ declare global {
250
+ namespace JSX {
251
+ // Declare custom tags, with type-checked props
252
+ interface IntrinsicElements {
253
+ box: { color?: string };
254
+ }
255
+
256
+ // Accept an extra prop on every component
257
+ interface IntrinsicAttributes {
258
+ testId?: string;
259
+ }
260
+
261
+ // Require every component to return an object with a `type`
262
+ interface ComponentObject {
263
+ type: string;
264
+ }
265
+ }
266
+ }
267
+ ```
268
+
269
+ Members added to `ComponentObject` apply to every component, whether it's sync or async, or returns another component's JSX. Use optional members to allow a property without requiring it. If a member uses literal types, such as `type: 'text' | 'stack'`, components must return those values `as const`, since TypeScript otherwise widens them to `string`.
270
+
271
+ You can add members and new types, but you can't redefine existing ones: `JSX.Element` is fixed, `ComponentObject` keeps its `any` index signature, and existing interface members, such as `key`, keep their types.
272
+
273
+ ## Behavior Notes
274
+
275
+ ### Errors
276
+
277
+ If an async component throws or rejects, the whole tree rejects with that error, and parent components are never called.
278
+
279
+ ### No built-in tags
280
+
281
+ There are no intrinsic elements such as `<div>`. A lowercase tag simply returns its children, and TypeScript rejects it unless you declare it yourself, as shown in [Extending the JSX types](#extending-the-jsx-types).
282
+
283
+ ### `key` is reserved
284
+
285
+ The JSX transform strips the `key` prop before it reaches your components. If you need a similar prop, use another name such as `id`.
286
+
287
+ ## Compatibility
288
+
289
+ - Ships both ESM and CommonJS builds, with type declarations for each.
290
+ - No runtime dependencies. Runs in any ES2018+ environment.
291
+ - Requires TypeScript 4.1 or later, for `jsxImportSource` support.
292
+
293
+ ## Contributing
294
+
295
+ ```shell
296
+ npm install
297
+ npm test # run the unit tests
298
+ npm run build # build the package into dist/
299
+ ```
300
+
301
+ ## Credits
302
+
303
+ This library was based on the concept of [Kita Html](https://html.kitajs.org/).
304
+
305
+ ## License
306
+
307
+ [MIT](./LICENSE)
package/dist/index.cjs ADDED
@@ -0,0 +1,6 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ // src/index.ts
3
+ function Fragment(props) {
4
+ return props.children ?? [];
5
+ }
6
+ exports.Fragment = Fragment;
@@ -0,0 +1,42 @@
1
+ declare global {
2
+ namespace JSX {
3
+ interface ComponentObject {
4
+ [key: string]: any;
5
+ }
6
+ /**
7
+ * A `JSX.Element` is always the component object, unless one of their children is a Promise,
8
+ * which makes it also be a Promise
9
+ */
10
+ type Element<T = ComponentObject> = T | Promise<T>;
11
+ interface IntrinsicAttributes {
12
+ /**
13
+ * In `react-jsx`, the `'key'` attribute serves as a reserved attribute name.
14
+ * Consequently, the `'key'` attribute is not included in the properties parameter
15
+ * of any component or element.
16
+ *
17
+ * **If you intend to utilize a similar property, please opt for an alternate
18
+ * name.**
19
+ *
20
+ * @see https://github.com/reactjs/rfcs/pull/107
21
+ */
22
+ key?: undefined | never;
23
+ }
24
+ interface ElementChildrenAttribute {
25
+ children?: undefined | Children;
26
+ }
27
+ /**
28
+ * No intrinsic elements are defined in this JSX namespace.
29
+ *
30
+ * This is intentional, as the JSX namespace is designed to be extended by other libraries or
31
+ * frameworks that define their own intrinsic elements.
32
+ */
33
+ interface IntrinsicElements {}
34
+ }
35
+ }
36
+ export type Children = null | undefined | JSX.Element | Promise<Children> | Children[];
37
+ export type PropsWithChildren<T = {}> = {
38
+ children?: Children;
39
+ } & T;
40
+ export type Component<T = {}> = (this: void, props: PropsWithChildren<T>) => JSX.Element;
41
+ export declare function Fragment(props: PropsWithChildren): JSX.Element;
42
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":["_$__index_js0.Children"],"sources":["../src/jsx.ts","../src/index.ts"],"mappings":"A,QAAQ;YACI;cACE;OACP;;;;;;SAOE,QAAQ,IAAI,mBAAmB,IAAI,QAAQ;cAEtC;;;;;;;;;;;MAWR;;cAGQ;MACR,uBAjBsCA;;;;;;;;cA0B9B;;;YClCF,8BAGR,IAAI,UACJ,QAAQ,YACR;YAEQ,kBAAkB;EAAY,WAAW;IAAa;YAEtD,UAAU,WAAW,YAAY,OAAO,kBAAkB,OAAO,IAAI;wBAEjE,SACd,OAAO,oBACN,IAAI"}
@@ -0,0 +1,42 @@
1
+ declare global {
2
+ namespace JSX {
3
+ interface ComponentObject {
4
+ [key: string]: any;
5
+ }
6
+ /**
7
+ * A `JSX.Element` is always the component object, unless one of their children is a Promise,
8
+ * which makes it also be a Promise
9
+ */
10
+ type Element<T = ComponentObject> = T | Promise<T>;
11
+ interface IntrinsicAttributes {
12
+ /**
13
+ * In `react-jsx`, the `'key'` attribute serves as a reserved attribute name.
14
+ * Consequently, the `'key'` attribute is not included in the properties parameter
15
+ * of any component or element.
16
+ *
17
+ * **If you intend to utilize a similar property, please opt for an alternate
18
+ * name.**
19
+ *
20
+ * @see https://github.com/reactjs/rfcs/pull/107
21
+ */
22
+ key?: undefined | never;
23
+ }
24
+ interface ElementChildrenAttribute {
25
+ children?: undefined | Children;
26
+ }
27
+ /**
28
+ * No intrinsic elements are defined in this JSX namespace.
29
+ *
30
+ * This is intentional, as the JSX namespace is designed to be extended by other libraries or
31
+ * frameworks that define their own intrinsic elements.
32
+ */
33
+ interface IntrinsicElements {}
34
+ }
35
+ }
36
+ export type Children = null | undefined | JSX.Element | Promise<Children> | Children[];
37
+ export type PropsWithChildren<T = {}> = {
38
+ children?: Children;
39
+ } & T;
40
+ export type Component<T = {}> = (this: void, props: PropsWithChildren<T>) => JSX.Element;
41
+ export declare function Fragment(props: PropsWithChildren): JSX.Element;
42
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":["_$__index_js0.Children"],"sources":["../src/jsx.ts","../src/index.ts"],"mappings":"A,QAAQ;YACI;cACE;OACP;;;;;;SAOE,QAAQ,IAAI,mBAAmB,IAAI,QAAQ;cAEtC;;;;;;;;;;;MAWR;;cAGQ;MACR,uBAjBsCA;;;;;;;;cA0B9B;;;YClCF,8BAGR,IAAI,UACJ,QAAQ,YACR;YAEQ,kBAAkB;EAAY,WAAW;IAAa;YAEtD,UAAU,WAAW,YAAY,OAAO,kBAAkB,OAAO,IAAI;wBAEjE,SACd,OAAO,oBACN,IAAI"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ // src/index.ts
2
+ function Fragment(props) {
3
+ return props.children ?? [];
4
+ }
5
+ export { Fragment };
6
+
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import './jsx.js';\n\nexport type Children =\n | null\n | undefined\n | JSX.Element\n | Promise<Children>\n | Children[]\n\nexport type PropsWithChildren<T = {}> = { children?: Children } & T\n\nexport type Component<T = {}> = (this: void, props: PropsWithChildren<T>) => JSX.Element\n\nexport function Fragment(\n props: PropsWithChildren\n): JSX.Element {\n return props.children ?? [];\n}\n"],"mappings":";AAaA,SAAgB,SACd,OACa;CACb,OAAO,MAAM,YAAY,CAAC;AAC5B"}
@@ -0,0 +1,23 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_index = require("./index.cjs");
3
+ const require_jsx_runtime = require("./jsx-runtime.cjs");
4
+ // src/jsx-dev-runtime.ts
5
+ /**
6
+ * Generates an object from an attribute name of component and it's props.
7
+ *
8
+ * This function is meant to be used by the jsx runtime and should not be called directly.
9
+ *
10
+ * @param name The name of the element to create or another component function
11
+ * @param attributes The props to apply to the component
12
+ * @param key The element key, which is ignored
13
+ * @param isStaticChildren Whether the children are a static array, as passed to {@linkcode jsxs}
14
+ * @retuns The generated object or a promise that resolves to the generated object
15
+ */
16
+ function jsxDEV(name, attributes, key, isStaticChildren) {
17
+ if (isStaticChildren && Array.isArray(attributes.children)) return require_jsx_runtime.jsxs(name, attributes);
18
+ return require_jsx_runtime.jsx(name, attributes);
19
+ }
20
+ exports.Fragment = require_index.Fragment;
21
+ exports.jsx = require_jsx_runtime.jsx;
22
+ exports.jsxDEV = jsxDEV;
23
+ exports.jsxs = require_jsx_runtime.jsxs;
@@ -0,0 +1,19 @@
1
+ import { Children, Fragment } from "./index.cjs";
2
+ import { jsx, jsxs } from "./jsx-runtime.cjs";
3
+ /**
4
+ * Generates an object from an attribute name of component and it's props.
5
+ *
6
+ * This function is meant to be used by the jsx runtime and should not be called directly.
7
+ *
8
+ * @param name The name of the element to create or another component function
9
+ * @param attributes The props to apply to the component
10
+ * @param key The element key, which is ignored
11
+ * @param isStaticChildren Whether the children are a static array, as passed to {@linkcode jsxs}
12
+ * @retuns The generated object or a promise that resolves to the generated object
13
+ */
14
+ export declare function jsxDEV(this: void, name: string | Function, attributes: {
15
+ children?: Children;
16
+ [k: string]: any;
17
+ }, key?: unknown, isStaticChildren?: boolean): JSX.Element;
18
+ export { Fragment, jsx, jsxs };
19
+ //# sourceMappingURL=jsx-dev-runtime.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsx-dev-runtime.d.cts","names":[],"sources":["../src/jsx-dev-runtime.ts"],"mappings":";;;;;;;;;;;;;wBAgBgB,OACd,YACA,eAAe,UACf;EAAc,WAAW;GAAW;GACpC,eACA,6BACC,IAAI"}
@@ -0,0 +1,19 @@
1
+ import { Children, Fragment } from "./index.js";
2
+ import { jsx, jsxs } from "./jsx-runtime.js";
3
+ /**
4
+ * Generates an object from an attribute name of component and it's props.
5
+ *
6
+ * This function is meant to be used by the jsx runtime and should not be called directly.
7
+ *
8
+ * @param name The name of the element to create or another component function
9
+ * @param attributes The props to apply to the component
10
+ * @param key The element key, which is ignored
11
+ * @param isStaticChildren Whether the children are a static array, as passed to {@linkcode jsxs}
12
+ * @retuns The generated object or a promise that resolves to the generated object
13
+ */
14
+ export declare function jsxDEV(this: void, name: string | Function, attributes: {
15
+ children?: Children;
16
+ [k: string]: any;
17
+ }, key?: unknown, isStaticChildren?: boolean): JSX.Element;
18
+ export { Fragment, jsx, jsxs };
19
+ //# sourceMappingURL=jsx-dev-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsx-dev-runtime.d.ts","names":[],"sources":["../src/jsx-dev-runtime.ts"],"mappings":";;;;;;;;;;;;;wBAgBgB,OACd,YACA,eAAe,UACf;EAAc,WAAW;GAAW;GACpC,eACA,6BACC,IAAI"}
@@ -0,0 +1,21 @@
1
+ import { Fragment } from "./index.js";
2
+ import { jsx, jsxs } from "./jsx-runtime.js";
3
+ // src/jsx-dev-runtime.ts
4
+ /**
5
+ * Generates an object from an attribute name of component and it's props.
6
+ *
7
+ * This function is meant to be used by the jsx runtime and should not be called directly.
8
+ *
9
+ * @param name The name of the element to create or another component function
10
+ * @param attributes The props to apply to the component
11
+ * @param key The element key, which is ignored
12
+ * @param isStaticChildren Whether the children are a static array, as passed to {@linkcode jsxs}
13
+ * @retuns The generated object or a promise that resolves to the generated object
14
+ */
15
+ function jsxDEV(name, attributes, key, isStaticChildren) {
16
+ if (isStaticChildren && Array.isArray(attributes.children)) return jsxs(name, attributes);
17
+ return jsx(name, attributes);
18
+ }
19
+ export { Fragment, jsx, jsxDEV, jsxs };
20
+
21
+ //# sourceMappingURL=jsx-dev-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsx-dev-runtime.js","names":[],"sources":["../src/jsx-dev-runtime.ts"],"sourcesContent":["import type { Children } from './index.js'\nimport { jsx, jsxs } from './jsx-runtime.js'\n\nexport { Fragment, jsx, jsxs } from './jsx-runtime.js'\n\n/**\n * Generates an object from an attribute name of component and it's props.\n *\n * This function is meant to be used by the jsx runtime and should not be called directly.\n *\n * @param name The name of the element to create or another component function\n * @param attributes The props to apply to the component\n * @param key The element key, which is ignored\n * @param isStaticChildren Whether the children are a static array, as passed to {@linkcode jsxs}\n * @retuns The generated object or a promise that resolves to the generated object\n */\nexport function jsxDEV(\n this: void,\n name: string | Function,\n attributes: { children?: Children; [k: string]: any },\n key?: unknown,\n isStaticChildren?: boolean\n): JSX.Element {\n if (isStaticChildren && Array.isArray(attributes.children)) {\n return jsxs(name, attributes as { children: Children[]; [k: string]: any })\n }\n\n return jsx(name, attributes)\n}\n"],"mappings":";;;;;;;;;;;;;;AAgBA,SAAgB,OAEd,MACA,YACA,KACA,kBACa;CACb,IAAI,oBAAoB,MAAM,QAAQ,WAAW,QAAQ,GACvD,OAAO,KAAK,MAAM,UAAwD;CAG5E,OAAO,IAAI,MAAM,UAAU;AAC7B"}
@@ -0,0 +1,39 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_index = require("./index.cjs");
3
+ // src/jsx-runtime.ts
4
+ const processResult = (name, props, children) => {
5
+ if (typeof name === "function") return name({
6
+ ...props,
7
+ children
8
+ });
9
+ return children;
10
+ };
11
+ const isPromise = (value) => {
12
+ return value && typeof value === "object" && typeof value.then === "function";
13
+ };
14
+ /**
15
+ * Checks whether the children are a promise or contain one, at any array depth.
16
+ * Mapped children (e.g. `{items.map(...)}`) are nested arrays inside the children array.
17
+ */
18
+ const hasPromise = (children) => {
19
+ return isPromise(children) || Array.isArray(children) && children.some(hasPromise);
20
+ };
21
+ /**
22
+ * Resolves every promise in the children, keeping nested arrays in place.
23
+ */
24
+ const resolveChildren = (children) => {
25
+ if (Array.isArray(children)) return Promise.all(children.map(resolveChildren));
26
+ return Promise.resolve(children);
27
+ };
28
+ function jsx(name, attributes) {
29
+ if (hasPromise(attributes.children)) return resolveChildren(attributes.children).then((children) => {
30
+ return processResult(name, attributes, children);
31
+ });
32
+ return processResult(name, attributes, attributes.children);
33
+ }
34
+ function jsxs(name, attributes) {
35
+ return jsx(name, attributes);
36
+ }
37
+ exports.Fragment = require_index.Fragment;
38
+ exports.jsx = jsx;
39
+ exports.jsxs = jsxs;
@@ -0,0 +1,11 @@
1
+ import { Children, Fragment } from "./index.cjs";
2
+ export declare function jsx(this: void, name: string | Function, attributes: {
3
+ children?: Children;
4
+ [k: string]: any;
5
+ }): JSX.Element;
6
+ export declare function jsxs(this: void, name: string | Function, attributes: {
7
+ children: Children[];
8
+ [k: string]: any;
9
+ }): JSX.Element;
10
+ export { Fragment };
11
+ //# sourceMappingURL=jsx-runtime.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsx-runtime.d.cts","names":[],"sources":["../src/jsx-runtime.ts"],"mappings":";wBAiCgB,IACd,YACA,eAAe,UACf;EAAc,WAAW;GAAW;IACnC,IAAI;wBAUS,KACd,YACA,eAAe,UACf;EAAc,UAAU;GAAa;IACpC,IAAI"}
@@ -0,0 +1,11 @@
1
+ import { Children, Fragment } from "./index.js";
2
+ export declare function jsx(this: void, name: string | Function, attributes: {
3
+ children?: Children;
4
+ [k: string]: any;
5
+ }): JSX.Element;
6
+ export declare function jsxs(this: void, name: string | Function, attributes: {
7
+ children: Children[];
8
+ [k: string]: any;
9
+ }): JSX.Element;
10
+ export { Fragment };
11
+ //# sourceMappingURL=jsx-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsx-runtime.d.ts","names":[],"sources":["../src/jsx-runtime.ts"],"mappings":";wBAiCgB,IACd,YACA,eAAe,UACf;EAAc,WAAW;GAAW;IACnC,IAAI;wBAUS,KACd,YACA,eAAe,UACf;EAAc,UAAU;GAAa;IACpC,IAAI"}
@@ -0,0 +1,38 @@
1
+ import { Fragment } from "./index.js";
2
+ // src/jsx-runtime.ts
3
+ const processResult = (name, props, children) => {
4
+ if (typeof name === "function") return name({
5
+ ...props,
6
+ children
7
+ });
8
+ return children;
9
+ };
10
+ const isPromise = (value) => {
11
+ return value && typeof value === "object" && typeof value.then === "function";
12
+ };
13
+ /**
14
+ * Checks whether the children are a promise or contain one, at any array depth.
15
+ * Mapped children (e.g. `{items.map(...)}`) are nested arrays inside the children array.
16
+ */
17
+ const hasPromise = (children) => {
18
+ return isPromise(children) || Array.isArray(children) && children.some(hasPromise);
19
+ };
20
+ /**
21
+ * Resolves every promise in the children, keeping nested arrays in place.
22
+ */
23
+ const resolveChildren = (children) => {
24
+ if (Array.isArray(children)) return Promise.all(children.map(resolveChildren));
25
+ return Promise.resolve(children);
26
+ };
27
+ function jsx(name, attributes) {
28
+ if (hasPromise(attributes.children)) return resolveChildren(attributes.children).then((children) => {
29
+ return processResult(name, attributes, children);
30
+ });
31
+ return processResult(name, attributes, attributes.children);
32
+ }
33
+ function jsxs(name, attributes) {
34
+ return jsx(name, attributes);
35
+ }
36
+ export { Fragment, jsx, jsxs };
37
+
38
+ //# sourceMappingURL=jsx-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsx-runtime.js","names":[],"sources":["../src/jsx-runtime.ts"],"sourcesContent":["import type { Children } from './index.js';\n\nconst processResult = (name: string | Function, props: object, children: Children) => {\n if (typeof name === 'function') {\n return name({ ...props, children });\n }\n\n return children;\n}\n\nconst isPromise = (value: any): value is Promise<any> => {\n return value && typeof value === 'object' && typeof value.then === 'function';\n}\n\n/**\n * Checks whether the children are a promise or contain one, at any array depth.\n * Mapped children (e.g. `{items.map(...)}`) are nested arrays inside the children array.\n */\nconst hasPromise = (children: any): boolean => {\n return isPromise(children) || (Array.isArray(children) && children.some(hasPromise));\n}\n\n/**\n * Resolves every promise in the children, keeping nested arrays in place.\n */\nconst resolveChildren = (children: any): Promise<any> => {\n if (Array.isArray(children)) {\n return Promise.all(children.map(resolveChildren));\n }\n\n return Promise.resolve(children);\n}\n\nexport function jsx(\n this: void,\n name: string | Function,\n attributes: { children?: Children; [k: string]: any }\n): JSX.Element {\n if (hasPromise(attributes.children)) {\n return resolveChildren(attributes.children).then(children => {\n return processResult(name, attributes, children);\n });\n }\n\n return processResult(name, attributes, attributes.children);\n}\n\nexport function jsxs(\n this: void,\n name: string | Function,\n attributes: { children: Children[]; [k: string]: any }\n): JSX.Element {\n return jsx(name, attributes);\n}\n\nexport { Fragment } from './index.js'\n"],"mappings":";;AAEA,MAAM,iBAAiB,MAAyB,OAAe,aAAuB;CACpF,IAAI,OAAO,SAAS,YAClB,OAAO,KAAK;EAAE,GAAG;EAAO;CAAS,CAAC;CAGpC,OAAO;AACT;AAEA,MAAM,aAAa,UAAsC;CACvD,OAAO,SAAS,OAAO,UAAU,YAAY,OAAO,MAAM,SAAS;AACrE;;;;;AAMA,MAAM,cAAc,aAA2B;CAC7C,OAAO,UAAU,QAAQ,KAAM,MAAM,QAAQ,QAAQ,KAAK,SAAS,KAAK,UAAU;AACpF;;;;AAKA,MAAM,mBAAmB,aAAgC;CACvD,IAAI,MAAM,QAAQ,QAAQ,GACxB,OAAO,QAAQ,IAAI,SAAS,IAAI,eAAe,CAAC;CAGlD,OAAO,QAAQ,QAAQ,QAAQ;AACjC;AAEA,SAAgB,IAEd,MACA,YACa;CACb,IAAI,WAAW,WAAW,QAAQ,GAChC,OAAO,gBAAgB,WAAW,QAAQ,CAAC,CAAC,MAAK,aAAY;EAC3D,OAAO,cAAc,MAAM,YAAY,QAAQ;CACjD,CAAC;CAGH,OAAO,cAAc,MAAM,YAAY,WAAW,QAAQ;AAC5D;AAEA,SAAgB,KAEd,MACA,YACa;CACb,OAAO,IAAI,MAAM,UAAU;AAC7B"}
package/package.json CHANGED
@@ -1,6 +1,58 @@
1
1
  {
2
2
  "name": "jsx-object",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "sideEffects": false,
6
+ "description": "Tiny, dependency-free JSX runtime that turns JSX into plain JavaScript objects, with async components. Great for server-driven UI and JSON templating.",
7
+ "keywords": [
8
+ "jsx",
9
+ "tsx",
10
+ "jsx-runtime",
11
+ "json",
12
+ "object",
13
+ "template",
14
+ "templating",
15
+ "server-driven-ui",
16
+ "sdui",
17
+ "async",
18
+ "components",
19
+ "typescript"
20
+ ],
21
+ "author": "Guichaguri",
22
+ "license": "MIT",
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "main": "./dist/index.cjs",
27
+ "module": "./dist/index.js",
28
+ "types": "./dist/index.d.cts",
29
+ "exports": {
30
+ ".": {
31
+ "import": "./dist/index.js",
32
+ "require": "./dist/index.cjs"
33
+ },
34
+ "./jsx-dev-runtime": {
35
+ "import": "./dist/jsx-dev-runtime.js",
36
+ "require": "./dist/jsx-dev-runtime.cjs"
37
+ },
38
+ "./jsx-runtime": {
39
+ "import": "./dist/jsx-runtime.js",
40
+ "require": "./dist/jsx-runtime.cjs"
41
+ },
42
+ "./package.json": "./package.json"
43
+ },
44
+ "scripts": {
45
+ "build": "tsdown",
46
+ "prepublishOnly": "npm run build",
47
+ "test": "vitest run",
48
+ "test:watch": "vitest",
49
+ "coverage": "vitest run --coverage --coverage.include=src/**"
50
+ },
51
+ "devDependencies": {
52
+ "@vitest/coverage-v8": "^5.1.0",
53
+ "publint": "^0.3.25",
54
+ "tsdown": "^0.23.5",
55
+ "typescript": "^7.0.2",
56
+ "vitest": "^5.1.0"
57
+ }
58
+ }