@hyperspan/plugin-preact 0.1.3 → 0.1.5

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.
Files changed (2) hide show
  1. package/package.json +2 -2
  2. package/src/index.ts +27 -22
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperspan/plugin-preact",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Hyperspan Plugin for Preact",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -29,7 +29,7 @@
29
29
  },
30
30
  "peerDependencies": {
31
31
  "@hyperspan/html": "^0.1.7",
32
- "@hyperspan/framework": "^0.2.0"
32
+ "@hyperspan/framework": "^0.3.3"
33
33
  },
34
34
  "dependencies": {
35
35
  "preact": "^10.26.5",
package/src/index.ts CHANGED
@@ -18,14 +18,14 @@ async function copyPreactToPublicFolder() {
18
18
  target: 'browser',
19
19
  });
20
20
 
21
- clientImportMap.set('preact', '' + PREACT_PUBLIC_FILE_PATH);
22
- clientImportMap.set('preact/compat', '' + PREACT_PUBLIC_FILE_PATH);
23
- clientImportMap.set('preact/hooks', '' + PREACT_PUBLIC_FILE_PATH);
24
- clientImportMap.set('preact/jsx-runtime', '' + PREACT_PUBLIC_FILE_PATH);
21
+ clientImportMap.set('preact', PREACT_PUBLIC_FILE_PATH);
22
+ clientImportMap.set('preact/compat', PREACT_PUBLIC_FILE_PATH);
23
+ clientImportMap.set('preact/hooks', PREACT_PUBLIC_FILE_PATH);
24
+ clientImportMap.set('preact/jsx-runtime', PREACT_PUBLIC_FILE_PATH);
25
25
 
26
26
  if (!clientImportMap.has('react')) {
27
- clientImportMap.set('react', '.' + PREACT_PUBLIC_FILE_PATH);
28
- clientImportMap.set('react-dom', '.' + PREACT_PUBLIC_FILE_PATH);
27
+ clientImportMap.set('react', PREACT_PUBLIC_FILE_PATH);
28
+ clientImportMap.set('react-dom', PREACT_PUBLIC_FILE_PATH);
29
29
  }
30
30
  }
31
31
 
@@ -50,6 +50,11 @@ export async function preactPlugin() {
50
50
  };
51
51
  }
52
52
 
53
+ // Ensure Preact can be loaded on the client
54
+ if (!clientImportMap.has('preact')) {
55
+ await copyPreactToPublicFolder();
56
+ }
57
+
53
58
  if (contents) {
54
59
  // We need to build the file to ensure we can ship it to the client with dependencies
55
60
  // Ironic, right? Calling Bun.build() inside of a plugin that runs on Bun.build()?
@@ -57,7 +62,7 @@ export async function preactPlugin() {
57
62
  entrypoints: [args.path],
58
63
  //outdir: './public/' + ISLAND_PUBLIC_PATH,
59
64
  //naming: '[name]-[hash].js',
60
- external: ['react', 'preact', 'preact/compat', 'preact/hooks', 'preact/jsx-runtime'],
65
+ external: Array.from(clientImportMap.keys()),
61
66
  minify: true,
62
67
  format: 'esm',
63
68
  target: 'browser',
@@ -66,11 +71,6 @@ export async function preactPlugin() {
66
71
  contents = await result.outputs[0].text();
67
72
  }
68
73
 
69
- // Ensure Preact can be loaded on the client
70
- if (!clientImportMap.has('preact')) {
71
- await copyPreactToPublicFolder();
72
- }
73
-
74
74
  // Look for the default export
75
75
  const RE_EXPORT_DEFAULT = /export\{(\w+) as default\}/;
76
76
  const RE_EXPORT_DEFAULT_FN = /export default function\s+(\w+)/;
@@ -104,26 +104,31 @@ export async function preactPlugin() {
104
104
  // All imports needed for this work are prefixed with __hs_ to avoid clashing with other imports in the module, as some of them may be duplicates.
105
105
  // Finally, we need to export all of the functions that do this work in a special way so we don't change the default export or other functions in the module, so that only the Hyperspan renderIsland() function can use them.
106
106
  const moduleCode = `// hyperspan:processed
107
- import { html as __hs_html } from '@hyperspan/html';
108
107
  import { render as __hs_renderToString } from 'preact-render-to-string';
109
108
 
110
109
  // Original file contents
111
110
  ${contents}
112
111
 
113
112
  // hyperspan:preact-plugin
113
+ function __hs_renderIsland(jsContent = '', ssrContent = '', options = {}) {
114
+ if (options.loading === 'lazy') {
115
+ return \`<div id="${jsId}">\${ssrContent}</div><div data-loading="lazy" style="height:1px;width:1px;overflow:hidden;"><template><script type="module" data-source-id="${jsId}">${contents}\${jsContent}</script></template></div>\`;
116
+ }
117
+
118
+ return \`<div id="${jsId}">\${ssrContent}</div><script type="module" data-source-id="${jsId}">${contents}\${jsContent}</script>\`;
119
+ }
114
120
  ${componentName}.__HS_ISLAND = {
115
121
  id: "${jsId}",
116
- ssr: (props) => {
122
+ render: (props, options = {}) => {
123
+ if (options.ssr === false) {
124
+ const jsContent = \`__hs_render(__hs_h(${componentName}, \${JSON.stringify(props)}), document.getElementById("${jsId}"));\`;
125
+ return __hs_renderIsland(jsContent, '', options);
126
+ }
127
+
117
128
  const ssrContent = __hs_renderToString(__hs_h(${componentName}, props));
118
- const postContent = \`__hs_hydrate(__hs_h(${componentName}, \${JSON.stringify(props)}), document.getElementById("${jsId}"));\`;
119
- return __hs_html.raw(\`<div id="${jsId}">\${ssrContent}</div><script type="module" data-source-id="${jsId}">${contents}\${postContent}</script>\`);
120
- },
121
- clientOnly: (props) => {
122
- const postContent = \`__hs_render(__hs_h(${componentName}, \${JSON.stringify(props)}), document.getElementById("${jsId}"));\`;
129
+ const jsContent = \`__hs_hydrate(__hs_h(${componentName}, \${JSON.stringify(props)}), document.getElementById("${jsId}"));\`;
130
+ return __hs_renderIsland(jsContent, ssrContent, options);
123
131
 
124
- return __hs_html.raw(
125
- \`<div id="${jsId}"></div><script type="module" data-source-id="${jsId}">${contents}\${postContent}</script>\`
126
- );
127
132
  }
128
133
  }
129
134
  `;