payload-live-preview 2.3.1 → 2.4.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.
- package/README.md +13 -46
- package/dist/adapters/astro/index.js +1 -1
- package/dist/adapters/astro/index.js.map +1 -1
- package/dist/adapters/astro/middleware-entry.js +1 -1
- package/dist/adapters/astro/middleware-entry.js.map +1 -1
- package/dist/adapters/nextjs/client.d.ts +28 -0
- package/dist/adapters/nextjs/client.js +3 -0
- package/dist/adapters/nextjs/client.js.map +1 -0
- package/dist/adapters/nextjs/index.d.ts +34 -12
- package/dist/adapters/nextjs/index.js +1 -1
- package/dist/adapters/nextjs/index.js.map +1 -1
- package/dist/adapters/nuxt/client.d.ts +29 -0
- package/dist/adapters/nuxt/client.js +2 -0
- package/dist/adapters/nuxt/client.js.map +1 -0
- package/dist/adapters/nuxt/index.js +1 -1
- package/dist/adapters/nuxt/index.js.map +1 -1
- package/dist/adapters/nuxt/module.d.ts +23 -3
- package/dist/adapters/nuxt/module.js +1 -1
- package/dist/adapters/nuxt/module.js.map +1 -1
- package/dist/adapters/react/index.d.ts +2 -2
- package/dist/adapters/react/index.js +1 -1
- package/dist/adapters/react/index.js.map +1 -1
- package/dist/adapters/sveltekit/client.d.ts +37 -0
- package/dist/adapters/sveltekit/client.js +2 -0
- package/dist/adapters/sveltekit/client.js.map +1 -0
- package/dist/adapters/sveltekit/index.js +1 -1
- package/dist/adapters/sveltekit/index.js.map +1 -1
- package/dist/adapters/vue/index.d.ts +2 -2
- package/dist/adapters/vue/index.js +1 -1
- package/dist/adapters/vue/index.js.map +1 -1
- package/dist/client.cjs +1 -1
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/dist/core.cjs +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +22 -14
- package/dist/core.d.ts +22 -14
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/{document-session-BuYuO3ae.d.ts → document-session-oK92QjES.d.ts} +7 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lean.cjs +1 -1
- package/dist/lean.cjs.map +1 -1
- package/dist/lean.js +1 -1
- package/dist/lean.js.map +1 -1
- package/dist/lexical.cjs.map +1 -1
- package/dist/lexical.js.map +1 -1
- package/dist/plugins.cjs +1 -1
- package/dist/plugins.cjs.map +1 -1
- package/dist/plugins.js +1 -1
- package/dist/plugins.js.map +1 -1
- package/dist/server.cjs.map +1 -1
- package/dist/server.js.map +1 -1
- package/dist/structural.cjs.map +1 -1
- package/dist/structural.js.map +1 -1
- package/package.json +23 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The client half of the Nuxt module: what the plugin it registers runs in the
|
|
3
|
+
* browser. It tells the runtime when a client navigation has committed and
|
|
4
|
+
* lends it `refreshNuxtData()` for route updates, the glue a Nuxt preview kept
|
|
5
|
+
* in its own `plugins/` before 2.4.
|
|
6
|
+
*
|
|
7
|
+
* Nuxt's composables are passed in by the generated plugin, which imports them
|
|
8
|
+
* from `#app`; that alias exists only inside a Nuxt build. The app is
|
|
9
|
+
* duck-typed for the same reason the module is: no build-time `nuxt` types.
|
|
10
|
+
*/
|
|
11
|
+
/** The part of the Nuxt app this reads: its router and one hook. */
|
|
12
|
+
interface NuxtNavigationApp {
|
|
13
|
+
readonly $router: {
|
|
14
|
+
readonly currentRoute: {
|
|
15
|
+
readonly value: {
|
|
16
|
+
readonly fullPath: string;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
readonly hook: (name: 'page:loading:end', callback: () => void) => () => void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Binds both seams and returns their cleanup. The plugin also hands the cleanup
|
|
24
|
+
* to hot replacement; an ordinary unload runs it, a back/forward-cache entry
|
|
25
|
+
* keeps the bridge for its `pageshow`.
|
|
26
|
+
*/
|
|
27
|
+
declare function bindNuxtNavigation(nuxtApp: NuxtNavigationApp, refreshNuxtData: () => Promise<unknown>): () => void;
|
|
28
|
+
|
|
29
|
+
export { type NuxtNavigationApp, bindNuxtNavigation };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{nextTick as e}from"vue";var t="__livePreviewRouteRefresh";function n(n,o){let i=n.$router.currentRoute.value.fullPath;const r=n.hook("page:loading:end",()=>{const e=n.$router.currentRoute.value.fullPath;e!==i&&(i=e,document.dispatchEvent(new Event("payload-live-preview:navigation")))}),a=function registerRouteRefresh(e){const n="undefined"==typeof window?void 0:window;return void 0===n?()=>{}:(n[t]=e,()=>{n[t]===e&&(n[t]=void 0)})}(async()=>{await o(),await e()});let d=!1;const u=()=>{d||(d=!0,r(),a(),window.removeEventListener("pagehide",v))},v=e=>{e.persisted||u()};return window.addEventListener("pagehide",v),u}export{n as bindNuxtNavigation};
|
|
2
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","names":["SLOT","bindNuxtNavigation","nuxtApp","refreshNuxtData","committedRoute","$router","currentRoute","value","fullPath","removeLoadingEnd","hook","route","document","dispatchEvent","Event","removeRefresh","registerRouteRefresh","refresh","target","window","async","nextTick","cleaned","cleanup","removeEventListener","onPageHide","event","persisted","addEventListener"],"sources":["../../../src/core/navigation-lifecycle.ts","../../../src/core/route-refresh.ts","../../../src/adapters/nuxt/client.ts"],"sourcesContent":["/**\n * Binds the document lifecycle the runtime cannot see: a back/forward-cache\n * restore re-runs no scripts, so a client that stayed attached comes back\n * bound to a frozen document and quietly stops updating; a soft navigation\n * replaces the content the binding cache describes. Both are silent failures.\n */\n\n/** The part of the client this owner drives. */\nexport interface NavigationLifecycleTarget {\n suspend(): boolean;\n resume(): boolean;\n /** Re-scan bindings after replacing markup without crossing a navigation boundary. */\n refreshCache(): void;\n /** Re-scan and replay the last accepted document after a committed router navigation. */\n refreshAfterNavigation?(): void;\n}\n\n/** Package-owned event dispatched after a framework router commit. @internal */\nexport const NAVIGATION_COMMIT_EVENT = 'payload-live-preview:navigation';\nconst ASTRO_INITIAL_PAGE_LOAD_EVENT = 'astro:page-load';\nconst ASTRO_AFTER_SWAP_EVENT = 'astro:after-swap';\n\nexport interface NavigationLifecycleOptions {\n /** Where `pagehide`/`pageshow` fire; they exist only on the window. Defaults to `window`. */\n readonly windowTarget?: EventTarget;\n /** Event target for soft-navigation events. Defaults to `document`. */\n readonly documentTarget?: EventTarget;\n /**\n * Events after which the DOM was replaced and the current editor state must\n * be replayed, e.g. `astro:page-load`. Empty by default: only the host knows\n * which its router fires.\n */\n readonly softNavigationEvents?: readonly string[];\n}\n\n/** Returns an unbind function; calling it twice is harmless. */\nexport function bindNavigationLifecycle(\n target: NavigationLifecycleTarget,\n options: NavigationLifecycleOptions = {},\n): () => void {\n const windowTarget = options.windowTarget ?? (globalThis as { window?: EventTarget }).window;\n const documentTarget =\n options.documentTarget ?? (globalThis as { document?: EventTarget }).document;\n const softEvents = [...new Set(options.softNavigationEvents ?? [])];\n\n const onPageHide = (): void => {\n target.suspend();\n };\n const onPageShow = (event: Event): void => {\n // Only a persisted restore needs reacquiring; an ordinary load already started.\n if ((event as Event & { readonly persisted?: boolean }).persisted === true) {\n target.resume();\n }\n };\n let astroNavigationArmed = false;\n const onAstroAfterSwap = (): void => {\n astroNavigationArmed = true;\n };\n const onSoftNavigation = (event: Event): void => {\n // Astro emits page-load for the initial document too. A client-router\n // commit is the page-load preceded by after-swap, including before the\n // browser's initial `load` when a subresource is slow.\n if (event.type === ASTRO_INITIAL_PAGE_LOAD_EVENT) {\n if (!astroNavigationArmed) return;\n astroNavigationArmed = false;\n }\n if (target.refreshAfterNavigation === undefined) target.refreshCache();\n else target.refreshAfterNavigation();\n };\n\n let unbound = false;\n\n windowTarget?.addEventListener('pagehide', onPageHide);\n windowTarget?.addEventListener('pageshow', onPageShow);\n for (const name of softEvents) documentTarget?.addEventListener(name, onSoftNavigation);\n const observesAstro = softEvents.includes(ASTRO_INITIAL_PAGE_LOAD_EVENT);\n if (observesAstro) documentTarget?.addEventListener(ASTRO_AFTER_SWAP_EVENT, onAstroAfterSwap);\n\n return (): void => {\n if (unbound) return;\n unbound = true;\n windowTarget?.removeEventListener('pagehide', onPageHide);\n windowTarget?.removeEventListener('pageshow', onPageShow);\n for (const name of softEvents) documentTarget?.removeEventListener(name, onSoftNavigation);\n if (observesAstro) {\n documentTarget?.removeEventListener(ASTRO_AFTER_SWAP_EVENT, onAstroAfterSwap);\n }\n };\n}\n","/**\n * The seam between a host framework's own router and the route strategy.\n *\n * The route strategy answers a revision by fetching the route and morphing it\n * into the living page. On a page whose DOM belongs to a reconciler that is\n * working against the framework, and it was seen to break once: `removeChild`\n * on `null` inside React's commit phase, over markup this package had patched.\n * A host that re-renders the route itself does the same job without the morph\n * and without the second HTML request, so it is given the chance to.\n *\n * Why a named slot on `window` and not a reference: the runtime is an inline\n * script that builds its strategy before any application code has hydrated, so\n * there is nothing to hand a component; `window.__livePreview`, the only other\n * public surface, is created later and not at all outside a preview; and the\n * two richer extension points — plugins and events — are reachable only through\n * the programmatic client, which a page using an adapter does not have. One\n * slot, written by whoever mounts and read at the moment of a refresh, is the\n * smallest thing that survives both orders of arrival.\n */\n\n/**\n * A host's own route refresh. It must settle once the fresh markup is\n * committed: the runtime re-applies the revision on top of it, and doing that\n * against the markup being replaced would write into nodes about to be dropped.\n * A function that returns nothing is taken as already committed; the route\n * strategy says once that it could not wait (LP0810), and 3.0 requires the\n * promise (ADR 0028).\n */\nexport type RouteRefresh = () => void | Promise<void>;\n\n/** Read late, so it does not matter whether the runtime or the component came first. */\nconst SLOT = '__livePreviewRouteRefresh';\n\ntype WindowSlot = Record<string, RouteRefresh | undefined>;\n\nfunction slot(): WindowSlot | undefined {\n return typeof window === 'undefined' ? undefined : (window as unknown as WindowSlot);\n}\n\n/**\n * Lend the runtime the host's route refresh; the return value undoes it, for a\n * component's cleanup. A later registration wins, and undoing one that has\n * already been replaced does nothing — two components on one page would\n * otherwise take the slot from each other on unmount.\n */\nexport function registerRouteRefresh(refresh: RouteRefresh): () => void {\n const target = slot();\n if (target === undefined) return () => undefined;\n target[SLOT] = refresh;\n return () => {\n // Cleared rather than deleted: the slot is read through `?.` anyway, and\n // removing the key buys nothing a lint rule would not have to be argued out of.\n if (target[SLOT] === refresh) target[SLOT] = undefined;\n };\n}\n\n/** The registered refresh, or `undefined` on a page that registered none. */\nexport function readRouteRefresh(): RouteRefresh | undefined {\n return slot()?.[SLOT];\n}\n","/**\n * The client half of the Nuxt module: what the plugin it registers runs in the\n * browser. It tells the runtime when a client navigation has committed and\n * lends it `refreshNuxtData()` for route updates, the glue a Nuxt preview kept\n * in its own `plugins/` before 2.4.\n *\n * Nuxt's composables are passed in by the generated plugin, which imports them\n * from `#app`; that alias exists only inside a Nuxt build. The app is\n * duck-typed for the same reason the module is: no build-time `nuxt` types.\n */\n\nimport { nextTick } from 'vue';\nimport { NAVIGATION_COMMIT_EVENT } from '@core/navigation-lifecycle';\nimport { registerRouteRefresh } from '@core/route-refresh';\n\n/** The part of the Nuxt app this reads: its router and one hook. */\nexport interface NuxtNavigationApp {\n readonly $router: { readonly currentRoute: { readonly value: { readonly fullPath: string } } };\n readonly hook: (name: 'page:loading:end', callback: () => void) => () => void;\n}\n\n/**\n * Binds both seams and returns their cleanup. The plugin also hands the cleanup\n * to hot replacement; an ordinary unload runs it, a back/forward-cache entry\n * keeps the bridge for its `pageshow`.\n */\nexport function bindNuxtNavigation(\n nuxtApp: NuxtNavigationApp,\n refreshNuxtData: () => Promise<unknown>,\n): () => void {\n let committedRoute = nuxtApp.$router.currentRoute.value.fullPath;\n // `page:loading:end` follows a page commit and a same-page query update,\n // where Nuxt emits no `page:finish`. Reading the route at once keeps a\n // redirect from letting an earlier completion claim the later route.\n const removeLoadingEnd = nuxtApp.hook('page:loading:end', () => {\n const route = nuxtApp.$router.currentRoute.value.fullPath;\n if (route === committedRoute) return;\n committedRoute = route;\n document.dispatchEvent(new Event(NAVIGATION_COMMIT_EVENT));\n });\n const removeRefresh = registerRouteRefresh(async () => {\n await refreshNuxtData();\n await nextTick();\n });\n\n let cleaned = false;\n const cleanup = (): void => {\n if (cleaned) return;\n cleaned = true;\n removeLoadingEnd();\n removeRefresh();\n window.removeEventListener('pagehide', onPageHide);\n };\n const onPageHide = (event: PageTransitionEvent): void => {\n if (!event.persisted) cleanup();\n };\n window.addEventListener('pagehide', onPageHide);\n return cleanup;\n}\n"],"mappings":"+BAkBO,ICaDA,EAAO,4BCLN,SAASC,EACdC,EACAC,GAEA,IAAIC,EAAiBF,EAAQG,QAAQC,aAAaC,MAAMC,SAIxD,MAAMC,EAAmBP,EAAQQ,KAAK,mBAAoB,KACxD,MAAMC,EAAQT,EAAQG,QAAQC,aAAaC,MAAMC,SAC7CG,IAAUP,IACdA,EAAiBO,EACjBC,SAASC,cAAc,IAAIC,MFpBQ,uCEsB/BC,EDKD,SAASC,qBAAqBC,GACnC,MAAMC,EAVmB,oBAAXC,YAAyB,EAAaA,OAWpD,YAAe,IAAXD,EAA6B,QACjCA,EAAOlB,GAAQiB,EACR,KAGDC,EAAOlB,KAAUiB,IAASC,EAAOlB,QAAQ,IAEjD,CCdwBgB,CAAqBI,gBACnCjB,UACAkB,MAGR,IAAIC,GAAU,EACd,MAAMC,EAAU,KACVD,IACJA,GAAU,EACVb,IACAM,IACAI,OAAOK,oBAAoB,WAAYC,KAEnCA,EAAcC,IACbA,EAAMC,WAAWJ,KAGxB,OADAJ,OAAOS,iBAAiB,WAAYH,GAC7BF,CACT,Q","ignoreList":[]}
|