@@ -3,6 +3,13 @@ import { h, hydrate } from 'preact';
33
44import loaders from './loaders.mjs' ;
55
6+ /**
7+ * Adds the generator's component map to the registry.
8+ *
9+ * @param {Record<string, () => Promise<{ default: import('preact').ComponentType }>> } components
10+ */
11+ export const registerIslands = components => Object . assign ( loaders , components ) ;
12+
613/**
714 * Re-renders an island's server-rendered children as the markup they already
815 * are. Preact keeps the existing DOM because the HTML is identical, so nothing
@@ -26,7 +33,10 @@ Island.addInitType('preact', async island => {
2633 return ;
2734 }
2835
29- const script = island . querySelector ( ':scope > script[data-island-props]' ) ;
36+ const script = [ ...island . children ] . find ( child =>
37+ child . matches ( 'script[data-island-props]' )
38+ ) ;
39+
3040 const props = script ? JSON . parse ( script . textContent ) : { } ;
3141
3242 // Preact hydrates by walking the container's children in order, so the props
@@ -39,5 +49,13 @@ Island.addInitType('preact', async island => {
3949 props . children = h ( Slot , { html : slot . innerHTML } ) ;
4050 }
4151
42- hydrate ( h ( await loader ( ) , props ) , island ) ;
52+ try {
53+ const { default : Component } = await loader ( ) ;
54+
55+ hydrate ( h ( Component , props ) , island ) ;
56+ } catch ( error ) {
57+ // is-land awaits this callback, so a rejection would leave the island
58+ // silently stuck: never marked ready, and never reported anywhere.
59+ console . error ( `[is-land] "${ name } " failed to hydrate` , error ) ;
60+ }
4361} ) ;
0 commit comments