@slidev/client 52.11.5 → 52.12.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,83 @@
1
+ import type { SlideRoute } from '@slidev/types'
2
+ import type { ComputedRef, Ref } from 'vue'
3
+ import configs from '#slidev/configs'
4
+ import { watchEffect } from 'vue'
5
+
6
+ const loaded = new Set<string>()
7
+ const loading = new Set<string>()
8
+
9
+ function resolveUrl(url: string): string {
10
+ if (url.startsWith('http') || url.startsWith('//'))
11
+ return url
12
+ const base = (import.meta.env.BASE_URL || '/').replace(/\/$/, '')
13
+ return `${base}${url.startsWith('/') ? url : `/${url}`}`
14
+ }
15
+
16
+ function preloadImage(url: string): void {
17
+ const resolved = resolveUrl(url)
18
+ if (loaded.has(resolved) || loading.has(resolved))
19
+ return
20
+ loading.add(resolved)
21
+ const img = new Image()
22
+ img.onload = () => {
23
+ loading.delete(resolved)
24
+ loaded.add(resolved)
25
+ }
26
+ img.onerror = () => {
27
+ loading.delete(resolved)
28
+ }
29
+ img.src = resolved
30
+ }
31
+
32
+ function preloadSlideImages(route: SlideRoute): void {
33
+ const images = route.meta?.slide?.images
34
+ if (images?.length) {
35
+ for (const url of images)
36
+ preloadImage(url)
37
+ }
38
+ }
39
+
40
+ export function usePreloadImages(
41
+ currentRoute: ComputedRef<SlideRoute>,
42
+ prevRoute: ComputedRef<SlideRoute>,
43
+ nextRoute: ComputedRef<SlideRoute>,
44
+ slides: Ref<SlideRoute[]>,
45
+ ): void {
46
+ const config = configs.preloadImages
47
+ if (config === false)
48
+ return
49
+
50
+ const ahead = (typeof config === 'object' && config?.ahead) || 3
51
+
52
+ // Preload current + prev + next + look-ahead window
53
+ watchEffect(() => {
54
+ const current = currentRoute.value
55
+ const all = slides.value
56
+ if (!current || !all?.length)
57
+ return
58
+
59
+ preloadSlideImages(current)
60
+ preloadSlideImages(prevRoute.value)
61
+ preloadSlideImages(nextRoute.value)
62
+
63
+ // Preload ahead window
64
+ const currentIdx = current.no - 1
65
+ for (let i = 1; i <= ahead; i++) {
66
+ const idx = currentIdx + i
67
+ if (idx < all.length)
68
+ preloadSlideImages(all[idx])
69
+ }
70
+ })
71
+
72
+ // Preload all remaining slides after 3s
73
+ watchEffect((onCleanup) => {
74
+ const all = slides.value
75
+ const timeout = setTimeout(() => {
76
+ if (all?.length) {
77
+ for (const route of all)
78
+ preloadSlideImages(route)
79
+ }
80
+ }, 3000)
81
+ onCleanup(() => clearTimeout(timeout))
82
+ })
83
+ }
package/constants.ts CHANGED
@@ -87,4 +87,5 @@ export const HEADMATTER_FIELDS = [
87
87
  'seoMeta',
88
88
  'notesAutoRuby',
89
89
  'magicMoveDuration',
90
+ 'preloadImages',
90
91
  ]
@@ -5,6 +5,7 @@ import { recomputeAllPoppers } from 'floating-vue'
5
5
  import { computed, shallowRef, TransitionGroup, watchEffect } from 'vue'
6
6
  import { createFixedClicks } from '../composables/useClicks'
7
7
  import { useNav } from '../composables/useNav'
8
+ import { usePreloadImages } from '../composables/usePreloadImages'
8
9
  import { useViewTransition } from '../composables/useViewTransition'
9
10
  import { CLICKS_MAX } from '../constants'
10
11
  import { activeDragElement, disableTransition, hmrSkipTransition } from '../state'
@@ -49,6 +50,9 @@ watchEffect((onCleanup) => {
49
50
  onCleanup(() => clearTimeout(timeout))
50
51
  })
51
52
 
53
+ // preload images for nearby slides
54
+ usePreloadImages(currentSlideRoute, prevRoute, nextRoute, slides)
55
+
52
56
  const hasViewTransition = useViewTransition()
53
57
 
54
58
  const DrawingLayer = shallowRef<any>()
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@slidev/client",
3
3
  "type": "module",
4
- "version": "52.11.5",
4
+ "version": "52.12.0",
5
5
  "description": "Presentation slides for developers",
6
6
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",
@@ -61,8 +61,8 @@
61
61
  "vue": "^3.5.27",
62
62
  "vue-router": "^4.6.4",
63
63
  "yaml": "^2.8.2",
64
- "@slidev/types": "52.11.5",
65
- "@slidev/parser": "52.11.5"
64
+ "@slidev/parser": "52.12.0",
65
+ "@slidev/types": "52.12.0"
66
66
  },
67
67
  "devDependencies": {
68
68
  "vite": "^7.3.1"