defuss-astro 1.4.8 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.cjs +1 -114
- package/dist/client.d.cts +1 -27
- package/dist/client.d.mts +1 -27
- package/dist/client.mjs +2 -112
- package/dist/index.cjs +88 -14
- package/dist/index.d.cts +12 -1
- package/dist/index.d.mts +12 -1
- package/dist/index.mjs +88 -14
- package/package.json +3 -8
- package/dist/endpoint/image-endpoint.cjs +0 -67
- package/dist/endpoint/image-endpoint.d.cts +0 -5
- package/dist/endpoint/image-endpoint.d.mts +0 -5
- package/dist/endpoint/image-endpoint.mjs +0 -65
package/dist/client.cjs
CHANGED
|
@@ -1,121 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
3
|
var client$1 = require('defuss/client');
|
|
6
4
|
var render = require('./render-DkMOLcUd.cjs');
|
|
7
|
-
var jsxRuntime = require('defuss/jsx-runtime');
|
|
8
5
|
require('defuss');
|
|
9
6
|
|
|
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 = ({
|
|
54
|
-
src: src2,
|
|
55
|
-
height: height2,
|
|
56
|
-
width: width2,
|
|
57
|
-
quality: quality2,
|
|
58
|
-
format: format2
|
|
59
|
-
}) => {
|
|
60
|
-
const transformOptions = new URLSearchParams({
|
|
61
|
-
href: src2,
|
|
62
|
-
h: height2.toString(),
|
|
63
|
-
w: width2.toString(),
|
|
64
|
-
q: quality2.toString(),
|
|
65
|
-
f: format2
|
|
66
|
-
});
|
|
67
|
-
return `/${astroAssetsPath}?${transformOptions.toString()}`;
|
|
68
|
-
};
|
|
69
|
-
const lazyLoad = () => {
|
|
70
|
-
if (loaded) return;
|
|
71
|
-
const transformedSrc2 = getTransformOptionsPath2({
|
|
72
|
-
src,
|
|
73
|
-
height,
|
|
74
|
-
width,
|
|
75
|
-
quality,
|
|
76
|
-
format
|
|
77
|
-
});
|
|
78
|
-
img.src = transformedSrc2;
|
|
79
|
-
img.onload = () => {
|
|
80
|
-
img.classList.remove("blur");
|
|
81
|
-
img.classList.add("loaded");
|
|
82
|
-
img.style.filter = "blur(0px)";
|
|
83
|
-
loaded = true;
|
|
84
|
-
};
|
|
85
|
-
};
|
|
86
|
-
const observer = new window.IntersectionObserver(
|
|
87
|
-
(entries, observer2) => {
|
|
88
|
-
entries.forEach((entry) => {
|
|
89
|
-
if (entry.isIntersecting) {
|
|
90
|
-
lazyLoad();
|
|
91
|
-
observer2.unobserve(entry.target);
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
},
|
|
95
|
-
{ threshold: 0.1 }
|
|
96
|
-
);
|
|
97
|
-
observer.observe(imgRef.current);
|
|
98
|
-
};
|
|
99
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
100
|
-
"img",
|
|
101
|
-
{
|
|
102
|
-
id,
|
|
103
|
-
ref: imgRef,
|
|
104
|
-
onMount: whenImageMounts,
|
|
105
|
-
alt,
|
|
106
|
-
class: `${className || _class} blur`,
|
|
107
|
-
src: transformedSrc,
|
|
108
|
-
style: {
|
|
109
|
-
filter: "blur(40px)",
|
|
110
|
-
transition: "0.125s filter linear",
|
|
111
|
-
...style
|
|
112
|
-
},
|
|
113
|
-
width,
|
|
114
|
-
height
|
|
115
|
-
}
|
|
116
|
-
);
|
|
117
|
-
};
|
|
118
|
-
|
|
119
7
|
var client = (element) => async (Component, props, { default: children, ...slotted }, { client }) => {
|
|
120
8
|
const isHydrate = element.hasAttribute("ssr") && (client === "visible" || client === "idle" || client === "load" || client === "media");
|
|
121
9
|
if (!element.hasAttribute("ssr")) return;
|
|
@@ -190,5 +78,4 @@ var client = (element) => async (Component, props, { default: children, ...slott
|
|
|
190
78
|
);
|
|
191
79
|
};
|
|
192
80
|
|
|
193
|
-
exports
|
|
194
|
-
exports.default = client;
|
|
81
|
+
module.exports = client;
|
package/dist/client.d.cts
CHANGED
|
@@ -1,29 +1,3 @@
|
|
|
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
|
-
/**
|
|
18
|
-
* Image component for displaying responsive images with automatic format conversion.
|
|
19
|
-
*
|
|
20
|
-
* Default style: {
|
|
21
|
-
* filter: "blur(40px)",
|
|
22
|
-
* transition: "0.125s filter linear",
|
|
23
|
-
* }
|
|
24
|
-
*/
|
|
25
|
-
declare const Img: ({ id, src, alt, height, width, previewQuality, quality, className, class: _class, style, format, astroAssetsPath, }: ImgProps) => any;
|
|
26
|
-
|
|
27
1
|
declare const _default: (element: HTMLElement) => (Component: any, props: Record<string, any>, { default: children, ...slotted }: Record<string, any>, { client }: Record<string, string>) => Promise<void>;
|
|
28
2
|
|
|
29
|
-
export {
|
|
3
|
+
export { _default as default };
|
package/dist/client.d.mts
CHANGED
|
@@ -1,29 +1,3 @@
|
|
|
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
|
-
/**
|
|
18
|
-
* Image component for displaying responsive images with automatic format conversion.
|
|
19
|
-
*
|
|
20
|
-
* Default style: {
|
|
21
|
-
* filter: "blur(40px)",
|
|
22
|
-
* transition: "0.125s filter linear",
|
|
23
|
-
* }
|
|
24
|
-
*/
|
|
25
|
-
declare const Img: ({ id, src, alt, height, width, previewQuality, quality, className, class: _class, style, format, astroAssetsPath, }: ImgProps) => any;
|
|
26
|
-
|
|
27
1
|
declare const _default: (element: HTMLElement) => (Component: any, props: Record<string, any>, { default: children, ...slotted }: Record<string, any>, { client }: Record<string, string>) => Promise<void>;
|
|
28
2
|
|
|
29
|
-
export {
|
|
3
|
+
export { _default as default };
|
package/dist/client.mjs
CHANGED
|
@@ -1,117 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { hydrate, renderSync, DANGEROUSLY_SET_INNER_HTML_ATTRIBUTE, REF_ATTRIBUTE_NAME } from 'defuss/client';
|
|
2
2
|
import { S as StaticHtml } from './render-viAgneG-.mjs';
|
|
3
|
-
import { jsx } from 'defuss/jsx-runtime';
|
|
4
3
|
import 'defuss';
|
|
5
4
|
|
|
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 = ({
|
|
50
|
-
src: src2,
|
|
51
|
-
height: height2,
|
|
52
|
-
width: width2,
|
|
53
|
-
quality: quality2,
|
|
54
|
-
format: format2
|
|
55
|
-
}) => {
|
|
56
|
-
const transformOptions = new URLSearchParams({
|
|
57
|
-
href: src2,
|
|
58
|
-
h: height2.toString(),
|
|
59
|
-
w: width2.toString(),
|
|
60
|
-
q: quality2.toString(),
|
|
61
|
-
f: format2
|
|
62
|
-
});
|
|
63
|
-
return `/${astroAssetsPath}?${transformOptions.toString()}`;
|
|
64
|
-
};
|
|
65
|
-
const lazyLoad = () => {
|
|
66
|
-
if (loaded) return;
|
|
67
|
-
const transformedSrc2 = getTransformOptionsPath2({
|
|
68
|
-
src,
|
|
69
|
-
height,
|
|
70
|
-
width,
|
|
71
|
-
quality,
|
|
72
|
-
format
|
|
73
|
-
});
|
|
74
|
-
img.src = transformedSrc2;
|
|
75
|
-
img.onload = () => {
|
|
76
|
-
img.classList.remove("blur");
|
|
77
|
-
img.classList.add("loaded");
|
|
78
|
-
img.style.filter = "blur(0px)";
|
|
79
|
-
loaded = true;
|
|
80
|
-
};
|
|
81
|
-
};
|
|
82
|
-
const observer = new window.IntersectionObserver(
|
|
83
|
-
(entries, observer2) => {
|
|
84
|
-
entries.forEach((entry) => {
|
|
85
|
-
if (entry.isIntersecting) {
|
|
86
|
-
lazyLoad();
|
|
87
|
-
observer2.unobserve(entry.target);
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
},
|
|
91
|
-
{ threshold: 0.1 }
|
|
92
|
-
);
|
|
93
|
-
observer.observe(imgRef.current);
|
|
94
|
-
};
|
|
95
|
-
return /* @__PURE__ */ jsx(
|
|
96
|
-
"img",
|
|
97
|
-
{
|
|
98
|
-
id,
|
|
99
|
-
ref: imgRef,
|
|
100
|
-
onMount: whenImageMounts,
|
|
101
|
-
alt,
|
|
102
|
-
class: `${className || _class} blur`,
|
|
103
|
-
src: transformedSrc,
|
|
104
|
-
style: {
|
|
105
|
-
filter: "blur(40px)",
|
|
106
|
-
transition: "0.125s filter linear",
|
|
107
|
-
...style
|
|
108
|
-
},
|
|
109
|
-
width,
|
|
110
|
-
height
|
|
111
|
-
}
|
|
112
|
-
);
|
|
113
|
-
};
|
|
114
|
-
|
|
115
5
|
var client = (element) => async (Component, props, { default: children, ...slotted }, { client }) => {
|
|
116
6
|
const isHydrate = element.hasAttribute("ssr") && (client === "visible" || client === "idle" || client === "load" || client === "media");
|
|
117
7
|
if (!element.hasAttribute("ssr")) return;
|
|
@@ -186,4 +76,4 @@ var client = (element) => async (Component, props, { default: children, ...slott
|
|
|
186
76
|
);
|
|
187
77
|
};
|
|
188
78
|
|
|
189
|
-
export {
|
|
79
|
+
export { client as default };
|
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var vite = require('vite');
|
|
6
|
+
var core = require('@swc/core');
|
|
6
7
|
var node_url = require('node:url');
|
|
7
8
|
var glob = require('fast-glob');
|
|
8
9
|
var node_perf_hooks = require('node:perf_hooks');
|
|
@@ -12,6 +13,90 @@ var promises = require('node:fs/promises');
|
|
|
12
13
|
var purgecss = require('purgecss');
|
|
13
14
|
var node_fs = require('node:fs');
|
|
14
15
|
|
|
16
|
+
function parseId(url) {
|
|
17
|
+
return { id: url.split("?", 2)[0] };
|
|
18
|
+
}
|
|
19
|
+
function defussVitePlugin({
|
|
20
|
+
include,
|
|
21
|
+
exclude
|
|
22
|
+
} = {}) {
|
|
23
|
+
let config;
|
|
24
|
+
const shouldTransform = vite.createFilter(
|
|
25
|
+
include || [/\.[cm]?[tj]sx?$/],
|
|
26
|
+
exclude || [/node_modules/]
|
|
27
|
+
);
|
|
28
|
+
const jsxPlugin = {
|
|
29
|
+
name: "vite:defuss-jsx",
|
|
30
|
+
enforce: "pre",
|
|
31
|
+
config() {
|
|
32
|
+
return {
|
|
33
|
+
esbuild: {
|
|
34
|
+
// we want Vite to handle JSX transformations
|
|
35
|
+
jsxImportSource: "defuss",
|
|
36
|
+
jsxFactory: "jsx",
|
|
37
|
+
jsxFragment: "Fragment"
|
|
38
|
+
},
|
|
39
|
+
optimizeDeps: {
|
|
40
|
+
// we want Vite to optimize the runtime code
|
|
41
|
+
include: ["defuss"],
|
|
42
|
+
// we don't want Vite to optimize this plugin code
|
|
43
|
+
exclude: ["defuss-vite"]
|
|
44
|
+
},
|
|
45
|
+
ssr: {
|
|
46
|
+
// LinkeDOM (used by defuss/render) imports perf_hooks
|
|
47
|
+
// which is actually just an empty placeholder package,
|
|
48
|
+
// therefore, we externalize it
|
|
49
|
+
external: ["perf_hooks"]
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
},
|
|
53
|
+
configResolved(resolvedConfig) {
|
|
54
|
+
config = resolvedConfig;
|
|
55
|
+
},
|
|
56
|
+
async transform(code, url) {
|
|
57
|
+
const { id } = parseId(url);
|
|
58
|
+
if (!shouldTransform(id)) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
const prevSourceMap = this.getCombinedSourcemap?.();
|
|
62
|
+
const inputSourceMap = prevSourceMap ? JSON.stringify({ code, map: prevSourceMap }) : void 0;
|
|
63
|
+
const result = await core.transform(code, {
|
|
64
|
+
jsc: {
|
|
65
|
+
parser: {
|
|
66
|
+
syntax: "typescript",
|
|
67
|
+
tsx: true,
|
|
68
|
+
dynamicImport: true,
|
|
69
|
+
decorators: true
|
|
70
|
+
},
|
|
71
|
+
transform: {
|
|
72
|
+
react: {
|
|
73
|
+
development: true,
|
|
74
|
+
useBuiltins: false,
|
|
75
|
+
throwIfNamespace: false,
|
|
76
|
+
pragma: "jsx",
|
|
77
|
+
pragmaFrag: "Fragment",
|
|
78
|
+
runtime: "automatic",
|
|
79
|
+
importSource: "defuss"
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
target: "es2024"
|
|
83
|
+
},
|
|
84
|
+
sourceMaps: true,
|
|
85
|
+
sourceFileName: id,
|
|
86
|
+
filename: id,
|
|
87
|
+
sourceRoot: config.root,
|
|
88
|
+
inputSourceMap
|
|
89
|
+
});
|
|
90
|
+
if (!result) return null;
|
|
91
|
+
return {
|
|
92
|
+
code: result.code || code,
|
|
93
|
+
map: result.map
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
return jsxPlugin;
|
|
98
|
+
}
|
|
99
|
+
|
|
15
100
|
const logMessage = (message) => {
|
|
16
101
|
const date = (/* @__PURE__ */ new Date()).toLocaleTimeString();
|
|
17
102
|
console.log(`${date} \x1B[32mdefuss-astro:\x1B[0m ${message}`);
|
|
@@ -76,16 +161,8 @@ function index({
|
|
|
76
161
|
config,
|
|
77
162
|
addRenderer,
|
|
78
163
|
updateConfig,
|
|
79
|
-
command
|
|
80
|
-
injectScript,
|
|
81
|
-
injectRoute
|
|
164
|
+
command
|
|
82
165
|
}) => {
|
|
83
|
-
injectRoute({
|
|
84
|
-
pattern: "/_defuss/image",
|
|
85
|
-
prerender: false,
|
|
86
|
-
entrypoint: "defuss-astro/image-endpoint.js"
|
|
87
|
-
});
|
|
88
|
-
node_url.fileURLToPath(config.publicDir);
|
|
89
166
|
config.compressHTML = true;
|
|
90
167
|
config.scopedStyleStrategy = "class";
|
|
91
168
|
if (!config.vite.build) {
|
|
@@ -98,10 +175,7 @@ function index({
|
|
|
98
175
|
optimizeDeps: {
|
|
99
176
|
include: ["defuss-astro/client.js", "defuss-astro/server.js"]
|
|
100
177
|
},
|
|
101
|
-
|
|
102
|
-
noExternal: ["lightningimg-node"]
|
|
103
|
-
},
|
|
104
|
-
plugins: [defussPlugin()]
|
|
178
|
+
plugins: [defussVitePlugin()]
|
|
105
179
|
}
|
|
106
180
|
});
|
|
107
181
|
},
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import { AstroIntegration, ContainerRenderer } from 'astro';
|
|
2
|
-
import {
|
|
2
|
+
import { FilterPattern } from 'vite';
|
|
3
|
+
|
|
4
|
+
interface DefussVitePluginOptions {
|
|
5
|
+
/**
|
|
6
|
+
* RegExp or glob to match files to be transformed
|
|
7
|
+
*/
|
|
8
|
+
include?: FilterPattern;
|
|
9
|
+
/**
|
|
10
|
+
* RegExp or glob to match files to NOT be transformed
|
|
11
|
+
*/
|
|
12
|
+
exclude?: FilterPattern;
|
|
13
|
+
}
|
|
3
14
|
|
|
4
15
|
interface Options extends Pick<DefussVitePluginOptions, "exclude" | "include"> {
|
|
5
16
|
devtools?: boolean;
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import { AstroIntegration, ContainerRenderer } from 'astro';
|
|
2
|
-
import {
|
|
2
|
+
import { FilterPattern } from 'vite';
|
|
3
|
+
|
|
4
|
+
interface DefussVitePluginOptions {
|
|
5
|
+
/**
|
|
6
|
+
* RegExp or glob to match files to be transformed
|
|
7
|
+
*/
|
|
8
|
+
include?: FilterPattern;
|
|
9
|
+
/**
|
|
10
|
+
* RegExp or glob to match files to NOT be transformed
|
|
11
|
+
*/
|
|
12
|
+
exclude?: FilterPattern;
|
|
13
|
+
}
|
|
3
14
|
|
|
4
15
|
interface Options extends Pick<DefussVitePluginOptions, "exclude" | "include"> {
|
|
5
16
|
devtools?: boolean;
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { createFilter } from 'vite';
|
|
2
|
+
import { transform } from '@swc/core';
|
|
2
3
|
import { fileURLToPath } from 'node:url';
|
|
3
4
|
import glob from 'fast-glob';
|
|
4
5
|
import { performance } from 'node:perf_hooks';
|
|
@@ -8,6 +9,90 @@ import { readFile, writeFile } from 'node:fs/promises';
|
|
|
8
9
|
import { PurgeCSS } from 'purgecss';
|
|
9
10
|
import { existsSync } from 'node:fs';
|
|
10
11
|
|
|
12
|
+
function parseId(url) {
|
|
13
|
+
return { id: url.split("?", 2)[0] };
|
|
14
|
+
}
|
|
15
|
+
function defussVitePlugin({
|
|
16
|
+
include,
|
|
17
|
+
exclude
|
|
18
|
+
} = {}) {
|
|
19
|
+
let config;
|
|
20
|
+
const shouldTransform = createFilter(
|
|
21
|
+
include || [/\.[cm]?[tj]sx?$/],
|
|
22
|
+
exclude || [/node_modules/]
|
|
23
|
+
);
|
|
24
|
+
const jsxPlugin = {
|
|
25
|
+
name: "vite:defuss-jsx",
|
|
26
|
+
enforce: "pre",
|
|
27
|
+
config() {
|
|
28
|
+
return {
|
|
29
|
+
esbuild: {
|
|
30
|
+
// we want Vite to handle JSX transformations
|
|
31
|
+
jsxImportSource: "defuss",
|
|
32
|
+
jsxFactory: "jsx",
|
|
33
|
+
jsxFragment: "Fragment"
|
|
34
|
+
},
|
|
35
|
+
optimizeDeps: {
|
|
36
|
+
// we want Vite to optimize the runtime code
|
|
37
|
+
include: ["defuss"],
|
|
38
|
+
// we don't want Vite to optimize this plugin code
|
|
39
|
+
exclude: ["defuss-vite"]
|
|
40
|
+
},
|
|
41
|
+
ssr: {
|
|
42
|
+
// LinkeDOM (used by defuss/render) imports perf_hooks
|
|
43
|
+
// which is actually just an empty placeholder package,
|
|
44
|
+
// therefore, we externalize it
|
|
45
|
+
external: ["perf_hooks"]
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
},
|
|
49
|
+
configResolved(resolvedConfig) {
|
|
50
|
+
config = resolvedConfig;
|
|
51
|
+
},
|
|
52
|
+
async transform(code, url) {
|
|
53
|
+
const { id } = parseId(url);
|
|
54
|
+
if (!shouldTransform(id)) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
const prevSourceMap = this.getCombinedSourcemap?.();
|
|
58
|
+
const inputSourceMap = prevSourceMap ? JSON.stringify({ code, map: prevSourceMap }) : void 0;
|
|
59
|
+
const result = await transform(code, {
|
|
60
|
+
jsc: {
|
|
61
|
+
parser: {
|
|
62
|
+
syntax: "typescript",
|
|
63
|
+
tsx: true,
|
|
64
|
+
dynamicImport: true,
|
|
65
|
+
decorators: true
|
|
66
|
+
},
|
|
67
|
+
transform: {
|
|
68
|
+
react: {
|
|
69
|
+
development: true,
|
|
70
|
+
useBuiltins: false,
|
|
71
|
+
throwIfNamespace: false,
|
|
72
|
+
pragma: "jsx",
|
|
73
|
+
pragmaFrag: "Fragment",
|
|
74
|
+
runtime: "automatic",
|
|
75
|
+
importSource: "defuss"
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
target: "es2024"
|
|
79
|
+
},
|
|
80
|
+
sourceMaps: true,
|
|
81
|
+
sourceFileName: id,
|
|
82
|
+
filename: id,
|
|
83
|
+
sourceRoot: config.root,
|
|
84
|
+
inputSourceMap
|
|
85
|
+
});
|
|
86
|
+
if (!result) return null;
|
|
87
|
+
return {
|
|
88
|
+
code: result.code || code,
|
|
89
|
+
map: result.map
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
return jsxPlugin;
|
|
94
|
+
}
|
|
95
|
+
|
|
11
96
|
const logMessage = (message) => {
|
|
12
97
|
const date = (/* @__PURE__ */ new Date()).toLocaleTimeString();
|
|
13
98
|
console.log(`${date} \x1B[32mdefuss-astro:\x1B[0m ${message}`);
|
|
@@ -72,16 +157,8 @@ function index({
|
|
|
72
157
|
config,
|
|
73
158
|
addRenderer,
|
|
74
159
|
updateConfig,
|
|
75
|
-
command
|
|
76
|
-
injectScript,
|
|
77
|
-
injectRoute
|
|
160
|
+
command
|
|
78
161
|
}) => {
|
|
79
|
-
injectRoute({
|
|
80
|
-
pattern: "/_defuss/image",
|
|
81
|
-
prerender: false,
|
|
82
|
-
entrypoint: "defuss-astro/image-endpoint.js"
|
|
83
|
-
});
|
|
84
|
-
fileURLToPath(config.publicDir);
|
|
85
162
|
config.compressHTML = true;
|
|
86
163
|
config.scopedStyleStrategy = "class";
|
|
87
164
|
if (!config.vite.build) {
|
|
@@ -94,10 +171,7 @@ function index({
|
|
|
94
171
|
optimizeDeps: {
|
|
95
172
|
include: ["defuss-astro/client.js", "defuss-astro/server.js"]
|
|
96
173
|
},
|
|
97
|
-
|
|
98
|
-
noExternal: ["lightningimg-node"]
|
|
99
|
-
},
|
|
100
|
-
plugins: [defussPlugin()]
|
|
174
|
+
plugins: [defussVitePlugin()]
|
|
101
175
|
}
|
|
102
176
|
});
|
|
103
177
|
},
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "defuss-astro",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
8
8
|
"license": "MIT",
|
|
9
|
-
"description": "
|
|
9
|
+
"description": "defuss integration for Astro",
|
|
10
10
|
"keywords": [
|
|
11
11
|
"jsx",
|
|
12
12
|
"render",
|
|
@@ -56,10 +56,6 @@
|
|
|
56
56
|
"types": "./dist/server.d.mts",
|
|
57
57
|
"default": "./dist/server.mjs"
|
|
58
58
|
}
|
|
59
|
-
},
|
|
60
|
-
"./image-endpoint.js": {
|
|
61
|
-
"types": "./dist/endpoint/image-endpoint.d.mts",
|
|
62
|
-
"default": "./dist/endpoint/image-endpoint.mjs"
|
|
63
59
|
}
|
|
64
60
|
},
|
|
65
61
|
"main": "./dist/index.cjs",
|
|
@@ -78,12 +74,11 @@
|
|
|
78
74
|
},
|
|
79
75
|
"dependencies": {
|
|
80
76
|
"defuss": "^2.1.10",
|
|
81
|
-
"
|
|
77
|
+
"@swc/core": "^1.10.2",
|
|
82
78
|
"astro": "^5.16.11",
|
|
83
79
|
"vite": "^6.4.1",
|
|
84
80
|
"fast-glob": "^3.3.3",
|
|
85
81
|
"svgo": "^4.0.0",
|
|
86
|
-
"lightningimg": "^1.0.3",
|
|
87
82
|
"purgecss": "^7.0.2",
|
|
88
83
|
"file-type": "^21.3.0"
|
|
89
84
|
}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var fileType = require('file-type');
|
|
4
|
-
var lightningimg = require('lightningimg');
|
|
5
|
-
|
|
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 imageDimensions = await lightningimg.getImageInfo(imageBuffer);
|
|
24
|
-
const fileExtension = (await fileType.fileTypeFromBuffer(imageBuffer))?.ext;
|
|
25
|
-
if (!fileExtension) {
|
|
26
|
-
console.log("Error fetching fileExtension", { fileExtension, response });
|
|
27
|
-
return new Response("Error getting file extension", { status: 500 });
|
|
28
|
-
}
|
|
29
|
-
if (fileExtension === "webp") {
|
|
30
|
-
return new Response(imageBuffer, {
|
|
31
|
-
headers: {
|
|
32
|
-
"Content-Type": "image/webp",
|
|
33
|
-
"Content-Length": imageBuffer.byteLength.toString()
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
let convertedImageBuffer;
|
|
38
|
-
try {
|
|
39
|
-
convertedImageBuffer = await lightningimg.convertImageBuffer(
|
|
40
|
-
imageBuffer,
|
|
41
|
-
width ? Number.parseInt(width) : imageDimensions.width,
|
|
42
|
-
height ? Number.parseInt(height) : imageDimensions.height
|
|
43
|
-
);
|
|
44
|
-
if (!convertedImageBuffer) {
|
|
45
|
-
throw new Error("Error converting image: no buffer returned");
|
|
46
|
-
}
|
|
47
|
-
} catch (error) {
|
|
48
|
-
console.log("Error converting image", {
|
|
49
|
-
fileExtension,
|
|
50
|
-
bufferLength: imageBuffer.byteLength,
|
|
51
|
-
error
|
|
52
|
-
});
|
|
53
|
-
return new Response("Error converting image", { status: 500 });
|
|
54
|
-
}
|
|
55
|
-
const mimeType = `image/${fileExtension}`;
|
|
56
|
-
return new Response(convertedImageBuffer, {
|
|
57
|
-
headers: {
|
|
58
|
-
"Content-Type": mimeType,
|
|
59
|
-
"Content-Length": convertedImageBuffer.length.toString()
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
} catch (error) {
|
|
63
|
-
return new Response(`Error fetching image: ${error}`, { status: 500 });
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
exports.GET = GET;
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { fileTypeFromBuffer } from 'file-type';
|
|
2
|
-
import { getImageInfo, convertImageBuffer } from 'lightningimg';
|
|
3
|
-
|
|
4
|
-
const GET = async ({ url }) => {
|
|
5
|
-
try {
|
|
6
|
-
const imgHrefRelative = url.searchParams.get("href");
|
|
7
|
-
const height = url.searchParams.get("h");
|
|
8
|
-
const width = url.searchParams.get("w");
|
|
9
|
-
const quality = url.searchParams.get("q");
|
|
10
|
-
if (!imgHrefRelative) {
|
|
11
|
-
return new Response("Image URL is required", { status: 400 });
|
|
12
|
-
}
|
|
13
|
-
const imgHrefAbsolute = `${url.protocol}//${url.host}${imgHrefRelative}`;
|
|
14
|
-
console.log("GET /_defuss/image (transforming: ", imgHrefAbsolute, ")");
|
|
15
|
-
const response = await fetch(imgHrefAbsolute);
|
|
16
|
-
if (!response.ok) {
|
|
17
|
-
console.log("Error fetching image", { imgHrefAbsolute, response });
|
|
18
|
-
return new Response("Error fetching image", { status: 500 });
|
|
19
|
-
}
|
|
20
|
-
const imageBuffer = Buffer.from(await response.arrayBuffer());
|
|
21
|
-
const imageDimensions = await getImageInfo(imageBuffer);
|
|
22
|
-
const fileExtension = (await fileTypeFromBuffer(imageBuffer))?.ext;
|
|
23
|
-
if (!fileExtension) {
|
|
24
|
-
console.log("Error fetching fileExtension", { fileExtension, response });
|
|
25
|
-
return new Response("Error getting file extension", { status: 500 });
|
|
26
|
-
}
|
|
27
|
-
if (fileExtension === "webp") {
|
|
28
|
-
return new Response(imageBuffer, {
|
|
29
|
-
headers: {
|
|
30
|
-
"Content-Type": "image/webp",
|
|
31
|
-
"Content-Length": imageBuffer.byteLength.toString()
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
let convertedImageBuffer;
|
|
36
|
-
try {
|
|
37
|
-
convertedImageBuffer = await convertImageBuffer(
|
|
38
|
-
imageBuffer,
|
|
39
|
-
width ? Number.parseInt(width) : imageDimensions.width,
|
|
40
|
-
height ? Number.parseInt(height) : imageDimensions.height
|
|
41
|
-
);
|
|
42
|
-
if (!convertedImageBuffer) {
|
|
43
|
-
throw new Error("Error converting image: no buffer returned");
|
|
44
|
-
}
|
|
45
|
-
} catch (error) {
|
|
46
|
-
console.log("Error converting image", {
|
|
47
|
-
fileExtension,
|
|
48
|
-
bufferLength: imageBuffer.byteLength,
|
|
49
|
-
error
|
|
50
|
-
});
|
|
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
|
-
export { GET };
|