@cloudwerk/ui 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,27 @@
1
+ // src/clientWrapper.tsx
2
+ import { serializeProps, escapeHtmlAttribute } from "@cloudwerk/utils";
3
+ import { jsx } from "hono/jsx/jsx-runtime";
4
+ function createClientComponentWrapper(Component, meta) {
5
+ if (typeof window !== "undefined") {
6
+ return Component;
7
+ }
8
+ const { componentId, bundlePath } = meta;
9
+ return function WrappedClientComponent(props) {
10
+ const rendered = Component(props);
11
+ const serializedProps = serializeProps(props);
12
+ const escapedProps = escapeHtmlAttribute(serializedProps);
13
+ return /* @__PURE__ */ jsx(
14
+ "div",
15
+ {
16
+ "data-hydrate-id": componentId,
17
+ "data-hydrate-props": escapedProps,
18
+ "data-hydrate-bundle": bundlePath,
19
+ children: rendered
20
+ }
21
+ );
22
+ };
23
+ }
24
+
25
+ export {
26
+ createClientComponentWrapper
27
+ };
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @cloudwerk/ui - Client Component Wrapper
3
+ *
4
+ * Wraps client components with hydration metadata for server-side rendering.
5
+ * This wrapper is used by the esbuild plugin to transform imports of client components.
6
+ */
7
+ /**
8
+ * Metadata for a wrapped client component.
9
+ */
10
+ interface ClientComponentMeta {
11
+ /** Unique component ID for hydration */
12
+ componentId: string;
13
+ /** Path to the client bundle */
14
+ bundlePath: string;
15
+ }
16
+ /**
17
+ * Creates a wrapper component that adds hydration metadata.
18
+ *
19
+ * The wrapper:
20
+ * 1. Server-renders the original component
21
+ * 2. Wraps the output with a div containing hydration attributes
22
+ * 3. The client-side hydration script uses these attributes to hydrate
23
+ *
24
+ * @param Component - The original client component
25
+ * @param meta - Component metadata for hydration
26
+ * @returns Wrapped component that includes hydration metadata
27
+ *
28
+ * @example
29
+ * ```tsx
30
+ * // Original import:
31
+ * import Counter from './components/counter'
32
+ *
33
+ * // Transformed to:
34
+ * import _Counter from './components/counter'
35
+ * const Counter = createClientComponentWrapper(_Counter, {
36
+ * componentId: 'components_counter',
37
+ * bundlePath: '/__cloudwerk/components_counter.js'
38
+ * })
39
+ * ```
40
+ */
41
+ declare function createClientComponentWrapper<P extends Record<string, unknown>>(Component: (props: P) => unknown, meta: ClientComponentMeta): (props: P) => unknown;
42
+ /**
43
+ * Type for a client component wrapper function.
44
+ */
45
+ type ClientComponentWrapper = typeof createClientComponentWrapper;
46
+
47
+ export { type ClientComponentMeta, type ClientComponentWrapper, createClientComponentWrapper };
package/dist/client.js ADDED
@@ -0,0 +1,6 @@
1
+ import {
2
+ createClientComponentWrapper
3
+ } from "./chunk-C4MFDUV4.js";
4
+ export {
5
+ createClientComponentWrapper
6
+ };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { HydrationManifest } from '@cloudwerk/core';
1
+ import { HydrationManifest } from '@cloudwerk/core/build';
2
+ export { ClientComponentMeta, ClientComponentWrapper, createClientComponentWrapper } from './client.js';
2
3
 
3
4
  /**
4
5
  * @cloudwerk/ui - Type Definitions
@@ -212,9 +213,12 @@ declare function generateHydrationScript(manifest: HydrationManifest, options?:
212
213
  * This adds modulepreload hints for better performance.
213
214
  *
214
215
  * @param manifest - Hydration manifest with component metadata
216
+ * @param options - Options for generating hints
215
217
  * @returns Link tags for modulepreload
216
218
  */
