defuss-astro 1.0.0 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,89 +1,94 @@
1
- <h1 align="center">defuss-astro</h1>
1
+ <h1 align="center">
2
2
 
3
- > Explicit simplicity for Astro.
3
+ <img src="assets/defuss_mascott.png" width="100px" />
4
4
 
5
- <h2 align="center">The Complexity Problem</h2>
5
+ `defuss`
6
6
 
7
- Modern web frontend development is complex, but it must not be.
8
- While others pile layers of complexity, changing APIs like underwear
9
- and drive poor developers crazy, `defuss` brings back the feeling
10
- of simple web development.
7
+ <sup align="center">
11
8
 
12
- <h2 align="center">Features</h2>
9
+ Astro Integration
13
10
 
14
- - ✅ Does render JSX/TSX on client and server - DOM (`render`) and HTML (`renderToString`)
15
- - ✅ Allows to render `Function`al components like `<Foo />`
16
- - ✅ Supports every JSX feature you know, including Fragments `<></>`, Refs `ref={}` and `onMount={fn}`
17
- - ✅ Allows to render a whole HTML document server-side, starting with `<html>`
18
- - ✅ Available as a simple API
19
- - ✅ Supports `dangerouslySetInnerHTML={{ __html: '<... />' }`
20
- - ✅ Just `1113 byte` nano sized (ESM, gizpped) on client
21
- - ✅ Just `1254 byte` nano sized (ESM, gizpped) on server
22
- - ✅ Tree-shakable and side-effect free
23
- - ✅ First class TypeScript support
24
- - ✅ 100% Unit Test coverage
11
+ </sup>
25
12
 
26
- <img src="./coverage_report.png" />
13
+ </h1>
27
14
 
28
- <h2 align="center">Example usage</h2>
29
15
 
30
- <h3 align="center">Setup</h3>
16
+ > `defuss` is a simple, tiny and modern web framework. It stops **complexity**, promotes **explicit code**, and brings back the **joy** of building for the web! 😊
31
17
 
32
- - yarn: `yarn add @jsheaven/render`
33
- - npm: `npm install @jsheaven/render`
18
+ **💡 Can you imagine?** The whole Astro Integration including it's custom `defuss/render` integration is written in only ~180 Lines of Code.
34
19
 
35
- <h3 align="center">ESM</h3>
20
+ This package implements the Astro Integration that uses `defuss-vite` plugin and `defuss/render` to bring the `defuss` experience to Astro.
36
21
 
37
- Configure the following values in your `tsconfig.json` or likewise,
38
- in the configuration options of your favourite bundler:
22
+ <h3 align="center">
39
23
 
40
- ```json
41
- {
42
- ...
43
- "jsx": "react",
44
- "jsxFactory": "tsx",
45
- "jsxFragmentFactory": "Fragment",
46
- ...
47
- }
48
- ```
24
+ Integrating `defuss` in an existing Astro project
49
25
 
50
- This will make sure that the JSX syntax is correctly transformed into a
51
- JavaScript object tree (AOT, at compile time) that can be rendered by this library
52
- at runtime (SSG, SSR or even, if desired, in-browser).
26
+ </h3>
53
27
 
54
- <h4 align="center">Server-side usage:</h4>
28
+ **🚀 Looking for a template to start from?** `examples/with-astro-ts` is an Astro project pre-configured to work with `defuss` out-of-the-box.
55
29
 
56
- ```tsx
57
- import { render, renderToString, tsx, Fragment } from '@jsheaven/render/dist/server.esm.js'
30
+ If you've arrived here to add `defuss` to your Astro project, you're just two steps away from success:
58
31
 
59
- // HTMLElement
60
- const dom: Node = render(
61
- <html>
62
- <head></head>
63
- <body></body>
64
- </html>,
65
- )
32
+ #### 1. Install `defuss-astro`:
66
33
 
67
- // <html><head></head><body></body></html>
68
- const html: string = renderToString(dom)
34
+ ```bash
35
+ # from your project root folder, add defuss-astro to the devDependencies
36
+ shell > npm install --save-dev defuss-astro
69
37
  ```
70
38
 
71
- <h4 align="center">Client-side/in-browser usage:</h4>
39
+ #### 2. Integrate `defuss-astro`:
40
+
41
+ > In **astro.config.mjs** or **astro.config.ts**:
42
+ ```ts
43
+ import { defineConfig } from 'astro/config';
72
44
 
