-
Notifications
You must be signed in to change notification settings - Fork 5
/
index.js
89 lines (74 loc) · 1.95 KB
/
index.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
81
82
83
84
85
86
87
88
89
var parallel = require('run-parallel')
var IDLE = 0
var LOADING = 1
var LOADED = 2
module.exports = function () {
var loaders = []
// Store these for `loadAll()`
var _state, _emit
store.storeName = 'choo-lazy-route'
function store (state, emitter, _app) {
_state = state
_emit = emitter.emit
}
function route (load) {
var view = null
var loadingState = IDLE
var promise = null
function doLoad (state, emit) {
if (loadingState === LOADING) return promise
var route = state.route
emit('lazy-route:load', route)
loadingState = LOADING
promise = new Promise(function (resolve, reject) {
var p = load(function (err, _view) {
if (err) {
loadingState = IDLE
return reject(err)
}
emit('lazy-route:loaded', route, _view)
loadingState = LOADED
view = _view
resolve()
})
if (p && p.then) p.then(resolve, reject)
})
if (state._experimental_prefetch) {
state._experimental_prefetch.push(promise)
}
return promise
}
loaders.push(doLoad)
return function (state, emit) {
// already loaded
if (view) {
return view(state, emit)
}
// Did not start loading
if (!promise) {
doLoad(state, emit).catch(function (err) {
emit('error', err)
})
}
// TODO custom loading views
var str = new String('<body></body>') // eslint-disable-line no-new-wrappers
str.__encoded = true
return str
}
}
function loadAll (cb) {
var promises = loaders.map(function (load) {
return load(_state, _emit)
})
return Promise.all(promises).then(cb.bind(null, null), cb)
}
function lazy (a, b, c) {
if (arguments.length === 3) return store(a, b, c)
return route(a)
}
lazy.store = store
lazy.storeName = store.storeName
lazy.route = route
lazy.all = loadAll
return lazy
}