-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.next.js
80 lines (70 loc) · 2.31 KB
/
index.next.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import { component, pure } from 'riot'
import { cleanNode } from '@riotjs/util/dom'
// this object will contain all the components implementations lazy loaded
const cache = new WeakMap()
// expose the cache as static property
lazy.cache = cache
// static attribute in case we want to just export a lazy riot component
lazy.export = function lazyExport(Loader, Component) {
// it could be that the user don't want to use a loader for whatever reason
const hasLoader = Loader && Component
const LazyComponent = hasLoader ? Component : Loader
const load = () =>
typeof LazyComponent === 'function'
? LazyComponent()
: Promise.resolve(LazyComponent)
const cachedComponent = cache.get(LazyComponent)
return pure(({ slots, attributes, props }) => ({
mount(el, parentScope) {
this.el = el
this.isMounted = true
const mount = () => {
this.mountLazyComponent(parentScope)
this.el.dispatchEvent(new Event('load'))
}
if (cachedComponent) {
mount()
} else {
if (hasLoader) this.createManagedComponent(Loader, parentScope)
load().then((data) => {
cache.set(LazyComponent, data.default || data)
mount()
})
}
},
createManagedComponent(Child, parentScope) {
this.component = component(Child)(this.el, props, {
attributes,
slots,
parentScope,
})
},
mountLazyComponent(parentScope) {
// if this component was unmounted just return here
if (!this.isMounted) return
// unmount the loader if it was previously created
if (this.component) {
// unmount the bindings (keeping the root node)
this.component.unmount(true)
// clean the DOM
if (this.el.children.length) cleanNode(this.el)
}
// replace the old component instance with the new lazy loaded component
this.createManagedComponent(cache.get(LazyComponent), parentScope)
},
update(parentScope) {
if (this.isMounted && this.component)
this.component.update({}, parentScope)
},
unmount(...args) {
this.isMounted = false
if (this.component) this.component.unmount(...args)
},
}))
}
export default function lazy(Loader, Component) {
return {
name: 'lazy',
exports: lazy.export(Loader, Component),
}
}