jsx-object 0.0.0-stage → 1.0.1
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 +21 -0
- package/README.md +306 -2
- package/dist/index.cjs +6 -0
- package/dist/index.d.cts +42 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/jsx-dev-runtime.cjs +23 -0
- package/dist/jsx-dev-runtime.d.cts +19 -0
- package/dist/jsx-dev-runtime.d.cts.map +1 -0
- package/dist/jsx-dev-runtime.d.ts +19 -0
- package/dist/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/jsx-dev-runtime.js +21 -0
- package/dist/jsx-dev-runtime.js.map +1 -0
- package/dist/jsx-runtime.cjs +39 -0
- package/dist/jsx-runtime.d.cts +11 -0
- package/dist/jsx-runtime.d.cts.map +1 -0
- package/dist/jsx-runtime.d.ts +11 -0
- package/dist/jsx-runtime.d.ts.map +1 -0
- package/dist/jsx-runtime.js +38 -0
- package/dist/jsx-runtime.js.map +1 -0
- package/package.json +56 -4
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
|
-
#
|
|
1
|
+
# jsx-object
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/jsx-object)
|
|
4
|
+
[](https://bundlephobia.com/package/jsx-object)
|
|
5
|
+
[](./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
package/dist/index.d.cts
ADDED
|
@@ -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 = ComponentObject | Promise<ComponentObject>;
|
|
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,UAAU,kBAAkB,QAAQ;cAE/B;;;;;;;;;;;MAWR;;cAGQ;MACR,uBAjB+BA;;;;;;;;cA0BvB;;;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.d.ts
ADDED
|
@@ -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 = ComponentObject | Promise<ComponentObject>;
|
|
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,UAAU,kBAAkB,QAAQ;cAE/B;;;;;;;;;;;MAWR;;cAGQ;MACR,uBAjB+BA;;;;;;;;cA0BvB;;;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 @@
|
|
|
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) => {
|
|
5
|
+
if (typeof name === "function") return name(props);
|
|
6
|
+
return props.children;
|
|
7
|
+
};
|
|
8
|
+
const isPromise = (value) => {
|
|
9
|
+
return value && typeof value === "object" && typeof value.then === "function";
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Checks whether the children are a promise or contain one, at any array depth.
|
|
13
|
+
* Mapped children (e.g. `{items.map(...)}`) are nested arrays inside the children array.
|
|
14
|
+
*/
|
|
15
|
+
const hasPromise = (children) => {
|
|
16
|
+
return isPromise(children) || Array.isArray(children) && children.some(hasPromise);
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Resolves every promise in the children, keeping nested arrays in place.
|
|
20
|
+
*/
|
|
21
|
+
const resolveChildren = (children) => {
|
|
22
|
+
if (Array.isArray(children)) return Promise.all(children.map(resolveChildren));
|
|
23
|
+
return Promise.resolve(children);
|
|
24
|
+
};
|
|
25
|
+
function jsx(name, attributes) {
|
|
26
|
+
if (hasPromise(attributes.children)) return resolveChildren(attributes.children).then((children) => {
|
|
27
|
+
return processResult(name, {
|
|
28
|
+
...attributes,
|
|
29
|
+
children
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
return processResult(name, attributes);
|
|
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":";wBAoCgB,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":";wBAoCgB,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) => {
|
|
4
|
+
if (typeof name === "function") return name(props);
|
|
5
|
+
return props.children;
|
|
6
|
+
};
|
|
7
|
+
const isPromise = (value) => {
|
|
8
|
+
return value && typeof value === "object" && typeof value.then === "function";
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Checks whether the children are a promise or contain one, at any array depth.
|
|
12
|
+
* Mapped children (e.g. `{items.map(...)}`) are nested arrays inside the children array.
|
|
13
|
+
*/
|
|
14
|
+
const hasPromise = (children) => {
|
|
15
|
+
return isPromise(children) || Array.isArray(children) && children.some(hasPromise);
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Resolves every promise in the children, keeping nested arrays in place.
|
|
19
|
+
*/
|
|
20
|
+
const resolveChildren = (children) => {
|
|
21
|
+
if (Array.isArray(children)) return Promise.all(children.map(resolveChildren));
|
|
22
|
+
return Promise.resolve(children);
|
|
23
|
+
};
|
|
24
|
+
function jsx(name, attributes) {
|
|
25
|
+
if (hasPromise(attributes.children)) return resolveChildren(attributes.children).then((children) => {
|
|
26
|
+
return processResult(name, {
|
|
27
|
+
...attributes,
|
|
28
|
+
children
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
return processResult(name, attributes);
|
|
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 = (\n name: string | Function,\n props: { children?: Children; [k: string]: any },\n) => {\n if (typeof name === 'function') {\n return name(props);\n }\n\n return props.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);\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,iBACJ,MACA,UACG;CACH,IAAI,OAAO,SAAS,YAClB,OAAO,KAAK,KAAK;CAGnB,OAAO,MAAM;AACf;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;GAAE,GAAG;GAAY;EAAS,CAAC;CACxD,CAAC;CAGH,OAAO,cAAc,MAAM,UAAU;AACvC;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": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.1",
|
|
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
|
+
}
|