@knighted/jsx 1.8.0 → 1.9.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/README.md +15 -0
- package/dist/cjs/internal/dom-create-element.cjs +76 -0
- package/dist/cjs/internal/dom-create-element.d.cts +21 -0
- package/dist/cjs/internal/jsx-types.cjs +2 -0
- package/dist/cjs/internal/jsx-types.d.cts +7 -0
- package/dist/cjs/jsx.cjs +13 -3
- package/dist/cjs/jsx.d.cts +9 -7
- package/dist/cjs/node/debug/index.d.cts +5 -1
- package/dist/cjs/node/index.d.cts +5 -1
- package/dist/cjs/transpile.cjs +137 -4
- package/dist/cjs/transpile.d.cts +2 -0
- package/dist/internal/dom-create-element.d.ts +21 -0
- package/dist/internal/dom-create-element.js +72 -0
- package/dist/internal/jsx-types.d.ts +7 -0
- package/dist/internal/jsx-types.js +1 -0
- package/dist/jsx.d.ts +9 -7
- package/dist/jsx.js +12 -1
- package/dist/lite/debug/index.js +5 -5
- package/dist/lite/index.js +7 -7
- package/dist/lite/node/debug/index.js +8 -8
- package/dist/lite/node/index.js +7 -7
- package/dist/node/debug/index.d.ts +5 -1
- package/dist/node/index.d.ts +5 -1
- package/dist/transpile.d.ts +2 -0
- package/dist/transpile.js +137 -4
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -94,6 +94,21 @@ transpileJsxSource(input, {
|
|
|
94
94
|
})
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
+
By default, TypeScript syntax is preserved in the output. If your source needs to run directly
|
|
98
|
+
as JavaScript (for example, code entered in an editor), enable type stripping:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
transpileJsxSource(input, {
|
|
102
|
+
typescript: 'strip',
|
|
103
|
+
})
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Supported `typescript` modes:
|
|
107
|
+
|
|
108
|
+
- `'preserve'` (default): keep TypeScript syntax in output.
|
|
109
|
+
- `'strip'`: remove type-only declarations and erase inline type syntax (`: T`, `as T`,
|
|
110
|
+
`satisfies T`, non-null assertions, and type assertions) while still transpiling JSX.
|
|
111
|
+
|
|
97
112
|
### React runtime (`reactJsx`)
|
|
98
113
|
|
|
99
114
|
Need to compose React elements instead of DOM nodes? Import the dedicated helper from the `@knighted/jsx/react` subpath (React 18+ and `react-dom` are still required to mount the tree):
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createDomCreateElement = exports.Fragment = void 0;
|
|
4
|
+
exports.Fragment = Symbol.for('@knighted/jsx::Fragment');
|
|
5
|
+
const CREATE_ELEMENT_NAMESPACE_PROP = '__jsxNs';
|
|
6
|
+
const resolveChildrenForCreateElement = (props, children) => {
|
|
7
|
+
if (children.length > 0) {
|
|
8
|
+
return children;
|
|
9
|
+
}
|
|
10
|
+
if (!Object.prototype.hasOwnProperty.call(props, 'children')) {
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
return [props.children];
|
|
14
|
+
};
|
|
15
|
+
const createPropsForComponent = (props, children) => {
|
|
16
|
+
const nextProps = { ...props };
|
|
17
|
+
if (children.length === 1) {
|
|
18
|
+
nextProps.children = children[0];
|
|
19
|
+
}
|
|
20
|
+
else if (children.length > 1) {
|
|
21
|
+
nextProps.children = children;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
delete nextProps.children;
|
|
25
|
+
}
|
|
26
|
+
return nextProps;
|
|
27
|
+
};
|
|
28
|
+
const resolveNamespaceOverride = (props) => {
|
|
29
|
+
if (!Object.prototype.hasOwnProperty.call(props, CREATE_ELEMENT_NAMESPACE_PROP)) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
const override = props[CREATE_ELEMENT_NAMESPACE_PROP];
|
|
33
|
+
delete props[CREATE_ELEMENT_NAMESPACE_PROP];
|
|
34
|
+
if (override === 'svg' || override === null) {
|
|
35
|
+
return override;
|
|
36
|
+
}
|
|
37
|
+
throw new Error(`${CREATE_ELEMENT_NAMESPACE_PROP} must be "svg" or null when provided.`);
|
|
38
|
+
};
|
|
39
|
+
const createDomCreateElement = ({ ensureDomAvailable, appendChildValue, setDomProp, isPromiseLike, }) => {
|
|
40
|
+
function createElement(type, props, ...children) {
|
|
41
|
+
ensureDomAvailable();
|
|
42
|
+
const nextProps = props ? { ...props } : {};
|
|
43
|
+
const resolvedChildren = resolveChildrenForCreateElement(nextProps, children);
|
|
44
|
+
if (type === exports.Fragment) {
|
|
45
|
+
const fragment = document.createDocumentFragment();
|
|
46
|
+
resolvedChildren.forEach(child => appendChildValue(fragment, child));
|
|
47
|
+
return fragment;
|
|
48
|
+
}
|
|
49
|
+
if (typeof type === 'function') {
|
|
50
|
+
const result = type(createPropsForComponent(nextProps, resolvedChildren));
|
|
51
|
+
if (isPromiseLike(result)) {
|
|
52
|
+
throw new Error('Async jsx components are not supported.');
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
if (typeof type !== 'string') {
|
|
57
|
+
throw new Error(`Unsupported jsx createElement type: ${String(type)}`);
|
|
58
|
+
}
|
|
59
|
+
delete nextProps.children;
|
|
60
|
+
const namespaceOverride = resolveNamespaceOverride(nextProps);
|
|
61
|
+
const nextNamespace = namespaceOverride ?? (type === 'svg' ? 'svg' : null);
|
|
62
|
+
const domElement = nextNamespace === 'svg'
|
|
63
|
+
? document.createElementNS('http://www.w3.org/2000/svg', type)
|
|
64
|
+
: document.createElement(type);
|
|
65
|
+
Object.entries(nextProps).forEach(([name, value]) => {
|
|
66
|
+
if (name === 'key') {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
setDomProp(domElement, name, value, nextNamespace);
|
|
70
|
+
});
|
|
71
|
+
resolvedChildren.forEach(value => appendChildValue(domElement, value));
|
|
72
|
+
return domElement;
|
|
73
|
+
}
|
|
74
|
+
return createElement;
|
|
75
|
+
};
|
|
76
|
+
exports.createDomCreateElement = createDomCreateElement;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Namespace } from './attribute-resolution.cjs';
|
|
2
|
+
import type { JsxComponent, JsxRenderable } from './jsx-types.cjs';
|
|
3
|
+
export declare const FragmentToken: unique symbol;
|
|
4
|
+
export type JsxFragmentToken = typeof FragmentToken;
|
|
5
|
+
export declare const Fragment: JsxFragmentToken;
|
|
6
|
+
type JsxPropsRecord = Record<string, unknown>;
|
|
7
|
+
export type JsxCreateElement = {
|
|
8
|
+
(type: JsxFragmentToken, props: null, ...children: JsxRenderable[]): DocumentFragment;
|
|
9
|
+
<Props extends JsxPropsRecord>(type: JsxComponent<Props>, props: (Props & {
|
|
10
|
+
children?: JsxRenderable | JsxRenderable[];
|
|
11
|
+
}) | null, ...children: JsxRenderable[]): JsxRenderable;
|
|
12
|
+
(type: string, props: JsxPropsRecord | null, ...children: JsxRenderable[]): JsxRenderable;
|
|
13
|
+
};
|
|
14
|
+
type DomCreateElementHelpers = {
|
|
15
|
+
ensureDomAvailable: () => void;
|
|
16
|
+
appendChildValue: (parent: Node & ParentNode, value: JsxRenderable) => void;
|
|
17
|
+
setDomProp: (element: Element, name: string, value: unknown, namespace: Namespace) => void;
|
|
18
|
+
isPromiseLike: (value: unknown) => value is PromiseLike<unknown>;
|
|
19
|
+
};
|
|
20
|
+
export declare const createDomCreateElement: ({ ensureDomAvailable, appendChildValue, setDomProp, isPromiseLike, }: DomCreateElementHelpers) => JsxCreateElement;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type JsxRenderable = Node | DocumentFragment | string | number | bigint | boolean | null | undefined | Iterable<JsxRenderable>;
|
|
2
|
+
export type JsxComponent<Props = Record<string, unknown>> = {
|
|
3
|
+
(props: Props & {
|
|
4
|
+
children?: JsxRenderable | JsxRenderable[];
|
|
5
|
+
}): JsxRenderable;
|
|
6
|
+
displayName?: string;
|
|
7
|
+
};
|
package/dist/cjs/jsx.cjs
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.jsx = void 0;
|
|
3
|
+
exports.jsx = exports.createElement = void 0;
|
|
4
4
|
const oxc_parser_1 = require("oxc-parser");
|
|
5
5
|
const shared_js_1 = require("./runtime/shared.cjs");
|
|
6
6
|
const property_information_1 = require("property-information");
|
|
7
7
|
const attribute_resolution_js_1 = require("./internal/attribute-resolution.cjs");
|
|
8
8
|
const event_bindings_js_1 = require("./internal/event-bindings.cjs");
|
|
9
|
+
const dom_create_element_js_1 = require("./internal/dom-create-element.cjs");
|
|
9
10
|
const ensureDomAvailable = () => {
|
|
10
11
|
if (typeof document === 'undefined' || typeof document.createElement !== 'function') {
|
|
11
12
|
throw new Error('The jsx template tag requires a DOM-like environment (document missing).');
|
|
@@ -306,7 +307,13 @@ const evaluateJsxNode = (node, ctx, namespace) => {
|
|
|
306
307
|
}
|
|
307
308
|
return evaluateJsxElement(node, ctx, namespace);
|
|
308
309
|
};
|
|
309
|
-
|
|
310
|
+
exports.createElement = (0, dom_create_element_js_1.createDomCreateElement)({
|
|
311
|
+
ensureDomAvailable,
|
|
312
|
+
appendChildValue,
|
|
313
|
+
setDomProp,
|
|
314
|
+
isPromiseLike,
|
|
315
|
+
});
|
|
316
|
+
const jsxTag = (templates, ...values) => {
|
|
310
317
|
ensureDomAvailable();
|
|
311
318
|
const build = (0, shared_js_1.buildTemplate)(templates, values);
|
|
312
319
|
const result = (0, oxc_parser_1.parseSync)('inline.jsx', build.source, shared_js_1.parserOptions);
|
|
@@ -321,4 +328,7 @@ const jsx = (templates, ...values) => {
|
|
|
321
328
|
};
|
|
322
329
|
return evaluateJsxNode(root, ctx, null);
|
|
323
330
|
};
|
|
324
|
-
exports.jsx =
|
|
331
|
+
exports.jsx = Object.assign(jsxTag, {
|
|
332
|
+
createElement: exports.createElement,
|
|
333
|
+
Fragment: dom_create_element_js_1.Fragment,
|
|
334
|
+
});
|
package/dist/cjs/jsx.d.cts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { type JsxFragmentToken, type JsxCreateElement } from './internal/dom-create-element.cjs';
|
|
2
|
+
import type { JsxRenderable } from './internal/jsx-types.cjs';
|
|
3
|
+
export type { JsxRenderable, JsxComponent } from './internal/jsx-types.cjs';
|
|
4
|
+
export declare const createElement: JsxCreateElement;
|
|
5
|
+
type JsxTaggedTemplate = {
|
|
6
|
+
(templates: TemplateStringsArray, ...values: unknown[]): JsxRenderable;
|
|
7
|
+
createElement: typeof createElement;
|
|
8
|
+
Fragment: JsxFragmentToken;
|
|
7
9
|
};
|
|
8
|
-
export declare const jsx:
|
|
10
|
+
export declare const jsx: JsxTaggedTemplate;
|
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
export declare const jsx:
|
|
1
|
+
export declare const jsx: {
|
|
2
|
+
(templates: TemplateStringsArray, ...values: unknown[]): import("../../jsx.cjs").JsxRenderable;
|
|
3
|
+
createElement: typeof import("../../jsx.cjs").createElement;
|
|
4
|
+
Fragment: import("../../internal/dom-create-element.cjs").JsxFragmentToken;
|
|
5
|
+
};
|
|
2
6
|
export type { JsxRenderable, JsxComponent } from '../../jsx.cjs';
|
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
export declare const jsx:
|
|
1
|
+
export declare const jsx: {
|
|
2
|
+
(templates: TemplateStringsArray, ...values: unknown[]): import("../jsx.cjs").JsxRenderable;
|
|
3
|
+
createElement: typeof import("../jsx.cjs").createElement;
|
|
4
|
+
Fragment: import("../internal/dom-create-element.cjs").JsxFragmentToken;
|
|
5
|
+
};
|
|
2
6
|
export type { JsxRenderable, JsxComponent } from '../jsx.cjs';
|
package/dist/cjs/transpile.cjs
CHANGED
|
@@ -35,15 +35,24 @@ const isSourceRange = (value) => Array.isArray(value) &&
|
|
|
35
35
|
typeof value[0] === 'number' &&
|
|
36
36
|
typeof value[1] === 'number';
|
|
37
37
|
const hasSourceRange = (value) => isObjectRecord(value) && isSourceRange(value.range);
|
|
38
|
+
const tsWrapperExpressionNodeTypes = new Set([
|
|
39
|
+
'TSAsExpression',
|
|
40
|
+
'TSSatisfiesExpression',
|
|
41
|
+
'TSInstantiationExpression',
|
|
42
|
+
'TSNonNullExpression',
|
|
43
|
+
'TSTypeAssertion',
|
|
44
|
+
]);
|
|
38
45
|
const compareByRangeStartDesc = (first, second) => second.range[0] - first.range[0];
|
|
39
46
|
class SourceJsxReactBuilder {
|
|
40
47
|
source;
|
|
41
48
|
createElementRef;
|
|
42
49
|
fragmentRef;
|
|
43
|
-
|
|
50
|
+
stripTypes;
|
|
51
|
+
constructor(source, createElementRef, fragmentRef, stripTypes) {
|
|
44
52
|
this.source = source;
|
|
45
53
|
this.createElementRef = createElementRef;
|
|
46
54
|
this.fragmentRef = fragmentRef;
|
|
55
|
+
this.stripTypes = stripTypes;
|
|
47
56
|
}
|
|
48
57
|
compile(node) {
|
|
49
58
|
return this.compileNode(node);
|
|
@@ -179,6 +188,17 @@ class SourceJsxReactBuilder {
|
|
|
179
188
|
if (node.type === 'JSXElement' || node.type === 'JSXFragment') {
|
|
180
189
|
return this.compileNode(node);
|
|
181
190
|
}
|
|
191
|
+
if (this.stripTypes && isObjectRecord(node)) {
|
|
192
|
+
if ('expression' in node && node.type === 'ParenthesizedExpression') {
|
|
193
|
+
return `(${this.compileExpression(node.expression)})`;
|
|
194
|
+
}
|
|
195
|
+
if ('expression' in node &&
|
|
196
|
+
typeof node.type === 'string' &&
|
|
197
|
+
tsWrapperExpressionNodeTypes.has(node.type)) {
|
|
198
|
+
return this.compileExpression(node.expression);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/* c8 ignore next 3 -- defensive guard for malformed external AST nodes */
|
|
182
202
|
if (!hasSourceRange(node)) {
|
|
183
203
|
throw new Error('[jsx] Unable to read source range for expression node.');
|
|
184
204
|
}
|
|
@@ -230,21 +250,134 @@ const collectRootJsxNodes = (root) => {
|
|
|
230
250
|
walk(root, false);
|
|
231
251
|
return nodes;
|
|
232
252
|
};
|
|
253
|
+
const hasStringProperty = (value, key) => isObjectRecord(value) && typeof value[key] === 'string';
|
|
254
|
+
const hasSourceAndExpressionRanges = (value) => isObjectRecord(value) &&
|
|
255
|
+
typeof value.type === 'string' &&
|
|
256
|
+
hasSourceRange(value) &&
|
|
257
|
+
'expression' in value &&
|
|
258
|
+
hasSourceRange(value.expression);
|
|
259
|
+
const isTypeOnlyImportExport = (value) => hasStringProperty(value, 'importKind')
|
|
260
|
+
? value.importKind === 'type'
|
|
261
|
+
: hasStringProperty(value, 'exportKind') && value.exportKind === 'type';
|
|
262
|
+
const isTypeOnlyNode = (value) => {
|
|
263
|
+
if (!isObjectRecord(value) || typeof value.type !== 'string') {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
return [
|
|
267
|
+
'TSTypeAnnotation',
|
|
268
|
+
'TSTypeParameterDeclaration',
|
|
269
|
+
'TSTypeAliasDeclaration',
|
|
270
|
+
'TSInterfaceDeclaration',
|
|
271
|
+
'TSDeclareFunction',
|
|
272
|
+
'TSImportEqualsDeclaration',
|
|
273
|
+
'TSNamespaceExportDeclaration',
|
|
274
|
+
'TSModuleDeclaration',
|
|
275
|
+
].includes(value.type);
|
|
276
|
+
};
|
|
277
|
+
const createStripEditForTsWrapper = (value, source) => {
|
|
278
|
+
if (!hasSourceAndExpressionRanges(value)) {
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
if (value.type !== 'TSAsExpression' &&
|
|
282
|
+
value.type !== 'TSSatisfiesExpression' &&
|
|
283
|
+
value.type !== 'TSInstantiationExpression' &&
|
|
284
|
+
value.type !== 'TSNonNullExpression' &&
|
|
285
|
+
value.type !== 'TSTypeAssertion') {
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
const [exprStart, exprEnd] = value.expression.range;
|
|
289
|
+
return {
|
|
290
|
+
range: value.range,
|
|
291
|
+
replacement: source.slice(exprStart, exprEnd),
|
|
292
|
+
};
|
|
293
|
+
};
|
|
294
|
+
const collectTypeScriptStripEdits = (source, root) => {
|
|
295
|
+
const edits = [];
|
|
296
|
+
const walk = (value) => {
|
|
297
|
+
if (!isObjectRecord(value)) {
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
if (Array.isArray(value)) {
|
|
301
|
+
value.forEach(walk);
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
if (hasSourceRange(value)) {
|
|
305
|
+
if (isTypeOnlyNode(value) || isTypeOnlyImportExport(value)) {
|
|
306
|
+
edits.push({ range: value.range });
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
const wrapperEdit = createStripEditForTsWrapper(value, source);
|
|
311
|
+
if (wrapperEdit) {
|
|
312
|
+
edits.push(wrapperEdit);
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
for (const entry of Object.values(value)) {
|
|
318
|
+
walk(entry);
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
walk(root);
|
|
322
|
+
return edits;
|
|
323
|
+
};
|
|
324
|
+
const rangeOverlaps = (first, second) => first[0] < second[1] && second[0] < first[1];
|
|
325
|
+
const compareStripEditPriority = (first, second) => {
|
|
326
|
+
const firstLength = first.range[1] - first.range[0];
|
|
327
|
+
const secondLength = second.range[1] - second.range[0];
|
|
328
|
+
if (firstLength !== secondLength) {
|
|
329
|
+
return secondLength - firstLength;
|
|
330
|
+
}
|
|
331
|
+
return compareByRangeStartDesc(first, second);
|
|
332
|
+
};
|
|
333
|
+
const applyStripEdits = (magic, edits) => {
|
|
334
|
+
if (!edits.length) {
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
const appliedRanges = [];
|
|
338
|
+
let changed = false;
|
|
339
|
+
edits
|
|
340
|
+
.slice()
|
|
341
|
+
.sort(compareStripEditPriority)
|
|
342
|
+
.forEach(edit => {
|
|
343
|
+
/* c8 ignore next -- overlap handling is defensive after de-duplicated collection */
|
|
344
|
+
if (appliedRanges.some(range => rangeOverlaps(range, edit.range))) {
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
const [start, end] = edit.range;
|
|
348
|
+
if (edit.replacement === undefined) {
|
|
349
|
+
magic.remove(start, end);
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
magic.overwrite(start, end, edit.replacement);
|
|
353
|
+
}
|
|
354
|
+
appliedRanges.push(edit.range);
|
|
355
|
+
changed = true;
|
|
356
|
+
});
|
|
357
|
+
return changed;
|
|
358
|
+
};
|
|
233
359
|
function transpileJsxSource(source, options = {}) {
|
|
234
360
|
const sourceType = options.sourceType ?? 'module';
|
|
235
361
|
const createElementRef = options.createElement ?? 'React.createElement';
|
|
236
362
|
const fragmentRef = options.fragment ?? 'React.Fragment';
|
|
363
|
+
const typescriptMode = options.typescript ?? 'preserve';
|
|
237
364
|
const parsed = (0, oxc_parser_1.parseSync)('transpile-jsx-source.tsx', source, createModuleParserOptions(sourceType));
|
|
238
365
|
const firstError = parsed.errors[0];
|
|
239
366
|
if (firstError) {
|
|
240
367
|
throw new Error(formatParserError(firstError));
|
|
241
368
|
}
|
|
369
|
+
const magic = new magic_string_1.default(source);
|
|
370
|
+
const stripChanged = typescriptMode === 'strip'
|
|
371
|
+
? applyStripEdits(magic, collectTypeScriptStripEdits(source, parsed.program))
|
|
372
|
+
: false;
|
|
242
373
|
const jsxRoots = collectRootJsxNodes(parsed.program);
|
|
243
374
|
if (!jsxRoots.length) {
|
|
244
|
-
return {
|
|
375
|
+
return {
|
|
376
|
+
code: stripChanged ? magic.toString() : source,
|
|
377
|
+
changed: stripChanged,
|
|
378
|
+
};
|
|
245
379
|
}
|
|
246
|
-
const builder = new SourceJsxReactBuilder(source, createElementRef, fragmentRef);
|
|
247
|
-
const magic = new magic_string_1.default(source);
|
|
380
|
+
const builder = new SourceJsxReactBuilder(source, createElementRef, fragmentRef, typescriptMode === 'strip');
|
|
248
381
|
jsxRoots.sort(compareByRangeStartDesc).forEach(node => {
|
|
249
382
|
magic.overwrite(node.range[0], node.range[1], builder.compile(node));
|
|
250
383
|
});
|
package/dist/cjs/transpile.d.cts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
type TranspileSourceType = 'module' | 'script';
|
|
2
|
+
type TranspileTypeScriptMode = 'preserve' | 'strip';
|
|
2
3
|
export type TranspileJsxSourceOptions = {
|
|
3
4
|
sourceType?: TranspileSourceType;
|
|
4
5
|
createElement?: string;
|
|
5
6
|
fragment?: string;
|
|
7
|
+
typescript?: TranspileTypeScriptMode;
|
|
6
8
|
};
|
|
7
9
|
export type TranspileJsxSourceResult = {
|
|
8
10
|
code: string;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Namespace } from './attribute-resolution.js';
|
|
2
|
+
import type { JsxComponent, JsxRenderable } from './jsx-types.js';
|
|
3
|
+
export declare const FragmentToken: unique symbol;
|
|
4
|
+
export type JsxFragmentToken = typeof FragmentToken;
|
|
5
|
+
export declare const Fragment: JsxFragmentToken;
|
|
6
|
+
type JsxPropsRecord = Record<string, unknown>;
|
|
7
|
+
export type JsxCreateElement = {
|
|
8
|
+
(type: JsxFragmentToken, props: null, ...children: JsxRenderable[]): DocumentFragment;
|
|
9
|
+
<Props extends JsxPropsRecord>(type: JsxComponent<Props>, props: (Props & {
|
|
10
|
+
children?: JsxRenderable | JsxRenderable[];
|
|
11
|
+
}) | null, ...children: JsxRenderable[]): JsxRenderable;
|
|
12
|
+
(type: string, props: JsxPropsRecord | null, ...children: JsxRenderable[]): JsxRenderable;
|
|
13
|
+
};
|
|
14
|
+
type DomCreateElementHelpers = {
|
|
15
|
+
ensureDomAvailable: () => void;
|
|
16
|
+
appendChildValue: (parent: Node & ParentNode, value: JsxRenderable) => void;
|
|
17
|
+
setDomProp: (element: Element, name: string, value: unknown, namespace: Namespace) => void;
|
|
18
|
+
isPromiseLike: (value: unknown) => value is PromiseLike<unknown>;
|
|
19
|
+
};
|
|
20
|
+
export declare const createDomCreateElement: ({ ensureDomAvailable, appendChildValue, setDomProp, isPromiseLike, }: DomCreateElementHelpers) => JsxCreateElement;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export const Fragment = Symbol.for('@knighted/jsx::Fragment');
|
|
2
|
+
const CREATE_ELEMENT_NAMESPACE_PROP = '__jsxNs';
|
|
3
|
+
const resolveChildrenForCreateElement = (props, children) => {
|
|
4
|
+
if (children.length > 0) {
|
|
5
|
+
return children;
|
|
6
|
+
}
|
|
7
|
+
if (!Object.prototype.hasOwnProperty.call(props, 'children')) {
|
|
8
|
+
return [];
|
|
9
|
+
}
|
|
10
|
+
return [props.children];
|
|
11
|
+
};
|
|
12
|
+
const createPropsForComponent = (props, children) => {
|
|
13
|
+
const nextProps = { ...props };
|
|
14
|
+
if (children.length === 1) {
|
|
15
|
+
nextProps.children = children[0];
|
|
16
|
+
}
|
|
17
|
+
else if (children.length > 1) {
|
|
18
|
+
nextProps.children = children;
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
delete nextProps.children;
|
|
22
|
+
}
|
|
23
|
+
return nextProps;
|
|
24
|
+
};
|
|
25
|
+
const resolveNamespaceOverride = (props) => {
|
|
26
|
+
if (!Object.prototype.hasOwnProperty.call(props, CREATE_ELEMENT_NAMESPACE_PROP)) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
const override = props[CREATE_ELEMENT_NAMESPACE_PROP];
|
|
30
|
+
delete props[CREATE_ELEMENT_NAMESPACE_PROP];
|
|
31
|
+
if (override === 'svg' || override === null) {
|
|
32
|
+
return override;
|
|
33
|
+
}
|
|
34
|
+
throw new Error(`${CREATE_ELEMENT_NAMESPACE_PROP} must be "svg" or null when provided.`);
|
|
35
|
+
};
|
|
36
|
+
export const createDomCreateElement = ({ ensureDomAvailable, appendChildValue, setDomProp, isPromiseLike, }) => {
|
|
37
|
+
function createElement(type, props, ...children) {
|
|
38
|
+
ensureDomAvailable();
|
|
39
|
+
const nextProps = props ? { ...props } : {};
|
|
40
|
+
const resolvedChildren = resolveChildrenForCreateElement(nextProps, children);
|
|
41
|
+
if (type === Fragment) {
|
|
42
|
+
const fragment = document.createDocumentFragment();
|
|
43
|
+
resolvedChildren.forEach(child => appendChildValue(fragment, child));
|
|
44
|
+
return fragment;
|
|
45
|
+
}
|
|
46
|
+
if (typeof type === 'function') {
|
|
47
|
+
const result = type(createPropsForComponent(nextProps, resolvedChildren));
|
|
48
|
+
if (isPromiseLike(result)) {
|
|
49
|
+
throw new Error('Async jsx components are not supported.');
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
if (typeof type !== 'string') {
|
|
54
|
+
throw new Error(`Unsupported jsx createElement type: ${String(type)}`);
|
|
55
|
+
}
|
|
56
|
+
delete nextProps.children;
|
|
57
|
+
const namespaceOverride = resolveNamespaceOverride(nextProps);
|
|
58
|
+
const nextNamespace = namespaceOverride ?? (type === 'svg' ? 'svg' : null);
|
|
59
|
+
const domElement = nextNamespace === 'svg'
|
|
60
|
+
? document.createElementNS('http://www.w3.org/2000/svg', type)
|
|
61
|
+
: document.createElement(type);
|
|
62
|
+
Object.entries(nextProps).forEach(([name, value]) => {
|
|
63
|
+
if (name === 'key') {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
setDomProp(domElement, name, value, nextNamespace);
|
|
67
|
+
});
|
|
68
|
+
resolvedChildren.forEach(value => appendChildValue(domElement, value));
|
|
69
|
+
return domElement;
|
|
70
|
+
}
|
|
71
|
+
return createElement;
|
|
72
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type JsxRenderable = Node | DocumentFragment | string | number | bigint | boolean | null | undefined | Iterable<JsxRenderable>;
|
|
2
|
+
export type JsxComponent<Props = Record<string, unknown>> = {
|
|
3
|
+
(props: Props & {
|
|
4
|
+
children?: JsxRenderable | JsxRenderable[];
|
|
5
|
+
}): JsxRenderable;
|
|
6
|
+
displayName?: string;
|
|
7
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/jsx.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { type JsxFragmentToken, type JsxCreateElement } from './internal/dom-create-element.js';
|
|
2
|
+
import type { JsxRenderable } from './internal/jsx-types.js';
|
|
3
|
+
export type { JsxRenderable, JsxComponent } from './internal/jsx-types.js';
|
|
4
|
+
export declare const createElement: JsxCreateElement;
|
|
5
|
+
type JsxTaggedTemplate = {
|
|
6
|
+
(templates: TemplateStringsArray, ...values: unknown[]): JsxRenderable;
|
|
7
|
+
createElement: typeof createElement;
|
|
8
|
+
Fragment: JsxFragmentToken;
|
|
7
9
|
};
|
|
8
|
-
export declare const jsx:
|
|
10
|
+
export declare const jsx: JsxTaggedTemplate;
|
package/dist/jsx.js
CHANGED
|
@@ -3,6 +3,7 @@ import { buildTemplate, evaluateExpression, extractRootNode, formatTaggedTemplat
|
|
|
3
3
|
import { find as findPropertyInfo, html as htmlProperties, svg as svgProperties, } from 'property-information';
|
|
4
4
|
import { createResolveAttributes, } from './internal/attribute-resolution.js';
|
|
5
5
|
import { parseEventPropName, resolveEventHandlerValue, } from './internal/event-bindings.js';
|
|
6
|
+
import { Fragment, createDomCreateElement, } from './internal/dom-create-element.js';
|
|
6
7
|
const ensureDomAvailable = () => {
|
|
7
8
|
if (typeof document === 'undefined' || typeof document.createElement !== 'function') {
|
|
8
9
|
throw new Error('The jsx template tag requires a DOM-like environment (document missing).');
|
|
@@ -303,7 +304,13 @@ const evaluateJsxNode = (node, ctx, namespace) => {
|
|
|
303
304
|
}
|
|
304
305
|
return evaluateJsxElement(node, ctx, namespace);
|
|
305
306
|
};
|
|
306
|
-
export const
|
|
307
|
+
export const createElement = createDomCreateElement({
|
|
308
|
+
ensureDomAvailable,
|
|
309
|
+
appendChildValue,
|
|
310
|
+
setDomProp,
|
|
311
|
+
isPromiseLike,
|
|
312
|
+
});
|
|
313
|
+
const jsxTag = (templates, ...values) => {
|
|
307
314
|
ensureDomAvailable();
|
|
308
315
|
const build = buildTemplate(templates, values);
|
|
309
316
|
const result = parseSync('inline.jsx', build.source, parserOptions);
|
|
@@ -318,3 +325,7 @@ export const jsx = (templates, ...values) => {
|
|
|
318
325
|
};
|
|
319
326
|
return evaluateJsxNode(root, ctx, null);
|
|
320
327
|
};
|
|
328
|
+
export const jsx = Object.assign(jsxTag, {
|
|
329
|
+
createElement,
|
|
330
|
+
Fragment,
|
|
331
|
+
});
|
package/dist/lite/debug/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {parseSync}from'oxc-parser';import {find,svg,html}from'property-information';var w=null
|
|
2
|
-
`),a=
|
|
3
|
-
`)},
|
|
1
|
+
import {parseSync}from'oxc-parser';import {find,svg,html}from'property-information';var w=null,O=e=>{w=e;},le=e=>{w?.warnLowercaseEventProp?.(e);},me=e=>{w?.ensureValidDangerouslySetInnerHTML?.(e);},F=e=>{let{getIdentifierName:t,evaluateExpressionWithNamespace:n}=e;return (r,s,o)=>{let a={},c=(i,p)=>{i==="dangerouslySetInnerHTML"&&me(p),a[i]=p;};return r.forEach(i=>{if(i.type==="JSXSpreadAttribute"){let l=n(i.argument,s,o);l&&typeof l=="object"&&!Array.isArray(l)&&Object.assign(a,l);return}let p=t(i.name);if(le(p),!i.value){c(p,true);return}if(i.value.type==="Literal"){c(p,i.value.value);return}if(i.value.type==="JSXExpressionContainer"){if(i.value.expression.type==="JSXEmptyExpression")return;c(p,n(i.value.expression,s,o));}}),a}};var _=null,H=e=>{_=e;},L="Capture",I=e=>e.endsWith(L)?{eventName:e.slice(0,-L.length),capture:true}:{eventName:e,capture:false},B=e=>{if(!e.startsWith("on"))return null;if(e.startsWith("on:")){let r=e.slice(3);if(!r)return null;let s=I(r);return s.eventName?s:null}let t=e.slice(2);if(!t)return null;let n=I(t);return n.eventName?{eventName:n.eventName.toLowerCase(),capture:n.capture}:null},W=e=>!e||typeof e!="object"?false:"handleEvent"in e&&typeof e.handleEvent=="function",ue=e=>{if(!e||typeof e!="object"||!("handler"in e))return false;let t=e.handler;return typeof t=="function"?true:W(t)},de=(e,t)=>{_?.onInvalidHandler?.(e,t);},V=(e,t)=>{if(typeof t=="function"||W(t))return {listener:t};if(!ue(t))return de(e,t),null;let n=t,r=n.options?{...n.options}:void 0,s=(o,a)=>{a!=null&&(r||(r={}),r[o]=a);};return s("capture",n.capture),s("once",n.once),s("passive",n.passive),s("signal",n.signal??void 0),{listener:n.handler,options:r}};var ge="@knighted/jsx",U=e=>`${ge}: ${e}`,C=()=>typeof process<"u"&&process.env?.KNIGHTED_JSX_DEBUG==="1",v=e=>{if(e===null)return "null";if(e===void 0)return "undefined";if(typeof e=="function")return e.name?`function ${e.name}`:"function";if(Array.isArray(e))return "array";if(typeof e=="object"){let t=e.constructor;return t&&typeof t.name=="string"&&t.name&&t.name!=="Object"?`${t.name} instance`:"object"}return typeof e},b=e=>new Error(U(e)),z=(e,t=false)=>{!t&&!C()||typeof console<"u"&&typeof console.warn=="function"&&console.warn(U(e));};var fe=e=>e>="a"&&e<="z",S="env",k=()=>S==="always"||S==="env"&&C(),xe=()=>S==="always",ye={warnLowercaseEventProp(e){if(!k()||!e.startsWith("on")||e.startsWith("on:")||e.length<3)return;let t=e[2]??"";if(!fe(t))return;let n=`${e.slice(0,2)}${t.toUpperCase()}${e.slice(3)}`;z(`Use camelCase DOM event props when targeting runtime jsx templates. Received "${e}"; did you mean "${n}"?`,xe());},ensureValidDangerouslySetInnerHTML(e){if(!k())return;if(!e||typeof e!="object"||Array.isArray(e))throw b("dangerouslySetInnerHTML expects an object with a string __html field.");let t=e.__html;if(typeof t!="string")throw b(`dangerouslySetInnerHTML.__html must be a string but received ${v(t)}.`)}},Ee={onInvalidHandler(e,t){if(k())throw b(`The "${e}" prop expects a function, EventListenerObject, or descriptor ({ handler }) but received ${v(t)}.`)}},K=e=>{S=e?.mode,O(ye),H(Ee);};var G=e=>{let t=e.replace(/\r/g,"").replace(/\n\s+/g," "),n=e.match(/^\s*/)?.[0]??"",r=e.match(/\s*$/)?.[0]??"",s=/\n/.test(n),o=/\n/.test(r),a=t;return s&&(a=a.replace(/^\s+/,"")),o&&(a=a.replace(/\s+$/,"")),a.length===0||a.trim().length===0?null:a};var he="oxc-parser",be=e=>{let t=e.raw??e,n=t[0]??"",r=[];for(let s=0;s<t.length-1;s++){let o="${expr#"+s+"}",a=n.length;n+=o;let c=n.length;r.push({index:s,templateStart:a,templateEnd:c,label:o}),n+=t[s+1]??"";}return {source:n,spans:r}},Se=(e,t)=>{let n=new Map;return t.forEach(r=>{n.set(r.index,r);}),e.expressionRanges.map(r=>{let s=n.get(r.index);if(!s)return null;let o=Math.max(0,r.sourceEnd-r.sourceStart),a=Math.max(0,s.templateEnd-s.templateStart);return {sourceStart:r.sourceStart,sourceEnd:r.sourceEnd,templateStart:s.templateStart,templateEnd:s.templateEnd,delta:a-o}}).filter(r=>!!r).sort((r,s)=>r.sourceStart-s.sourceStart)},Je=(e,t,n)=>{if(!Number.isFinite(e)||e<=0)return 0;let r=0;for(let o of t){if(e<o.sourceStart)break;if(e<o.sourceEnd){let a=Math.max(0,e-o.sourceStart),c=Math.max(0,o.templateEnd-o.templateStart);if(c===0)return o.templateStart;let i=Math.min(a,Math.max(0,c-1));return o.templateStart+i}r+=o.delta;}let s=e+r;return s<=0?0:s>=n?n:s},Z=(e,t)=>{let n=Math.max(0,Math.min(t,e.length)),r=1,s=1;for(let o=0;o<n;o++){if(e.charCodeAt(o)===10){r++,s=1;continue}s++;}return {line:r,column:s}},Te=e=>{let t=[],n=0;return e.forEach((r,s)=>{t.push(n),n+=r.length,s<e.length-1&&(n+=1);}),t},we=(e,t,n,r,s,o,a)=>{let c=n+t.length,i=Math.max(r,n),p=Math.min(s,c);if(p>i){let l=Math.max(0,i-n),u=Math.max(1,p-i);return " ".repeat(l)+"^".repeat(u)}if(t.length===0&&e>=o&&e<=a)return "^";if(e===o){let l=Math.max(0,r-n);return " ".repeat(Math.min(l,t.length))+"^"}return ""},Ce=(e,t,n,r,s)=>{if(!e.length)return "";let o=e.split(`
|
|
2
|
+
`),a=Te(o),c=Math.max(1,r-1),i=Math.min(o.length,s+1),p=String(i).length,l=[];for(let u=c;u<=i;u++){let d=o[u-1]??"",m=String(u).padStart(p," ");l.push(`${m} | ${d}`);let g=we(u,d,a[u-1]??0,t,n,r,s);g&&l.push(`${" ".repeat(p)} | ${g}`);}return l.join(`
|
|
3
|
+
`)},A=(e,t,n,r,s)=>{let o=he,a=`[${o}] ${r.message}`,c=r.labels?.[0];if(!c)return a;let{source:i,spans:p}=be(t),l=Se(n,p),u=y=>Je(typeof y=="number"?y:0,l,i.length),d=u(c.start),m=u(c.end);m<=d&&(m=Math.min(i.length,d+1));let g=Z(i,d),x=Z(i,Math.max(d,m-1)),h=Ce(i,d,m,g.line,x.line),f=`[${o}] ${r.message}`;return f+=`
|
|
4
4
|
--> ${e} template:${g.line}:${g.column}`,c.message&&(f+=`
|
|
5
5
|
${c.message}`),h&&(f+=`
|
|
6
6
|
${h}`),r.helpMessage&&(f+=`
|
|
7
|
-
${r.helpMessage}`),f};var
|
|
8
|
-
export{
|
|
7
|
+
${r.helpMessage}`),f};var ve=/<\s*$/,ke=/<\/\s*$/,Q="__KX_EXPR__",q=new RegExp(`${Q}\\d+_\\d+__`,"g"),Ae=0;var Y={lang:"jsx",sourceType:"module",range:true,preserveParens:true},ee=e=>{for(let t of e.body)if(t.type==="ExpressionStatement"){let n=t.expression;if(n.type==="JSXElement"||n.type==="JSXFragment")return n}throw new Error("The jsx template must contain a single JSX element or fragment.")},J=e=>{switch(e.type){case "JSXIdentifier":return e.name;case "JSXNamespacedName":return `${e.namespace.name}:${e.name.name}`;case "JSXMemberExpression":return `${J(e.object)}.${e.property.name}`;default:return ""}},R=(e,t)=>{if(!e||typeof e!="object")return;let n=e;typeof n.type=="string"&&(t(n),Object.values(n).forEach(r=>{if(r){if(Array.isArray(r)){r.forEach(s=>R(s,t));return}typeof r=="object"&&R(r,t);}}));},te=(e,t)=>{let n=G(e);if(!n)return [];let r=[];q.lastIndex=0;let s=0,o;for(;o=q.exec(n);){let c=o.index,i=n.slice(s,c);i&&r.push(i);let p=o[0];t.has(p)?r.push(t.get(p)):r.push(p),s=c+p.length;}let a=n.slice(s);return a&&r.push(a),r},Re=(e,t)=>{let n=new Set;return R(e,r=>{r.type==="Identifier"&&t.placeholders.has(r.name)&&n.add(r.name);}),Array.from(n)},ne=(e,t,n)=>{if(e.type==="JSXElement"||e.type==="JSXFragment")return n(e);if(!("range"in e)||!e.range)throw new Error("Unable to evaluate expression: missing source range information.");let[r,s]=e.range,o=t.source.slice(r,s),a=Re(e,t);try{let c=new Function(...a,`"use strict"; return (${o});`),i=a.map(p=>t.placeholders.get(p));return c(...i)}catch(c){throw new Error(`Failed to evaluate expression ${o}: ${c.message}`,{cause:c})}},De=e=>{let t=e.replace(/[^a-zA-Z0-9_$]/g,"");return t?/[A-Za-z_$]/.test(t[0])?t:`Component${t}`:"Component"},Ne=(e,t,n)=>{let r=n.get(e);if(r)return r;let s=e.displayName||e.name||`Component${t.length}`,o=De(s??""),a=o,c=1;for(;t.some(p=>p.name===a);)a=`${o}${c++}`;let i={name:a,value:e};return t.push(i),n.set(e,i),i},re=(e,t)=>{let n=e.raw??e,r=new Map,s=[],o=new Map,a=n[0]??"",c=Ae++,i=0,p=[];for(let l=0;l<t.length;l++){let u=n[l]??"",d=n[l+1]??"",m=t[l],g=ve.test(u)||ke.test(u),x;if(g&&typeof m=="function")x=Ne(m,s,o).name;else if(g&&typeof m=="string")x=m;else {let y=`${Q}${c}_${i++}__`;r.set(y,m),x=y;}let h=a.length;a+=x;let f=a.length;p.push({index:l,sourceStart:h,sourceEnd:f}),a+=d;}return {source:a,placeholders:r,bindings:s,diagnostics:{expressionRanges:p}}};var D=Symbol.for("@knighted/jsx::Fragment"),T="__jsxNs",Pe=(e,t)=>t.length>0?t:Object.prototype.hasOwnProperty.call(e,"children")?[e.children]:[],je=(e,t)=>{let n={...e};return t.length===1?n.children=t[0]:t.length>1?n.children=t:delete n.children,n},Xe=e=>{if(!Object.prototype.hasOwnProperty.call(e,T))return;let t=e[T];if(delete e[T],t==="svg"||t===null)return t;throw new Error(`${T} must be "svg" or null when provided.`)},oe=({ensureDomAvailable:e,appendChildValue:t,setDomProp:n,isPromiseLike:r})=>{function s(o,a,...c){e();let i=a?{...a}:{},p=Pe(i,c);if(o===D){let m=document.createDocumentFragment();return p.forEach(g=>t(m,g)),m}if(typeof o=="function"){let m=o(je(i,p));if(r(m))throw new Error("Async jsx components are not supported.");return m}if(typeof o!="string")throw new Error(`Unsupported jsx createElement type: ${String(o)}`);delete i.children;let u=Xe(i)??(o==="svg"?"svg":null),d=u==="svg"?document.createElementNS("http://www.w3.org/2000/svg",o):document.createElement(o);return Object.entries(i).forEach(([m,g])=>{m!=="key"&&n(d,m,g,u);}),p.forEach(m=>t(d,m)),d}return s};var ae=()=>{if(typeof document>"u"||typeof document.createElement!="function")throw new Error("The jsx template tag requires a DOM-like environment (document missing).")},Le=e=>typeof Node>"u"?false:e instanceof Node||e instanceof DocumentFragment,Ie=e=>!e||typeof e=="string"?false:typeof e[Symbol.iterator]=="function",X=e=>!e||typeof e!="object"&&typeof e!="function"?false:typeof e.then=="function",_e={xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},ie=e=>{if(!(!e||e==="html"||e==="svg"))return _e[e]},He=e=>e==="svg"?svg:html,N=(e,t,n)=>{let r=ie(t.space),s=String(n);if(r){e.setAttributeNS(r,t.attribute,s);return}e.setAttribute(t.attribute,s);},se=(e,t)=>{let n=ie(t.space);if(n){e.removeAttributeNS(n,t.attribute);return}e.removeAttribute(t.attribute);},P=(e,t)=>Array.isArray(e)?e.filter(Boolean).join(t):e,Be=(e,t,n)=>t==="svg"||!n.property||n.property.includes(":")?false:n.property in e,pe=(e,t,n,r)=>{if(n==null)return;if(t==="dangerouslySetInnerHTML"&&typeof n=="object"&&n&&"__html"in n){e.innerHTML=String(n.__html??"");return}if(t==="ref"){if(typeof n=="function"){n(e);return}if(n&&typeof n=="object"){n.current=e;return}}if(t==="style"&&typeof n=="object"&&n!==null){let p=n,l=e.style;if(!l)return;let u=l;Object.entries(p).forEach(([d,m])=>{if(m!=null){if(d.startsWith("--")){l.setProperty(d,String(m));return}u[d]=m;}});return}let s=B(t);if(s){let p=V(t,n);if(p){let l=p.options?{...p.options}:void 0;s.capture&&(l?l.capture=true:l={capture:true}),e.addEventListener(s.eventName,p.listener,l);return}}let o=find(He(r),t),a=e,c=Be(e,r,o);if(o.mustUseProperty){let p=o.boolean?!!n:n;a[o.property]=p;return}if(o.boolean){let p=!!n;c&&(a[o.property]=p),p?N(e,o,""):se(e,o);return}let i=n;if(o.spaceSeparated?i=P(n," "):o.commaSeparated?i=P(n,","):o.commaOrSpaceSeparated&&(i=P(n," ")),o.booleanish&&typeof i=="boolean"&&(i=i?"true":"false"),o.overloadedBoolean){if(i===false){se(e,o);return}if(i===true){N(e,o,"");return}}if(c){a[o.property]=i;return}i!==false&&N(e,o,i);},E=(e,t)=>{if(t!=null&&typeof t!="boolean"){if(X(t))throw new Error("Async values are not supported inside jsx template results.");if(Array.isArray(t)){t.forEach(n=>E(e,n));return}if(Ie(t)){for(let n of t)E(e,n);return}if(Le(t)){e.appendChild(t);return}e.appendChild(document.createTextNode(String(t)));}},j=(e,t,n)=>ne(e,t,r=>$(r,t,n)),ce=F({getIdentifierName:J,evaluateExpressionWithNamespace:j}),We=(e,t,n,r)=>{let s=ce(t,n,r);Object.entries(s).forEach(([o,a])=>{if(o!=="key"){if(o==="children"){E(e,a);return}pe(e,o,a,r);}});},M=(e,t,n)=>{let r=[];return e.forEach(s=>{switch(s.type){case "JSXText":{te(s.value,t.placeholders).forEach(a=>{r.push(a);});break}case "JSXExpressionContainer":{if(s.expression.type==="JSXEmptyExpression")break;r.push(j(s.expression,t,n));break}case "JSXSpreadChild":{let o=j(s.expression,t,n);o!=null&&r.push(o);break}case "JSXElement":case "JSXFragment":{r.push($(s,t,n));break}}}),r},Ve=(e,t,n,r)=>{let s=ce(e.openingElement.attributes,t,r),o=M(e.children,t,r);o.length===1?s.children=o[0]:o.length>1&&(s.children=o);let a=n(s);if(X(a))throw new Error("Async jsx components are not supported.");return a},Ue=(e,t,n)=>{let r=e.openingElement,s=J(r.name),o=t.components.get(s);if(o)return Ve(e,t,o,n);if(/[A-Z]/.test(s[0]??""))throw new Error(`Unknown component "${s}". Did you interpolate it with the template literal?`);let a=s==="svg"?"svg":n,c=s==="foreignObject"?null:a,i=a==="svg"?document.createElementNS("http://www.w3.org/2000/svg",s):document.createElement(s);return We(i,r.attributes,t,a),M(e.children,t,c).forEach(l=>E(i,l)),i},$=(e,t,n)=>{if(e.type==="JSXFragment"){let r=document.createDocumentFragment();return M(e.children,t,n).forEach(o=>E(r,o)),r}return Ue(e,t,n)},ze=oe({ensureDomAvailable:ae,appendChildValue:E,setDomProp:pe,isPromiseLike:X}),Ke=(e,...t)=>{ae();let n=re(e,t),r=parseSync("inline.jsx",n.source,Y);if(r.errors.length>0)throw new Error(A("jsx",e,n.diagnostics,r.errors[0]));let s=ee(r.program),o={source:n.source,placeholders:n.placeholders,components:new Map(n.bindings.map(a=>[a.name,a.value]))};return $(s,o,null)},Ge=Object.assign(Ke,{createElement:ze,Fragment:D});K({mode:"always"});
|
|
8
|
+
export{Ge as jsx};
|
package/dist/lite/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {parseSync}from'oxc-parser';import {find,svg,html}from'property-information';var
|
|
2
|
-
`),a=
|
|
3
|
-
`)},
|
|
4
|
-
--> ${e} template:${g.line}:${g.column}`,
|
|
5
|
-
${
|
|
1
|
+
import {parseSync}from'oxc-parser';import {find,svg,html}from'property-information';var P=e=>{let t=e.replace(/\r/g,"").replace(/\n\s+/g," "),n=e.match(/^\s*/)?.[0]??"",r=e.match(/\s*$/)?.[0]??"",s=/\n/.test(n),o=/\n/.test(r),a=t;return s&&(a=a.replace(/^\s+/,"")),o&&(a=a.replace(/\s+$/,"")),a.length===0||a.trim().length===0?null:a};var Y="oxc-parser",ee=e=>{let t=e.raw??e,n=t[0]??"",r=[];for(let s=0;s<t.length-1;s++){let o="${expr#"+s+"}",a=n.length;n+=o;let l=n.length;r.push({index:s,templateStart:a,templateEnd:l,label:o}),n+=t[s+1]??"";}return {source:n,spans:r}},te=(e,t)=>{let n=new Map;return t.forEach(r=>{n.set(r.index,r);}),e.expressionRanges.map(r=>{let s=n.get(r.index);if(!s)return null;let o=Math.max(0,r.sourceEnd-r.sourceStart),a=Math.max(0,s.templateEnd-s.templateStart);return {sourceStart:r.sourceStart,sourceEnd:r.sourceEnd,templateStart:s.templateStart,templateEnd:s.templateEnd,delta:a-o}}).filter(r=>!!r).sort((r,s)=>r.sourceStart-s.sourceStart)},ne=(e,t,n)=>{if(!Number.isFinite(e)||e<=0)return 0;let r=0;for(let o of t){if(e<o.sourceStart)break;if(e<o.sourceEnd){let a=Math.max(0,e-o.sourceStart),l=Math.max(0,o.templateEnd-o.templateStart);if(l===0)return o.templateStart;let i=Math.min(a,Math.max(0,l-1));return o.templateStart+i}r+=o.delta;}let s=e+r;return s<=0?0:s>=n?n:s},X=(e,t)=>{let n=Math.max(0,Math.min(t,e.length)),r=1,s=1;for(let o=0;o<n;o++){if(e.charCodeAt(o)===10){r++,s=1;continue}s++;}return {line:r,column:s}},re=e=>{let t=[],n=0;return e.forEach((r,s)=>{t.push(n),n+=r.length,s<e.length-1&&(n+=1);}),t},oe=(e,t,n,r,s,o,a)=>{let l=n+t.length,i=Math.max(r,n),p=Math.min(s,l);if(p>i){let c=Math.max(0,i-n),u=Math.max(1,p-i);return " ".repeat(c)+"^".repeat(u)}if(t.length===0&&e>=o&&e<=a)return "^";if(e===o){let c=Math.max(0,r-n);return " ".repeat(Math.min(c,t.length))+"^"}return ""},se=(e,t,n,r,s)=>{if(!e.length)return "";let o=e.split(`
|
|
2
|
+
`),a=re(o),l=Math.max(1,r-1),i=Math.min(o.length,s+1),p=String(i).length,c=[];for(let u=l;u<=i;u++){let d=o[u-1]??"",m=String(u).padStart(p," ");c.push(`${m} | ${d}`);let g=oe(u,d,a[u-1]??0,t,n,r,s);g&&c.push(`${" ".repeat(p)} | ${g}`);}return c.join(`
|
|
3
|
+
`)},J=(e,t,n,r,s)=>{let o=Y,a=`[${o}] ${r.message}`,l=r.labels?.[0];if(!l)return a;let{source:i,spans:p}=ee(t),c=te(n,p),u=E=>ne(typeof E=="number"?E:0,c,i.length),d=u(l.start),m=u(l.end);m<=d&&(m=Math.min(i.length,d+1));let g=X(i,d),x=X(i,Math.max(d,m-1)),h=se(i,d,m,g.line,x.line),f=`[${o}] ${r.message}`;return f+=`
|
|
4
|
+
--> ${e} template:${g.line}:${g.column}`,l.message&&(f+=`
|
|
5
|
+
${l.message}`),h&&(f+=`
|
|
6
6
|
${h}`),r.helpMessage&&(f+=`
|
|
7
|
-
${r.helpMessage}`),f};var
|
|
8
|
-
export{
|
|
7
|
+
${r.helpMessage}`),f};var ae=/<\s*$/,ie=/<\/\s*$/,D="__KX_EXPR__",j=new RegExp(`${D}\\d+_\\d+__`,"g"),pe=0;var F={lang:"jsx",sourceType:"module",range:true,preserveParens:true},M=e=>{for(let t of e.body)if(t.type==="ExpressionStatement"){let n=t.expression;if(n.type==="JSXElement"||n.type==="JSXFragment")return n}throw new Error("The jsx template must contain a single JSX element or fragment.")},b=e=>{switch(e.type){case "JSXIdentifier":return e.name;case "JSXNamespacedName":return `${e.namespace.name}:${e.name.name}`;case "JSXMemberExpression":return `${b(e.object)}.${e.property.name}`;default:return ""}},T=(e,t)=>{if(!e||typeof e!="object")return;let n=e;typeof n.type=="string"&&(t(n),Object.values(n).forEach(r=>{if(r){if(Array.isArray(r)){r.forEach(s=>T(s,t));return}typeof r=="object"&&T(r,t);}}));},O=(e,t)=>{let n=P(e);if(!n)return [];let r=[];j.lastIndex=0;let s=0,o;for(;o=j.exec(n);){let l=o.index,i=n.slice(s,l);i&&r.push(i);let p=o[0];t.has(p)?r.push(t.get(p)):r.push(p),s=l+p.length;}let a=n.slice(s);return a&&r.push(a),r},le=(e,t)=>{let n=new Set;return T(e,r=>{r.type==="Identifier"&&t.placeholders.has(r.name)&&n.add(r.name);}),Array.from(n)},L=(e,t,n)=>{if(e.type==="JSXElement"||e.type==="JSXFragment")return n(e);if(!("range"in e)||!e.range)throw new Error("Unable to evaluate expression: missing source range information.");let[r,s]=e.range,o=t.source.slice(r,s),a=le(e,t);try{let l=new Function(...a,`"use strict"; return (${o});`),i=a.map(p=>t.placeholders.get(p));return l(...i)}catch(l){throw new Error(`Failed to evaluate expression ${o}: ${l.message}`,{cause:l})}},ce=e=>{let t=e.replace(/[^a-zA-Z0-9_$]/g,"");return t?/[A-Za-z_$]/.test(t[0])?t:`Component${t}`:"Component"},me=(e,t,n)=>{let r=n.get(e);if(r)return r;let s=e.displayName||e.name||`Component${t.length}`,o=ce(s??""),a=o,l=1;for(;t.some(p=>p.name===a);)a=`${o}${l++}`;let i={name:a,value:e};return t.push(i),n.set(e,i),i},$=(e,t)=>{let n=e.raw??e,r=new Map,s=[],o=new Map,a=n[0]??"",l=pe++,i=0,p=[];for(let c=0;c<t.length;c++){let u=n[c]??"",d=n[c+1]??"",m=t[c],g=ae.test(u)||ie.test(u),x;if(g&&typeof m=="function")x=me(m,s,o).name;else if(g&&typeof m=="string")x=m;else {let E=`${D}${l}_${i++}__`;r.set(E,m),x=E;}let h=a.length;a+=x;let f=a.length;p.push({index:c,sourceStart:h,sourceEnd:f}),a+=d;}return {source:a,placeholders:r,bindings:s,diagnostics:{expressionRanges:p}}};var _=e=>{let{getIdentifierName:t,evaluateExpressionWithNamespace:n}=e;return (r,s,o)=>{let a={},l=(i,p)=>{a[i]=p;};return r.forEach(i=>{if(i.type==="JSXSpreadAttribute"){let c=n(i.argument,s,o);c&&typeof c=="object"&&!Array.isArray(c)&&Object.assign(a,c);return}let p=t(i.name);if(!i.value){l(p,true);return}if(i.value.type==="Literal"){l(p,i.value.value);return}if(i.value.type==="JSXExpressionContainer"){if(i.value.expression.type==="JSXEmptyExpression")return;l(p,n(i.value.expression,s,o));}}),a}};var H="Capture",B=e=>e.endsWith(H)?{eventName:e.slice(0,-H.length),capture:true}:{eventName:e,capture:false},W=e=>{if(!e.startsWith("on"))return null;if(e.startsWith("on:")){let r=e.slice(3);if(!r)return null;let s=B(r);return s.eventName?s:null}let t=e.slice(2);if(!t)return null;let n=B(t);return n.eventName?{eventName:n.eventName.toLowerCase(),capture:n.capture}:null},V=e=>!e||typeof e!="object"?false:"handleEvent"in e&&typeof e.handleEvent=="function",fe=e=>{if(!e||typeof e!="object"||!("handler"in e))return false;let t=e.handler;return typeof t=="function"?true:V(t)},z=(e,t)=>{if(typeof t=="function"||V(t))return {listener:t};if(!fe(t))return null;let n=t,r=n.options?{...n.options}:void 0,s=(o,a)=>{a!=null&&(r||(r={}),r[o]=a);};return s("capture",n.capture),s("once",n.once),s("passive",n.passive),s("signal",n.signal??void 0),{listener:n.handler,options:r}};var w=Symbol.for("@knighted/jsx::Fragment"),S="__jsxNs",Ee=(e,t)=>t.length>0?t:Object.prototype.hasOwnProperty.call(e,"children")?[e.children]:[],ye=(e,t)=>{let n={...e};return t.length===1?n.children=t[0]:t.length>1?n.children=t:delete n.children,n},he=e=>{if(!Object.prototype.hasOwnProperty.call(e,S))return;let t=e[S];if(delete e[S],t==="svg"||t===null)return t;throw new Error(`${S} must be "svg" or null when provided.`)},U=({ensureDomAvailable:e,appendChildValue:t,setDomProp:n,isPromiseLike:r})=>{function s(o,a,...l){e();let i=a?{...a}:{},p=Ee(i,l);if(o===w){let m=document.createDocumentFragment();return p.forEach(g=>t(m,g)),m}if(typeof o=="function"){let m=o(ye(i,p));if(r(m))throw new Error("Async jsx components are not supported.");return m}if(typeof o!="string")throw new Error(`Unsupported jsx createElement type: ${String(o)}`);delete i.children;let u=he(i)??(o==="svg"?"svg":null),d=u==="svg"?document.createElementNS("http://www.w3.org/2000/svg",o):document.createElement(o);return Object.entries(i).forEach(([m,g])=>{m!=="key"&&n(d,m,g,u);}),p.forEach(m=>t(d,m)),d}return s};var Z=()=>{if(typeof document>"u"||typeof document.createElement!="function")throw new Error("The jsx template tag requires a DOM-like environment (document missing).")},we=e=>typeof Node>"u"?false:e instanceof Node||e instanceof DocumentFragment,Ce=e=>!e||typeof e=="string"?false:typeof e[Symbol.iterator]=="function",R=e=>!e||typeof e!="object"&&typeof e!="function"?false:typeof e.then=="function",ke={xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},q=e=>{if(!(!e||e==="html"||e==="svg"))return ke[e]},ve=e=>e==="svg"?svg:html,C=(e,t,n)=>{let r=q(t.space),s=String(n);if(r){e.setAttributeNS(r,t.attribute,s);return}e.setAttribute(t.attribute,s);},K=(e,t)=>{let n=q(t.space);if(n){e.removeAttributeNS(n,t.attribute);return}e.removeAttribute(t.attribute);},k=(e,t)=>Array.isArray(e)?e.filter(Boolean).join(t):e,Re=(e,t,n)=>t==="svg"||!n.property||n.property.includes(":")?false:n.property in e,G=(e,t,n,r)=>{if(n==null)return;if(t==="dangerouslySetInnerHTML"&&typeof n=="object"&&n&&"__html"in n){e.innerHTML=String(n.__html??"");return}if(t==="ref"){if(typeof n=="function"){n(e);return}if(n&&typeof n=="object"){n.current=e;return}}if(t==="style"&&typeof n=="object"&&n!==null){let p=n,c=e.style;if(!c)return;let u=c;Object.entries(p).forEach(([d,m])=>{if(m!=null){if(d.startsWith("--")){c.setProperty(d,String(m));return}u[d]=m;}});return}let s=W(t);if(s){let p=z(t,n);if(p){let c=p.options?{...p.options}:void 0;s.capture&&(c?c.capture=true:c={capture:true}),e.addEventListener(s.eventName,p.listener,c);return}}let o=find(ve(r),t),a=e,l=Re(e,r,o);if(o.mustUseProperty){let p=o.boolean?!!n:n;a[o.property]=p;return}if(o.boolean){let p=!!n;l&&(a[o.property]=p),p?C(e,o,""):K(e,o);return}let i=n;if(o.spaceSeparated?i=k(n," "):o.commaSeparated?i=k(n,","):o.commaOrSpaceSeparated&&(i=k(n," ")),o.booleanish&&typeof i=="boolean"&&(i=i?"true":"false"),o.overloadedBoolean){if(i===false){K(e,o);return}if(i===true){C(e,o,"");return}}if(l){a[o.property]=i;return}i!==false&&C(e,o,i);},y=(e,t)=>{if(t!=null&&typeof t!="boolean"){if(R(t))throw new Error("Async values are not supported inside jsx template results.");if(Array.isArray(t)){t.forEach(n=>y(e,n));return}if(Ce(t)){for(let n of t)y(e,n);return}if(we(t)){e.appendChild(t);return}e.appendChild(document.createTextNode(String(t)));}},v=(e,t,n)=>L(e,t,r=>N(r,t,n)),Q=_({getIdentifierName:b,evaluateExpressionWithNamespace:v}),Ae=(e,t,n,r)=>{let s=Q(t,n,r);Object.entries(s).forEach(([o,a])=>{if(o!=="key"){if(o==="children"){y(e,a);return}G(e,o,a,r);}});},A=(e,t,n)=>{let r=[];return e.forEach(s=>{switch(s.type){case "JSXText":{O(s.value,t.placeholders).forEach(a=>{r.push(a);});break}case "JSXExpressionContainer":{if(s.expression.type==="JSXEmptyExpression")break;r.push(v(s.expression,t,n));break}case "JSXSpreadChild":{let o=v(s.expression,t,n);o!=null&&r.push(o);break}case "JSXElement":case "JSXFragment":{r.push(N(s,t,n));break}}}),r},Ne=(e,t,n,r)=>{let s=Q(e.openingElement.attributes,t,r),o=A(e.children,t,r);o.length===1?s.children=o[0]:o.length>1&&(s.children=o);let a=n(s);if(R(a))throw new Error("Async jsx components are not supported.");return a},Pe=(e,t,n)=>{let r=e.openingElement,s=b(r.name),o=t.components.get(s);if(o)return Ne(e,t,o,n);if(/[A-Z]/.test(s[0]??""))throw new Error(`Unknown component "${s}". Did you interpolate it with the template literal?`);let a=s==="svg"?"svg":n,l=s==="foreignObject"?null:a,i=a==="svg"?document.createElementNS("http://www.w3.org/2000/svg",s):document.createElement(s);return Ae(i,r.attributes,t,a),A(e.children,t,l).forEach(c=>y(i,c)),i},N=(e,t,n)=>{if(e.type==="JSXFragment"){let r=document.createDocumentFragment();return A(e.children,t,n).forEach(o=>y(r,o)),r}return Pe(e,t,n)},Xe=U({ensureDomAvailable:Z,appendChildValue:y,setDomProp:G,isPromiseLike:R}),je=(e,...t)=>{Z();let n=$(e,t),r=parseSync("inline.jsx",n.source,F);if(r.errors.length>0)throw new Error(J("jsx",e,n.diagnostics,r.errors[0]));let s=M(r.program),o={source:n.source,placeholders:n.placeholders,components:new Map(n.bindings.map(a=>[a.name,a.value]))};return N(s,o,null)},De=Object.assign(je,{createElement:Xe,Fragment:w});
|
|
8
|
+
export{De as jsx};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {createRequire}from'module';import {parseSync}from'oxc-parser';import {find,svg,html}from'property-information';var T=null,I=e=>{T=e;},
|
|
2
|
-
`),a=
|
|
3
|
-
`)},
|
|
4
|
-
--> ${e} template:${
|
|
5
|
-
${c.message}`),
|
|
6
|
-
${
|
|
7
|
-
${r.helpMessage}`),
|
|
8
|
-
export{
|
|
1
|
+
import {createRequire}from'module';import {parseSync}from'oxc-parser';import {find,svg,html}from'property-information';var T=null,I=e=>{T=e;},Ee=e=>{T?.warnLowercaseEventProp?.(e);},ye=e=>{T?.ensureValidDangerouslySetInnerHTML?.(e);},$=e=>{let{getIdentifierName:t,evaluateExpressionWithNamespace:n}=e;return (r,s,o)=>{let a={},c=(i,p)=>{i==="dangerouslySetInnerHTML"&&ye(p),a[i]=p;};return r.forEach(i=>{if(i.type==="JSXSpreadAttribute"){let l=n(i.argument,s,o);l&&typeof l=="object"&&!Array.isArray(l)&&Object.assign(a,l);return}let p=t(i.name);if(Ee(p),!i.value){c(p,true);return}if(i.value.type==="Literal"){c(p,i.value.value);return}if(i.value.type==="JSXExpressionContainer"){if(i.value.expression.type==="JSXEmptyExpression")return;c(p,n(i.value.expression,s,o));}}),a}};var W=null,B=e=>{W=e;},F="Capture",H=e=>e.endsWith(F)?{eventName:e.slice(0,-F.length),capture:true}:{eventName:e,capture:false},V=e=>{if(!e.startsWith("on"))return null;if(e.startsWith("on:")){let r=e.slice(3);if(!r)return null;let s=H(r);return s.eventName?s:null}let t=e.slice(2);if(!t)return null;let n=H(t);return n.eventName?{eventName:n.eventName.toLowerCase(),capture:n.capture}:null},U=e=>!e||typeof e!="object"?false:"handleEvent"in e&&typeof e.handleEvent=="function",he=e=>{if(!e||typeof e!="object"||!("handler"in e))return false;let t=e.handler;return typeof t=="function"?true:U(t)},be=(e,t)=>{W?.onInvalidHandler?.(e,t);},z=(e,t)=>{if(typeof t=="function"||U(t))return {listener:t};if(!he(t))return be(e,t),null;let n=t,r=n.options?{...n.options}:void 0,s=(o,a)=>{a!=null&&(r||(r={}),r[o]=a);};return s("capture",n.capture),s("once",n.once),s("passive",n.passive),s("signal",n.signal??void 0),{listener:n.handler,options:r}};var Se="@knighted/jsx",q=e=>`${Se}: ${e}`,C=()=>typeof process<"u"&&process.env?.KNIGHTED_JSX_DEBUG==="1",k=e=>{if(e===null)return "null";if(e===void 0)return "undefined";if(typeof e=="function")return e.name?`function ${e.name}`:"function";if(Array.isArray(e))return "array";if(typeof e=="object"){let t=e.constructor;return t&&typeof t.name=="string"&&t.name&&t.name!=="Object"?`${t.name} instance`:"object"}return typeof e},b=e=>new Error(q(e)),G=(e,t=false)=>{!t&&!C()||typeof console<"u"&&typeof console.warn=="function"&&console.warn(q(e));};var we=e=>e>="a"&&e<="z",S="env",v=()=>S==="always"||S==="env"&&C(),Je=()=>S==="always",Te={warnLowercaseEventProp(e){if(!v()||!e.startsWith("on")||e.startsWith("on:")||e.length<3)return;let t=e[2]??"";if(!we(t))return;let n=`${e.slice(0,2)}${t.toUpperCase()}${e.slice(3)}`;G(`Use camelCase DOM event props when targeting runtime jsx templates. Received "${e}"; did you mean "${n}"?`,Je());},ensureValidDangerouslySetInnerHTML(e){if(!v())return;if(!e||typeof e!="object"||Array.isArray(e))throw b("dangerouslySetInnerHTML expects an object with a string __html field.");let t=e.__html;if(typeof t!="string")throw b(`dangerouslySetInnerHTML.__html must be a string but received ${k(t)}.`)}},Ce={onInvalidHandler(e,t){if(v())throw b(`The "${e}" prop expects a function, EventListenerObject, or descriptor ({ handler }) but received ${k(t)}.`)}},K=e=>{S=e?.mode,I(Te),B(Ce);};var ve=createRequire(import.meta.url),Y=()=>ve,Q="<!doctype html><html><body></body></html>",Re=["window","self","document","HTMLElement","Element","Node","DocumentFragment","customElements","Text","Comment","MutationObserver","navigator"],Ae=()=>typeof document<"u"&&typeof document.createElement=="function",Ne=e=>{let t=globalThis,n=e;Re.forEach(r=>{t[r]===void 0&&n[r]!==void 0&&(t[r]=n[r]);});},D=()=>{let{parseHTML:e}=Y()("linkedom"),{window:t}=e(Q);return t},R=()=>{let{JSDOM:e}=Y()("jsdom"),{window:t}=new e(Q);return t},Pe=()=>{let e=typeof process<"u"&&process.env?.KNIGHTED_JSX_NODE_SHIM?process.env.KNIGHTED_JSX_NODE_SHIM.toLowerCase():void 0;return e==="linkedom"||e==="jsdom"?e:"auto"},je=()=>{let e=Pe();return e==="linkedom"?[D,R]:e==="jsdom"?[R,D]:[D,R]},Me=()=>{let e=[];for(let n of je())try{return n()}catch(r){e.push(r);}let t='Unable to bootstrap a DOM-like environment. Install "linkedom" or "jsdom" (both optional peer dependencies) or set KNIGHTED_JSX_NODE_SHIM to pick one explicitly.';throw new AggregateError(e,t)},Z=false,ee=()=>{if(Ae()||Z)return;let e=Me();Ne(e),Z=true;};var te=e=>{let t=e.replace(/\r/g,"").replace(/\n\s+/g," "),n=e.match(/^\s*/)?.[0]??"",r=e.match(/\s*$/)?.[0]??"",s=/\n/.test(n),o=/\n/.test(r),a=t;return s&&(a=a.replace(/^\s+/,"")),o&&(a=a.replace(/\s+$/,"")),a.length===0||a.trim().length===0?null:a};var Xe="oxc-parser",Le=e=>{let t=e.raw??e,n=t[0]??"",r=[];for(let s=0;s<t.length-1;s++){let o="${expr#"+s+"}",a=n.length;n+=o;let c=n.length;r.push({index:s,templateStart:a,templateEnd:c,label:o}),n+=t[s+1]??"";}return {source:n,spans:r}},Oe=(e,t)=>{let n=new Map;return t.forEach(r=>{n.set(r.index,r);}),e.expressionRanges.map(r=>{let s=n.get(r.index);if(!s)return null;let o=Math.max(0,r.sourceEnd-r.sourceStart),a=Math.max(0,s.templateEnd-s.templateStart);return {sourceStart:r.sourceStart,sourceEnd:r.sourceEnd,templateStart:s.templateStart,templateEnd:s.templateEnd,delta:a-o}}).filter(r=>!!r).sort((r,s)=>r.sourceStart-s.sourceStart)},_e=(e,t,n)=>{if(!Number.isFinite(e)||e<=0)return 0;let r=0;for(let o of t){if(e<o.sourceStart)break;if(e<o.sourceEnd){let a=Math.max(0,e-o.sourceStart),c=Math.max(0,o.templateEnd-o.templateStart);if(c===0)return o.templateStart;let i=Math.min(a,Math.max(0,c-1));return o.templateStart+i}r+=o.delta;}let s=e+r;return s<=0?0:s>=n?n:s},ne=(e,t)=>{let n=Math.max(0,Math.min(t,e.length)),r=1,s=1;for(let o=0;o<n;o++){if(e.charCodeAt(o)===10){r++,s=1;continue}s++;}return {line:r,column:s}},Ie=e=>{let t=[],n=0;return e.forEach((r,s)=>{t.push(n),n+=r.length,s<e.length-1&&(n+=1);}),t},$e=(e,t,n,r,s,o,a)=>{let c=n+t.length,i=Math.max(r,n),p=Math.min(s,c);if(p>i){let l=Math.max(0,i-n),u=Math.max(1,p-i);return " ".repeat(l)+"^".repeat(u)}if(t.length===0&&e>=o&&e<=a)return "^";if(e===o){let l=Math.max(0,r-n);return " ".repeat(Math.min(l,t.length))+"^"}return ""},Fe=(e,t,n,r,s)=>{if(!e.length)return "";let o=e.split(`
|
|
2
|
+
`),a=Ie(o),c=Math.max(1,r-1),i=Math.min(o.length,s+1),p=String(i).length,l=[];for(let u=c;u<=i;u++){let d=o[u-1]??"",m=String(u).padStart(p," ");l.push(`${m} | ${d}`);let g=$e(u,d,a[u-1]??0,t,n,r,s);g&&l.push(`${" ".repeat(p)} | ${g}`);}return l.join(`
|
|
3
|
+
`)},A=(e,t,n,r,s)=>{let o=Xe,a=`[${o}] ${r.message}`,c=r.labels?.[0];if(!c)return a;let{source:i,spans:p}=Le(t),l=Oe(n,p),u=E=>_e(typeof E=="number"?E:0,l,i.length),d=u(c.start),m=u(c.end);m<=d&&(m=Math.min(i.length,d+1));let g=ne(i,d),x=ne(i,Math.max(d,m-1)),h=Fe(i,d,m,g.line,x.line),f=`[${o}] ${r.message}`;return f+=`
|
|
4
|
+
--> ${e} template:${g.line}:${g.column}`,c.message&&(f+=`
|
|
5
|
+
${c.message}`),h&&(f+=`
|
|
6
|
+
${h}`),r.helpMessage&&(f+=`
|
|
7
|
+
${r.helpMessage}`),f};var He=/<\s*$/,We=/<\/\s*$/,oe="__KX_EXPR__",re=new RegExp(`${oe}\\d+_\\d+__`,"g"),Be=0;var se={lang:"jsx",sourceType:"module",range:true,preserveParens:true},ae=e=>{for(let t of e.body)if(t.type==="ExpressionStatement"){let n=t.expression;if(n.type==="JSXElement"||n.type==="JSXFragment")return n}throw new Error("The jsx template must contain a single JSX element or fragment.")},w=e=>{switch(e.type){case "JSXIdentifier":return e.name;case "JSXNamespacedName":return `${e.namespace.name}:${e.name.name}`;case "JSXMemberExpression":return `${w(e.object)}.${e.property.name}`;default:return ""}},N=(e,t)=>{if(!e||typeof e!="object")return;let n=e;typeof n.type=="string"&&(t(n),Object.values(n).forEach(r=>{if(r){if(Array.isArray(r)){r.forEach(s=>N(s,t));return}typeof r=="object"&&N(r,t);}}));},ie=(e,t)=>{let n=te(e);if(!n)return [];let r=[];re.lastIndex=0;let s=0,o;for(;o=re.exec(n);){let c=o.index,i=n.slice(s,c);i&&r.push(i);let p=o[0];t.has(p)?r.push(t.get(p)):r.push(p),s=c+p.length;}let a=n.slice(s);return a&&r.push(a),r},Ve=(e,t)=>{let n=new Set;return N(e,r=>{r.type==="Identifier"&&t.placeholders.has(r.name)&&n.add(r.name);}),Array.from(n)},pe=(e,t,n)=>{if(e.type==="JSXElement"||e.type==="JSXFragment")return n(e);if(!("range"in e)||!e.range)throw new Error("Unable to evaluate expression: missing source range information.");let[r,s]=e.range,o=t.source.slice(r,s),a=Ve(e,t);try{let c=new Function(...a,`"use strict"; return (${o});`),i=a.map(p=>t.placeholders.get(p));return c(...i)}catch(c){throw new Error(`Failed to evaluate expression ${o}: ${c.message}`,{cause:c})}},Ue=e=>{let t=e.replace(/[^a-zA-Z0-9_$]/g,"");return t?/[A-Za-z_$]/.test(t[0])?t:`Component${t}`:"Component"},ze=(e,t,n)=>{let r=n.get(e);if(r)return r;let s=e.displayName||e.name||`Component${t.length}`,o=Ue(s??""),a=o,c=1;for(;t.some(p=>p.name===a);)a=`${o}${c++}`;let i={name:a,value:e};return t.push(i),n.set(e,i),i},ce=(e,t)=>{let n=e.raw??e,r=new Map,s=[],o=new Map,a=n[0]??"",c=Be++,i=0,p=[];for(let l=0;l<t.length;l++){let u=n[l]??"",d=n[l+1]??"",m=t[l],g=He.test(u)||We.test(u),x;if(g&&typeof m=="function")x=ze(m,s,o).name;else if(g&&typeof m=="string")x=m;else {let E=`${oe}${c}_${i++}__`;r.set(E,m),x=E;}let h=a.length;a+=x;let f=a.length;p.push({index:l,sourceStart:h,sourceEnd:f}),a+=d;}return {source:a,placeholders:r,bindings:s,diagnostics:{expressionRanges:p}}};var P=Symbol.for("@knighted/jsx::Fragment"),J="__jsxNs",qe=(e,t)=>t.length>0?t:Object.prototype.hasOwnProperty.call(e,"children")?[e.children]:[],Ge=(e,t)=>{let n={...e};return t.length===1?n.children=t[0]:t.length>1?n.children=t:delete n.children,n},Ke=e=>{if(!Object.prototype.hasOwnProperty.call(e,J))return;let t=e[J];if(delete e[J],t==="svg"||t===null)return t;throw new Error(`${J} must be "svg" or null when provided.`)},le=({ensureDomAvailable:e,appendChildValue:t,setDomProp:n,isPromiseLike:r})=>{function s(o,a,...c){e();let i=a?{...a}:{},p=qe(i,c);if(o===P){let m=document.createDocumentFragment();return p.forEach(g=>t(m,g)),m}if(typeof o=="function"){let m=o(Ge(i,p));if(r(m))throw new Error("Async jsx components are not supported.");return m}if(typeof o!="string")throw new Error(`Unsupported jsx createElement type: ${String(o)}`);delete i.children;let u=Ke(i)??(o==="svg"?"svg":null),d=u==="svg"?document.createElementNS("http://www.w3.org/2000/svg",o):document.createElement(o);return Object.entries(i).forEach(([m,g])=>{m!=="key"&&n(d,m,g,u);}),p.forEach(m=>t(d,m)),d}return s};var ue=()=>{if(typeof document>"u"||typeof document.createElement!="function")throw new Error("The jsx template tag requires a DOM-like environment (document missing).")},tt=e=>typeof Node>"u"?false:e instanceof Node||e instanceof DocumentFragment,nt=e=>!e||typeof e=="string"?false:typeof e[Symbol.iterator]=="function",L=e=>!e||typeof e!="object"&&typeof e!="function"?false:typeof e.then=="function",rt={xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},de=e=>{if(!(!e||e==="html"||e==="svg"))return rt[e]},ot=e=>e==="svg"?svg:html,j=(e,t,n)=>{let r=de(t.space),s=String(n);if(r){e.setAttributeNS(r,t.attribute,s);return}e.setAttribute(t.attribute,s);},me=(e,t)=>{let n=de(t.space);if(n){e.removeAttributeNS(n,t.attribute);return}e.removeAttribute(t.attribute);},M=(e,t)=>Array.isArray(e)?e.filter(Boolean).join(t):e,st=(e,t,n)=>t==="svg"||!n.property||n.property.includes(":")?false:n.property in e,ge=(e,t,n,r)=>{if(n==null)return;if(t==="dangerouslySetInnerHTML"&&typeof n=="object"&&n&&"__html"in n){e.innerHTML=String(n.__html??"");return}if(t==="ref"){if(typeof n=="function"){n(e);return}if(n&&typeof n=="object"){n.current=e;return}}if(t==="style"&&typeof n=="object"&&n!==null){let p=n,l=e.style;if(!l)return;let u=l;Object.entries(p).forEach(([d,m])=>{if(m!=null){if(d.startsWith("--")){l.setProperty(d,String(m));return}u[d]=m;}});return}let s=V(t);if(s){let p=z(t,n);if(p){let l=p.options?{...p.options}:void 0;s.capture&&(l?l.capture=true:l={capture:true}),e.addEventListener(s.eventName,p.listener,l);return}}let o=find(ot(r),t),a=e,c=st(e,r,o);if(o.mustUseProperty){let p=o.boolean?!!n:n;a[o.property]=p;return}if(o.boolean){let p=!!n;c&&(a[o.property]=p),p?j(e,o,""):me(e,o);return}let i=n;if(o.spaceSeparated?i=M(n," "):o.commaSeparated?i=M(n,","):o.commaOrSpaceSeparated&&(i=M(n," ")),o.booleanish&&typeof i=="boolean"&&(i=i?"true":"false"),o.overloadedBoolean){if(i===false){me(e,o);return}if(i===true){j(e,o,"");return}}if(c){a[o.property]=i;return}i!==false&&j(e,o,i);},y=(e,t)=>{if(t!=null&&typeof t!="boolean"){if(L(t))throw new Error("Async values are not supported inside jsx template results.");if(Array.isArray(t)){t.forEach(n=>y(e,n));return}if(nt(t)){for(let n of t)y(e,n);return}if(tt(t)){e.appendChild(t);return}e.appendChild(document.createTextNode(String(t)));}},X=(e,t,n)=>pe(e,t,r=>_(r,t,n)),fe=$({getIdentifierName:w,evaluateExpressionWithNamespace:X}),at=(e,t,n,r)=>{let s=fe(t,n,r);Object.entries(s).forEach(([o,a])=>{if(o!=="key"){if(o==="children"){y(e,a);return}ge(e,o,a,r);}});},O=(e,t,n)=>{let r=[];return e.forEach(s=>{switch(s.type){case "JSXText":{ie(s.value,t.placeholders).forEach(a=>{r.push(a);});break}case "JSXExpressionContainer":{if(s.expression.type==="JSXEmptyExpression")break;r.push(X(s.expression,t,n));break}case "JSXSpreadChild":{let o=X(s.expression,t,n);o!=null&&r.push(o);break}case "JSXElement":case "JSXFragment":{r.push(_(s,t,n));break}}}),r},it=(e,t,n,r)=>{let s=fe(e.openingElement.attributes,t,r),o=O(e.children,t,r);o.length===1?s.children=o[0]:o.length>1&&(s.children=o);let a=n(s);if(L(a))throw new Error("Async jsx components are not supported.");return a},pt=(e,t,n)=>{let r=e.openingElement,s=w(r.name),o=t.components.get(s);if(o)return it(e,t,o,n);if(/[A-Z]/.test(s[0]??""))throw new Error(`Unknown component "${s}". Did you interpolate it with the template literal?`);let a=s==="svg"?"svg":n,c=s==="foreignObject"?null:a,i=a==="svg"?document.createElementNS("http://www.w3.org/2000/svg",s):document.createElement(s);return at(i,r.attributes,t,a),O(e.children,t,c).forEach(l=>y(i,l)),i},_=(e,t,n)=>{if(e.type==="JSXFragment"){let r=document.createDocumentFragment();return O(e.children,t,n).forEach(o=>y(r,o)),r}return pt(e,t,n)},ct=le({ensureDomAvailable:ue,appendChildValue:y,setDomProp:ge,isPromiseLike:L}),lt=(e,...t)=>{ue();let n=ce(e,t),r=parseSync("inline.jsx",n.source,se);if(r.errors.length>0)throw new Error(A("jsx",e,n.diagnostics,r.errors[0]));let s=ae(r.program),o={source:n.source,placeholders:n.placeholders,components:new Map(n.bindings.map(a=>[a.name,a.value]))};return _(s,o,null)},xe=Object.assign(lt,{createElement:ct,Fragment:P});K({mode:"always"});ee();var Ot=xe;
|
|
8
|
+
export{Ot as jsx};
|
package/dist/lite/node/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {createRequire}from'module';import {parseSync}from'oxc-parser';import {find,svg,html}from'property-information';var
|
|
2
|
-
`),a=
|
|
3
|
-
`)},T=(e,n,
|
|
4
|
-
--> ${e} template:${f.line}:${f.column}`,
|
|
5
|
-
${
|
|
1
|
+
import {createRequire}from'module';import {parseSync}from'oxc-parser';import {find,svg,html}from'property-information';var ie=createRequire(import.meta.url),X=()=>ie,M="<!doctype html><html><body></body></html>",le=["window","self","document","HTMLElement","Element","Node","DocumentFragment","customElements","Text","Comment","MutationObserver","navigator"],ce=()=>typeof document<"u"&&typeof document.createElement=="function",me=e=>{let t=globalThis,n=e;le.forEach(r=>{t[r]===void 0&&n[r]!==void 0&&(t[r]=n[r]);});},J=()=>{let{parseHTML:e}=X()("linkedom"),{window:t}=e(M);return t},w=()=>{let{JSDOM:e}=X()("jsdom"),{window:t}=new e(M);return t},ue=()=>{let e=typeof process<"u"&&process.env?.KNIGHTED_JSX_NODE_SHIM?process.env.KNIGHTED_JSX_NODE_SHIM.toLowerCase():void 0;return e==="linkedom"||e==="jsdom"?e:"auto"},de=()=>{let e=ue();return e==="linkedom"?[J,w]:e==="jsdom"?[w,J]:[J,w]},fe=()=>{let e=[];for(let n of de())try{return n()}catch(r){e.push(r);}let t='Unable to bootstrap a DOM-like environment. Install "linkedom" or "jsdom" (both optional peer dependencies) or set KNIGHTED_JSX_NODE_SHIM to pick one explicitly.';throw new AggregateError(e,t)},D=false,L=()=>{if(ce()||D)return;let e=fe();me(e),D=true;};var O=e=>{let t=e.replace(/\r/g,"").replace(/\n\s+/g," "),n=e.match(/^\s*/)?.[0]??"",r=e.match(/\s*$/)?.[0]??"",s=/\n/.test(n),o=/\n/.test(r),a=t;return s&&(a=a.replace(/^\s+/,"")),o&&(a=a.replace(/\s+$/,"")),a.length===0||a.trim().length===0?null:a};var ge="oxc-parser",xe=e=>{let t=e.raw??e,n=t[0]??"",r=[];for(let s=0;s<t.length-1;s++){let o="${expr#"+s+"}",a=n.length;n+=o;let l=n.length;r.push({index:s,templateStart:a,templateEnd:l,label:o}),n+=t[s+1]??"";}return {source:n,spans:r}},Ee=(e,t)=>{let n=new Map;return t.forEach(r=>{n.set(r.index,r);}),e.expressionRanges.map(r=>{let s=n.get(r.index);if(!s)return null;let o=Math.max(0,r.sourceEnd-r.sourceStart),a=Math.max(0,s.templateEnd-s.templateStart);return {sourceStart:r.sourceStart,sourceEnd:r.sourceEnd,templateStart:s.templateStart,templateEnd:s.templateEnd,delta:a-o}}).filter(r=>!!r).sort((r,s)=>r.sourceStart-s.sourceStart)},he=(e,t,n)=>{if(!Number.isFinite(e)||e<=0)return 0;let r=0;for(let o of t){if(e<o.sourceStart)break;if(e<o.sourceEnd){let a=Math.max(0,e-o.sourceStart),l=Math.max(0,o.templateEnd-o.templateStart);if(l===0)return o.templateStart;let i=Math.min(a,Math.max(0,l-1));return o.templateStart+i}r+=o.delta;}let s=e+r;return s<=0?0:s>=n?n:s},F=(e,t)=>{let n=Math.max(0,Math.min(t,e.length)),r=1,s=1;for(let o=0;o<n;o++){if(e.charCodeAt(o)===10){r++,s=1;continue}s++;}return {line:r,column:s}},ye=e=>{let t=[],n=0;return e.forEach((r,s)=>{t.push(n),n+=r.length,s<e.length-1&&(n+=1);}),t},be=(e,t,n,r,s,o,a)=>{let l=n+t.length,i=Math.max(r,n),p=Math.min(s,l);if(p>i){let c=Math.max(0,i-n),u=Math.max(1,p-i);return " ".repeat(c)+"^".repeat(u)}if(t.length===0&&e>=o&&e<=a)return "^";if(e===o){let c=Math.max(0,r-n);return " ".repeat(Math.min(c,t.length))+"^"}return ""},Se=(e,t,n,r,s)=>{if(!e.length)return "";let o=e.split(`
|
|
2
|
+
`),a=ye(o),l=Math.max(1,r-1),i=Math.min(o.length,s+1),p=String(i).length,c=[];for(let u=l;u<=i;u++){let d=o[u-1]??"",m=String(u).padStart(p," ");c.push(`${m} | ${d}`);let f=be(u,d,a[u-1]??0,t,n,r,s);f&&c.push(`${" ".repeat(p)} | ${f}`);}return c.join(`
|
|
3
|
+
`)},T=(e,t,n,r,s)=>{let o=ge,a=`[${o}] ${r.message}`,l=r.labels?.[0];if(!l)return a;let{source:i,spans:p}=xe(t),c=Ee(n,p),u=E=>he(typeof E=="number"?E:0,c,i.length),d=u(l.start),m=u(l.end);m<=d&&(m=Math.min(i.length,d+1));let f=F(i,d),x=F(i,Math.max(d,m-1)),y=Se(i,d,m,f.line,x.line),g=`[${o}] ${r.message}`;return g+=`
|
|
4
|
+
--> ${e} template:${f.line}:${f.column}`,l.message&&(g+=`
|
|
5
|
+
${l.message}`),y&&(g+=`
|
|
6
6
|
${y}`),r.helpMessage&&(g+=`
|
|
7
|
-
${r.helpMessage}`),g};var
|
|
8
|
-
export{
|
|
7
|
+
${r.helpMessage}`),g};var Je=/<\s*$/,we=/<\/\s*$/,_="__KX_EXPR__",I=new RegExp(`${_}\\d+_\\d+__`,"g"),Te=0;var $={lang:"jsx",sourceType:"module",range:true,preserveParens:true},H=e=>{for(let t of e.body)if(t.type==="ExpressionStatement"){let n=t.expression;if(n.type==="JSXElement"||n.type==="JSXFragment")return n}throw new Error("The jsx template must contain a single JSX element or fragment.")},b=e=>{switch(e.type){case "JSXIdentifier":return e.name;case "JSXNamespacedName":return `${e.namespace.name}:${e.name.name}`;case "JSXMemberExpression":return `${b(e.object)}.${e.property.name}`;default:return ""}},C=(e,t)=>{if(!e||typeof e!="object")return;let n=e;typeof n.type=="string"&&(t(n),Object.values(n).forEach(r=>{if(r){if(Array.isArray(r)){r.forEach(s=>C(s,t));return}typeof r=="object"&&C(r,t);}}));},W=(e,t)=>{let n=O(e);if(!n)return [];let r=[];I.lastIndex=0;let s=0,o;for(;o=I.exec(n);){let l=o.index,i=n.slice(s,l);i&&r.push(i);let p=o[0];t.has(p)?r.push(t.get(p)):r.push(p),s=l+p.length;}let a=n.slice(s);return a&&r.push(a),r},Ce=(e,t)=>{let n=new Set;return C(e,r=>{r.type==="Identifier"&&t.placeholders.has(r.name)&&n.add(r.name);}),Array.from(n)},B=(e,t,n)=>{if(e.type==="JSXElement"||e.type==="JSXFragment")return n(e);if(!("range"in e)||!e.range)throw new Error("Unable to evaluate expression: missing source range information.");let[r,s]=e.range,o=t.source.slice(r,s),a=Ce(e,t);try{let l=new Function(...a,`"use strict"; return (${o});`),i=a.map(p=>t.placeholders.get(p));return l(...i)}catch(l){throw new Error(`Failed to evaluate expression ${o}: ${l.message}`,{cause:l})}},ke=e=>{let t=e.replace(/[^a-zA-Z0-9_$]/g,"");return t?/[A-Za-z_$]/.test(t[0])?t:`Component${t}`:"Component"},ve=(e,t,n)=>{let r=n.get(e);if(r)return r;let s=e.displayName||e.name||`Component${t.length}`,o=ke(s??""),a=o,l=1;for(;t.some(p=>p.name===a);)a=`${o}${l++}`;let i={name:a,value:e};return t.push(i),n.set(e,i),i},V=(e,t)=>{let n=e.raw??e,r=new Map,s=[],o=new Map,a=n[0]??"",l=Te++,i=0,p=[];for(let c=0;c<t.length;c++){let u=n[c]??"",d=n[c+1]??"",m=t[c],f=Je.test(u)||we.test(u),x;if(f&&typeof m=="function")x=ve(m,s,o).name;else if(f&&typeof m=="string")x=m;else {let E=`${_}${l}_${i++}__`;r.set(E,m),x=E;}let y=a.length;a+=x;let g=a.length;p.push({index:c,sourceStart:y,sourceEnd:g}),a+=d;}return {source:a,placeholders:r,bindings:s,diagnostics:{expressionRanges:p}}};var U=e=>{let{getIdentifierName:t,evaluateExpressionWithNamespace:n}=e;return (r,s,o)=>{let a={},l=(i,p)=>{a[i]=p;};return r.forEach(i=>{if(i.type==="JSXSpreadAttribute"){let c=n(i.argument,s,o);c&&typeof c=="object"&&!Array.isArray(c)&&Object.assign(a,c);return}let p=t(i.name);if(!i.value){l(p,true);return}if(i.value.type==="Literal"){l(p,i.value.value);return}if(i.value.type==="JSXExpressionContainer"){if(i.value.expression.type==="JSXEmptyExpression")return;l(p,n(i.value.expression,s,o));}}),a}};var q="Capture",K=e=>e.endsWith(q)?{eventName:e.slice(0,-q.length),capture:true}:{eventName:e,capture:false},G=e=>{if(!e.startsWith("on"))return null;if(e.startsWith("on:")){let r=e.slice(3);if(!r)return null;let s=K(r);return s.eventName?s:null}let t=e.slice(2);if(!t)return null;let n=K(t);return n.eventName?{eventName:n.eventName.toLowerCase(),capture:n.capture}:null},Z=e=>!e||typeof e!="object"?false:"handleEvent"in e&&typeof e.handleEvent=="function",Pe=e=>{if(!e||typeof e!="object"||!("handler"in e))return false;let t=e.handler;return typeof t=="function"?true:Z(t)},Y=(e,t)=>{if(typeof t=="function"||Z(t))return {listener:t};if(!Pe(t))return null;let n=t,r=n.options?{...n.options}:void 0,s=(o,a)=>{a!=null&&(r||(r={}),r[o]=a);};return s("capture",n.capture),s("once",n.once),s("passive",n.passive),s("signal",n.signal??void 0),{listener:n.handler,options:r}};var k=Symbol.for("@knighted/jsx::Fragment"),S="__jsxNs",De=(e,t)=>t.length>0?t:Object.prototype.hasOwnProperty.call(e,"children")?[e.children]:[],Xe=(e,t)=>{let n={...e};return t.length===1?n.children=t[0]:t.length>1?n.children=t:delete n.children,n},Me=e=>{if(!Object.prototype.hasOwnProperty.call(e,S))return;let t=e[S];if(delete e[S],t==="svg"||t===null)return t;throw new Error(`${S} must be "svg" or null when provided.`)},Q=({ensureDomAvailable:e,appendChildValue:t,setDomProp:n,isPromiseLike:r})=>{function s(o,a,...l){e();let i=a?{...a}:{},p=De(i,l);if(o===k){let m=document.createDocumentFragment();return p.forEach(f=>t(m,f)),m}if(typeof o=="function"){let m=o(Xe(i,p));if(r(m))throw new Error("Async jsx components are not supported.");return m}if(typeof o!="string")throw new Error(`Unsupported jsx createElement type: ${String(o)}`);delete i.children;let u=Me(i)??(o==="svg"?"svg":null),d=u==="svg"?document.createElementNS("http://www.w3.org/2000/svg",o):document.createElement(o);return Object.entries(i).forEach(([m,f])=>{m!=="key"&&n(d,m,f,u);}),p.forEach(m=>t(d,m)),d}return s};var te=()=>{if(typeof document>"u"||typeof document.createElement!="function")throw new Error("The jsx template tag requires a DOM-like environment (document missing).")},_e=e=>typeof Node>"u"?false:e instanceof Node||e instanceof DocumentFragment,$e=e=>!e||typeof e=="string"?false:typeof e[Symbol.iterator]=="function",A=e=>!e||typeof e!="object"&&typeof e!="function"?false:typeof e.then=="function",He={xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},ne=e=>{if(!(!e||e==="html"||e==="svg"))return He[e]},We=e=>e==="svg"?svg:html,v=(e,t,n)=>{let r=ne(t.space),s=String(n);if(r){e.setAttributeNS(r,t.attribute,s);return}e.setAttribute(t.attribute,s);},ee=(e,t)=>{let n=ne(t.space);if(n){e.removeAttributeNS(n,t.attribute);return}e.removeAttribute(t.attribute);},R=(e,t)=>Array.isArray(e)?e.filter(Boolean).join(t):e,Be=(e,t,n)=>t==="svg"||!n.property||n.property.includes(":")?false:n.property in e,re=(e,t,n,r)=>{if(n==null)return;if(t==="dangerouslySetInnerHTML"&&typeof n=="object"&&n&&"__html"in n){e.innerHTML=String(n.__html??"");return}if(t==="ref"){if(typeof n=="function"){n(e);return}if(n&&typeof n=="object"){n.current=e;return}}if(t==="style"&&typeof n=="object"&&n!==null){let p=n,c=e.style;if(!c)return;let u=c;Object.entries(p).forEach(([d,m])=>{if(m!=null){if(d.startsWith("--")){c.setProperty(d,String(m));return}u[d]=m;}});return}let s=G(t);if(s){let p=Y(t,n);if(p){let c=p.options?{...p.options}:void 0;s.capture&&(c?c.capture=true:c={capture:true}),e.addEventListener(s.eventName,p.listener,c);return}}let o=find(We(r),t),a=e,l=Be(e,r,o);if(o.mustUseProperty){let p=o.boolean?!!n:n;a[o.property]=p;return}if(o.boolean){let p=!!n;l&&(a[o.property]=p),p?v(e,o,""):ee(e,o);return}let i=n;if(o.spaceSeparated?i=R(n," "):o.commaSeparated?i=R(n,","):o.commaOrSpaceSeparated&&(i=R(n," ")),o.booleanish&&typeof i=="boolean"&&(i=i?"true":"false"),o.overloadedBoolean){if(i===false){ee(e,o);return}if(i===true){v(e,o,"");return}}if(l){a[o.property]=i;return}i!==false&&v(e,o,i);},h=(e,t)=>{if(t!=null&&typeof t!="boolean"){if(A(t))throw new Error("Async values are not supported inside jsx template results.");if(Array.isArray(t)){t.forEach(n=>h(e,n));return}if($e(t)){for(let n of t)h(e,n);return}if(_e(t)){e.appendChild(t);return}e.appendChild(document.createTextNode(String(t)));}},N=(e,t,n)=>B(e,t,r=>j(r,t,n)),oe=U({getIdentifierName:b,evaluateExpressionWithNamespace:N}),Ve=(e,t,n,r)=>{let s=oe(t,n,r);Object.entries(s).forEach(([o,a])=>{if(o!=="key"){if(o==="children"){h(e,a);return}re(e,o,a,r);}});},P=(e,t,n)=>{let r=[];return e.forEach(s=>{switch(s.type){case "JSXText":{W(s.value,t.placeholders).forEach(a=>{r.push(a);});break}case "JSXExpressionContainer":{if(s.expression.type==="JSXEmptyExpression")break;r.push(N(s.expression,t,n));break}case "JSXSpreadChild":{let o=N(s.expression,t,n);o!=null&&r.push(o);break}case "JSXElement":case "JSXFragment":{r.push(j(s,t,n));break}}}),r},ze=(e,t,n,r)=>{let s=oe(e.openingElement.attributes,t,r),o=P(e.children,t,r);o.length===1?s.children=o[0]:o.length>1&&(s.children=o);let a=n(s);if(A(a))throw new Error("Async jsx components are not supported.");return a},Ue=(e,t,n)=>{let r=e.openingElement,s=b(r.name),o=t.components.get(s);if(o)return ze(e,t,o,n);if(/[A-Z]/.test(s[0]??""))throw new Error(`Unknown component "${s}". Did you interpolate it with the template literal?`);let a=s==="svg"?"svg":n,l=s==="foreignObject"?null:a,i=a==="svg"?document.createElementNS("http://www.w3.org/2000/svg",s):document.createElement(s);return Ve(i,r.attributes,t,a),P(e.children,t,l).forEach(c=>h(i,c)),i},j=(e,t,n)=>{if(e.type==="JSXFragment"){let r=document.createDocumentFragment();return P(e.children,t,n).forEach(o=>h(r,o)),r}return Ue(e,t,n)},qe=Q({ensureDomAvailable:te,appendChildValue:h,setDomProp:re,isPromiseLike:A}),Ke=(e,...t)=>{te();let n=V(e,t),r=parseSync("inline.jsx",n.source,$);if(r.errors.length>0)throw new Error(T("jsx",e,n.diagnostics,r.errors[0]));let s=H(r.program),o={source:n.source,placeholders:n.placeholders,components:new Map(n.bindings.map(a=>[a.name,a.value]))};return j(s,o,null)},se=Object.assign(Ke,{createElement:qe,Fragment:k});L();var xt=se;
|
|
8
|
+
export{xt as jsx};
|
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
export declare const jsx:
|
|
1
|
+
export declare const jsx: {
|
|
2
|
+
(templates: TemplateStringsArray, ...values: unknown[]): import("../../jsx.js").JsxRenderable;
|
|
3
|
+
createElement: typeof import("../../jsx.js").createElement;
|
|
4
|
+
Fragment: import("../../internal/dom-create-element.js").JsxFragmentToken;
|
|
5
|
+
};
|
|
2
6
|
export type { JsxRenderable, JsxComponent } from '../../jsx.js';
|
package/dist/node/index.d.ts
CHANGED
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
export declare const jsx:
|
|
1
|
+
export declare const jsx: {
|
|
2
|
+
(templates: TemplateStringsArray, ...values: unknown[]): import("../jsx.js").JsxRenderable;
|
|
3
|
+
createElement: typeof import("../jsx.js").createElement;
|
|
4
|
+
Fragment: import("../internal/dom-create-element.js").JsxFragmentToken;
|
|
5
|
+
};
|
|
2
6
|
export type { JsxRenderable, JsxComponent } from '../jsx.js';
|
package/dist/transpile.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
type TranspileSourceType = 'module' | 'script';
|
|
2
|
+
type TranspileTypeScriptMode = 'preserve' | 'strip';
|
|
2
3
|
export type TranspileJsxSourceOptions = {
|
|
3
4
|
sourceType?: TranspileSourceType;
|
|
4
5
|
createElement?: string;
|
|
5
6
|
fragment?: string;
|
|
7
|
+
typescript?: TranspileTypeScriptMode;
|
|
6
8
|
};
|
|
7
9
|
export type TranspileJsxSourceResult = {
|
|
8
10
|
code: string;
|
package/dist/transpile.js
CHANGED
|
@@ -29,15 +29,24 @@ const isSourceRange = (value) => Array.isArray(value) &&
|
|
|
29
29
|
typeof value[0] === 'number' &&
|
|
30
30
|
typeof value[1] === 'number';
|
|
31
31
|
const hasSourceRange = (value) => isObjectRecord(value) && isSourceRange(value.range);
|
|
32
|
+
const tsWrapperExpressionNodeTypes = new Set([
|
|
33
|
+
'TSAsExpression',
|
|
34
|
+
'TSSatisfiesExpression',
|
|
35
|
+
'TSInstantiationExpression',
|
|
36
|
+
'TSNonNullExpression',
|
|
37
|
+
'TSTypeAssertion',
|
|
38
|
+
]);
|
|
32
39
|
const compareByRangeStartDesc = (first, second) => second.range[0] - first.range[0];
|
|
33
40
|
class SourceJsxReactBuilder {
|
|
34
41
|
source;
|
|
35
42
|
createElementRef;
|
|
36
43
|
fragmentRef;
|
|
37
|
-
|
|
44
|
+
stripTypes;
|
|
45
|
+
constructor(source, createElementRef, fragmentRef, stripTypes) {
|
|
38
46
|
this.source = source;
|
|
39
47
|
this.createElementRef = createElementRef;
|
|
40
48
|
this.fragmentRef = fragmentRef;
|
|
49
|
+
this.stripTypes = stripTypes;
|
|
41
50
|
}
|
|
42
51
|
compile(node) {
|
|
43
52
|
return this.compileNode(node);
|
|
@@ -173,6 +182,17 @@ class SourceJsxReactBuilder {
|
|
|
173
182
|
if (node.type === 'JSXElement' || node.type === 'JSXFragment') {
|
|
174
183
|
return this.compileNode(node);
|
|
175
184
|
}
|
|
185
|
+
if (this.stripTypes && isObjectRecord(node)) {
|
|
186
|
+
if ('expression' in node && node.type === 'ParenthesizedExpression') {
|
|
187
|
+
return `(${this.compileExpression(node.expression)})`;
|
|
188
|
+
}
|
|
189
|
+
if ('expression' in node &&
|
|
190
|
+
typeof node.type === 'string' &&
|
|
191
|
+
tsWrapperExpressionNodeTypes.has(node.type)) {
|
|
192
|
+
return this.compileExpression(node.expression);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/* c8 ignore next 3 -- defensive guard for malformed external AST nodes */
|
|
176
196
|
if (!hasSourceRange(node)) {
|
|
177
197
|
throw new Error('[jsx] Unable to read source range for expression node.');
|
|
178
198
|
}
|
|
@@ -224,21 +244,134 @@ const collectRootJsxNodes = (root) => {
|
|
|
224
244
|
walk(root, false);
|
|
225
245
|
return nodes;
|
|
226
246
|
};
|
|
247
|
+
const hasStringProperty = (value, key) => isObjectRecord(value) && typeof value[key] === 'string';
|
|
248
|
+
const hasSourceAndExpressionRanges = (value) => isObjectRecord(value) &&
|
|
249
|
+
typeof value.type === 'string' &&
|
|
250
|
+
hasSourceRange(value) &&
|
|
251
|
+
'expression' in value &&
|
|
252
|
+
hasSourceRange(value.expression);
|
|
253
|
+
const isTypeOnlyImportExport = (value) => hasStringProperty(value, 'importKind')
|
|
254
|
+
? value.importKind === 'type'
|
|
255
|
+
: hasStringProperty(value, 'exportKind') && value.exportKind === 'type';
|
|
256
|
+
const isTypeOnlyNode = (value) => {
|
|
257
|
+
if (!isObjectRecord(value) || typeof value.type !== 'string') {
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
return [
|
|
261
|
+
'TSTypeAnnotation',
|
|
262
|
+
'TSTypeParameterDeclaration',
|
|
263
|
+
'TSTypeAliasDeclaration',
|
|
264
|
+
'TSInterfaceDeclaration',
|
|
265
|
+
'TSDeclareFunction',
|
|
266
|
+
'TSImportEqualsDeclaration',
|
|
267
|
+
'TSNamespaceExportDeclaration',
|
|
268
|
+
'TSModuleDeclaration',
|
|
269
|
+
].includes(value.type);
|
|
270
|
+
};
|
|
271
|
+
const createStripEditForTsWrapper = (value, source) => {
|
|
272
|
+
if (!hasSourceAndExpressionRanges(value)) {
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
if (value.type !== 'TSAsExpression' &&
|
|
276
|
+
value.type !== 'TSSatisfiesExpression' &&
|
|
277
|
+
value.type !== 'TSInstantiationExpression' &&
|
|
278
|
+
value.type !== 'TSNonNullExpression' &&
|
|
279
|
+
value.type !== 'TSTypeAssertion') {
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
const [exprStart, exprEnd] = value.expression.range;
|
|
283
|
+
return {
|
|
284
|
+
range: value.range,
|
|
285
|
+
replacement: source.slice(exprStart, exprEnd),
|
|
286
|
+
};
|
|
287
|
+
};
|
|
288
|
+
const collectTypeScriptStripEdits = (source, root) => {
|
|
289
|
+
const edits = [];
|
|
290
|
+
const walk = (value) => {
|
|
291
|
+
if (!isObjectRecord(value)) {
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
if (Array.isArray(value)) {
|
|
295
|
+
value.forEach(walk);
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
if (hasSourceRange(value)) {
|
|
299
|
+
if (isTypeOnlyNode(value) || isTypeOnlyImportExport(value)) {
|
|
300
|
+
edits.push({ range: value.range });
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
const wrapperEdit = createStripEditForTsWrapper(value, source);
|
|
305
|
+
if (wrapperEdit) {
|
|
306
|
+
edits.push(wrapperEdit);
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
for (const entry of Object.values(value)) {
|
|
312
|
+
walk(entry);
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
walk(root);
|
|
316
|
+
return edits;
|
|
317
|
+
};
|
|
318
|
+
const rangeOverlaps = (first, second) => first[0] < second[1] && second[0] < first[1];
|
|
319
|
+
const compareStripEditPriority = (first, second) => {
|
|
320
|
+
const firstLength = first.range[1] - first.range[0];
|
|
321
|
+
const secondLength = second.range[1] - second.range[0];
|
|
322
|
+
if (firstLength !== secondLength) {
|
|
323
|
+
return secondLength - firstLength;
|
|
324
|
+
}
|
|
325
|
+
return compareByRangeStartDesc(first, second);
|
|
326
|
+
};
|
|
327
|
+
const applyStripEdits = (magic, edits) => {
|
|
328
|
+
if (!edits.length) {
|
|
329
|
+
return false;
|
|
330
|
+
}
|
|
331
|
+
const appliedRanges = [];
|
|
332
|
+
let changed = false;
|
|
333
|
+
edits
|
|
334
|
+
.slice()
|
|
335
|
+
.sort(compareStripEditPriority)
|
|
336
|
+
.forEach(edit => {
|
|
337
|
+
/* c8 ignore next -- overlap handling is defensive after de-duplicated collection */
|
|
338
|
+
if (appliedRanges.some(range => rangeOverlaps(range, edit.range))) {
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
const [start, end] = edit.range;
|
|
342
|
+
if (edit.replacement === undefined) {
|
|
343
|
+
magic.remove(start, end);
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
magic.overwrite(start, end, edit.replacement);
|
|
347
|
+
}
|
|
348
|
+
appliedRanges.push(edit.range);
|
|
349
|
+
changed = true;
|
|
350
|
+
});
|
|
351
|
+
return changed;
|
|
352
|
+
};
|
|
227
353
|
export function transpileJsxSource(source, options = {}) {
|
|
228
354
|
const sourceType = options.sourceType ?? 'module';
|
|
229
355
|
const createElementRef = options.createElement ?? 'React.createElement';
|
|
230
356
|
const fragmentRef = options.fragment ?? 'React.Fragment';
|
|
357
|
+
const typescriptMode = options.typescript ?? 'preserve';
|
|
231
358
|
const parsed = parseSync('transpile-jsx-source.tsx', source, createModuleParserOptions(sourceType));
|
|
232
359
|
const firstError = parsed.errors[0];
|
|
233
360
|
if (firstError) {
|
|
234
361
|
throw new Error(formatParserError(firstError));
|
|
235
362
|
}
|
|
363
|
+
const magic = new MagicString(source);
|
|
364
|
+
const stripChanged = typescriptMode === 'strip'
|
|
365
|
+
? applyStripEdits(magic, collectTypeScriptStripEdits(source, parsed.program))
|
|
366
|
+
: false;
|
|
236
367
|
const jsxRoots = collectRootJsxNodes(parsed.program);
|
|
237
368
|
if (!jsxRoots.length) {
|
|
238
|
-
return {
|
|
369
|
+
return {
|
|
370
|
+
code: stripChanged ? magic.toString() : source,
|
|
371
|
+
changed: stripChanged,
|
|
372
|
+
};
|
|
239
373
|
}
|
|
240
|
-
const builder = new SourceJsxReactBuilder(source, createElementRef, fragmentRef);
|
|
241
|
-
const magic = new MagicString(source);
|
|
374
|
+
const builder = new SourceJsxReactBuilder(source, createElementRef, fragmentRef, typescriptMode === 'strip');
|
|
242
375
|
jsxRoots.sort(compareByRangeStartDesc).forEach(node => {
|
|
243
376
|
magic.overwrite(node.range[0], node.range[1], builder.compile(node));
|
|
244
377
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knighted/jsx",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.1",
|
|
4
4
|
"description": "Runtime JSX tagged template that renders DOM or React trees anywhere with or without a build step.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jsx runtime",
|
|
@@ -136,6 +136,7 @@
|
|
|
136
136
|
"test:watch": "cross-env KNIGHTED_JSX_CLI_TEST=1 vitest",
|
|
137
137
|
"test:e2e": "npm run build && npm run setup:wasm && npm run build:fixture && playwright test",
|
|
138
138
|
"build:fixture": "node scripts/build-rspack-fixture.mjs",
|
|
139
|
+
"demo:e2e-fixture": "npm run build && npx serve . -l tcp://127.0.0.1:4173",
|
|
139
140
|
"demo:node-ssr": "node test/fixtures/node-ssr/render.mjs",
|
|
140
141
|
"dev": "vite dev --config vite.config.ts",
|
|
141
142
|
"build:demo": "vite build --config vite.config.ts",
|