crelte 0.1.2 → 0.2.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/dist/CrelteRequest.d.ts +11 -6
- package/dist/CrelteRequest.d.ts.map +1 -1
- package/dist/CrelteRequest.js +14 -14
- package/dist/graphql/GraphQl.d.ts +1 -1
- package/dist/graphql/GraphQl.d.ts.map +1 -1
- package/dist/graphql/GraphQl.js +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/init/client.d.ts.map +1 -1
- package/dist/init/client.js +5 -5
- package/dist/init/server.d.ts +2 -0
- package/dist/init/server.d.ts.map +1 -1
- package/dist/init/server.js +24 -10
- package/dist/init/shared.d.ts +3 -3
- package/dist/init/shared.d.ts.map +1 -1
- package/dist/init/shared.js +1 -1
- package/dist/loadData/index.d.ts +11 -5
- package/dist/loadData/index.d.ts.map +1 -1
- package/dist/loadData/index.js +15 -6
- package/dist/routing/History.d.ts +5 -3
- package/dist/routing/History.d.ts.map +1 -1
- package/dist/routing/History.js +9 -4
- package/dist/routing/InnerRouter.d.ts +13 -9
- package/dist/routing/InnerRouter.d.ts.map +1 -1
- package/dist/routing/InnerRouter.js +30 -35
- package/dist/routing/PageLoader.d.ts +4 -5
- package/dist/routing/PageLoader.d.ts.map +1 -1
- package/dist/routing/PageLoader.js +5 -5
- package/dist/routing/Request.d.ts +9 -2
- package/dist/routing/Request.d.ts.map +1 -1
- package/dist/routing/Request.js +16 -1
- package/dist/routing/Route.d.ts +25 -12
- package/dist/routing/Route.d.ts.map +1 -1
- package/dist/routing/Route.js +35 -14
- package/dist/routing/Router.d.ts +5 -7
- package/dist/routing/Router.d.ts.map +1 -1
- package/dist/routing/Router.js +26 -37
- package/dist/routing/Site.js +1 -1
- package/dist/routing/utils.d.ts +2 -0
- package/dist/routing/utils.d.ts.map +1 -0
- package/dist/routing/utils.js +3 -0
- package/package.json +3 -2
- package/src/CrelteRequest.ts +14 -19
- package/src/graphql/GraphQl.ts +5 -2
- package/src/index.ts +17 -3
- package/src/init/client.ts +5 -10
- package/src/init/server.ts +31 -11
- package/src/init/shared.ts +4 -4
- package/src/loadData/index.ts +47 -15
- package/src/routing/History.ts +12 -5
- package/src/routing/InnerRouter.ts +42 -39
- package/src/routing/PageLoader.ts +7 -17
- package/src/routing/Request.ts +20 -6
- package/src/routing/Route.ts +40 -16
- package/src/routing/Router.ts +33 -46
- package/src/routing/Site.ts +1 -1
- package/src/routing/utils.ts +3 -0
|
@@ -7,8 +7,13 @@ import Route from './Route.js';
|
|
|
7
7
|
*/
|
|
8
8
|
export default class InnerRouter {
|
|
9
9
|
sites;
|
|
10
|
+
/**
|
|
11
|
+
* The current route
|
|
12
|
+
*
|
|
13
|
+
* ## Null
|
|
14
|
+
* It might be null on the first targetToRequest, open, and routeFromUrl call
|
|
15
|
+
*/
|
|
10
16
|
route;
|
|
11
|
-
site;
|
|
12
17
|
history;
|
|
13
18
|
preloadOnMouseOver;
|
|
14
19
|
/**
|
|
@@ -27,7 +32,6 @@ export default class InnerRouter {
|
|
|
27
32
|
constructor(sites, opts) {
|
|
28
33
|
this.sites = sites.map(s => new Site(s));
|
|
29
34
|
this.route = null;
|
|
30
|
-
this.site = this.defaultSite();
|
|
31
35
|
// @ts-ignore
|
|
32
36
|
this.history = import.meta.env.SSR
|
|
33
37
|
? new ServerHistory()
|
|
@@ -44,14 +48,14 @@ export default class InnerRouter {
|
|
|
44
48
|
initClient() {
|
|
45
49
|
this.listen();
|
|
46
50
|
// let's first try to load from the state
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (
|
|
51
|
-
|
|
51
|
+
const req = this.targetToRequest(window.location.href);
|
|
52
|
+
req._fillFromState(window.history.state);
|
|
53
|
+
req.origin = 'init';
|
|
54
|
+
if (req.search.get('x-craft-live-preview')) {
|
|
55
|
+
req.origin = 'live-preview-init';
|
|
52
56
|
}
|
|
53
57
|
window.history.scrollRestoration = 'manual';
|
|
54
|
-
this.open(
|
|
58
|
+
this.open(req, {}, false);
|
|
55
59
|
}
|
|
56
60
|
/**
|
|
57
61
|
* Initializes the router when running on the server.
|
|
@@ -60,8 +64,7 @@ export default class InnerRouter {
|
|
|
60
64
|
/**
|
|
61
65
|
* Get a site and if possible use the accept lang header.
|
|
62
66
|
*
|
|
63
|
-
* @param
|
|
64
|
-
* @return {Site}
|
|
67
|
+
* @param acceptLang Accept Language header.
|
|
65
68
|
*/
|
|
66
69
|
siteByAcceptLang(acceptLang = null) {
|
|
67
70
|
if (!acceptLang)
|
|
@@ -102,7 +105,7 @@ export default class InnerRouter {
|
|
|
102
105
|
* Get the default site
|
|
103
106
|
*/
|
|
104
107
|
defaultSite() {
|
|
105
|
-
return this.sites[0];
|
|
108
|
+
return this.sites.find(s => s.primary) ?? this.sites[0];
|
|
106
109
|
}
|
|
107
110
|
/**
|
|
108
111
|
* Tries to get a site by it's id
|
|
@@ -116,10 +119,12 @@ export default class InnerRouter {
|
|
|
116
119
|
* @param target
|
|
117
120
|
* @return Returns null if the url does not match our host (the protocol get's ignored)
|
|
118
121
|
*/
|
|
119
|
-
targetToRequest(target) {
|
|
122
|
+
targetToRequest(target, opts = {}) {
|
|
120
123
|
if (typeof target === 'string') {
|
|
121
124
|
if (target.startsWith('/')) {
|
|
122
|
-
|
|
125
|
+
// todo should we use the language matching or throw if the route does not
|
|
126
|
+
// exists
|
|
127
|
+
const site = this.route?.site ?? this.defaultSite();
|
|
123
128
|
target = new URL(site.uri + target, site.url);
|
|
124
129
|
}
|
|
125
130
|
else {
|
|
@@ -130,8 +135,9 @@ export default class InnerRouter {
|
|
|
130
135
|
target = this.routeFromUrl(target);
|
|
131
136
|
}
|
|
132
137
|
if (!isRequest(target)) {
|
|
133
|
-
return Request.fromRoute(target);
|
|
138
|
+
return Request.fromRoute(target, opts);
|
|
134
139
|
}
|
|
140
|
+
target._updateOpts(opts);
|
|
135
141
|
return target;
|
|
136
142
|
}
|
|
137
143
|
/**
|
|
@@ -161,7 +167,9 @@ export default class InnerRouter {
|
|
|
161
167
|
continue;
|
|
162
168
|
site = s;
|
|
163
169
|
}
|
|
164
|
-
|
|
170
|
+
// todo should we throw if we can't find a site
|
|
171
|
+
// or use the site which matches the language
|
|
172
|
+
route.site = site ?? this.defaultSite();
|
|
165
173
|
return route;
|
|
166
174
|
}
|
|
167
175
|
listen() {
|
|
@@ -239,7 +247,7 @@ export default class InnerRouter {
|
|
|
239
247
|
// for the scrollY in our open call so we just clear the current
|
|
240
248
|
// route since it is now already the new route
|
|
241
249
|
this.route = null;
|
|
242
|
-
this.open(route, false);
|
|
250
|
+
this.open(route, {}, false);
|
|
243
251
|
});
|
|
244
252
|
}
|
|
245
253
|
/**
|
|
@@ -248,8 +256,8 @@ export default class InnerRouter {
|
|
|
248
256
|
* @param route a route object or an url or uri, never input the same route object again
|
|
249
257
|
* @param pushState if true pushed the state to the window.history
|
|
250
258
|
*/
|
|
251
|
-
open(target, pushState = true) {
|
|
252
|
-
const req = this.targetToRequest(target);
|
|
259
|
+
open(target, opts = {}, pushState = true) {
|
|
260
|
+
const req = this.targetToRequest(target, opts);
|
|
253
261
|
const current = this.route;
|
|
254
262
|
if (current) {
|
|
255
263
|
// if the scrollY would still be updated we clear the timeout
|
|
@@ -270,12 +278,12 @@ export default class InnerRouter {
|
|
|
270
278
|
if ((current && current.url.origin !== req.url.origin) ||
|
|
271
279
|
// @ts-ignore
|
|
272
280
|
import.meta.env.SSR) {
|
|
273
|
-
this.history.open(req
|
|
281
|
+
this.history.open(req);
|
|
274
282
|
return;
|
|
275
283
|
}
|
|
276
284
|
if (pushState) {
|
|
277
285
|
req.index = (current?.index ?? 0) + 1;
|
|
278
|
-
this.onRoute(req,
|
|
286
|
+
this.onRoute(req, () => {
|
|
279
287
|
this.pushState(req.toRoute());
|
|
280
288
|
});
|
|
281
289
|
}
|
|
@@ -293,9 +301,7 @@ export default class InnerRouter {
|
|
|
293
301
|
*/
|
|
294
302
|
setRoute(req) {
|
|
295
303
|
this.route = req.toRoute();
|
|
296
|
-
|
|
297
|
-
this.site = req.site;
|
|
298
|
-
this.onRoute(req, this.site, () => { });
|
|
304
|
+
this.onRoute(req, () => { });
|
|
299
305
|
}
|
|
300
306
|
/**
|
|
301
307
|
* This pushes the state of the route without triggering a currentRoute
|
|
@@ -310,8 +316,6 @@ export default class InnerRouter {
|
|
|
310
316
|
const url = route.url;
|
|
311
317
|
this.history.pushState(route._toState(), url.pathname + url.search + url.hash);
|
|
312
318
|
this.route = route;
|
|
313
|
-
if (route.site)
|
|
314
|
-
this.site = route.site;
|
|
315
319
|
}
|
|
316
320
|
/**
|
|
317
321
|
* This replaces the state of the route without triggering a currentRoute
|
|
@@ -323,8 +327,6 @@ export default class InnerRouter {
|
|
|
323
327
|
const url = route.url;
|
|
324
328
|
this.history.replaceState(route._toState(), url.pathname + url.search + url.hash);
|
|
325
329
|
this.route = route;
|
|
326
|
-
if (route.site)
|
|
327
|
-
this.site = route.site;
|
|
328
330
|
}
|
|
329
331
|
/**
|
|
330
332
|
* Preload a url
|
|
@@ -335,18 +337,11 @@ export default class InnerRouter {
|
|
|
335
337
|
*/
|
|
336
338
|
preload(target) {
|
|
337
339
|
const req = this.targetToRequest(target);
|
|
338
|
-
// todo, don't think this makes any sense
|
|
339
|
-
// if the domain of the current site is different than the domain of the
|
|
340
|
-
// new site id does not make sense to preload
|
|
341
|
-
if (this.site.url.origin !== req.url.origin) {
|
|
342
|
-
return;
|
|
343
|
-
}
|
|
344
340
|
const current = this.route;
|
|
345
|
-
const site = req.site ?? this.site;
|
|
346
341
|
// if the origin matches, the route will be able to be load
|
|
347
342
|
// so let's preload it
|
|
348
343
|
if (current && current.url.origin === req.url.origin) {
|
|
349
|
-
this.onPreload(req
|
|
344
|
+
this.onPreload(req);
|
|
350
345
|
}
|
|
351
346
|
}
|
|
352
347
|
domReady(req) {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import Request from './Request.js';
|
|
2
|
-
import Site from './Site.js';
|
|
3
2
|
export type PageLoaderOptions = {
|
|
4
3
|
debugTiming: boolean;
|
|
5
4
|
};
|
|
@@ -7,7 +6,7 @@ export type LoadResponse = {
|
|
|
7
6
|
success: boolean;
|
|
8
7
|
data: any;
|
|
9
8
|
};
|
|
10
|
-
export type LoadFn = (req: Request,
|
|
9
|
+
export type LoadFn = (req: Request, opts: LoadOptions) => Promise<any> | any;
|
|
11
10
|
export type LoadOptions = {
|
|
12
11
|
setProgress: (num: number) => void;
|
|
13
12
|
};
|
|
@@ -18,7 +17,7 @@ export default class PageLoader<More> {
|
|
|
18
17
|
private debugTiming;
|
|
19
18
|
private preloadedUrls;
|
|
20
19
|
private loadingVersion;
|
|
21
|
-
onLoaded: (resp: LoadResponse, req: Request,
|
|
20
|
+
onLoaded: (resp: LoadResponse, req: Request, more: More) => void;
|
|
22
21
|
onProgress: (loading: boolean, progress?: number) => void;
|
|
23
22
|
loadFn: LoadFn;
|
|
24
23
|
/**
|
|
@@ -31,7 +30,7 @@ export default class PageLoader<More> {
|
|
|
31
30
|
* Discard the current page load if one is happening
|
|
32
31
|
*/
|
|
33
32
|
discard(): void;
|
|
34
|
-
load(req: Request,
|
|
35
|
-
preload(req: Request
|
|
33
|
+
load(req: Request, more: More): Promise<void>;
|
|
34
|
+
preload(req: Request): Promise<void>;
|
|
36
35
|
}
|
|
37
36
|
//# sourceMappingURL=PageLoader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PageLoader.d.ts","sourceRoot":"","sources":["../../../../src/routing/PageLoader.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"PageLoader.d.ts","sourceRoot":"","sources":["../../../../src/routing/PageLoader.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,cAAc,CAAC;AAEnC,MAAM,MAAM,iBAAiB,GAAG;IAC/B,WAAW,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,GAAG,CAAC;CACV,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;AAE7E,MAAM,MAAM,WAAW,GAAG;IACzB,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,UAAU,CAAC,IAAI;IACnC,OAAO,CAAC,WAAW,CAAU;IAC7B,OAAO,CAAC,aAAa,CAAc;IAEnC,OAAO,CAAC,cAAc,CAAS;IAE/B,QAAQ,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACjE,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D,MAAM,EAAE,MAAM,CAAC;IAEf;;;;OAIG;gBACS,OAAO,EAAE,iBAAiB;IAWtC;;OAEG;IACH,OAAO;IAKD,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI;IAiC7B,OAAO,CAAC,GAAG,EAAE,OAAO;CAc1B"}
|
|
@@ -28,7 +28,7 @@ export default class PageLoader {
|
|
|
28
28
|
this.loadingVersion++;
|
|
29
29
|
this.onProgress(false);
|
|
30
30
|
}
|
|
31
|
-
async load(req,
|
|
31
|
+
async load(req, more) {
|
|
32
32
|
this.onProgress(true);
|
|
33
33
|
const version = ++this.loadingVersion;
|
|
34
34
|
const startTime = this.debugTiming ? Date.now() : null;
|
|
@@ -39,7 +39,7 @@ export default class PageLoader {
|
|
|
39
39
|
};
|
|
40
40
|
const resp = { success: false, data: null };
|
|
41
41
|
try {
|
|
42
|
-
resp.data = await this.loadFn(req,
|
|
42
|
+
resp.data = await this.loadFn(req, { setProgress });
|
|
43
43
|
resp.success = true;
|
|
44
44
|
}
|
|
45
45
|
catch (e) {
|
|
@@ -52,16 +52,16 @@ export default class PageLoader {
|
|
|
52
52
|
if (this.loadingVersion !== version)
|
|
53
53
|
return console.log('route changed quickly, ignoring response');
|
|
54
54
|
this.onProgress(false);
|
|
55
|
-
this.onLoaded(resp, req,
|
|
55
|
+
this.onLoaded(resp, req, more);
|
|
56
56
|
}
|
|
57
57
|
// you don't need to wait on this call
|
|
58
|
-
async preload(req
|
|
58
|
+
async preload(req) {
|
|
59
59
|
const url = req.url.origin + req.url.pathname;
|
|
60
60
|
if (this.preloadedUrls.has(url))
|
|
61
61
|
return;
|
|
62
62
|
this.preloadedUrls.add(url);
|
|
63
63
|
try {
|
|
64
|
-
await this.loadFn(req,
|
|
64
|
+
await this.loadFn(req, { setProgress: () => null });
|
|
65
65
|
}
|
|
66
66
|
catch (_e) {
|
|
67
67
|
console.log('preload failed');
|
|
@@ -9,6 +9,7 @@ export type RequestOptions = {
|
|
|
9
9
|
index?: number;
|
|
10
10
|
origin?: RouteOrigin;
|
|
11
11
|
disableScroll?: boolean;
|
|
12
|
+
statusCode?: number;
|
|
12
13
|
};
|
|
13
14
|
/**
|
|
14
15
|
* A Request is a Route with some extra options
|
|
@@ -21,16 +22,20 @@ export default class Request extends Route {
|
|
|
21
22
|
* @default false
|
|
22
23
|
*/
|
|
23
24
|
disableScroll: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* The Status code that should be returned for a redirect
|
|
27
|
+
*/
|
|
28
|
+
statusCode: number | null;
|
|
24
29
|
/** @hidden */
|
|
25
30
|
_renderBarrier: RenderBarrier;
|
|
26
31
|
/**
|
|
27
32
|
* Create a new Request
|
|
28
33
|
*/
|
|
29
|
-
constructor(url: string | URL, site: Site
|
|
34
|
+
constructor(url: string | URL, site: Site, opts?: RequestOptions);
|
|
30
35
|
/**
|
|
31
36
|
* Create a Request from a Route
|
|
32
37
|
*/
|
|
33
|
-
static fromRoute(route: Route): Request;
|
|
38
|
+
static fromRoute(route: Route, opts?: RequestOptions): Request;
|
|
34
39
|
/**
|
|
35
40
|
* With delayRender you can make sure that the render waits
|
|
36
41
|
* until you are ready. This is useful for building page transitions.
|
|
@@ -68,6 +73,8 @@ export default class Request extends Route {
|
|
|
68
73
|
* Create a Route from the Request
|
|
69
74
|
*/
|
|
70
75
|
toRoute(): Route;
|
|
76
|
+
/** @hidden */
|
|
77
|
+
_updateOpts(opts?: RequestOptions): void;
|
|
71
78
|
}
|
|
72
79
|
export declare function isRequest(req: any): req is Request;
|
|
73
80
|
declare class RenderBarrier {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Request.d.ts","sourceRoot":"","sources":["../../../../src/routing/Request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Request.d.ts","sourceRoot":"","sources":["../../../../src/routing/Request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,KAAK;IACzC;;;OAGG;IACH,aAAa,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAE1B,cAAc;IACd,cAAc,EAAE,aAAa,CAAC;IAE9B;;OAEG;gBACS,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,GAAE,cAAmB;IAQpE;;OAEG;IACH,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,GAAE,cAAmB;IASxD;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,WAAW,IAAI,WAAW;IAI1B;;OAEG;IACH,KAAK;IAUL;;OAEG;IACH,OAAO;IAQP,cAAc;IACd,WAAW,CAAC,IAAI,GAAE,cAAmB;CAOrC;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,OAAO,CAElD;AAED,cAAM,aAAa;IAClB,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,WAAW,CAAC;;IAQlB,MAAM,IAAI,OAAO;IAIjB,GAAG,IAAI,WAAW;IAclB,cAAc;IACd,MAAM;IAQN,cAAc;IACd,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;CAGzB;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACzB;;;;;OAKG;IACH,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAE9B;;OAEG;IACH,MAAM,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC"}
|
package/dist/routing/Request.js
CHANGED
|
@@ -11,6 +11,10 @@ export default class Request extends Route {
|
|
|
11
11
|
* @default false
|
|
12
12
|
*/
|
|
13
13
|
disableScroll;
|
|
14
|
+
/**
|
|
15
|
+
* The Status code that should be returned for a redirect
|
|
16
|
+
*/
|
|
17
|
+
statusCode;
|
|
14
18
|
/** @hidden */
|
|
15
19
|
_renderBarrier;
|
|
16
20
|
/**
|
|
@@ -19,16 +23,18 @@ export default class Request extends Route {
|
|
|
19
23
|
constructor(url, site, opts = {}) {
|
|
20
24
|
super(url, site, opts);
|
|
21
25
|
this.disableScroll = opts.disableScroll ?? false;
|
|
26
|
+
this.statusCode = opts.statusCode ?? null;
|
|
22
27
|
this._renderBarrier = new RenderBarrier();
|
|
23
28
|
}
|
|
24
29
|
/**
|
|
25
30
|
* Create a Request from a Route
|
|
26
31
|
*/
|
|
27
|
-
static fromRoute(route) {
|
|
32
|
+
static fromRoute(route, opts = {}) {
|
|
28
33
|
return new Request(route.url.href, route.site, {
|
|
29
34
|
scrollY: route.scrollY ?? undefined,
|
|
30
35
|
index: route.index,
|
|
31
36
|
origin: route.origin,
|
|
37
|
+
...opts,
|
|
32
38
|
});
|
|
33
39
|
}
|
|
34
40
|
/**
|
|
@@ -71,6 +77,7 @@ export default class Request extends Route {
|
|
|
71
77
|
index: this.index,
|
|
72
78
|
origin: this.origin,
|
|
73
79
|
disableScroll: this.disableScroll,
|
|
80
|
+
statusCode: this.statusCode ?? undefined,
|
|
74
81
|
});
|
|
75
82
|
}
|
|
76
83
|
/**
|
|
@@ -83,6 +90,14 @@ export default class Request extends Route {
|
|
|
83
90
|
origin: this.origin,
|
|
84
91
|
});
|
|
85
92
|
}
|
|
93
|
+
/** @hidden */
|
|
94
|
+
_updateOpts(opts = {}) {
|
|
95
|
+
this.scrollY = opts.scrollY ?? this.scrollY;
|
|
96
|
+
this.index = opts.index ?? this.index;
|
|
97
|
+
this.origin = opts.origin ?? this.origin;
|
|
98
|
+
this.disableScroll = opts.disableScroll ?? this.disableScroll;
|
|
99
|
+
this.statusCode = opts.statusCode ?? this.statusCode;
|
|
100
|
+
}
|
|
86
101
|
}
|
|
87
102
|
export function isRequest(req) {
|
|
88
103
|
return typeof req === 'object' && req !== null && req instanceof Request;
|
package/dist/routing/Route.d.ts
CHANGED
|
@@ -28,9 +28,16 @@ export default class Route {
|
|
|
28
28
|
*/
|
|
29
29
|
url: URL;
|
|
30
30
|
/**
|
|
31
|
-
* The site of the route
|
|
31
|
+
* The site of the route
|
|
32
|
+
*
|
|
33
|
+
* ## Note
|
|
34
|
+
* The site might not always match with the current route
|
|
35
|
+
* but be the site default site or one that matches the
|
|
36
|
+
* users language.
|
|
37
|
+
*
|
|
38
|
+
* If that is important call `route.siteMatches()` to verify
|
|
32
39
|
*/
|
|
33
|
-
site: Site
|
|
40
|
+
site: Site;
|
|
34
41
|
/**
|
|
35
42
|
* The scroll position of the current route
|
|
36
43
|
*/
|
|
@@ -47,7 +54,7 @@ export default class Route {
|
|
|
47
54
|
/**
|
|
48
55
|
* Creates a new Route
|
|
49
56
|
*/
|
|
50
|
-
constructor(url: string | URL, site: Site
|
|
57
|
+
constructor(url: string | URL, site: Site, opts?: RouteOptions);
|
|
51
58
|
/**
|
|
52
59
|
* Returns the uri of the route
|
|
53
60
|
*
|
|
@@ -55,12 +62,13 @@ export default class Route {
|
|
|
55
62
|
*
|
|
56
63
|
* ## Example
|
|
57
64
|
* ```
|
|
58
|
-
* const
|
|
59
|
-
*
|
|
65
|
+
* const site = _; // site with url https://example.com/fo
|
|
66
|
+
* const route = new Route('https://example.com/foo/bar/', site);
|
|
67
|
+
* console.log(route.uri); // '/bar'
|
|
60
68
|
*
|
|
61
|
-
* const
|
|
62
|
-
* const route2 = new Route('https://example.com/foo/bar/?a=1',
|
|
63
|
-
* console.log(route2.uri); // '/bar'
|
|
69
|
+
* const site2 = _; // site with url https://example.com/other
|
|
70
|
+
* const route2 = new Route('https://example.com/foo/bar/?a=1', site2);
|
|
71
|
+
* console.log(route2.uri); // '/foo/bar'
|
|
64
72
|
* ```
|
|
65
73
|
*/
|
|
66
74
|
get uri(): string;
|
|
@@ -71,12 +79,13 @@ export default class Route {
|
|
|
71
79
|
*
|
|
72
80
|
* ## Example
|
|
73
81
|
* ```
|
|
82
|
+
* const site = _; // site with url https://example.com/foo
|
|
74
83
|
* const route = new Route('https://example.com/foo/bar/', null);
|
|
75
|
-
* console.log(route.baseUrl); // 'https://example.com'
|
|
84
|
+
* console.log(route.baseUrl); // 'https://example.com/foo'
|
|
76
85
|
*
|
|
77
|
-
* const
|
|
78
|
-
* const route2 = new Route('https://example.com/foo/bar/',
|
|
79
|
-
* console.log(route2.baseUrl); // 'https://example.com
|
|
86
|
+
* const site2 = _; // site with url https://example.com/other
|
|
87
|
+
* const route2 = new Route('https://example.com/foo/bar/', site2);
|
|
88
|
+
* console.log(route2.baseUrl); // 'https://example.com'
|
|
80
89
|
* ```
|
|
81
90
|
*/
|
|
82
91
|
get baseUrl(): string;
|
|
@@ -103,6 +112,10 @@ export default class Route {
|
|
|
103
112
|
* ```
|
|
104
113
|
*/
|
|
105
114
|
get hash(): string;
|
|
115
|
+
/**
|
|
116
|
+
* Returns if the site matches the url
|
|
117
|
+
*/
|
|
118
|
+
siteMatches(): boolean;
|
|
106
119
|
/**
|
|
107
120
|
* Checks if the route is equal to another route
|
|
108
121
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Route.d.ts","sourceRoot":"","sources":["../../../../src/routing/Route.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Route.d.ts","sourceRoot":"","sources":["../../../../src/routing/Route.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,MAAM,MAAM,YAAY,GAAG;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,MAAM,WAAW,GACpB,MAAM,GACN,mBAAmB,GACnB,QAAQ,GACR,OAAO,GACP,KAAK,CAAC;AAET;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,OAAO,KAAK;IACzB;;OAEG;IACH,GAAG,EAAE,GAAG,CAAC;IAET;;;;;;;;;OASG;IACH,IAAI,EAAE,IAAI,CAAC;IAEX;;OAEG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvB;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,MAAM,EAAE,WAAW,CAAC;IAEpB;;OAEG;gBACS,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,GAAE,YAAiB;IASlE;;;;;;;;;;;;;;;OAeG;IACH,IAAI,GAAG,IAAI,MAAM,CAQhB;IAED;;;;;;;;;;;;;;;OAeG;IACH,IAAI,OAAO,IAAI,MAAM,CAIpB;IAED;;;;;;;;;;;OAWG;IACH,IAAI,MAAM,IAAI,eAAe,CAE5B;IAED;;;;;;;;OAQG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;OAEG;IACH,WAAW,IAAI,OAAO;IAatB;;;;;OAKG;IACH,EAAE,CAAC,KAAK,EAAE,KAAK;IAwBf;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;;;;;;;OAQG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAI1C;;;;;;;;;;;;OAYG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAQ1D;;OAEG;IACH,KAAK;IAQL,cAAc;IACd,cAAc,CAAC,KAAK,EAAE,GAAG;IAQzB,cAAc;IACd,QAAQ,IAAI,GAAG;CAQf"}
|
package/dist/routing/Route.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { trimSlashEnd } from './
|
|
1
|
+
import { trimSlashEnd } from './utils.js';
|
|
2
2
|
/**
|
|
3
3
|
* A Route contains information about the current page for example the url and
|
|
4
4
|
* the site id
|
|
@@ -12,7 +12,14 @@ export default class Route {
|
|
|
12
12
|
*/
|
|
13
13
|
url;
|
|
14
14
|
/**
|
|
15
|
-
* The site of the route
|
|
15
|
+
* The site of the route
|
|
16
|
+
*
|
|
17
|
+
* ## Note
|
|
18
|
+
* The site might not always match with the current route
|
|
19
|
+
* but be the site default site or one that matches the
|
|
20
|
+
* users language.
|
|
21
|
+
*
|
|
22
|
+
* If that is important call `route.siteMatches()` to verify
|
|
16
23
|
*/
|
|
17
24
|
site;
|
|
18
25
|
/**
|
|
@@ -45,17 +52,17 @@ export default class Route {
|
|
|
45
52
|
*
|
|
46
53
|
* ## Example
|
|
47
54
|
* ```
|
|
48
|
-
* const
|
|
49
|
-
*
|
|
55
|
+
* const site = _; // site with url https://example.com/fo
|
|
56
|
+
* const route = new Route('https://example.com/foo/bar/', site);
|
|
57
|
+
* console.log(route.uri); // '/bar'
|
|
50
58
|
*
|
|
51
|
-
* const
|
|
52
|
-
* const route2 = new Route('https://example.com/foo/bar/?a=1',
|
|
53
|
-
* console.log(route2.uri); // '/bar'
|
|
59
|
+
* const site2 = _; // site with url https://example.com/other
|
|
60
|
+
* const route2 = new Route('https://example.com/foo/bar/?a=1', site2);
|
|
61
|
+
* console.log(route2.uri); // '/foo/bar'
|
|
54
62
|
* ```
|
|
55
63
|
*/
|
|
56
64
|
get uri() {
|
|
57
|
-
|
|
58
|
-
if (this.site) {
|
|
65
|
+
if (this.siteMatches()) {
|
|
59
66
|
return trimSlashEnd(this.url.pathname.substring(this.site.uri.length));
|
|
60
67
|
}
|
|
61
68
|
return trimSlashEnd(this.url.pathname);
|
|
@@ -67,16 +74,17 @@ export default class Route {
|
|
|
67
74
|
*
|
|
68
75
|
* ## Example
|
|
69
76
|
* ```
|
|
77
|
+
* const site = _; // site with url https://example.com/foo
|
|
70
78
|
* const route = new Route('https://example.com/foo/bar/', null);
|
|
71
|
-
* console.log(route.baseUrl); // 'https://example.com'
|
|
79
|
+
* console.log(route.baseUrl); // 'https://example.com/foo'
|
|
72
80
|
*
|
|
73
|
-
* const
|
|
74
|
-
* const route2 = new Route('https://example.com/foo/bar/',
|
|
75
|
-
* console.log(route2.baseUrl); // 'https://example.com
|
|
81
|
+
* const site2 = _; // site with url https://example.com/other
|
|
82
|
+
* const route2 = new Route('https://example.com/foo/bar/', site2);
|
|
83
|
+
* console.log(route2.baseUrl); // 'https://example.com'
|
|
76
84
|
* ```
|
|
77
85
|
*/
|
|
78
86
|
get baseUrl() {
|
|
79
|
-
if (this.
|
|
87
|
+
if (this.siteMatches())
|
|
80
88
|
return trimSlashEnd(this.site.url.href);
|
|
81
89
|
return this.url.origin;
|
|
82
90
|
}
|
|
@@ -107,6 +115,19 @@ export default class Route {
|
|
|
107
115
|
get hash() {
|
|
108
116
|
return this.url.hash;
|
|
109
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* Returns if the site matches the url
|
|
120
|
+
*/
|
|
121
|
+
siteMatches() {
|
|
122
|
+
if (this.url.origin !== this.site.url.origin)
|
|
123
|
+
return false;
|
|
124
|
+
// now we need to validate the pathname we should make sure both end with a slash
|
|
125
|
+
// todo can we do this better?
|
|
126
|
+
// make sure that urls like pathname: /abcbc and site: /abc don't match
|
|
127
|
+
return (this.url.pathname + '/').startsWith(
|
|
128
|
+
// uri never returns a slash at the end
|
|
129
|
+
this.site.uri + '/');
|
|
130
|
+
}
|
|
110
131
|
/**
|
|
111
132
|
* Checks if the route is equal to another route
|
|
112
133
|
*
|
package/dist/routing/Router.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import Route from './Route.js';
|
|
|
2
2
|
import Site, { SiteFromGraphQl } from './Site.js';
|
|
3
3
|
import { LoadFn } from './PageLoader.js';
|
|
4
4
|
import { Readable } from 'crelte-std/stores';
|
|
5
|
-
import Request from './Request.js';
|
|
5
|
+
import Request, { RequestOptions } from './Request.js';
|
|
6
6
|
export type RouterOptions = {
|
|
7
7
|
preloadOnMouseOver?: boolean;
|
|
8
8
|
debugTiming?: boolean;
|
|
@@ -11,7 +11,7 @@ export type RouterOptions = {
|
|
|
11
11
|
* internal only
|
|
12
12
|
*/
|
|
13
13
|
type Internal = {
|
|
14
|
-
onLoaded: (success: boolean, req: Request,
|
|
14
|
+
onLoaded: (success: boolean, req: Request, ready: () => any) => void;
|
|
15
15
|
onLoad: LoadFn;
|
|
16
16
|
domReady: (req: Request) => void;
|
|
17
17
|
initClient: () => void;
|
|
@@ -21,10 +21,8 @@ type ServerInited = {
|
|
|
21
21
|
success: boolean;
|
|
22
22
|
redirect: boolean;
|
|
23
23
|
req: Request;
|
|
24
|
-
site: Site;
|
|
25
24
|
props: any;
|
|
26
25
|
};
|
|
27
|
-
export declare function trimSlashEnd(str: string): string;
|
|
28
26
|
export default class Router {
|
|
29
27
|
/**
|
|
30
28
|
* The current route
|
|
@@ -89,7 +87,7 @@ export default class Router {
|
|
|
89
87
|
* // the following page will be opened https://example.com/de/foo/bar
|
|
90
88
|
* ```
|
|
91
89
|
*/
|
|
92
|
-
open(target: string | URL | Route): void;
|
|
90
|
+
open(target: string | URL | Route, opts?: RequestOptions): void;
|
|
93
91
|
/**
|
|
94
92
|
* This pushes the state of the route without triggering an event
|
|
95
93
|
*
|
|
@@ -147,7 +145,7 @@ export default class Router {
|
|
|
147
145
|
*
|
|
148
146
|
* @returns a function to remove the listener
|
|
149
147
|
*/
|
|
150
|
-
onRoute(fn: (route: Route
|
|
148
|
+
onRoute(fn: (route: Route) => void): () => void;
|
|
151
149
|
/**
|
|
152
150
|
* Add a listener for the onRequest event
|
|
153
151
|
*
|
|
@@ -155,7 +153,7 @@ export default class Router {
|
|
|
155
153
|
*
|
|
156
154
|
* @returns a function to remove the listener
|
|
157
155
|
*/
|
|
158
|
-
onRequest(fn: (req: Request
|
|
156
|
+
onRequest(fn: (req: Request) => void): () => void;
|
|
159
157
|
private setNewRoute;
|
|
160
158
|
private _initClient;
|
|
161
159
|
private _initServer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Router.d.ts","sourceRoot":"","sources":["../../../../src/routing/Router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAC;AAC/B,OAAO,IAAI,EAAE,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAElD,OAAmB,EAAE,MAAM,EAAgB,MAAM,iBAAiB,CAAC;AAEnE,OAAO,EAAE,QAAQ,EAAY,MAAM,mBAAmB,CAAC;AAEvD,OAAO,OAAO,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"Router.d.ts","sourceRoot":"","sources":["../../../../src/routing/Router.ts"],"names":[],"mappings":"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"}
|