73
- ```tsx
74
- import { render, renderToString, tsx, Fragment } from '@jsheaven/render/dist/client.esm.js'
45
+ // import our Astro Integration
46
+ import defuss from 'defuss-astro';
75
47
 
76
- // HTMLParagraphElement
77
- const dom: Node = render(<p>Some paragraph</p>)
48
+ // https://astro.build/config
49
+ export default defineConfig({
78
50
 
79
- // <p>Some paragraph</p>
80
- const html: string = renderToString(dom)
51
+ // add the defuss integration
52
+ integrations: [defuss()]
53
+ });
81
54
  ```
82
55
 
83
- <h3 align="center">CommonJS</h3>
56
+ **Note on Advanced Usage:** `defuss({ ... })` can be called with arguments to `include` and `exclude` files from the underlaying `babel` transpilation. Using the `babel` property, a specific `babel` configuration can be provided. Please find the `DefussPluginOptions` [here]().
84
57
 
85
- ```ts
86
- const { render, renderToString, tsx } = require('@jsheaven/render/client.cjs.js')
58
+ <h3 align="center">
59
+
60
+ 🚀 How does `defuss-astro` work?
61
+
62
+ </h3>
63
+
64
+ Inside this package, you'll find the following relevant folders and files:
87
65
 
88
- // same API like ESM variant
66
+ ```text
67
+ /
68
+ ├── scripts/finalize-build.ts
69
+ ├── src/index.ts
70
+ ├── src/types.ts
71
+ ├── src/render.ts
72
+ ├── src/client.ts
73
+ ├── src/server.ts
74
+ ├── tsconfig.json
75
+ ├── LICENSE
76
+ ├── package.json
89
77
  ```
78
+
79
+ The `src/index.ts` file is the "entry point" for our Astro Integration. Its default exported function is called in any `astro.config.(mjs|ts)` of any integrating Astro project *(see above)*.
80
+
81
+ ## 🧞 Commands
82
+
83
+ All commands are run from the root of the project, from a terminal:
84
+
85
+ | Command | Action |
86
+ | :------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
87
+ | `npm build` | Build a new version of the integration. |
88
+ | `npm publish` | Publish a new version of the `defuss-astro` integration package. |
89
+
90
+ ---
91
+
92
+ <img src="assets/defuss_comic.png" />
93
+
94
+ <caption><i><b>Come visit us on defuss island!</b></i></caption>
@@ -0,0 +1,40 @@
1
+ 'use strict';
2
+
3
+ var client$1 = require('defuss/client');
4
+ var defuss = require('defuss');
5
+ var render = require('./render-DkMOLcUd.cjs');
6
+
7
+ var client = (element) => async (Component, props, { default: children, ...slotted }, { client }) => {
8
+ console.log("client render", client);
9
+ if (!element.hasAttribute("ssr")) return;
10
+ globalThis.jsx = defuss.jsx;
11
+ Object.entries(slotted).forEach(([key, value]) => {
12
+ props[key] = render.StaticHtml(value);
13
+ });
14
+ const componentProps = { ...props };
15
+ if (children) {
16
+ if (!Array.isArray(children)) {
17
+ children = [children];
18
+ }
19
+ for (let i = 0; i < children.length; i++) {
20
+ if (typeof children[i] === "string") {
21
+ children[i] = render.StaticHtml(children[i]);
22
+ }
23
+ }
24
+ componentProps.children = children;
25
+ }
26
+ const dom = client$1.render(Component(componentProps), element);
27
+ for (const [key, value] of Object.entries(props)) {
28
+ if (key !== "children") {
29
+ dom.setAttribute(key, value);
30
+ }
31
+ }
32
+ element.addEventListener("astro:unmount", () => {
33
+ if (dom.parentNode) {
34
+ dom.parentNode.removeChild(dom);
35
+ }
36
+ }, { once: true });
37
+ };
38
+
39
+ module.exports = client;
40
+ //# sourceMappingURL=client.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.cjs","sources":["../src/client.ts"],"sourcesContent":["import { type Props, render } from 'defuss/client'\nimport { jsx } from 'defuss'\nimport { StaticHtml } from './render.js';\n\n// TODO: is a differential update possible?\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\tconsole.log('client render', client);\n\t\t\n\t\tif (!element.hasAttribute('ssr')) return;\n\n\t\t// we use \"classic\" runtime, so we need to set the global jsx function\n\t\t// otherwise it would need to be imported in every component\n\t\t(globalThis as any).jsx = jsx;\n\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\t// turn the component AST into an actual DOM element and attach it to the element passed in\n\t\tconst dom: HTMLElement = render(Component(componentProps), 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":["jsx","StaticHtml","render"],"mappings":";;;;;;AAIA,aAAe,CAAC,OAAO,KAAK,OAAO,SAAS,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK;AACvG,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC;AACtC,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;AACpC,EAAE,UAAU,CAAC,GAAG,GAAGA,UAAG;AACtB,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK;AACpD,IAAI,KAAK,CAAC,GAAG,CAAC,GAAGC,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,GAAG,GAAGC,eAAM,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;AACxD,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;;;;"}
@@ -0,0 +1,3 @@
1
+ declare const _default: (element: HTMLElement) => (Component: any, props: Record<string, any>, { default: children, ...slotted }: Record<string, any>, { client }: Record<string, string>) => Promise<void>;
2
+
3
+ export { _default as default };
@@ -0,0 +1,3 @@
1
+ declare const _default: (element: HTMLElement) => (Component: any, props: Record<string, any>, { default: children, ...slotted }: Record<string, any>, { client }: Record<string, string>) => Promise<void>;
2
+
3
+ export { _default as default };
@@ -0,0 +1,38 @@
1
+ import { render } from 'defuss/client';
2
+ import { jsx } from 'defuss';
3
+ import { S as StaticHtml } from './render-viAgneG-.mjs';
4
+
5
+ var client = (element) => async (Component, props, { default: children, ...slotted }, { client }) => {
6
+ console.log("client render", client);
7
+ if (!element.hasAttribute("ssr")) return;
8
+ globalThis.jsx = jsx;
9
+ Object.entries(slotted).forEach(([key, value]) => {
10
+ props[key] = StaticHtml(value);
11
+ });
12
+ const componentProps = { ...props };
13
+ if (children) {
14
+ if (!Array.isArray(children)) {
15
+ children = [children];
16
+ }
17
+ for (let i = 0; i < children.length; i++) {
18
+ if (typeof children[i] === "string") {
19
+ children[i] = StaticHtml(children[i]);
20
+ }
21
+ }
22
+ componentProps.children = children;
23
+ }
24
+ const dom = render(Component(componentProps), element);
25
+ for (const [key, value] of Object.entries(props)) {
26
+ if (key !== "children") {
27
+ dom.setAttribute(key, value);
28
+ }
29
+ }
30
+ element.addEventListener("astro:unmount", () => {
31
+ if (dom.parentNode) {
32
+ dom.parentNode.removeChild(dom);
33
+ }
34
+ }, { once: true });
35
+ };
36
+
37
+ export { client as default };
38
+ //# sourceMappingURL=client.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.mjs","sources":["../src/client.ts"],"sourcesContent":["import { type Props, render } from 'defuss/client'\nimport { jsx } from 'defuss'\nimport { StaticHtml } from './render.js';\n\n// TODO: is a differential update possible?\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\tconsole.log('client render', client);\n\t\t\n\t\tif (!element.hasAttribute('ssr')) return;\n\n\t\t// we use \"classic\" runtime, so we need to set the global jsx function\n\t\t// otherwise it would need to be imported in every component\n\t\t(globalThis as any).jsx = jsx;\n\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\t// turn the component AST into an actual DOM element and attach it to the element passed in\n\t\tconst dom: HTMLElement = render(Component(componentProps), 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":";;;;AAIA,aAAe,CAAC,OAAO,KAAK,OAAO,SAAS,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK;AACvG,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC;AACtC,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;AACpC,EAAE,UAAU,CAAC,GAAG,GAAG,GAAG;AACtB,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,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;AACxD,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;;;;"}