217
- declare function generatePreloadHints(manifest: HydrationManifest): string;
219
+ declare function generatePreloadHints(manifest: HydrationManifest, options?: {
220
+ hydrationEndpoint?: string;
221
+ }): string;
218
222
  /**
219
223
  * Generate the hydration runtime module for Hono JSX.
220
224
  *
package/dist/index.js CHANGED
@@ -1,3 +1,7 @@
1
+ import {
2
+ createClientComponentWrapper
3
+ } from "./chunk-C4MFDUV4.js";
4
+
1
5
  // src/renderers/hono-jsx.ts
2
6
  import { renderToReadableStream } from "hono/jsx/streaming";
3
7
  var honoJsxRenderer = {
@@ -205,7 +209,7 @@ function _resetRenderers() {
205
209
  }
206
210
 
207
211
  // src/hydration.ts
208
- import { serializeProps } from "@cloudwerk/core";
212
+ import { serializeProps } from "@cloudwerk/core/build";
209
213
  function wrapForHydration(html2, options) {
210
214
  const { componentId, props, wrapperTag = "div" } = options;
211
215
  const serializedProps = serializeProps(props);
@@ -234,6 +238,10 @@ function generateHydrationScript(manifest, options = {}) {
234
238
  const elements = document.querySelectorAll('[data-hydrate-id]');
235
239
  if (elements.length === 0) return;
236
240
 
241
+ // Import the runtime which includes jsx function and render
242
+ const runtime = await import('${hydrationEndpoint}/runtime.js');
243
+ const { render, jsx } = runtime;
244
+
237
245
  // Cache for loaded modules
238
246
  const moduleCache = new Map();
239
247
 
@@ -271,12 +279,13 @@ function generateHydrationScript(manifest, options = {}) {
271
279
  continue;
272
280
  }
273
281
 
274
- // Import hono/jsx/dom for hydration
275
- const { render } = await import('${hydrationEndpoint}/runtime.js');
282
+ // Create a proper JSX element using the jsx runtime function
283
+ // This allows hono/jsx/dom to manage the component lifecycle and re-renders
284
+ const element = jsx(Component, props);
276
285
 
277
286
  // Hydrate the component using hono/jsx/dom render
278
287
  // This safely replaces content using virtual DOM diffing
279
- render(Component(props), el);
288
+ render(element, el);
280
289
 
281
290
  // Remove hydration attributes after successful hydration
282
291
  el.removeAttribute('data-hydrate-id');
@@ -290,11 +299,21 @@ function generateHydrationScript(manifest, options = {}) {
290
299
  `.trim();
291
300
  return script;
292
301
  }
293
- function generatePreloadHints(manifest) {
302
+ function generatePreloadHints(manifest, options = {}) {
303
+ const { hydrationEndpoint = "/__cloudwerk" } = options;
294
304
  if (manifest.components.size === 0) {
295
305
  return "";
296
306
  }
297
307
  const hints = [];
308
+ const importMap = {
309
+ imports: {
310
+ "hono/jsx/dom": `${hydrationEndpoint}/runtime.js`,
311
+ "hono/jsx/dom/jsx-runtime": `${hydrationEndpoint}/runtime.js`,
312
+ "hono/jsx/dom/jsx-dev-runtime": `${hydrationEndpoint}/runtime.js`
313
+ }
314
+ };
315
+ hints.push(`<script type="importmap">${JSON.stringify(importMap)}</script>`);
316
+ hints.push(`<link rel="modulepreload" href="${hydrationEndpoint}/runtime.js">`);
298
317
  for (const meta of manifest.components.values()) {
299
318
  hints.push(`<link rel="modulepreload" href="${meta.bundlePath}">`);
300
319
  }
@@ -476,6 +495,7 @@ function hydrate(element, root) {
476
495
  }
477
496
  export {
478
497
  _resetRenderers,
498
+ createClientComponentWrapper,
479
499
  generateHydrationRuntime,
480
500
  generateHydrationScript,
481
501
  generatePreloadHints,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudwerk/ui",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "UI rendering abstraction for Cloudwerk",
5
5
  "repository": {
6
6
  "type": "git",
@@ -12,13 +12,18 @@
12
12
  ".": {
13
13
  "types": "./dist/index.d.ts",
14
14
  "import": "./dist/index.js"
15
+ },
16
+ "./client": {
17
+ "types": "./dist/client.d.ts",
18
+ "import": "./dist/client.js"
15
19
  }
16
20
  },
17
21
  "files": [
18
22
  "dist"
19
23
  ],
20
24
  "dependencies": {
21
- "@cloudwerk/core": "0.6.0"
25
+ "@cloudwerk/utils": "0.6.0",
26
+ "@cloudwerk/core": "0.7.0"
22
27
  },
23
28
  "peerDependencies": {
24
29
  "hono": "^4.0.0",