pudui 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,42 @@
1
+ import { g as PreloadMetadata } from "./core-Cypb6mR9.mjs";
2
+
3
+ //#region src/vite-runtime.d.ts
4
+ /**
5
+ * Resolves Vite hydration metadata into preload links.
6
+ *
7
+ * Pass this to `renderToString()` on the server when using the Pudui Vite
8
+ * plugin so hydrated components can preload their browser modules and styles.
9
+ *
10
+ * @param meta Hydration metadata generated by the Pudui Vite plugin.
11
+ * @returns Module and stylesheet preload metadata for the hydration boundary.
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * import { renderToString } from "pudui/server";
16
+ * import { preload } from "pudui/vite-runtime";
17
+ *
18
+ * const html = renderToString(<Document />, { preload });
19
+ * ```
20
+ */
21
+ declare function preload(meta: unknown): PreloadMetadata;
22
+ /**
23
+ * Loads a hydrated component module in the browser.
24
+ *
25
+ * Pass this to `hydrate()` when using the Pudui Vite plugin. It imports the
26
+ * component module, starts dependency imports, waits for stylesheets, and
27
+ * returns the component factory named by the hydration metadata.
28
+ *
29
+ * @param meta Hydration metadata generated by the Pudui Vite plugin.
30
+ * @returns The component factory exported by the hydrated module.
31
+ *
32
+ * @example
33
+ * ```tsx
34
+ * import { hydrate } from "pudui";
35
+ * import { load } from "pudui/vite-runtime";
36
+ *
37
+ * hydrate(document, { load });
38
+ * ```
39
+ */
40
+ declare function load(meta: unknown): Promise<any>;
41
+ //#endregion
42
+ export { load, preload };
@@ -0,0 +1,89 @@
1
+ //#region src/vite-runtime.ts
2
+ /**
3
+ * Resolves Vite hydration metadata into preload links.
4
+ *
5
+ * Pass this to `renderToString()` on the server when using the Pudui Vite
6
+ * plugin so hydrated components can preload their browser modules and styles.
7
+ *
8
+ * @param meta Hydration metadata generated by the Pudui Vite plugin.
9
+ * @returns Module and stylesheet preload metadata for the hydration boundary.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * import { renderToString } from "pudui/server";
14
+ * import { preload } from "pudui/vite-runtime";
15
+ *
16
+ * const html = renderToString(<Document />, { preload });
17
+ * ```
18
+ */
19
+ function preload(meta) {
20
+ const [moduleURL, _, dependencies, styles] = meta;
21
+ return {
22
+ modulePreloads: [...new Set([moduleURL, ...dependencies])],
23
+ stylePreloads: styles
24
+ };
25
+ }
26
+ const stylePromisesByHref = /* @__PURE__ */ new Map();
27
+ /**
28
+ * Loads a hydrated component module in the browser.
29
+ *
30
+ * Pass this to `hydrate()` when using the Pudui Vite plugin. It imports the
31
+ * component module, starts dependency imports, waits for stylesheets, and
32
+ * returns the component factory named by the hydration metadata.
33
+ *
34
+ * @param meta Hydration metadata generated by the Pudui Vite plugin.
35
+ * @returns The component factory exported by the hydrated module.
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * import { hydrate } from "pudui";
40
+ * import { load } from "pudui/vite-runtime";
41
+ *
42
+ * hydrate(document, { load });
43
+ * ```
44
+ */
45
+ async function load(meta) {
46
+ const [moduleURL, exportName, dependencies, styles] = meta;
47
+ const modPromise = import(
48
+ /* @vite-ignore */
49
+ moduleURL
50
+ );
51
+ dependencies.forEach((dependency) => {
52
+ import(
53
+ /* @vite-ignore */
54
+ dependency
55
+ );
56
+ });
57
+ await Promise.all(styles.map((href) => loadStyle(href)));
58
+ return (await modPromise)[exportName];
59
+ }
60
+ function loadStyle(href) {
61
+ if (typeof document === "undefined") return Promise.resolve();
62
+ const absoluteHref = new URL(href, document.baseURI).href;
63
+ const existingPromise = stylePromisesByHref.get(absoluteHref);
64
+ if (existingPromise !== void 0) return existingPromise;
65
+ if (hasStyleLink(absoluteHref)) {
66
+ const resolvedPromise = Promise.resolve();
67
+ stylePromisesByHref.set(absoluteHref, resolvedPromise);
68
+ return resolvedPromise;
69
+ }
70
+ const link = document.createElement("link");
71
+ link.rel = "stylesheet";
72
+ link.href = href;
73
+ const promise = new Promise((resolve, reject) => {
74
+ link.addEventListener("load", () => resolve(), { once: true });
75
+ link.addEventListener("error", () => {
76
+ stylePromisesByHref.delete(absoluteHref);
77
+ reject(/* @__PURE__ */ new Error(`Failed to load stylesheet: ${href}`));
78
+ }, { once: true });
79
+ });
80
+ stylePromisesByHref.set(absoluteHref, promise);
81
+ document.head.append(link);
82
+ return promise;
83
+ }
84
+ function hasStyleLink(absoluteHref) {
85
+ for (const link of document.querySelectorAll("link[rel=\"stylesheet\"]")) if (link.href === absoluteHref) return true;
86
+ return false;
87
+ }
88
+ //#endregion
89
+ export { load, preload };
@@ -0,0 +1,182 @@
1
+ //#region src/core/children.ts
2
+ /**
3
+ * Creates a raw child wrapper for trusted HTML.
4
+ *
5
+ * @param html Trusted HTML string.
6
+ * @returns Raw child wrapper.
7
+ */
8
+ function createRawChild(html) {
9
+ return {
10
+ r: true,
11
+ h: html
12
+ };
13
+ }
14
+ /**
15
+ * Checks whether a value is a raw child wrapper.
16
+ *
17
+ * @param value Value to inspect.
18
+ * @returns `true` when the value is a raw child.
19
+ */
20
+ function isRawChild(value) {
21
+ return typeof value === "object" && value !== null && value.r === true && typeof value.h === "string";
22
+ }
23
+ /**
24
+ * Reads trusted HTML from a raw child.
25
+ *
26
+ * @param raw Raw child wrapper.
27
+ * @returns Trusted HTML string.
28
+ */
29
+ function readRawChildHtml(raw) {
30
+ return raw.h;
31
+ }
32
+ /**
33
+ * Normalizes multiple children into Pudui's compact child representation.
34
+ *
35
+ * @param children Children to normalize.
36
+ * @returns `null`, a single child, or a normalized child array.
37
+ */
38
+ function packChildren(children) {
39
+ const normalized = normalizeChildren(children);
40
+ return normalized.length === 0 ? null : normalized.length === 1 ? normalized[0] : normalized;
41
+ }
42
+ /**
43
+ * Flattens children and removes empty child values.
44
+ *
45
+ * @param children Children to normalize.
46
+ * @returns Flat child array without booleans, `null`, or `undefined`.
47
+ */
48
+ function normalizeChildren(children) {
49
+ return children.flat(Infinity).filter((child) => !isEmptyChild(child));
50
+ }
51
+ /**
52
+ * Checks whether a child renders no output.
53
+ *
54
+ * @param child Child to inspect.
55
+ * @returns `true` for booleans, `null`, and `undefined`.
56
+ */
57
+ function isEmptyChild(child) {
58
+ return child == null || typeof child === "boolean";
59
+ }
60
+ //#endregion
61
+ //#region src/core/vnode.ts
62
+ const vnodeType = Symbol();
63
+ /**
64
+ * Returns its children without adding a wrapper element.
65
+ *
66
+ * This is the fragment implementation used by the JSX runtimes.
67
+ *
68
+ * @param props Fragment props.
69
+ * @returns The fragment children, or `null` when no children were provided.
70
+ *
71
+ * @example
72
+ * ```tsx
73
+ * <>
74
+ * <title>Dashboard</title>
75
+ * <meta name="description" content="Operations dashboard" />
76
+ * </>
77
+ * ```
78
+ */
79
+ function Fragment(props) {
80
+ return props.children ?? null;
81
+ }
82
+ /**
83
+ * Renders trusted HTML without escaping.
84
+ *
85
+ * Prefer normal JSX children whenever possible. Raw HTML is intended for HTML
86
+ * that has already been sanitized or generated by a trusted renderer.
87
+ *
88
+ * @param props Raw HTML props.
89
+ * @returns A raw child that renders its HTML verbatim.
90
+ *
91
+ * @example
92
+ * ```tsx
93
+ * <Raw>{"<span data-source=\"cms\">Published</span>"}</Raw>
94
+ * ```
95
+ */
96
+ function Raw(props) {
97
+ const html = props.children;
98
+ if (html === void 0) return createRawChild("");
99
+ if (typeof html !== "string") throw new TypeError("Raw string");
100
+ return createRawChild(html);
101
+ }
102
+ /**
103
+ * Creates a Pudui child using the classic JSX factory shape.
104
+ *
105
+ * Most applications use JSX and do not call this directly. It is exported for
106
+ * explicit factory configuration and low-level integrations.
107
+ *
108
+ * @param type Intrinsic tag name, component factory, {@link Fragment}, or {@link Raw}.
109
+ * @param rawProps Props to pass to the render target.
110
+ * @param children Children supplied after the props argument.
111
+ * @returns A renderable child value.
112
+ *
113
+ * @example
114
+ * ```tsx
115
+ * const child = createElement("button", { type: "button" }, "Save");
116
+ * ```
117
+ */
118
+ function createElement(type, rawProps, ...children) {
119
+ return createVNode(type, rawProps, void 0, children);
120
+ }
121
+ /**
122
+ * Creates a Pudui child using the automatic JSX runtime shape.
123
+ *
124
+ * This function is called by compilers configured for
125
+ * `jsxImportSource: "pudui"`.
126
+ *
127
+ * @param type Intrinsic tag name, component factory, {@link Fragment}, or {@link Raw}.
128
+ * @param props Props supplied by the JSX transform.
129
+ * @param key Optional key supplied by the JSX transform.
130
+ * @returns A renderable child value.
131
+ */
132
+ function jsx(type, props, key) {
133
+ return createVNode(type, props, key);
134
+ }
135
+ /**
136
+ * Development JSX runtime entry compatible with React's `jsxDEV` call shape.
137
+ */
138
+ const jsxDEV = jsx;
139
+ /**
140
+ * Checks whether a value is a Pudui virtual node.
141
+ *
142
+ * @param value Value to inspect.
143
+ * @returns `true` when the value is a virtual node created by Pudui's JSX runtime.
144
+ */
145
+ function isVNode(value) {
146
+ return typeof value === "object" && value !== null && value[vnodeType] === true;
147
+ }
148
+ /**
149
+ * Checks whether a virtual node targets a component factory.
150
+ *
151
+ * @param vnode Virtual node to inspect.
152
+ * @returns `true` when the node renders a component.
153
+ */
154
+ function isComponentVNode(vnode) {
155
+ return typeof vnode.type === "function";
156
+ }
157
+ /**
158
+ * Checks whether a virtual node targets an intrinsic element.
159
+ *
160
+ * @param vnode Virtual node to inspect.
161
+ * @returns `true` when the node renders a host element.
162
+ */
163
+ function isHostVNode(vnode) {
164
+ return typeof vnode.type === "string";
165
+ }
166
+ function createVNode(type, rawProps, key, fallbackChildren) {
167
+ const props = { ...rawProps };
168
+ const vnodeKey = key ?? props.key;
169
+ delete props.key;
170
+ if (fallbackChildren?.length) props.children = packChildren(fallbackChildren);
171
+ else if ("children" in props) props.children = packChildren([props.children]);
172
+ if (type === Fragment) return props.children ?? null;
173
+ if (type === Raw) return Raw(props);
174
+ return {
175
+ [vnodeType]: true,
176
+ key: vnodeKey,
177
+ props,
178
+ type
179
+ };
180
+ }
181
+ //#endregion
182
+ export { isHostVNode as a, jsxDEV as c, normalizeChildren as d, readRawChildHtml as f, isComponentVNode as i, isEmptyChild as l, Raw as n, isVNode as o, createElement as r, jsx as s, Fragment as t, isRawChild as u };
package/package.json ADDED
@@ -0,0 +1,99 @@
1
+ {
2
+ "name": "pudui",
3
+ "version": "0.0.0",
4
+ "description": "A tiny JSX UI runtime built from the ground up.",
5
+ "license": "MIT",
6
+ "files": [
7
+ "dist"
8
+ ],
9
+ "type": "module",
10
+ "types": "./dist/index.d.mts",
11
+ "imports": {
12
+ "#pudui": "./src/index.ts",
13
+ "#pudui/*": "./src/*.ts"
14
+ },
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.mts",
18
+ "import": "./dist/index.mjs",
19
+ "default": "./dist/index.mjs"
20
+ },
21
+ "./jsx-dev-runtime": {
22
+ "types": "./dist/jsx-dev-runtime.d.mts",
23
+ "import": "./dist/jsx-dev-runtime.mjs",
24
+ "default": "./dist/jsx-dev-runtime.mjs"
25
+ },
26
+ "./jsx-runtime": {
27
+ "types": "./dist/jsx-runtime.d.mts",
28
+ "import": "./dist/jsx-runtime.mjs",
29
+ "default": "./dist/jsx-runtime.mjs"
30
+ },
31
+ "./server": {
32
+ "types": "./dist/server.d.mts",
33
+ "import": "./dist/server.mjs",
34
+ "default": "./dist/server.mjs"
35
+ },
36
+ "./macros": {
37
+ "types": "./dist/macros.d.mts",
38
+ "import": "./dist/macros.mjs",
39
+ "default": "./dist/macros.mjs"
40
+ },
41
+ "./hmr-runtime": {
42
+ "types": "./dist/hmr-runtime.d.mts",
43
+ "import": "./dist/hmr-runtime.mjs",
44
+ "default": "./dist/hmr-runtime.mjs"
45
+ },
46
+ "./vite-runtime": {
47
+ "types": "./dist/vite-runtime.d.mts",
48
+ "import": "./dist/vite-runtime.mjs",
49
+ "default": "./dist/vite-runtime.mjs"
50
+ },
51
+ "./vite-plugin": {
52
+ "types": "./dist/vite-plugin.d.mts",
53
+ "import": "./dist/vite-plugin.mjs",
54
+ "default": "./dist/vite-plugin.mjs"
55
+ },
56
+ "./transforms": {
57
+ "types": "./dist/transforms.d.mts",
58
+ "import": "./dist/transforms.mjs",
59
+ "default": "./dist/transforms.mjs"
60
+ },
61
+ "./package.json": "./package.json"
62
+ },
63
+ "publishConfig": {
64
+ "access": "public"
65
+ },
66
+ "dependencies": {
67
+ "magic-string": "~0.30.21",
68
+ "oxc-parser": "~0.128.0"
69
+ },
70
+ "devDependencies": {
71
+ "@cloudflare/vite-plugin": "^1.35.0",
72
+ "@types/node": "^25.6.0",
73
+ "@typescript/native-preview": "7.0.0-dev.20260505.1",
74
+ "@vitest/ui": "^4.1.5",
75
+ "playwright": "^1.59.1",
76
+ "remix": "3.0.0-beta.0",
77
+ "todomvc-app-css": "^2.4.3",
78
+ "todomvc-common": "^1.0.5",
79
+ "typescript": "^6.0.3",
80
+ "vite-plus": "~0.1.20",
81
+ "wrangler": "^4.87.0"
82
+ },
83
+ "peerDependencies": {
84
+ "vite-plus": "*"
85
+ },
86
+ "peerDependenciesMeta": {
87
+ "vite-plus": {
88
+ "optional": true
89
+ }
90
+ },
91
+ "scripts": {
92
+ "build": "vp pack",
93
+ "dev": "vp pack --watch",
94
+ "test": "vp test",
95
+ "benchmark": "vp test bench",
96
+ "check": "vp check",
97
+ "bundle-size": "node scripts/bundle-size.ts"
98
+ }
99
+ }