Skip to content

Commit

Permalink
fix: broken runtime template
Browse files Browse the repository at this point in the history
Fixes #51
  • Loading branch information
harlan-zw committed Jul 20, 2024
1 parent f083e32 commit 24f05c7
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 26 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
],
"scripts": {
"dev": "nuxi dev .playground",
"stub": "nuxt-module-build build --stub",
"stub": "npx terser src/template/global.mjs -o src/runtime/template/global.mjs && npx terser src/template/replay.mjs -o src/runtime/template/replay.mjs && nuxt-module-build build --stub",
"build": "nuxi prepare .playground && nuxt-module-build build",
"lint": "eslint . --fix",
"release": "bumpp package.json packages/*/package.json --commit --push --tag",
Expand Down
16 changes: 10 additions & 6 deletions src/runtime/nitro-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,24 +50,28 @@ export default defineNitroPlugin((nitro) => {
return false
},
)
extraScripts = `_$delayHydration.then(e => {
extraScripts = `;window._$delayHydration.then(e => {
;(${JSON.stringify(toLoad)}).forEach(s => {
const script = document.createElement('script')
Object.entries(s).forEach(([k, v]) => script.setAttribute(k, v))
document.body.appendChild(script)
const script = document.createElement('script');
Object.entries(s).forEach(([k, v]) => script.setAttribute(k, v));
document.body.appendChild(script);
})
})`
}
if (replayScript)
extraScripts += `;${replayScript}`

// insert the hydration API, maybe insert delay script
htmlContext.bodyAppend.push(`<script>
let html = `<script>
(function() {
const w = window; w._$delayHydration = (function() { if (!('requestIdleCallback' in w) || !('requestAnimationFrame' in w)) { return new Promise(resolve => resolve('not supported')) } ${script} return hydrationPromise; })();
${debug ? 'w._$delayHydration.then((e) => { console.log(\'[nuxt-delay-hydration] Hydration event\', e) })' : ''}
${extraScripts}
})();
</script>`.replace(/\s+/g, ' ').replace(/[\n\r]/g, ''))
</script>`
if (!import.meta.dev) {
html = html.replace(/\s+/g, ' ').replace(/[\n\r]/g, '')
}
htmlContext.bodyAppend.push(html)
})
})
6 changes: 3 additions & 3 deletions src/runtime/nuxt-plugin.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { createFilter } from './util'
import type { HydrationMode } from './types'
import type { Mode } from './types'
import { exclude, include, mode } from '#nuxt-delay-hydration/api'
import { defineNuxtPlugin, useRequestEvent, useState } from '#imports'

export default defineNuxtPlugin(async (nuxtApp) => {
const hydrationMode = useState<HydrationMode>('nuxt-delay-hydration-mode', () => mode)
const hydrationMode = useState<Mode>('nuxt-delay-hydration-mode', () => mode)
if (import.meta.server) {
const event = useRequestEvent()
if (event?.context?._nitro?.routeRules?.delayHydration)
hydrationMode.value = routeRules.delayHydration
hydrationMode.value = event.context._nitro.routeRules.delayHydration
}
if (import.meta.client) {
if (hydrationMode.value === 'mount') {
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/template/global.mjs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
function eventListeners() { const c = new AbortController(); const p = new Promise((resolve) => { const hydrateOnEvents = '<%= options.hydrateOnEvents %>'.split(','); function handler(e) { hydrateOnEvents.forEach(e => w.removeEventListener(e, handler)); requestAnimationFrame(() => resolve(e)) }hydrateOnEvents.forEach((e) => { w.addEventListener(e, handler, { capture: true, once: true, passive: true, signal: c.signal }) }) }); return { c: () => c.abort(), p } } function idleListener() { let id; const p = new Promise((resolve) => { const isMobile = w.innerWidth < 640; const timeout = isMobile ? Number.parseInt('<%= options.postIdleTimeout.mobile %>') : Number.parseInt('<%= options.postIdleTimeout.desktop %>'); const timeoutDelay = () => setTimeout(() => requestAnimationFrame(() => resolve('timeout')), timeout); id = w.requestIdleCallback(timeoutDelay, { timeout: Number.parseInt('<%= options.idleCallbackTimeout %>') }) }); return { c: () => window.cancelIdleCallback(id), p } } const triggers = [idleListener(), eventListeners()]; const hydrationPromise = Promise.race(triggers.map(t => t.p)).finally(() => { triggers.forEach(t => t.c()) })
function eventListeners(){const c=new AbortController;const p=new Promise(resolve=>{const hydrateOnEvents="<%= options.hydrateOnEvents %>".split(",");function handler(e){hydrateOnEvents.forEach(e=>w.removeEventListener(e,handler));requestAnimationFrame(()=>resolve(e))}hydrateOnEvents.forEach(e=>{w.addEventListener(e,handler,{capture:true,once:true,passive:true,signal:c.signal})})});return{c:()=>c.abort(),p:p}}function idleListener(){let id;const p=new Promise(resolve=>{const isMobile=w.innerWidth<640;const timeout=isMobile?Number.parseInt("<%= options.postIdleTimeout.mobile %>"):Number.parseInt("<%= options.postIdleTimeout.desktop %>");const timeoutDelay=()=>setTimeout(()=>requestAnimationFrame(()=>resolve("timeout")),timeout);id=w.requestIdleCallback(timeoutDelay,{timeout:Number.parseInt("<%= options.idleCallbackTimeout %>")})});return{c:()=>window.cancelIdleCallback(id),p:p}}const triggers=[idleListener(),eventListeners()];const hydrationPromise=Promise.race(triggers.map(t=>t.p)).finally(()=>{triggers.forEach(t=>t.c())});
2 changes: 1 addition & 1 deletion src/runtime/template/replay.mjs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
(() => { w._$delayHydration.then((e) => { if (!(e instanceof PointerEvent) && !(e instanceof MouseEvent) && !(window.TouchEvent && e instanceof TouchEvent) || e instanceof MouseEvent && e.type !== 'click') { return }setTimeout(() => w.requestIdleCallback(() => setTimeout(() => e.target && e.target.click(), 500)), 50) }) })()
(()=>{w._$delayHydration.then(e=>{if(e instanceof PointerEvent||e instanceof MouseEvent&&e.type!=="click"||window.TouchEvent&&e instanceof TouchEvent){setTimeout(()=>w.requestIdleCallback(()=>setTimeout(()=>e.target&&e.target.click(),500)),50)}})})();
19 changes: 10 additions & 9 deletions src/template/global.mjs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
/* eslint-disable */
function eventListeners() {
const c = new AbortController()
const c = new AbortController();
const p = new Promise((resolve) => {
const hydrateOnEvents = '<%= options.hydrateOnEvents %>'.split(',')
const hydrateOnEvents = '<%= options.hydrateOnEvents %>'.split(',');
function handler(e) {
hydrateOnEvents.forEach(e => w.removeEventListener(e, handler))
requestAnimationFrame(() => resolve(e))
hydrateOnEvents.forEach(e => w.removeEventListener(e, handler));
requestAnimationFrame(() => resolve(e));
}
hydrateOnEvents.forEach((e) => {
w.addEventListener(e, handler, {
capture: true,
once: true,
passive: true,
signal: c.signal,
})
})
});
});
})
return { c: () => c.abort(), p }
}
Expand All @@ -26,14 +27,14 @@ function idleListener() {
const timeoutDelay = () => setTimeout(
() => requestAnimationFrame(() => resolve('timeout')),
timeout,
)
);
id = w.requestIdleCallback(timeoutDelay, { timeout: Number.parseInt('<%= options.idleCallbackTimeout %>') })
})
return { c: () => window.cancelIdleCallback(id), p }
}
const triggers = [idleListener(), eventListeners()]
const triggers = [idleListener(), eventListeners()];
const hydrationPromise = Promise.race(
triggers.map(t => t.p),
).finally(() => {
triggers.forEach(t => t.c())
})
});
12 changes: 7 additions & 5 deletions src/template/replay.mjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
/* eslint-disable */
(() => {
w._$delayHydration.then((e) => {
if ((!(e instanceof PointerEvent) && !(e instanceof MouseEvent) && !(window.TouchEvent && e instanceof TouchEvent)) || e instanceof MouseEvent && e.type !== 'click') {
return
if (e instanceof PointerEvent || (e instanceof MouseEvent && e.type !== 'click') || (window.TouchEvent && e instanceof TouchEvent)) {
setTimeout(() => {
return w.requestIdleCallback(() => setTimeout(() => e.target && e.target.click(), 500));
}, 50);
}
setTimeout(() => w.requestIdleCallback(() => setTimeout(() => e.target && e.target.click(), 500)), 50)
})
})()
});
})();

0 comments on commit 24f05c7

Please sign in to comment.