@@ -3,6 +3,7 @@ import { Component, ComponentConstructor, Params, Query, Route, RouteData, Scrol
3
3
4
4
const manifest = typeof window !== 'undefined' && window . __SAPPER__ ;
5
5
6
+ export let App : ComponentConstructor ;
6
7
export let component : Component ;
7
8
let target : Node ;
8
9
let store : Store ;
@@ -27,10 +28,10 @@ function select_route(url: URL): Target {
27
28
if ( url . origin !== window . location . origin ) return null ;
28
29
if ( ! url . pathname . startsWith ( manifest . baseUrl ) ) return null ;
29
30
30
- const pathname = url . pathname . slice ( manifest . baseUrl . length ) ;
31
+ const path = url . pathname . slice ( manifest . baseUrl . length ) ;
31
32
32
33
for ( const route of routes ) {
33
- const match = route . pattern . exec ( pathname ) ;
34
+ const match = route . pattern . exec ( path ) ;
34
35
if ( match ) {
35
36
if ( route . ignore ) return null ;
36
37
@@ -43,19 +44,18 @@ function select_route(url: URL): Target {
43
44
query [ key ] = value || true ;
44
45
} )
45
46
}
46
- return { url, route, data : { params, query } } ;
47
+ return { url, route, props : { params, query, path } } ;
47
48
}
48
49
}
49
50
}
50
51
52
+ let first_load = true ;
51
53
let current_token : { } ;
52
54
53
- function render ( Component : ComponentConstructor , data : any , scroll : ScrollPosition , token : { } ) {
55
+ function render ( Page : ComponentConstructor , props : any , scroll : ScrollPosition , token : { } ) {
54
56
if ( current_token !== token ) return ;
55
57
56
- if ( component ) {
57
- component . destroy ( ) ;
58
- } else {
58
+ if ( first_load ) {
59
59
// first load — remove SSR'd <head> contents
60
60
const start = document . querySelector ( '#sapper-head-start' ) ;
61
61
const end = document . querySelector ( '#sapper-head-end' ) ;
@@ -65,33 +65,43 @@ function render(Component: ComponentConstructor, data: any, scroll: ScrollPositi
65
65
detach ( start ) ;
66
66
detach ( end ) ;
67
67
}
68
- }
69
68
70
- component = new Component ( {
71
- target,
72
- data,
73
- store,
74
- hydrate : ! component
75
- } ) ;
69
+ component = new App ( {
70
+ target,
71
+ data : {
72
+ Page,
73
+ props
74
+ } ,
75
+ store,
76
+ hydrate : true
77
+ } ) ;
78
+
79
+ first_load = false ;
80
+ } else {
81
+ component . set ( {
82
+ Page,
83
+ props
84
+ } ) ;
85
+ }
76
86
77
87
if ( scroll ) {
78
88
window . scrollTo ( scroll . x , scroll . y ) ;
79
89
}
80
90
}
81
91
82
- function prepare_route ( Component : ComponentConstructor , data : RouteData ) {
92
+ function prepare_route ( Page : ComponentConstructor , props : RouteData ) {
83
93
let redirect : { statusCode : number , location : string } = null ;
84
94
let error : { statusCode : number , message : Error | string } = null ;
85
95
86
- if ( ! Component . preload ) {
87
- return { Component , data , redirect, error } ;
96
+ if ( ! Page . preload ) {
97
+ return { Page , props , redirect, error } ;
88
98
}
89
99
90
100
if ( ! component && manifest . preloaded ) {
91
- return { Component , data : Object . assign ( data , manifest . preloaded ) , redirect, error } ;
101
+ return { Page , props : Object . assign ( props , manifest . preloaded ) , redirect, error } ;
92
102
}
93
103
94
- return Promise . resolve ( Component . preload . call ( {
104
+ return Promise . resolve ( Page . preload . call ( {
95
105
store,
96
106
fetch : ( url : string , opts ?: any ) => window . fetch ( url , opts ) ,
97
107
redirect : ( statusCode : number , location : string ) => {
@@ -100,23 +110,23 @@ function prepare_route(Component: ComponentConstructor, data: RouteData) {
100
110
error : ( statusCode : number , message : Error | string ) => {
101
111
error = { statusCode, message } ;
102
112
}
103
- } , data ) ) . catch ( err => {
113
+ } , props ) ) . catch ( err => {
104
114
error = { statusCode : 500 , message : err } ;
105
115
} ) . then ( preloaded => {
106
116
if ( error ) {
107
117
const route = error . statusCode >= 400 && error . statusCode < 500
108
118
? errors [ '4xx' ]
109
119
: errors [ '5xx' ] ;
110
120
111
- return route . load ( ) . then ( ( { default : Component } : { default : ComponentConstructor } ) => {
121
+ return route . load ( ) . then ( ( { default : Page } : { default : ComponentConstructor } ) => {
112
122
const err = error . message instanceof Error ? error . message : new Error ( error . message ) ;
113
- Object . assign ( data , { status : error . statusCode , error : err } ) ;
114
- return { Component , data , redirect : null } ;
123
+ Object . assign ( props , { status : error . statusCode , error : err } ) ;
124
+ return { Page , props , redirect : null } ;
115
125
} ) ;
116
126
}
117
127
118
- Object . assign ( data , preloaded )
119
- return { Component , data , redirect } ;
128
+ Object . assign ( props , preloaded )
129
+ return { Page , props , redirect } ;
120
130
} ) ;
121
131
}
122
132
@@ -136,18 +146,18 @@ function navigate(target: Target, id: number) {
136
146
137
147
const loaded = prefetching && prefetching . href === target . url . href ?
138
148
prefetching . promise :
139
- target . route . load ( ) . then ( mod => prepare_route ( mod . default , target . data ) ) ;
149
+ target . route . load ( ) . then ( mod => prepare_route ( mod . default , target . props ) ) ;
140
150
141
151
prefetching = null ;
142
152
143
153
const token = current_token = { } ;
144
154
145
- return loaded . then ( ( { Component , data , redirect } ) => {
155
+ return loaded . then ( ( { Page , props , redirect } ) => {
146
156
if ( redirect ) {
147
157
return goto ( redirect . location , { replaceState : true } ) ;
148
158
}
149
159
150
- render ( Component , data , scroll_history [ id ] , token ) ;
160
+ render ( Page , props , scroll_history [ id ] , token ) ;
151
161
} ) ;
152
162
}
153
163
@@ -208,7 +218,7 @@ function handle_popstate(event: PopStateEvent) {
208
218
209
219
let prefetching : {
210
220
href : string ;
211
- promise : Promise < { Component : ComponentConstructor , data : any } > ;
221
+ promise : Promise < { Page : ComponentConstructor , props : any } > ;
212
222
} = null ;
213
223
214
224
export function prefetch ( href : string ) {
@@ -217,7 +227,7 @@ export function prefetch(href: string) {
217
227
if ( selected && ( ! prefetching || href !== prefetching . href ) ) {
218
228
prefetching = {
219
229
href,
220
- promise : selected . route . load ( ) . then ( mod => prepare_route ( mod . default , selected . data ) )
230
+ promise : selected . route . load ( ) . then ( mod => prepare_route ( mod . default , selected . props ) )
221
231
} ;
222
232
}
223
233
}
@@ -240,12 +250,13 @@ function trigger_prefetch(event: MouseEvent | TouchEvent) {
240
250
241
251
let inited : boolean ;
242
252
243
- export function init ( _target : Node , _routes : Route [ ] , opts ?: { store ?: ( data : any ) => Store } ) {
244
- target = _target ;
245
- routes = _routes . filter ( r => ! r . error ) ;
253
+ export function init ( opts : { App : ComponentConstructor , target : Node , routes : Route [ ] , store ?: ( data : any ) => Store } ) {
254
+ App = opts . App ;
255
+ target = opts . target ;
256
+ routes = opts . routes . filter ( r => ! r . error ) ;
246
257
errors = {
247
- '4xx' : _routes . find ( r => r . error === '4xx' ) ,
248
- '5xx' : _routes . find ( r => r . error === '5xx' )
258
+ '4xx' : opts . routes . find ( r => r . error === '4xx' ) ,
259
+ '5xx' : opts . routes . find ( r => r . error === '5xx' )
249
260
} ;
250
261
251
262
if ( opts && opts . store ) {
0 commit comments