|
55 | 55 | selected
|
56 | 56 | });
|
57 | 57 |
|
58 |
| - /** @type {import('$lib/types').Adapter} */ |
| 58 | + /** @type {import('$lib/types').Adapter | undefined} */ |
59 | 59 | let adapter;
|
60 | 60 |
|
61 | 61 | /** @type {Record<string, string>}*/
|
|
104 | 104 | const contents = model.getValue();
|
105 | 105 |
|
106 | 106 | if (!completing) {
|
107 |
| - adapter.update([{ ...stub, contents }]); |
| 107 | + adapter?.update([{ ...stub, contents }]); |
108 | 108 | }
|
109 | 109 | });
|
110 | 110 |
|
|
120 | 120 |
|
121 | 121 | completed = false;
|
122 | 122 |
|
| 123 | + load_webcontainer(); |
| 124 | + }); |
| 125 | +
|
| 126 | + async function load_webcontainer() { |
123 | 127 | clearTimeout(timeout);
|
124 | 128 | loading = true;
|
125 | 129 |
|
|
142 | 146 |
|
143 | 147 | try {
|
144 | 148 | await new Promise((fulfil, reject) => {
|
| 149 | + let called = false; |
| 150 | +
|
145 | 151 | window.addEventListener('message', function handler(e) {
|
146 |
| - if (e.origin !== adapter.base) return; |
| 152 | + if (e.origin !== adapter?.base) return; |
147 | 153 | if (e.data.type === 'ping') {
|
148 | 154 | window.removeEventListener('message', handler);
|
| 155 | + called = true; |
149 | 156 | fulfil(undefined);
|
150 | 157 | }
|
| 158 | + }); |
| 159 | +
|
| 160 | + setTimeout(() => { |
| 161 | + if (!called && adapter) { |
| 162 | + // Updating the iframe too soon sometimes results in a blank screen, |
| 163 | + // so we try again after a short delay if we haven't heard back |
| 164 | + set_iframe_src(adapter.base); |
| 165 | + } |
| 166 | + }, 2000); |
151 | 167 |
|
152 |
| - setTimeout(() => { |
| 168 | + setTimeout(() => { |
| 169 | + if (!called) { |
153 | 170 | reject(new Error('Timed out'));
|
154 |
| - }, 5000); |
155 |
| - }); |
| 171 | + } |
| 172 | + }, 5000); |
156 | 173 | });
|
157 | 174 |
|
158 | 175 | expected = await get_transformed_modules(data.section.scope.prefix, Object.values(b));
|
159 | 176 |
|
| 177 | + const stubs = Object.values(data.section.a); |
160 | 178 | await adapter.reset(stubs);
|
161 | 179 | const actual = await get_transformed_modules(data.section.scope.prefix, stubs);
|
162 | 180 |
|
|
169 | 187 | loading = false;
|
170 | 188 | initial = false;
|
171 | 189 | } catch (e) {
|
| 190 | + error = /** @type {Error} */ (e); |
172 | 191 | console.error(e);
|
173 | 192 | }
|
174 |
| - }); |
| 193 | + } |
175 | 194 |
|
176 | 195 | /** @type {NodeJS.Timeout} */
|
177 | 196 | let timeout;
|
|
186 | 205 |
|
187 | 206 | clearTimeout(timeout);
|
188 | 207 | timeout = setTimeout(() => {
|
189 |
| - if (dev && !iframe) return; |
| 208 | + if ((dev && !iframe) || !adapter) return; |
190 | 209 |
|
191 | 210 | // we lost contact, refresh the page
|
192 | 211 | loading = true;
|
|
361 | 380 | }
|
362 | 381 | }
|
363 | 382 |
|
364 |
| - adapter.update(changes); |
| 383 | + adapter?.update(changes); |
365 | 384 | completing = false;
|
366 | 385 | }}
|
367 | 386 | >
|
|
385 | 404 | {path}
|
386 | 405 | {loading}
|
387 | 406 | on:refresh={() => {
|
388 |
| - set_iframe_src(adapter.base + path); |
| 407 | + if (adapter) { |
| 408 | + set_iframe_src(adapter.base + path); |
| 409 | + } |
389 | 410 | }}
|
390 | 411 | on:change={(e) => {
|
391 |
| - const url = new URL(e.detail.value, adapter.base); |
392 |
| - path = url.pathname + url.search + url.hash; |
393 |
| - set_iframe_src(adapter.base + path); |
| 412 | + if (adapter) { |
| 413 | + const url = new URL(e.detail.value, adapter.base); |
| 414 | + path = url.pathname + url.search + url.hash; |
| 415 | + set_iframe_src(adapter.base + path); |
| 416 | + } |
394 | 417 | }}
|
395 | 418 | />
|
396 | 419 |
|
397 | 420 | <div class="content">
|
398 | 421 | <iframe bind:this={iframe} title="Output" />
|
399 | 422 |
|
400 | 423 | {#if loading || error}
|
401 |
| - <Loading {initial} {error} /> |
| 424 | + <Loading |
| 425 | + {initial} |
| 426 | + {error} |
| 427 | + on:reload={async () => { |
| 428 | + await adapter?.destroy(); |
| 429 | + adapter = undefined; |
| 430 | + load_webcontainer(); |
| 431 | + }} |
| 432 | + /> |
402 | 433 | {/if}
|
403 | 434 | </div>
|
404 | 435 | </section>
|
|
0 commit comments