defuss-astro 1.1.4 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2023 - 2024 Aron Homberg
3
+ Copyright (c) 2019 - 2025 Aron Homberg
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/dist/client.cjs CHANGED
@@ -1,19 +1,123 @@
1
1
  'use strict';
2
2
 
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
3
5
  var client$1 = require('defuss/client');
4
6
  var render = require('./render-DkMOLcUd.cjs');
7
+ var jsxRuntime = require('defuss/jsx-runtime');
5
8
  require('defuss');
6
9
 
10
+ const Img = ({
11
+ id,
12
+ src,
13
+ alt,
14
+ height = 100,
15
+ width = 100,
16
+ previewQuality = 5,
17
+ quality = 90,
18
+ className = "",
19
+ class: _class = "",
20
+ style = {},
21
+ format = "webp",
22
+ astroAssetsPath = "_defuss/image"
23
+ }) => {
24
+ const placeholderWidth = Math.round(width / 7);
25
+ const placeholderHeight = Math.round(height / 7);
26
+ const imgRef = client$1.createRef();
27
+ const getTransformOptionsPath = ({
28
+ src: src2,
29
+ height: height2,
30
+ width: width2,
31
+ quality: quality2 = previewQuality,
32
+ format: format2 = "webp"
33
+ }) => {
34
+ const transformOptions = new URLSearchParams({
35
+ href: src2,
36
+ h: height2.toString(),
37
+ w: width2.toString(),
38
+ q: quality2.toString(),
39
+ f: format2
40
+ });
41
+ return `/${astroAssetsPath}?${transformOptions.toString()}`;
42
+ };
43
+ const transformedSrc = getTransformOptionsPath({
44
+ src,
45
+ height: placeholderHeight,
46
+ width: placeholderWidth,
47
+ format
48
+ });
49
+ const whenImageMounts = () => {
50
+ const img = imgRef.current;
51
+ if (!img) return;
52
+ let loaded = false;
53
+ const getTransformOptionsPath2 = ({ src: src2, height: height2, width: width2, quality: quality2, format: format2 }) => {
54
+ const transformOptions = new URLSearchParams({
55
+ href: src2,
56
+ h: height2.toString(),
57
+ w: width2.toString(),
58
+ q: quality2.toString(),
59
+ f: format2
60
+ });
61
+ return `/${astroAssetsPath}?${transformOptions.toString()}`;
62
+ };
63
+ const lazyLoad = () => {
64
+ if (loaded) return;
65
+ const transformedSrc2 = getTransformOptionsPath2({
66
+ src,
67
+ height,
68
+ width,
69
+ quality,
70
+ format
71
+ });
72
+ img.src = transformedSrc2;
73
+ img.onload = () => {
74
+ img.classList.remove("blur");
75
+ img.classList.add("loaded");
76
+ img.style.filter = "blur(0px)";
77
+ loaded = true;
78
+ };
79
+ };
80
+ const observer = new window.IntersectionObserver((entries, observer2) => {
81
+ entries.forEach((entry) => {
82
+ if (entry.isIntersecting) {
83
+ lazyLoad();
84
+ observer2.unobserve(entry.target);
85
+ }
86
+ });
87
+ }, { threshold: 0.1 });
88
+ observer.observe(imgRef.current);
89
+ };
90
+ return /* @__PURE__ */ jsxRuntime.jsx(
91
+ "img",
92
+ {
93
+ id,
94
+ ref: imgRef,
95
+ onMount: whenImageMounts,
96
+ alt,
97
+ class: `${className || _class} blur`,
98
+ src: transformedSrc,
99
+ style: {
100
+ filter: "blur(40px)",
101
+ transition: "0.125s filter linear",
102
+ ...style
103
+ },
104
+ width,
105
+ height
106
+ }
107
+ );
108
+ };
109
+
7
110
  var client = (element) => async (Component, props, { default: children, ...slotted }, { client }) => {
8
- const isHydrate = client !== "only";
9
- if (element.hasAttribute("ssr")) {
10
- console.log("ssr attr found isHydrate", isHydrate, Component, "props", props, "slotted", slotted, "children", children, "client", client);
11
- }
111
+ const isHydrate = element.hasAttribute("ssr") && (client === "visible" || client === "idle" || client === "load" || client === "media");
12
112
  if (!element.hasAttribute("ssr")) return;
13
113
  Object.entries(slotted).forEach(([key, value]) => {
14
114
  props[key] = render.StaticHtml(value);
15
115
  });
16
- const componentProps = { ...props };
116
+ const componentProps = {
117
+ ...props,
118
+ // set hydration key to the component name by default, if not already set
119
+ key: props.key || Component.name
120
+ };
17
121
  if (children) {
18
122
  if (!Array.isArray(children)) {
19
123
  children = [children];
@@ -25,19 +129,45 @@ var client = (element) => async (Component, props, { default: children, ...slott
25
129
  }
26
130
  componentProps.children = children;
27
131
  }
28
- const vdom = Component(componentProps);
29
- const dom = client$1.render(vdom, element);
30
- for (const [key, value] of Object.entries(props)) {
31
- if (key !== "children") {
32
- dom.setAttribute(key, value);
132
+ if (isHydrate) {
133
+ let roots = Component(componentProps);
134
+ if (!Array.isArray(roots)) {
135
+ roots = [roots];
33
136
  }
137
+ client$1.hydrate(roots, Array.from(element.childNodes));
138
+ } else {
139
+ element.innerHTML = "";
140
+ let roots = client$1.render(Component(componentProps), element);
141
+ if (!Array.isArray(roots)) {
142
+ roots = [roots];
143
+ }
144
+ const attrs = {};
145
+ for (const [key, value] of Object.entries(props)) {
146
+ if (key !== "children") {
147
+ attrs[key] = value;
148
+ }
149
+ }
150
+ Object.entries(attrs).forEach(([key, value]) => {
151
+ if (typeof value === "undefined") return;
152
+ if (key === "dangerouslySetInnerHTML") return;
153
+ if (key === "ref" && typeof value === "object") {
154
+ value.current = element;
155
+ return;
156
+ }
157
+ element.setAttribute(key, String(value));
158
+ });
159
+ element.addEventListener("astro:unmount", () => {
160
+ roots.forEach((root) => {
161
+ if (root.parentNode) {
162
+ root.parentNode.removeChild(root);
163
+ }
164
+ });
165
+ }, { once: true });
34
166
  }
35
167
  element.addEventListener("astro:unmount", () => {
36
- if (dom.parentNode) {
37
- dom.parentNode.removeChild(dom);
38
- }
168
+ element.innerHTML = "";
39
169
  }, { once: true });
40
170
  };
41
171
 
42
- module.exports = client;
43
- //# sourceMappingURL=client.cjs.map
172
+ exports.Img = Img;
173
+ exports.default = client;
package/dist/client.d.cts CHANGED
@@ -1,3 +1,21 @@
1
+ import { Props, CSSProperties } from 'defuss/client';
2
+
3
+ interface ImgProps extends Props {
4
+ id?: string;
5
+ src: string;
6
+ width?: number;
7
+ height?: number;
8
+ alt: string;
9
+ style?: CSSProperties;
10
+ class?: string;
11
+ className?: string;
12
+ format?: string;
13
+ astroAssetsPath?: string;
14
+ previewQuality?: number;
15
+ quality?: number;
16
+ }
17
+ declare const Img: ({ id, src, alt, height, width, previewQuality, quality, className, class: _class, style, format, astroAssetsPath, }: ImgProps) => any;
18
+
1
19
  declare const _default: (element: HTMLElement) => (Component: any, props: Record<string, any>, { default: children, ...slotted }: Record<string, any>, { client }: Record<string, string>) => Promise<void>;
2
20
 
3
- export { _default as default };
21
+ export { Img, type ImgProps, _default as default };
package/dist/client.d.mts CHANGED
@@ -1,3 +1,21 @@
1
+ import { Props, CSSProperties } from 'defuss/client';
2
+
3
+ interface ImgProps extends Props {
4
+ id?: string;
5
+ src: string;
6
+ width?: number;
7
+ height?: number;
8
+ alt: string;
9
+ style?: CSSProperties;
10
+ class?: string;
11
+ className?: string;
12
+ format?: string;
13
+ astroAssetsPath?: string;
14
+ previewQuality?: number;
15
+ quality?: number;
16
+ }
17
+ declare const Img: ({ id, src, alt, height, width, previewQuality, quality, className, class: _class, style, format, astroAssetsPath, }: ImgProps) => any;
18
+
1
19
  declare const _default: (element: HTMLElement) => (Component: any, props: Record<string, any>, { default: children, ...slotted }: Record<string, any>, { client }: Record<string, string>) => Promise<void>;
2
20
 
3
- export { _default as default };
21
+ export { Img, type ImgProps, _default as default };
package/dist/client.mjs CHANGED
@@ -1,17 +1,119 @@
1
- import { render } from 'defuss/client';
1
+ import { createRef, hydrate, render } from 'defuss/client';
2
2
  import { S as StaticHtml } from './render-viAgneG-.mjs';
3
+ import { jsx } from 'defuss/jsx-runtime';
3
4
  import 'defuss';
4
5
 
6
+ const Img = ({
7
+ id,
8
+ src,
9
+ alt,
10
+ height = 100,
11
+ width = 100,
12
+ previewQuality = 5,
13
+ quality = 90,
14
+ className = "",
15
+ class: _class = "",
16
+ style = {},
17
+ format = "webp",
18
+ astroAssetsPath = "_defuss/image"
19
+ }) => {
20
+ const placeholderWidth = Math.round(width / 7);
21
+ const placeholderHeight = Math.round(height / 7);
22
+ const imgRef = createRef();
23
+ const getTransformOptionsPath = ({
24
+ src: src2,
25
+ height: height2,
26
+ width: width2,
27
+ quality: quality2 = previewQuality,
28
+ format: format2 = "webp"
29
+ }) => {
30
+ const transformOptions = new URLSearchParams({
31
+ href: src2,
32
+ h: height2.toString(),
33
+ w: width2.toString(),
34
+ q: quality2.toString(),
35
+ f: format2
36
+ });
37
+ return `/${astroAssetsPath}?${transformOptions.toString()}`;
38
+ };
39
+ const transformedSrc = getTransformOptionsPath({
40
+ src,
41
+ height: placeholderHeight,
42
+ width: placeholderWidth,
43
+ format
44
+ });
45
+ const whenImageMounts = () => {
46
+ const img = imgRef.current;
47
+ if (!img) return;
48
+ let loaded = false;
49
+ const getTransformOptionsPath2 = ({ src: src2, height: height2, width: width2, quality: quality2, format: format2 }) => {
50
+ const transformOptions = new URLSearchParams({
51
+ href: src2,
52
+ h: height2.toString(),
53
+ w: width2.toString(),
54
+ q: quality2.toString(),
55
+ f: format2
56
+ });
57
+ return `/${astroAssetsPath}?${transformOptions.toString()}`;
58
+ };
59
+ const lazyLoad = () => {
60
+ if (loaded) return;
61
+ const transformedSrc2 = getTransformOptionsPath2({
62
+ src,
63
+ height,
64
+ width,
65
+ quality,
66
+ format
67
+ });
68
+ img.src = transformedSrc2;
69
+ img.onload = () => {
70
+ img.classList.remove("blur");
71
+ img.classList.add("loaded");
72
+ img.style.filter = "blur(0px)";
73
+ loaded = true;
74
+ };
75
+ };
76
+ const observer = new window.IntersectionObserver((entries, observer2) => {
77
+ entries.forEach((entry) => {
78
+ if (entry.isIntersecting) {
79
+ lazyLoad();
80
+ observer2.unobserve(entry.target);
81
+ }
82
+ });
83
+ }, { threshold: 0.1 });
84
+ observer.observe(imgRef.current);
85
+ };
86
+ return /* @__PURE__ */ jsx(
87
+ "img",
88
+ {
89
+ id,
90
+ ref: imgRef,
91
+ onMount: whenImageMounts,
92
+ alt,
93
+ class: `${className || _class} blur`,
94
+ src: transformedSrc,
95
+ style: {
96
+ filter: "blur(40px)",
97
+ transition: "0.125s filter linear",
98
+ ...style
99
+ },
100
+ width,
101
+ height
102
+ }
103
+ );
104
+ };
105
+
5
106
  var client = (element) => async (Component, props, { default: children, ...slotted }, { client }) => {
6
- const isHydrate = client !== "only";
7
- if (element.hasAttribute("ssr")) {
8
- console.log("ssr attr found isHydrate", isHydrate, Component, "props", props, "slotted", slotted, "children", children, "client", client);
9
- }
107
+ const isHydrate = element.hasAttribute("ssr") && (client === "visible" || client === "idle" || client === "load" || client === "media");
10
108
  if (!element.hasAttribute("ssr")) return;
11
109
  Object.entries(slotted).forEach(([key, value]) => {
12
110
  props[key] = StaticHtml(value);
13
111
  });
14
- const componentProps = { ...props };
112
+ const componentProps = {
113
+ ...props,
114
+ // set hydration key to the component name by default, if not already set
115
+ key: props.key || Component.name
116
+ };
15
117
  if (children) {
16
118
  if (!Array.isArray(children)) {
17
119
  children = [children];
@@ -23,19 +125,44 @@ var client = (element) => async (Component, props, { default: children, ...slott
23
125
  }
24
126
  componentProps.children = children;
25
127
  }
26
- const vdom = Component(componentProps);
27
- const dom = render(vdom, element);
28
- for (const [key, value] of Object.entries(props)) {
29
- if (key !== "children") {
30
- dom.setAttribute(key, value);
128
+ if (isHydrate) {
129
+ let roots = Component(componentProps);
130
+ if (!Array.isArray(roots)) {
131
+ roots = [roots];
31
132
  }
133
+ hydrate(roots, Array.from(element.childNodes));
134
+ } else {
135
+ element.innerHTML = "";
136
+ let roots = render(Component(componentProps), element);
137
+ if (!Array.isArray(roots)) {
138
+ roots = [roots];
139
+ }
140
+ const attrs = {};
141
+ for (const [key, value] of Object.entries(props)) {
142
+ if (key !== "children") {
143
+ attrs[key] = value;
144
+ }
145
+ }
146
+ Object.entries(attrs).forEach(([key, value]) => {
147
+ if (typeof value === "undefined") return;
148
+ if (key === "dangerouslySetInnerHTML") return;
149
+ if (key === "ref" && typeof value === "object") {
150
+ value.current = element;
151
+ return;
152
+ }
153
+ element.setAttribute(key, String(value));
154
+ });
155
+ element.addEventListener("astro:unmount", () => {
156
+ roots.forEach((root) => {
157
+ if (root.parentNode) {
158
+ root.parentNode.removeChild(root);
159
+ }
160
+ });
161
+ }, { once: true });
32
162
  }
33
163
  element.addEventListener("astro:unmount", () => {
34
- if (dom.parentNode) {
35
- dom.parentNode.removeChild(dom);
36
- }
164
+ element.innerHTML = "";
37
165
  }, { once: true });
38
166
  };
39
167
 
40
- export { client as default };
41
- //# sourceMappingURL=client.mjs.map
168
+ export { Img, client as default };
@@ -0,0 +1,66 @@
1
+ 'use strict';
2
+
3
+ var fileType = require('file-type');
4
+ var node_module = require('node:module');
5
+
6
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
7
+ const nodeRequire = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('endpoint/image-endpoint.cjs', document.baseURI).href)));
8
+ const { convertToWebp } = nodeRequire("lightningimg-node");
9
+ const GET = async ({ url }) => {
10
+ try {
11
+ const imgHrefRelative = url.searchParams.get("href");
12
+ const height = url.searchParams.get("h");
13
+ const width = url.searchParams.get("w");
14
+ const quality = url.searchParams.get("q");
15
+ if (!imgHrefRelative) {
16
+ return new Response("Image URL is required", { status: 400 });
17
+ }
18
+ const imgHrefAbsolute = `${url.protocol}//${url.host}${imgHrefRelative}`;
19
+ console.log("GET /_defuss/image (transforming: ", imgHrefAbsolute, ")");
20
+ const response = await fetch(imgHrefAbsolute);
21
+ if (!response.ok) {
22
+ console.log("Error fetching image", { imgHrefAbsolute, response });
23
+ return new Response("Error fetching image", { status: 500 });
24
+ }
25
+ const imageBuffer = Buffer.from(await response.arrayBuffer());
26
+ const fileExtension = (await fileType.fileTypeFromBuffer(imageBuffer))?.ext;
27
+ if (!fileExtension) {
28
+ console.log("Error fetching fileExtension", { fileExtension, response });
29
+ return new Response("Error getting file extension", { status: 500 });
30
+ }
31
+ if (fileExtension === "webp") {
32
+ return new Response(imageBuffer, {
33
+ headers: {
34
+ "Content-Type": "image/webp",
35
+ "Content-Length": imageBuffer.byteLength.toString()
36
+ }
37
+ });
38
+ }
39
+ let convertedImageBuffer;
40
+ try {
41
+ convertedImageBuffer = convertToWebp(imageBuffer, fileExtension, {
42
+ height: height ? Number.parseInt(height) : void 0,
43
+ width: width ? Number.parseInt(width) : void 0,
44
+ quality: quality ? Number.parseInt(quality) : void 0
45
+ });
46
+ if (!convertedImageBuffer) {
47
+ throw new Error("Error converting image: no buffer returned");
48
+ }
49
+ } catch (error) {
50
+ console.log("Error converting image", { fileExtension, bufferLength: imageBuffer.byteLength, error });
51
+ return new Response("Error converting image", { status: 500 });
52
+ }
53
+ const mimeType = `image/${fileExtension}`;
54
+ return new Response(convertedImageBuffer, {
55
+ headers: {
56
+ "Content-Type": mimeType,
57
+ "Content-Length": convertedImageBuffer.length.toString()
58
+ }
59
+ });
60
+ } catch (error) {
61
+ return new Response(`Error fetching image: ${error}`, { status: 500 });
62
+ }
63
+ };
64
+
65
+ exports.GET = GET;
66
+ exports.nodeRequire = nodeRequire;
@@ -0,0 +1,6 @@
1
+ import { APIRoute } from 'astro';
2
+
3
+ declare const nodeRequire: NodeRequire;
4
+ declare const GET: APIRoute;
5
+
6
+ export { GET, nodeRequire };
@@ -0,0 +1,6 @@
1
+ import { APIRoute } from 'astro';
2
+
3
+ declare const nodeRequire: NodeRequire;
4
+ declare const GET: APIRoute;
5
+
6
+ export { GET, nodeRequire };
@@ -0,0 +1,62 @@
1
+ import { fileTypeFromBuffer } from 'file-type';
2
+ import { createRequire } from 'node:module';
3
+
4
+ const nodeRequire = createRequire(import.meta.url);
5
+ const { convertToWebp } = nodeRequire("lightningimg-node");
6
+ const GET = async ({ url }) => {
7
+ try {
8
+ const imgHrefRelative = url.searchParams.get("href");
9
+ const height = url.searchParams.get("h");
10
+ const width = url.searchParams.get("w");
11
+ const quality = url.searchParams.get("q");
12
+ if (!imgHrefRelative) {
13
+ return new Response("Image URL is required", { status: 400 });
14
+ }
15
+ const imgHrefAbsolute = `${url.protocol}//${url.host}${imgHrefRelative}`;
16
+ console.log("GET /_defuss/image (transforming: ", imgHrefAbsolute, ")");
17
+ const response = await fetch(imgHrefAbsolute);
18
+ if (!response.ok) {
19
+ console.log("Error fetching image", { imgHrefAbsolute, response });
20
+ return new Response("Error fetching image", { status: 500 });
21
+ }
22
+ const imageBuffer = Buffer.from(await response.arrayBuffer());
23
+ const fileExtension = (await fileTypeFromBuffer(imageBuffer))?.ext;
24
+ if (!fileExtension) {
25
+ console.log("Error fetching fileExtension", { fileExtension, response });
26
+ return new Response("Error getting file extension", { status: 500 });
27
+ }
28
+ if (fileExtension === "webp") {
29
+ return new Response(imageBuffer, {
30
+ headers: {
31
+ "Content-Type": "image/webp",
32
+ "Content-Length": imageBuffer.byteLength.toString()
33
+ }
34
+ });
35
+ }
36
+ let convertedImageBuffer;
37
+ try {
38
+ convertedImageBuffer = convertToWebp(imageBuffer, fileExtension, {
39
+ height: height ? Number.parseInt(height) : void 0,
40
+ width: width ? Number.parseInt(width) : void 0,
41
+ quality: quality ? Number.parseInt(quality) : void 0
42
+ });
43
+ if (!convertedImageBuffer) {
44
+ throw new Error("Error converting image: no buffer returned");
45
+ }
46
+ } catch (error) {
47
+ console.log("Error converting image", { fileExtension, bufferLength: imageBuffer.byteLength, error });
48
+ return new Response("Error converting image", { status: 500 });
49
+ }
50
+ const mimeType = `image/${fileExtension}`;
51
+ return new Response(convertedImageBuffer, {
52
+ headers: {
53
+ "Content-Type": mimeType,
54
+ "Content-Length": convertedImageBuffer.length.toString()
55
+ }
56
+ });
57
+ } catch (error) {
58
+ return new Response(`Error fetching image: ${error}`, { status: 500 });
59
+ }
60
+ };
61
+
62
+ export { GET, nodeRequire };
package/dist/index.cjs CHANGED
@@ -3,7 +3,24 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var defussPlugin = require('defuss-vite');
6
+ var node_url = require('node:url');
7
+ var glob = require('fast-glob');
8
+ var node_perf_hooks = require('node:perf_hooks');
9
+ var svgo = require('svgo');
10
+ var node_path = require('node:path');
11
+ var promises = require('node:fs/promises');
12
+ var purgecss = require('purgecss');
13
+ var node_fs = require('node:fs');
14
+ var node_module = require('node:module');
6
15
 
16
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
17
+ const logMessage = (message) => {
18
+ const date = (/* @__PURE__ */ new Date()).toLocaleTimeString();
19
+ console.log(`${date} \x1B[32mdefuss-astro:\x1B[0m ${message}`);
20
+ };
21
+
22
+ const nodeRequire = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
23
+ const { processDirectoryDestructive } = nodeRequire("lightningimg-node");
7
24
  const getRenderer = (development) => ({
8
25
  name: "defuss",
9
26
  clientEntrypoint: "defuss-astro/client.js",
@@ -13,20 +30,99 @@ const getContainerRenderer = () => ({
13
30
  name: "defuss",
14
31
  serverEntrypoint: "defuss-astro/server.js"
15
32
  });
33
+ const minifyAndWriteFile = async (cwd, filename, type) => {
34
+ const filePath = node_path.join(cwd, filename);
35
+ const fileOrg = await promises.readFile(filePath, "utf8");
36
+ switch (type) {
37
+ case "svg": {
38
+ const fileMin = svgo.optimize(fileOrg, {
39
+ multipass: true,
40
+ plugins: [
41
+ {
42
+ name: "preset-default",
43
+ params: {
44
+ overrides: {
45
+ removeViewBox: false
46
+ }
47
+ }
48
+ }
49
+ ]
50
+ });
51
+ await promises.writeFile(filePath, fileMin.data, "utf-8");
52
+ break;
53
+ }
54
+ case "css": {
55
+ const purgeCSSResult = await new purgecss.PurgeCSS().purge({
56
+ content: [`${cwd}**/*.html`],
57
+ css: [cwd + filename],
58
+ variables: false
59
+ });
60
+ for (const result of purgeCSSResult) {
61
+ if (result.file && node_fs.existsSync(result.file)) {
62
+ await promises.writeFile(result.file, result.css, "utf-8");
63
+ }
64
+ }
65
+ break;
66
+ }
67
+ }
68
+ };
16
69
  function index({ include, exclude, devtools } = {}) {
17
70
  return {
18
71
  name: "defuss",
19
72
  hooks: {
20
- "astro:config:setup": ({ addRenderer, updateConfig, command, injectScript }) => {
73
+ "astro:config:setup": async ({ config, addRenderer, updateConfig, command, injectScript, injectRoute }) => {
74
+ injectRoute({
75
+ pattern: "/_defuss/image",
76
+ prerender: false,
77
+ entrypoint: "defuss-astro/image-endpoint.js"
78
+ });
79
+ const publicDirPath = node_url.fileURLToPath(config.publicDir);
80
+ config.compressHTML = true;
81
+ config.scopedStyleStrategy = "class";
82
+ if (!config.vite.build) {
83
+ config.vite.build = {};
84
+ }
85
+ config.vite.build.cssMinify = "lightningcss";
86
+ processDirectoryDestructive(publicDirPath, false);
21
87
  addRenderer(getRenderer());
22
88
  updateConfig({
23
89
  vite: {
24
90
  optimizeDeps: {
25
91
  include: ["defuss-astro/client.js", "defuss-astro/server.js"]
26
92
  },
93
+ ssr: {
94
+ noExternal: ["lightningimg-node"]
95
+ },
27
96
  plugins: [defussPlugin()]
28
97
  }
29
98
  });
99
+ },
100
+ "astro:build:done": async ({ dir }) => {
101
+ const start = node_perf_hooks.performance.now();
102
+ const cwd = node_url.fileURLToPath(dir);
103
+ const [cssFiles, htmlFiles, imageFiles, svgFiles] = await Promise.all([
104
+ glob("**/*.css", { cwd, ignore: ["**/*-min.css", "**/*.min.css"] }),
105
+ glob("**/*.html", { cwd }),
106
+ glob("**/*.(jpg|jpeg|png|tiff)", { cwd }),
107
+ glob("**/*.svg", { cwd })
108
+ ]);
109
+ logMessage(`\u2734\uFE0F Optimizing ${imageFiles.length} images`);
110
+ processDirectoryDestructive(cwd, true);
111
+ if (htmlFiles.length === 0 && svgFiles.length === 0) return;
112
+ logMessage(`\u2734\uFE0F Optimizing ${svgFiles.length} SVG vector graphics`);
113
+ logMessage(`\u2734\uFE0F Optimizing ${cssFiles.length} CSS stylesheets`);
114
+ const minifyAndWritePromises = [];
115
+ for (const filename of cssFiles) {
116
+ minifyAndWritePromises.push(minifyAndWriteFile(cwd, filename, "css"));
117
+ }
118
+ for (const filename of svgFiles) {
119
+ minifyAndWritePromises.push(minifyAndWriteFile(cwd, filename, "svg"));
120
+ }
121
+ await Promise.all(minifyAndWritePromises);
122
+ const end = node_perf_hooks.performance.now();
123
+ const deltaT = end - start;
124
+ const humanTime = deltaT < 1e3 ? `${deltaT.toFixed(0)}ms` : `${(deltaT / 1e3).toFixed(1)}s`;
125
+ logMessage(`\u2734\uFE0F Optimization completed in ${humanTime}`);
30
126
  }
31
127
  }
32
128
  };
@@ -34,4 +130,4 @@ function index({ include, exclude, devtools } = {}) {
34
130
 
35
131
  exports.default = index;
36
132
  exports.getContainerRenderer = getContainerRenderer;
37
- //# sourceMappingURL=index.cjs.map
133
+ exports.nodeRequire = nodeRequire;
package/dist/index.d.cts CHANGED
@@ -5,7 +5,8 @@ interface Options extends Pick<DefussVitePluginOptions, "exclude" | "include"> {
5
5
  devtools?: boolean;
6
6
  }
7
7
 
8
+ declare const nodeRequire: NodeRequire;
8
9
  declare const getContainerRenderer: () => ContainerRenderer;
9
10
  declare function export_default({ include, exclude, devtools }?: Options): AstroIntegration;
10
11
 
11
- export { export_default as default, getContainerRenderer };
12
+ export { export_default as default, getContainerRenderer, nodeRequire };
package/dist/index.d.mts CHANGED
@@ -5,7 +5,8 @@ interface Options extends Pick<DefussVitePluginOptions, "exclude" | "include"> {
5
5
  devtools?: boolean;
6
6
  }
7
7
 
8
+ declare const nodeRequire: NodeRequire;
8
9
  declare const getContainerRenderer: () => ContainerRenderer;
9
10
  declare function export_default({ include, exclude, devtools }?: Options): AstroIntegration;
10
11
 
11
- export { export_default as default, getContainerRenderer };
12
+ export { export_default as default, getContainerRenderer, nodeRequire };
package/dist/index.mjs CHANGED
@@ -1,5 +1,21 @@
1
1
  import defussPlugin from 'defuss-vite';
2
+ import { fileURLToPath } from 'node:url';
3
+ import glob from 'fast-glob';
4
+ import { performance } from 'node:perf_hooks';
5
+ import { optimize } from 'svgo';
6
+ import { join } from 'node:path';
7
+ import { readFile, writeFile } from 'node:fs/promises';
8
+ import { PurgeCSS } from 'purgecss';
9
+ import { existsSync } from 'node:fs';
10
+ import { createRequire } from 'node:module';
2
11
 
12
+ const logMessage = (message) => {
13
+ const date = (/* @__PURE__ */ new Date()).toLocaleTimeString();
14
+ console.log(`${date} \x1B[32mdefuss-astro:\x1B[0m ${message}`);
15
+ };
16
+
17
+ const nodeRequire = createRequire(import.meta.url);
18
+ const { processDirectoryDestructive } = nodeRequire("lightningimg-node");
3
19
  const getRenderer = (development) => ({
4
20
  name: "defuss",
5
21
  clientEntrypoint: "defuss-astro/client.js",
@@ -9,24 +25,102 @@ const getContainerRenderer = () => ({
9
25
  name: "defuss",
10
26
  serverEntrypoint: "defuss-astro/server.js"
11
27
  });
28
+ const minifyAndWriteFile = async (cwd, filename, type) => {
29
+ const filePath = join(cwd, filename);
30
+ const fileOrg = await readFile(filePath, "utf8");
31
+ switch (type) {
32
+ case "svg": {
33
+ const fileMin = optimize(fileOrg, {
34
+ multipass: true,
35
+ plugins: [
36
+ {
37
+ name: "preset-default",
38
+ params: {
39
+ overrides: {
40
+ removeViewBox: false
41
+ }
42
+ }
43
+ }
44
+ ]
45
+ });
46
+ await writeFile(filePath, fileMin.data, "utf-8");
47
+ break;
48
+ }
49
+ case "css": {
50
+ const purgeCSSResult = await new PurgeCSS().purge({
51
+ content: [`${cwd}**/*.html`],
52
+ css: [cwd + filename],
53
+ variables: false
54
+ });
55
+ for (const result of purgeCSSResult) {
56
+ if (result.file && existsSync(result.file)) {
57
+ await writeFile(result.file, result.css, "utf-8");
58
+ }
59
+ }
60
+ break;
61
+ }
62
+ }
63
+ };
12
64
  function index({ include, exclude, devtools } = {}) {
13
65
  return {
14
66
  name: "defuss",
15
67
  hooks: {
16
- "astro:config:setup": ({ addRenderer, updateConfig, command, injectScript }) => {
68
+ "astro:config:setup": async ({ config, addRenderer, updateConfig, command, injectScript, injectRoute }) => {
69
+ injectRoute({
70
+ pattern: "/_defuss/image",
71
+ prerender: false,
72
+ entrypoint: "defuss-astro/image-endpoint.js"
73
+ });
74
+ const publicDirPath = fileURLToPath(config.publicDir);
75
+ config.compressHTML = true;
76
+ config.scopedStyleStrategy = "class";
77
+ if (!config.vite.build) {
78
+ config.vite.build = {};
79
+ }
80
+ config.vite.build.cssMinify = "lightningcss";
81
+ processDirectoryDestructive(publicDirPath, false);
17
82
  addRenderer(getRenderer());
18
83
  updateConfig({
19
84
  vite: {
20
85
  optimizeDeps: {
21
86
  include: ["defuss-astro/client.js", "defuss-astro/server.js"]
22
87
  },
88
+ ssr: {
89
+ noExternal: ["lightningimg-node"]
90
+ },
23
91
  plugins: [defussPlugin()]
24
92
  }
25
93
  });
94
+ },
95
+ "astro:build:done": async ({ dir }) => {
96
+ const start = performance.now();
97
+ const cwd = fileURLToPath(dir);
98
+ const [cssFiles, htmlFiles, imageFiles, svgFiles] = await Promise.all([
99
+ glob("**/*.css", { cwd, ignore: ["**/*-min.css", "**/*.min.css"] }),
100
+ glob("**/*.html", { cwd }),
101
+ glob("**/*.(jpg|jpeg|png|tiff)", { cwd }),
102
+ glob("**/*.svg", { cwd })
103
+ ]);
104
+ logMessage(`\u2734\uFE0F Optimizing ${imageFiles.length} images`);
105
+ processDirectoryDestructive(cwd, true);
106
+ if (htmlFiles.length === 0 && svgFiles.length === 0) return;
107
+ logMessage(`\u2734\uFE0F Optimizing ${svgFiles.length} SVG vector graphics`);
108
+ logMessage(`\u2734\uFE0F Optimizing ${cssFiles.length} CSS stylesheets`);
109
+ const minifyAndWritePromises = [];
110
+ for (const filename of cssFiles) {
111
+ minifyAndWritePromises.push(minifyAndWriteFile(cwd, filename, "css"));
112
+ }
113
+ for (const filename of svgFiles) {
114
+ minifyAndWritePromises.push(minifyAndWriteFile(cwd, filename, "svg"));
115
+ }
116
+ await Promise.all(minifyAndWritePromises);
117
+ const end = performance.now();
118
+ const deltaT = end - start;
119
+ const humanTime = deltaT < 1e3 ? `${deltaT.toFixed(0)}ms` : `${(deltaT / 1e3).toFixed(1)}s`;
120
+ logMessage(`\u2734\uFE0F Optimization completed in ${humanTime}`);
26
121
  }
27
122
  }
28
123
  };
29
124
  }
30
125
 
31
- export { index as default, getContainerRenderer };
32
- //# sourceMappingURL=index.mjs.map
126
+ export { index as default, getContainerRenderer, nodeRequire };
@@ -5,4 +5,3 @@ var defuss = require('defuss');
5
5
  const StaticHtml = (html) => !html ? null : defuss.jsx("astro-static-slot", { dangerouslySetInnerHTML: { __html: html } });
6
6
 
7
7
  exports.StaticHtml = StaticHtml;
8
- //# sourceMappingURL=render-DkMOLcUd.cjs.map
@@ -3,4 +3,3 @@ import { jsx } from 'defuss';
3
3
  const StaticHtml = (html) => !html ? null : jsx("astro-static-slot", { dangerouslySetInnerHTML: { __html: html } });
4
4
 
5
5
  export { StaticHtml as S };
6
- //# sourceMappingURL=render-viAgneG-.mjs.map
package/dist/server.cjs CHANGED
@@ -1,31 +1,11 @@
1
1
  'use strict';
2
2
 
3
3
  var server = require('defuss/server');
4
- require('defuss');
5
4
  var render = require('./render-DkMOLcUd.cjs');
6
-
7
- const contexts = /* @__PURE__ */ new WeakMap();
8
- function getContext(result) {
9
- if (contexts.has(result)) {
10
- return contexts.get(result);
11
- }
12
- const ctx = {
13
- c: 0,
14
- get id() {
15
- return `s${this.c.toString()}`;
16
- }
17
- };
18
- contexts.set(result, ctx);
19
- return ctx;
20
- }
21
- function incrementId(ctx) {
22
- const id = ctx.id;
23
- ctx.c++;
24
- return id;
25
- }
5
+ require('defuss');
26
6
 
27
7
  const slotName = (str) => str.trim().replace(/[-_]([a-z])/g, (_, w) => w.toUpperCase());
28
- async function check(Component, props, children) {
8
+ async function check(Component, _props, _children) {
29
9
  if (typeof Component !== "function") return false;
30
10
  if (Component.name === "QwikComponent") return false;
31
11
  if (Component.toString().includes("$$payload")) return false;
@@ -34,8 +14,6 @@ async function check(Component, props, children) {
34
14
  return true;
35
15
  }
36
16
  async function renderToStaticMarkup(Component, props, { default: children, ...slotted }, metadata) {
37
- const ctx = getContext(this.result);
38
- const renderId = metadata?.hydrate ? incrementId(ctx) : "";
39
17
  const needsHydrate = metadata?.astroStaticSlot ? !!metadata.hydrate : true;
40
18
  const tagName = needsHydrate ? "astro-slot" : "astro-static-slot";
41
19
  const slots = {};
@@ -52,20 +30,37 @@ async function renderToStaticMarkup(Component, props, { default: children, ...sl
52
30
  if (children) {
53
31
  componentProps.children = children;
54
32
  }
55
- let dom = server.render(Component(componentProps));
56
- const attrs = {
57
- "data-defuss-render-id": renderId
58
- };
33
+ let vdom;
34
+ const browserGlobals = server.getBrowserGlobals();
35
+ const document = server.getDocument(false, browserGlobals);
36
+ browserGlobals.document = document;
37
+ for (const key of Object.keys(browserGlobals)) {
38
+ if (typeof globalThis[key] === "undefined") {
39
+ globalThis[key] = browserGlobals[key];
40
+ }
41
+ }
42
+ try {
43
+ vdom = Component(componentProps);
44
+ } catch (error) {
45
+ vdom = server.createInPlaceErrorMessageVNode(error);
46
+ console.error("FATAL ERROR in top-level component JSX (SSR)", vdom);
47
+ console.error("Original error", error);
48
+ }
49
+ let roots;
50
+ let html = "";
51
+ const attrs = {};
52
+ roots = server.render(vdom, document.documentElement, {
53
+ browserGlobals
54
+ });
59
55
  for (const [key, value] of Object.entries(props)) {
60
56
  if (key !== "children") {
61
57
  attrs[key] = value;
62
58
  }
63
59
  }
64
- if (!Array.isArray(dom)) {
65
- dom = [dom];
60
+ if (!Array.isArray(roots)) {
61
+ roots = [roots];
66
62
  }
67
- let html = "";
68
- for (const el of dom) {
63
+ for (const el of roots) {
69
64
  html += server.renderToString(el);
70
65
  }
71
66
  return { attrs, html };
@@ -74,12 +69,7 @@ const renderer = {
74
69
  name: "defuss",
75
70
  check,
76
71
  renderToStaticMarkup,
77
- supportsAstroStaticSlot: true,
78
- renderHydrationScript: () => {
79
- console.log("renderHydrationScript");
80
- return "";
81
- }
72
+ supportsAstroStaticSlot: true
82
73
  };
83
74
 
84
75
  module.exports = renderer;
85
- //# sourceMappingURL=server.cjs.map
package/dist/server.mjs CHANGED
@@ -1,29 +1,9 @@
1
- import { render, renderToString } from 'defuss/server';
2
- import 'defuss';
1
+ import { getBrowserGlobals, getDocument, createInPlaceErrorMessageVNode, render, renderToString } from 'defuss/server';
3
2
  import { S as StaticHtml } from './render-viAgneG-.mjs';
4
-
5
- const contexts = /* @__PURE__ */ new WeakMap();
6
- function getContext(result) {
7
- if (contexts.has(result)) {
8
- return contexts.get(result);
9
- }
10
- const ctx = {
11
- c: 0,
12
- get id() {
13
- return `s${this.c.toString()}`;
14
- }
15
- };
16
- contexts.set(result, ctx);
17
- return ctx;
18
- }
19
- function incrementId(ctx) {
20
- const id = ctx.id;
21
- ctx.c++;
22
- return id;
23
- }
3
+ import 'defuss';
24
4
 
25
5
  const slotName = (str) => str.trim().replace(/[-_]([a-z])/g, (_, w) => w.toUpperCase());
26
- async function check(Component, props, children) {
6
+ async function check(Component, _props, _children) {
27
7
  if (typeof Component !== "function") return false;
28
8
  if (Component.name === "QwikComponent") return false;
29
9
  if (Component.toString().includes("$$payload")) return false;
@@ -32,8 +12,6 @@ async function check(Component, props, children) {
32
12
  return true;
33
13
  }
34
14
  async function renderToStaticMarkup(Component, props, { default: children, ...slotted }, metadata) {
35
- const ctx = getContext(this.result);
36
- const renderId = metadata?.hydrate ? incrementId(ctx) : "";
37
15
  const needsHydrate = metadata?.astroStaticSlot ? !!metadata.hydrate : true;
38
16
  const tagName = needsHydrate ? "astro-slot" : "astro-static-slot";
39
17
  const slots = {};
@@ -50,20 +28,37 @@ async function renderToStaticMarkup(Component, props, { default: children, ...sl
50
28
  if (children) {
51
29
  componentProps.children = children;
52
30
  }
53
- let dom = render(Component(componentProps));
54
- const attrs = {
55
- "data-defuss-render-id": renderId
56
- };
31
+ let vdom;
32
+ const browserGlobals = getBrowserGlobals();
33
+ const document = getDocument(false, browserGlobals);
34
+ browserGlobals.document = document;
35
+ for (const key of Object.keys(browserGlobals)) {
36
+ if (typeof globalThis[key] === "undefined") {
37
+ globalThis[key] = browserGlobals[key];
38
+ }
39
+ }
40
+ try {
41
+ vdom = Component(componentProps);
42
+ } catch (error) {
43
+ vdom = createInPlaceErrorMessageVNode(error);
44
+ console.error("FATAL ERROR in top-level component JSX (SSR)", vdom);
45
+ console.error("Original error", error);
46
+ }
47
+ let roots;
48
+ let html = "";
49
+ const attrs = {};
50
+ roots = render(vdom, document.documentElement, {
51
+ browserGlobals
52
+ });
57
53
  for (const [key, value] of Object.entries(props)) {
58
54
  if (key !== "children") {
59
55
  attrs[key] = value;
60
56
  }
61
57
  }
62
- if (!Array.isArray(dom)) {
63
- dom = [dom];
58
+ if (!Array.isArray(roots)) {
59
+ roots = [roots];
64
60
  }
65
- let html = "";
66
- for (const el of dom) {
61
+ for (const el of roots) {
67
62
  html += renderToString(el);
68
63
  }
69
64
  return { attrs, html };
@@ -72,12 +67,7 @@ const renderer = {
72
67
  name: "defuss",
73
68
  check,
74
69
  renderToStaticMarkup,
75
- supportsAstroStaticSlot: true,
76
- renderHydrationScript: () => {
77
- console.log("renderHydrationScript");
78
- return "";
79
- }
70
+ supportsAstroStaticSlot: true
80
71
  };
81
72
 
82
73
  export { renderer as default };
83
- //# sourceMappingURL=server.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "defuss-astro",
3
- "version": "1.1.4",
3
+ "version": "1.3.1",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -19,10 +19,10 @@
19
19
  "type": "git"
20
20
  },
21
21
  "scripts": {
22
- "clean": "rm -rf ./dist && rm -rf ./node_modules/.vite",
22
+ "clean": "rm -rf ./dist && rm -rf ./node_modules/.pnpm",
23
23
  "pretest": "pnpm run build",
24
24
  "prebuild": "pnpm run clean",
25
- "build": "pkgroll --sourcemap",
25
+ "build": "pkgroll",
26
26
  "postbuild": "tsx ./scripts/finalize-build.ts"
27
27
  },
28
28
  "author": "Aron Homberg <info@aron-homberg.de>",
@@ -57,6 +57,10 @@
57
57
  "types": "./dist/server.d.mts",
58
58
  "default": "./dist/server.mjs"
59
59
  }
60
+ },
61
+ "./image-endpoint.js": {
62
+ "types": "./dist/endpoint/image-endpoint.d.mts",
63
+ "default": "./dist/endpoint/image-endpoint.mjs"
60
64
  }
61
65
  },
62
66
  "main": "./dist/index.cjs",
@@ -74,9 +78,17 @@
74
78
  "node": "^18.17.1 || ^20.3.0 || >=21.0.0"
75
79
  },
76
80
  "dependencies": {
77
- "defuss": "^1.2.4",
78
- "defuss-vite": "^1.0.6",
79
- "astro": "^5.0.5",
80
- "vite": "^6.0.3"
81
+ "defuss": "workspace:*",
82
+ "defuss-vite": "workspace:*",
83
+ "astro": "^5.7.2",
84
+ "vite": "^6.2.6",
85
+ "fast-glob": "^3.3.2",
86
+ "svgo": "^3.3.2",
87
+ "lightningimg-node": "^0.3.3",
88
+ "purgecss": "^7.0.2",
89
+ "file-type": "^19.6.0"
90
+ },
91
+ "peerDependencies": {
92
+ "@minify-html/node": "^0.15.0"
81
93
  }
82
94
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.cjs","sources":["../src/client.ts"],"sourcesContent":["import { type Props, render } from 'defuss/client'\nimport { StaticHtml } from './render.js';\n\nexport default (element: HTMLElement) =>\n\tasync (\n\t\tComponent: any,\n\t\tprops: Record<string, any>,\n\t\t{ default: children, ...slotted }: Record<string, any>,\n\t\t{ client }: Record<string, string>,\n\t) => {\n\n\t\tconst isHydrate = client !== 'only';\n\n\t\tif (element.hasAttribute('ssr')) {\n\t\t\tconsole.log('ssr attr found isHydrate', isHydrate, Component, 'props', props, 'slotted', slotted, 'children', children, 'client', client);\n\t\t}\n\t\t\n\t\tif (!element.hasAttribute('ssr')) return;\n\t\t\n\t\t// <slot> mechanics\n\t\tObject.entries(slotted).forEach(([key, value]) => {\n\t\t\tprops[key] = StaticHtml(value);\n\t\t});\n\n\t\t// traverse the props object and create a new object with the same values\n\t\tconst componentProps: Props = { ...props };\n\n\t\t// children is a special prop that contains the children of the component\n\t\tif (children) {\n\t\t\t// all children are passed as an array\n\t\t\tif (!Array.isArray(children)) {\n\t\t\t\tchildren = [children];\n\t\t\t} \n\n\t\t\tfor (let i=0; i<children.length; i++) {\n\t\t\t\tif (typeof children[i] === 'string') {\n\t\t\t\t\t// turn static HTML into a component\n\t\t\t\t\tchildren[i] = StaticHtml(children[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcomponentProps.children = children;\n\t\t}\n\n\t\tconst vdom = Component(componentProps);\n\n\t\t// turn the component AST into an actual DOM element and attach it to the element passed in\n\t\tconst dom: HTMLElement = render(vdom, element) as HTMLElement;\n\n\t\t// set all props as top level attributes\n\t\tfor (const [key, value] of Object.entries(props)) {\n\t\t\tif (key !== 'children') {\n\t\t\t\tdom.setAttribute(key, value);\n\t\t\t}\n\t\t}\n\n\t\telement.addEventListener('astro:unmount', () => {\n\t\t\t// remove the rendered component from the DOM\n\t\t\tif (dom.parentNode) {\n\t\t\t\tdom.parentNode.removeChild(dom);\n\t\t\t}\n }, { once: true });\n\t};"],"names":["StaticHtml","render"],"mappings":";;;;;;AAGA,aAAe,CAAC,OAAO,KAAK,OAAO,SAAS,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK;AACvG,EAAE,MAAM,SAAS,GAAG,MAAM,KAAK,MAAM;AACrC,EAAE,IAAI,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;AACnC,IAAI,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC;AAC7I;AACA,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;AACpC,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK;AACpD,IAAI,KAAK,CAAC,GAAG,CAAC,GAAGA,iBAAU,CAAC,KAAK,CAAC;AAClC,GAAG,CAAC;AACJ,EAAE,MAAM,cAAc,GAAG,EAAE,GAAG,KAAK,EAAE;AACrC,EAAE,IAAI,QAAQ,EAAE;AAChB,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;AAClC,MAAM,QAAQ,GAAG,CAAC,QAAQ,CAAC;AAC3B;AACA,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AAC9C,MAAM,IAAI,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;AAC3C,QAAQ,QAAQ,CAAC,CAAC,CAAC,GAAGA,iBAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC7C;AACA;AACA,IAAI,cAAc,CAAC,QAAQ,GAAG,QAAQ;AACtC;AACA,EAAE,MAAM,IAAI,GAAG,SAAS,CAAC,cAAc,CAAC;AACxC,EAAE,MAAM,GAAG,GAAGC,eAAM,CAAC,IAAI,EAAE,OAAO,CAAC;AACnC,EAAE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AACpD,IAAI,IAAI,GAAG,KAAK,UAAU,EAAE;AAC5B,MAAM,GAAG,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC;AAClC;AACA;AACA,EAAE,OAAO,CAAC,gBAAgB,CAAC,eAAe,EAAE,MAAM;AAClD,IAAI,IAAI,GAAG,CAAC,UAAU,EAAE;AACxB,MAAM,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC;AACrC;AACA,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACpB,CAAC;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.mjs","sources":["../src/client.ts"],"sourcesContent":["import { type Props, render } from 'defuss/client'\nimport { StaticHtml } from './render.js';\n\nexport default (element: HTMLElement) =>\n\tasync (\n\t\tComponent: any,\n\t\tprops: Record<string, any>,\n\t\t{ default: children, ...slotted }: Record<string, any>,\n\t\t{ client }: Record<string, string>,\n\t) => {\n\n\t\tconst isHydrate = client !== 'only';\n\n\t\tif (element.hasAttribute('ssr')) {\n\t\t\tconsole.log('ssr attr found isHydrate', isHydrate, Component, 'props', props, 'slotted', slotted, 'children', children, 'client', client);\n\t\t}\n\t\t\n\t\tif (!element.hasAttribute('ssr')) return;\n\t\t\n\t\t// <slot> mechanics\n\t\tObject.entries(slotted).forEach(([key, value]) => {\n\t\t\tprops[key] = StaticHtml(value);\n\t\t});\n\n\t\t// traverse the props object and create a new object with the same values\n\t\tconst componentProps: Props = { ...props };\n\n\t\t// children is a special prop that contains the children of the component\n\t\tif (children) {\n\t\t\t// all children are passed as an array\n\t\t\tif (!Array.isArray(children)) {\n\t\t\t\tchildren = [children];\n\t\t\t} \n\n\t\t\tfor (let i=0; i<children.length; i++) {\n\t\t\t\tif (typeof children[i] === 'string') {\n\t\t\t\t\t// turn static HTML into a component\n\t\t\t\t\tchildren[i] = StaticHtml(children[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcomponentProps.children = children;\n\t\t}\n\n\t\tconst vdom = Component(componentProps);\n\n\t\t// turn the component AST into an actual DOM element and attach it to the element passed in\n\t\tconst dom: HTMLElement = render(vdom, element) as HTMLElement;\n\n\t\t// set all props as top level attributes\n\t\tfor (const [key, value] of Object.entries(props)) {\n\t\t\tif (key !== 'children') {\n\t\t\t\tdom.setAttribute(key, value);\n\t\t\t}\n\t\t}\n\n\t\telement.addEventListener('astro:unmount', () => {\n\t\t\t// remove the rendered component from the DOM\n\t\t\tif (dom.parentNode) {\n\t\t\t\tdom.parentNode.removeChild(dom);\n\t\t\t}\n }, { once: true });\n\t};"],"names":[],"mappings":";;;;AAGA,aAAe,CAAC,OAAO,KAAK,OAAO,SAAS,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK;AACvG,EAAE,MAAM,SAAS,GAAG,MAAM,KAAK,MAAM;AACrC,EAAE,IAAI,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;AACnC,IAAI,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC;AAC7I;AACA,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;AACpC,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK;AACpD,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC;AAClC,GAAG,CAAC;AACJ,EAAE,MAAM,cAAc,GAAG,EAAE,GAAG,KAAK,EAAE;AACrC,EAAE,IAAI,QAAQ,EAAE;AAChB,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;AAClC,MAAM,QAAQ,GAAG,CAAC,QAAQ,CAAC;AAC3B;AACA,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AAC9C,MAAM,IAAI,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;AAC3C,QAAQ,QAAQ,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC7C;AACA;AACA,IAAI,cAAc,CAAC,QAAQ,GAAG,QAAQ;AACtC;AACA,EAAE,MAAM,IAAI,GAAG,SAAS,CAAC,cAAc,CAAC;AACxC,EAAE,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC;AACnC,EAAE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AACpD,IAAI,IAAI,GAAG,KAAK,UAAU,EAAE;AAC5B,MAAM,GAAG,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC;AAClC;AACA;AACA,EAAE,OAAO,CAAC,gBAAgB,CAAC,eAAe,EAAE,MAAM;AAClD,IAAI,IAAI,GAAG,CAAC,UAAU,EAAE;AACxB,MAAM,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC;AACrC;AACA,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACpB,CAAC;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["import type { AstroIntegration, AstroRenderer, ContainerRenderer, ViteUserConfig } from 'astro';\nimport type { Options } from './types.js';\nimport defussPlugin from 'defuss-vite';\n\nconst getRenderer = (development: boolean): AstroRenderer => ({\n name: 'defuss',\n clientEntrypoint: 'defuss-astro/client.js',\n serverEntrypoint: 'defuss-astro/server.js',\n})\n\nexport const getContainerRenderer = (): ContainerRenderer => ({\n name: 'defuss',\n serverEntrypoint: 'defuss-astro/server.js',\n})\n\nexport default function ({ include, exclude, devtools }: Options = {}): AstroIntegration {\n\treturn {\n\t\tname: 'defuss',\n\t\thooks: {\n\t\t\t'astro:config:setup': ({ addRenderer, updateConfig, command, injectScript }) => {\n\t\t\t\taddRenderer(getRenderer(command === 'dev'));\n\t\t\t\tupdateConfig({\n\t\t\t\t\tvite: {\n\t\t\t\t\t\toptimizeDeps: {\n\t\t\t\t\t\t\tinclude: ['defuss-astro/client.js', 'defuss-astro/server.js'],\n\t\t\t\t\t\t},\n\t\t\t\t\t\tplugins: [defussPlugin()],\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\t/**\n\t\t\t\t * if (command === 'dev' && devtools) {\n\t\t\t\t\tinjectScript('page', 'import \"preact/debug\";');\n\t\t\t\t}*/\n\t\t\t},\n\t\t},\n\t};\n}"],"names":[],"mappings":";;;;;;AAEA,MAAM,WAAW,GAAG,CAAC,WAAW,MAAM;AACtC,EAAE,IAAI,EAAE,QAAQ;AAChB,EAAE,gBAAgB,EAAE,wBAAwB;AAC5C,EAAE,gBAAgB,EAAE;AACpB,CAAC,CAAC;AACU,MAAC,oBAAoB,GAAG,OAAO;AAC3C,EAAE,IAAI,EAAE,QAAQ;AAChB,EAAE,gBAAgB,EAAE;AACpB,CAAC;AACc,cAAQ,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE;AAC7D,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,QAAQ;AAClB,IAAI,KAAK,EAAE;AACX,MAAM,oBAAoB,EAAE,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK;AACtF,QAAQ,WAAW,CAAC,WAAW,CAAkB,CAAC,CAAC;AACnD,QAAQ,YAAY,CAAC;AACrB,UAAU,IAAI,EAAE;AAChB,YAAY,YAAY,EAAE;AAC1B,cAAc,OAAO,EAAE,CAAC,wBAAwB,EAAE,wBAAwB;AAC1E,aAAa;AACb,YAAY,OAAO,EAAE,CAAC,YAAY,EAAE;AACpC;AACA,SAAS,CAAC;AACV;AACA;AACA,GAAG;AACH;;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import type { AstroIntegration, AstroRenderer, ContainerRenderer, ViteUserConfig } from 'astro';\nimport type { Options } from './types.js';\nimport defussPlugin from 'defuss-vite';\n\nconst getRenderer = (development: boolean): AstroRenderer => ({\n name: 'defuss',\n clientEntrypoint: 'defuss-astro/client.js',\n serverEntrypoint: 'defuss-astro/server.js',\n})\n\nexport const getContainerRenderer = (): ContainerRenderer => ({\n name: 'defuss',\n serverEntrypoint: 'defuss-astro/server.js',\n})\n\nexport default function ({ include, exclude, devtools }: Options = {}): AstroIntegration {\n\treturn {\n\t\tname: 'defuss',\n\t\thooks: {\n\t\t\t'astro:config:setup': ({ addRenderer, updateConfig, command, injectScript }) => {\n\t\t\t\taddRenderer(getRenderer(command === 'dev'));\n\t\t\t\tupdateConfig({\n\t\t\t\t\tvite: {\n\t\t\t\t\t\toptimizeDeps: {\n\t\t\t\t\t\t\tinclude: ['defuss-astro/client.js', 'defuss-astro/server.js'],\n\t\t\t\t\t\t},\n\t\t\t\t\t\tplugins: [defussPlugin()],\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\t/**\n\t\t\t\t * if (command === 'dev' && devtools) {\n\t\t\t\t\tinjectScript('page', 'import \"preact/debug\";');\n\t\t\t\t}*/\n\t\t\t},\n\t\t},\n\t};\n}"],"names":[],"mappings":";;AAEA,MAAM,WAAW,GAAG,CAAC,WAAW,MAAM;AACtC,EAAE,IAAI,EAAE,QAAQ;AAChB,EAAE,gBAAgB,EAAE,wBAAwB;AAC5C,EAAE,gBAAgB,EAAE;AACpB,CAAC,CAAC;AACU,MAAC,oBAAoB,GAAG,OAAO;AAC3C,EAAE,IAAI,EAAE,QAAQ;AAChB,EAAE,gBAAgB,EAAE;AACpB,CAAC;AACc,cAAQ,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE;AAC7D,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,QAAQ;AAClB,IAAI,KAAK,EAAE;AACX,MAAM,oBAAoB,EAAE,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK;AACtF,QAAQ,WAAW,CAAC,WAAW,CAAkB,CAAC,CAAC;AACnD,QAAQ,YAAY,CAAC;AACrB,UAAU,IAAI,EAAE;AAChB,YAAY,YAAY,EAAE;AAC1B,cAAc,OAAO,EAAE,CAAC,wBAAwB,EAAE,wBAAwB;AAC1E,aAAa;AACb,YAAY,OAAO,EAAE,CAAC,YAAY,EAAE;AACpC;AACA,SAAS,CAAC;AACV;AACA;AACA,GAAG;AACH;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"render-DkMOLcUd.cjs","sources":["../src/render.ts"],"sourcesContent":["import { jsx } from \"defuss\";\n\nexport const StaticHtml = (html: string) => \n\t!html ? null : jsx('astro-static-slot', { dangerouslySetInnerHTML: { __html: html } });\n"],"names":["jsx"],"mappings":";;;;AAEY,MAAC,UAAU,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,GAAG,IAAI,GAAGA,UAAG,CAAC,mBAAmB,EAAE,EAAE,uBAAuB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"render-viAgneG-.mjs","sources":["../src/render.ts"],"sourcesContent":["import { jsx } from \"defuss\";\n\nexport const StaticHtml = (html: string) => \n\t!html ? null : jsx('astro-static-slot', { dangerouslySetInnerHTML: { __html: html } });\n"],"names":[],"mappings":";;AAEY,MAAC,UAAU,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,GAAG,IAAI,GAAG,GAAG,CAAC,mBAAmB,EAAE,EAAE,uBAAuB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"server.cjs","sources":["../src/context.ts","../src/server.ts"],"sourcesContent":["import type { RendererContext } from './types.js';\n\ntype Context = {\n\tid: string;\n\tc: number;\n};\n\nconst contexts = new WeakMap<RendererContext['result'], Context>();\n\nexport function getContext(result: RendererContext['result']): Context {\n\tif (contexts.has(result)) {\n\t\treturn contexts.get(result)!;\n\t}\n\tconst ctx: Context = {\n\t\tc: 0,\n\t\tget id() {\n\t\t\treturn `s${this.c.toString()}`;\n\t\t},\n\t};\n\tcontexts.set(result, ctx);\n\treturn ctx;\n}\n\nexport function incrementId(ctx: Context): string {\n\tconst id = ctx.id;\n\tctx.c++;\n\treturn id;\n}","import type { AstroComponentMetadata, NamedSSRLoadedRendererValue } from 'astro';\nimport type { RendererContext } from './types.js';\nimport { renderToString, render } from 'defuss/server'\nimport { type Props, jsx } from 'defuss'\nimport { StaticHtml } from './render.js';\nimport { getContext, incrementId } from './context.js';\n\nconst slotName = (str: string) => str.trim().replace(/[-_]([a-z])/g, (_, w) => w.toUpperCase());\n\nasync function check(\n\tthis: RendererContext,\n\tComponent: any,\n\tprops: Record<string, any>,\n\tchildren: any,\n) {\n\t\n\tif (typeof Component !== 'function') return false;\n\tif (Component.name === 'QwikComponent') return false;\n\t// Svelte component renders fine by Solid as an empty string. The only way to detect\n\t// if this isn't a Solid but Svelte component is to unfortunately copy the check\n\t// implementation of the Svelte renderer.\n\tif (Component.toString().includes('$$payload')) return false;\n\t// Preact forwarded-ref components can be functions, which we do not support\n\tif (typeof Component === 'function' && Component.$$typeof === Symbol.for('react.forward_ref'))\n\t\treturn false;\n\n\treturn true; // always (re-)render for now (TODO: implement proper check)\n}\n\nasync function renderToStaticMarkup(\n\tthis: RendererContext,\n\tComponent: any,\n\tprops: Record<string, any>,\n\t{ default: children, ...slotted }: Record<string, any>,\n\tmetadata: AstroComponentMetadata | undefined,\n) {\n\n\tconst ctx = getContext(this.result);\n\tconst renderId = metadata?.hydrate ? incrementId(ctx) : '';\n\tconst needsHydrate = metadata?.astroStaticSlot ? !!metadata.hydrate : true;\n\tconst tagName = needsHydrate ? 'astro-slot' : 'astro-static-slot';\n\n\tconst slots: Record<string, unknown> = {};\n\tfor (const [key, value] of Object.entries(slotted)) {\n\t\tconst name = slotName(key);\n\t\tslots[name] = StaticHtml(`<${tagName} name=\"${name}\">${value}</${tagName}>`);\n\t}\n\n\t// Note: create newProps to avoid mutating `props` before they are serialized\n\t// traverse the props object and create a new object with the same values\n\tconst componentProps: Props = {\n\t\t...props,\n\t\t...slots,\n\t\t// In Solid SSR mode, `ssr` creates the expected structure for `children`.\n\t\tchildren: children != null ? StaticHtml(`<${tagName}>${children}</${tagName}>`) : children,\n\t};\n\n\t// children is a special prop that contains the children of the component\n\tif (children) {\n\t\tcomponentProps.children = children;\n\t}\n\n\t// turn the component AST into an actual DOM element and attach it to the element passed in\n\tlet dom: HTMLElement|Array<HTMLElement> = render(Component(componentProps)) as HTMLElement;\n\n\tconst attrs = {\n\t\t'data-defuss-render-id': renderId,\n\t};\n\t\n\t// set all props as top level attributes\n\tfor (const [key, value] of Object.entries(props)) {\n\t\tif (key !== 'children') {\n\t\t\t(attrs as Record<string, unknown>)[key] = value;\n\t\t}\n\t}\n\n\tif (!Array.isArray(dom)) {\n\t\tdom = [dom];\n\t}\n\n\tlet html = '';\n\tfor (const el of dom) {\n\t\thtml += renderToString(el);\n\t}\n\treturn { attrs, html };\n}\n\nconst renderer: NamedSSRLoadedRendererValue = {\n\tname: 'defuss',\n\tcheck,\n\trenderToStaticMarkup,\n\tsupportsAstroStaticSlot: true,\n\trenderHydrationScript: () => {\n\t\tconsole.log('renderHydrationScript');\n\t\treturn '';\n\t},\n};\n\nexport default renderer;"],"names":["StaticHtml","render","renderToString"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"server.mjs","sources":["../src/context.ts","../src/server.ts"],"sourcesContent":["import type { RendererContext } from './types.js';\n\ntype Context = {\n\tid: string;\n\tc: number;\n};\n\nconst contexts = new WeakMap<RendererContext['result'], Context>();\n\nexport function getContext(result: RendererContext['result']): Context {\n\tif (contexts.has(result)) {\n\t\treturn contexts.get(result)!;\n\t}\n\tconst ctx: Context = {\n\t\tc: 0,\n\t\tget id() {\n\t\t\treturn `s${this.c.toString()}`;\n\t\t},\n\t};\n\tcontexts.set(result, ctx);\n\treturn ctx;\n}\n\nexport function incrementId(ctx: Context): string {\n\tconst id = ctx.id;\n\tctx.c++;\n\treturn id;\n}","import type { AstroComponentMetadata, NamedSSRLoadedRendererValue } from 'astro';\nimport type { RendererContext } from './types.js';\nimport { renderToString, render } from 'defuss/server'\nimport { type Props, jsx } from 'defuss'\nimport { StaticHtml } from './render.js';\nimport { getContext, incrementId } from './context.js';\n\nconst slotName = (str: string) => str.trim().replace(/[-_]([a-z])/g, (_, w) => w.toUpperCase());\n\nasync function check(\n\tthis: RendererContext,\n\tComponent: any,\n\tprops: Record<string, any>,\n\tchildren: any,\n) {\n\t\n\tif (typeof Component !== 'function') return false;\n\tif (Component.name === 'QwikComponent') return false;\n\t// Svelte component renders fine by Solid as an empty string. The only way to detect\n\t// if this isn't a Solid but Svelte component is to unfortunately copy the check\n\t// implementation of the Svelte renderer.\n\tif (Component.toString().includes('$$payload')) return false;\n\t// Preact forwarded-ref components can be functions, which we do not support\n\tif (typeof Component === 'function' && Component.$$typeof === Symbol.for('react.forward_ref'))\n\t\treturn false;\n\n\treturn true; // always (re-)render for now (TODO: implement proper check)\n}\n\nasync function renderToStaticMarkup(\n\tthis: RendererContext,\n\tComponent: any,\n\tprops: Record<string, any>,\n\t{ default: children, ...slotted }: Record<string, any>,\n\tmetadata: AstroComponentMetadata | undefined,\n) {\n\n\tconst ctx = getContext(this.result);\n\tconst renderId = metadata?.hydrate ? incrementId(ctx) : '';\n\tconst needsHydrate = metadata?.astroStaticSlot ? !!metadata.hydrate : true;\n\tconst tagName = needsHydrate ? 'astro-slot' : 'astro-static-slot';\n\n\tconst slots: Record<string, unknown> = {};\n\tfor (const [key, value] of Object.entries(slotted)) {\n\t\tconst name = slotName(key);\n\t\tslots[name] = StaticHtml(`<${tagName} name=\"${name}\">${value}</${tagName}>`);\n\t}\n\n\t// Note: create newProps to avoid mutating `props` before they are serialized\n\t// traverse the props object and create a new object with the same values\n\tconst componentProps: Props = {\n\t\t...props,\n\t\t...slots,\n\t\t// In Solid SSR mode, `ssr` creates the expected structure for `children`.\n\t\tchildren: children != null ? StaticHtml(`<${tagName}>${children}</${tagName}>`) : children,\n\t};\n\n\t// children is a special prop that contains the children of the component\n\tif (children) {\n\t\tcomponentProps.children = children;\n\t}\n\n\t// turn the component AST into an actual DOM element and attach it to the element passed in\n\tlet dom: HTMLElement|Array<HTMLElement> = render(Component(componentProps)) as HTMLElement;\n\n\tconst attrs = {\n\t\t'data-defuss-render-id': renderId,\n\t};\n\t\n\t// set all props as top level attributes\n\tfor (const [key, value] of Object.entries(props)) {\n\t\tif (key !== 'children') {\n\t\t\t(attrs as Record<string, unknown>)[key] = value;\n\t\t}\n\t}\n\n\tif (!Array.isArray(dom)) {\n\t\tdom = [dom];\n\t}\n\n\tlet html = '';\n\tfor (const el of dom) {\n\t\thtml += renderToString(el);\n\t}\n\treturn { attrs, html };\n}\n\nconst renderer: NamedSSRLoadedRendererValue = {\n\tname: 'defuss',\n\tcheck,\n\trenderToStaticMarkup,\n\tsupportsAstroStaticSlot: true,\n\trenderHydrationScript: () => {\n\t\tconsole.log('renderHydrationScript');\n\t\treturn '';\n\t},\n};\n\nexport default renderer;"],"names":[],"mappings":"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"}