crelte 0.1.1 → 0.1.3

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.
Files changed (118) hide show
  1. package/dist/Crelte.d.ts +89 -25
  2. package/dist/Crelte.d.ts.map +1 -1
  3. package/dist/Crelte.js +79 -38
  4. package/dist/CrelteRequest.d.ts +63 -0
  5. package/dist/CrelteRequest.d.ts.map +1 -0
  6. package/dist/CrelteRequest.js +94 -0
  7. package/dist/blocks/Blocks.d.ts +27 -3
  8. package/dist/blocks/Blocks.d.ts.map +1 -1
  9. package/dist/blocks/Blocks.js +8 -0
  10. package/dist/blocks/Blocks.svelte +1 -1
  11. package/dist/blocks/Blocks.svelte.d.ts +36 -4
  12. package/dist/blocks/Blocks.svelte.d.ts.map +1 -1
  13. package/dist/blocks/index.d.ts +6 -3
  14. package/dist/blocks/index.d.ts.map +1 -1
  15. package/dist/blocks/index.js +3 -2
  16. package/dist/cookies/ServerCookies.d.ts +1 -1
  17. package/dist/cookies/ServerCookies.d.ts.map +1 -1
  18. package/dist/cookies/index.d.ts +7 -0
  19. package/dist/cookies/index.d.ts.map +1 -1
  20. package/dist/graphql/GraphQl.d.ts +53 -14
  21. package/dist/graphql/GraphQl.d.ts.map +1 -1
  22. package/dist/graphql/GraphQl.js +44 -23
  23. package/dist/graphql/index.d.ts +1 -1
  24. package/dist/graphql/index.d.ts.map +1 -1
  25. package/dist/graphql/index.js +2 -2
  26. package/dist/index.d.ts +55 -22
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +50 -23
  29. package/dist/init/client.d.ts +43 -2
  30. package/dist/init/client.d.ts.map +1 -1
  31. package/dist/init/client.js +26 -6
  32. package/dist/init/server.d.ts +49 -2
  33. package/dist/init/server.d.ts.map +1 -1
  34. package/dist/init/server.js +56 -6
  35. package/dist/init/shared.d.ts +5 -4
  36. package/dist/init/shared.d.ts.map +1 -1
  37. package/dist/init/shared.js +3 -3
  38. package/dist/loadData/Globals.d.ts +41 -2
  39. package/dist/loadData/Globals.d.ts.map +1 -1
  40. package/dist/loadData/Globals.js +33 -5
  41. package/dist/loadData/index.d.ts +74 -11
  42. package/dist/loadData/index.d.ts.map +1 -1
  43. package/dist/loadData/index.js +5 -8
  44. package/dist/plugins/Events.d.ts +18 -5
  45. package/dist/plugins/Events.d.ts.map +1 -1
  46. package/dist/plugins/Events.js +3 -0
  47. package/dist/plugins/Plugins.d.ts +28 -2
  48. package/dist/plugins/Plugins.d.ts.map +1 -1
  49. package/dist/plugins/Plugins.js +8 -0
  50. package/dist/routing/History.d.ts +3 -0
  51. package/dist/routing/History.d.ts.map +1 -1
  52. package/dist/routing/History.js +6 -0
  53. package/dist/routing/InnerRouter.d.ts +10 -9
  54. package/dist/routing/InnerRouter.d.ts.map +1 -1
  55. package/dist/routing/InnerRouter.js +41 -33
  56. package/dist/routing/PageLoader.d.ts +5 -5
  57. package/dist/routing/PageLoader.d.ts.map +1 -1
  58. package/dist/routing/PageLoader.js +7 -7
  59. package/dist/routing/Request.d.ts +102 -0
  60. package/dist/routing/Request.d.ts.map +1 -0
  61. package/dist/routing/Request.js +128 -0
  62. package/dist/routing/Route.d.ts +73 -5
  63. package/dist/routing/Route.d.ts.map +1 -1
  64. package/dist/routing/Route.js +72 -7
  65. package/dist/routing/Router.d.ts +59 -53
  66. package/dist/routing/Router.d.ts.map +1 -1
  67. package/dist/routing/Router.js +92 -117
  68. package/dist/routing/Site.d.ts +1 -1
  69. package/dist/routing/Site.js +2 -2
  70. package/dist/routing/index.d.ts +4 -3
  71. package/dist/routing/index.d.ts.map +1 -1
  72. package/dist/routing/index.js +2 -1
  73. package/dist/routing/utils.d.ts +2 -0
  74. package/dist/routing/utils.d.ts.map +1 -0
  75. package/dist/routing/utils.js +3 -0
  76. package/dist/ssr/SsrCache.d.ts +17 -0
  77. package/dist/ssr/SsrCache.d.ts.map +1 -1
  78. package/dist/ssr/SsrCache.js +17 -4
  79. package/dist/ssr/SsrComponents.d.ts +1 -0
  80. package/dist/ssr/SsrComponents.d.ts.map +1 -1
  81. package/dist/ssr/SsrComponents.js +1 -0
  82. package/package.json +6 -6
  83. package/src/Crelte.ts +124 -52
  84. package/src/CrelteRequest.ts +124 -0
  85. package/src/blocks/Blocks.svelte +35 -18
  86. package/src/blocks/Blocks.ts +38 -6
  87. package/src/blocks/index.ts +19 -10
  88. package/src/cookies/ServerCookies.ts +1 -1
  89. package/src/cookies/index.ts +7 -1
  90. package/src/graphql/GraphQl.ts +79 -27
  91. package/src/graphql/index.ts +7 -1
  92. package/src/index.ts +65 -29
  93. package/src/init/client.ts +55 -10
  94. package/src/init/server.ts +70 -10
  95. package/src/init/shared.ts +8 -7
  96. package/src/loadData/Globals.ts +43 -7
  97. package/src/loadData/index.ts +76 -13
  98. package/src/plugins/Events.ts +16 -5
  99. package/src/plugins/Plugins.ts +28 -2
  100. package/src/routing/History.ts +9 -0
  101. package/src/routing/InnerRouter.ts +47 -37
  102. package/src/routing/PageLoader.ts +10 -10
  103. package/src/routing/Request.ts +175 -0
  104. package/src/routing/Route.ts +74 -9
  105. package/src/routing/Router.ts +103 -163
  106. package/src/routing/Site.ts +2 -2
  107. package/src/routing/index.ts +12 -3
  108. package/src/routing/utils.ts +3 -0
  109. package/src/ssr/SsrCache.ts +17 -4
  110. package/src/ssr/SsrComponents.ts +1 -0
  111. package/dist/CrelteBase.d.ts +0 -16
  112. package/dist/CrelteBase.d.ts.map +0 -1
  113. package/dist/CrelteBase.js +0 -1
  114. package/dist/CrelteRouted.d.ts +0 -50
  115. package/dist/CrelteRouted.d.ts.map +0 -1
  116. package/dist/CrelteRouted.js +0 -88
  117. package/src/CrelteBase.ts +0 -24
  118. package/src/CrelteRouted.ts +0 -128
@@ -25,13 +25,28 @@ export default class Globals {
25
25
  this.prevSiteId = null;
26
26
  }
27
27
 
28
- get(name: string): Global<any> | null {
28
+ /**
29
+ * returns a store which contains a globalSet
30
+ *
31
+ * ## Note
32
+ * This only works in loadData, in loadGlobalData this will
33
+ * always return null. In that context you should use
34
+ * `.getGlobalAsync`
35
+ */
36
+ get<T extends GlobalData>(name: string): Global<T> | null {
29
37
  return this.entries.get(name) ?? null;
30
38
  }
31
39
 
32
- // call this only in loadGlobalData when by default the global
33
- // is not available
34
- getAsync(name: string): Promise<Global<any> | null> | Global<any> | null {
40
+ /**
41
+ * Get a store which contains a globalSet and wait until it is loaded
42
+ *
43
+ * ## Note
44
+ * This is only useful in loadGlobalData in all other cases
45
+ * you can use `.getGlobal` which does return a Promise
46
+ */
47
+ getAsync<T extends GlobalData>(
48
+ name: string,
49
+ ): Promise<Global<T> | null> | Global<T> | null {
35
50
  if (this.loaded) return this.get(name);
36
51
 
37
52
  let waiter = this.waiters.get(name);
@@ -45,15 +60,15 @@ export default class Globals {
45
60
  });
46
61
  }
47
62
 
48
- // hidden
63
+ /** @hidden */
49
64
  _wasLoaded(): boolean {
50
65
  return this.loaded;
51
66
  }
52
67
 
53
- // hidden
54
68
  // data is the data from the global graphql
55
69
  // so it contains some keys and data which should be parsed
56
70
  // and created a store for each key
71
+ /** @hidden */
57
72
  _setData(siteId: number, data: any) {
58
73
  const wasLoaded = this.loaded;
59
74
  this.loaded = true;
@@ -70,6 +85,7 @@ export default class Globals {
70
85
  }
71
86
  }
72
87
 
88
+ /** @hidden */
73
89
  _globalsBySite(siteId: number): Map<string, any> {
74
90
  const map = new Map();
75
91
 
@@ -80,6 +96,7 @@ export default class Globals {
80
96
  return map;
81
97
  }
82
98
 
99
+ /** @hidden */
83
100
  _updateSiteId(siteId: number) {
84
101
  // todo we should only trigger
85
102
  if (this.prevSiteId === siteId) return;
@@ -88,10 +105,19 @@ export default class Globals {
88
105
  }
89
106
  }
90
107
 
108
+ /**
109
+ * A globalSet Data
110
+ *
111
+ * Each global query should contain the siteId
112
+ */
91
113
  export interface GlobalData {
92
114
  siteId?: number;
115
+ [key: string]: any;
93
116
  }
94
117
 
118
+ /**
119
+ * A globalSet store
120
+ */
95
121
  export class Global<T extends GlobalData> {
96
122
  private inner: Writable<T>;
97
123
  /// if languages is null this means we always have the same data
@@ -129,11 +155,20 @@ export class Global<T extends GlobalData> {
129
155
  return this.inner.subscribe(fn);
130
156
  }
131
157
 
158
+ /**
159
+ * The current value
160
+ */
132
161
  get(): T {
133
162
  return this.inner.get();
134
163
  }
135
164
 
136
- /// if you pass a siteId which comes from craft then you will never receive null
165
+ /**
166
+ * Get the value based on the siteId
167
+ *
168
+ * ## Note
169
+ * If you pass a siteId which comes from craft
170
+ * you will never receive null
171
+ */
137
172
  bySiteId(siteId: number): T | null {
138
173
  if (this.languages)
139
174
  return this.languages.find(d => d.siteId === siteId) ?? null;
@@ -141,6 +176,7 @@ export class Global<T extends GlobalData> {
141
176
  return this.inner.get();
142
177
  }
143
178
 
179
+ /** @hidden */
144
180
  _updateSiteId(siteId: number) {
145
181
  if (!this.languages) return;
146
182
 
@@ -1,22 +1,85 @@
1
- /**
2
- *
3
- */
4
-
5
- import type CrelteRouted from '../CrelteRouted.js';
1
+ import CrelteRequest from '../CrelteRequest.js';
6
2
  import { isGraphQlQuery, type GraphQlQuery } from '../graphql/GraphQl.js';
7
3
  import type Globals from './Globals.js';
8
4
  import type { Global } from './Globals.js';
9
5
 
10
6
  export type { Globals, Global };
11
7
 
8
+ /**
9
+ * Load data function
10
+ *
11
+ * There are three main ways `loadData` can be defined:
12
+ *
13
+ * ## Object
14
+ * This is the most common way loadData will be used.
15
+ * Each property should be a loadData type, each one is called in parallel.
16
+ * And will be available to your component with the same name.
17
+ * ```
18
+ * export const loadData = {
19
+ *
20
+ * import entriesQuery from '@/queries/entries.graphql';
21
+ * import { loadData as headerLoadData } from '@/layout/header.svelte';
22
+ *
23
+ * export const loadData = {
24
+ * entries: entriesQuery,
25
+ * header: headerLoadData
26
+ * };
27
+ * ```
28
+ *
29
+ * ## GraphQl
30
+ * You can just export a graphql query as a loadData type.
31
+ * This will export all queries from the graphql file as properties.
32
+ * ```
33
+ * import blogsQuery from '@/queries/blogs.graphql';
34
+ *
35
+ * export const loadData = blogsQuery;
36
+ *
37
+ * // or another option
38
+ * import { gql } from '@craft-svelte/core/graphql';
39
+ *
40
+ * export const loadData = gql`query {
41
+ * blogs: entries(section: "blogs") {
42
+ * title
43
+ * url
44
+ * }
45
+ * }`;
46
+ * ```
47
+ *
48
+ * ## Function
49
+ * Using a function gives you the most flexibility but also is the
50
+ * most cumbersome.
51
+ *
52
+ * ```
53
+ * import articlesQuery from '@/queries/articles.graphql';
54
+ *
55
+ * export async function loadData(cr, entry) {
56
+ * return await cr.query(articlesQuery, {
57
+ * category: entry.category
58
+ * });
59
+ * }
60
+ *
61
+ * // or
62
+ * export const loadData = (cr, entry) => cr.query(articlesQuery, {
63
+ * category: entry.category
64
+ * });
65
+ *
66
+ * // or if you're in the context of an object
67
+ * export const loadData = {
68
+ * articles: (cr, entry) => cr.query(articlesQuery, {
69
+ * category: entry.category
70
+ * })
71
+ * }
72
+ * ```
73
+ */
74
+
12
75
  export type LoadData<T> =
13
- | ((cr: CrelteRouted, ...args: any[]) => Promise<T>)
76
+ | ((cr: CrelteRequest, ...args: any[]) => Promise<T>)
14
77
  | GraphQlQuery
15
78
  | T;
16
79
 
17
80
  export async function callLoadData(
18
81
  ld: LoadData<unknown>,
19
- cr: CrelteRouted,
82
+ cr: CrelteRequest,
20
83
  ...args: any[]
21
84
  ): Promise<unknown> {
22
85
  // either we have a function
@@ -49,15 +112,15 @@ export async function callLoadData(
49
112
  * ## Example
50
113
  * ```
51
114
  * export const loadData = mergeLoadData(
52
- * {
53
- * filter: (cr) => cr.route.search.get('filter'),
54
- * },
55
- * (cr) => cr.query(myQuery, { siteId: cr.site.id })
56
- * )
115
+ * {
116
+ * filter: (cr) => cr.route.search.get('filter'),
117
+ * },
118
+ * (cr) => cr.query(myQuery, { siteId: cr.site.id })
119
+ * );
57
120
  * ```
58
121
  */
59
122
  export function mergeLoadData(...lds: LoadData<object>[]): LoadData<object> {
60
- return async (cr: CrelteRouted, ...args: any[]) => {
123
+ return async (cr: CrelteRequest, ...args: any[]) => {
61
124
  const datas = await Promise.all(
62
125
  lds.map(ld => callLoadData(ld, cr, ...args) as Promise<object>),
63
126
  );
@@ -1,4 +1,4 @@
1
- import { CrelteRouted } from '../index.js';
1
+ import { CrelteRequest } from '../index.js';
2
2
 
3
3
  export default class Events {
4
4
  inner: Map<string, Set<any>>;
@@ -7,19 +7,21 @@ export default class Events {
7
7
  this.inner = new Map();
8
8
  }
9
9
 
10
- /*
10
+ /**
11
11
  * Listens for an event.
12
+ *
13
+ * @returns a function to remove the listener
12
14
  */
13
15
  // override this function to add your own function signatures
14
16
  on(
15
17
  ev: 'loadGlobalData',
16
- fn: (cr: CrelteRouted) => Promise<any>,
18
+ fn: (cr: CrelteRequest) => Promise<any>,
17
19
  ): () => void;
18
20
  on(
19
21
  ev: 'loadData',
20
- fn: (cr: CrelteRouted, entry: any, data: any) => Promise<any>,
22
+ fn: (cr: CrelteRequest, entry: any) => Promise<any>,
21
23
  ): () => void;
22
- on(ev: 'beforeRender', fn: (cr: CrelteRouted) => void): () => void;
24
+ on(ev: 'beforeRender', fn: (cr: CrelteRequest) => void): () => void;
23
25
  on(ev: string, fn: (...args: any[]) => any): () => void {
24
26
  let set = this.inner.get(ev);
25
27
  if (!set) {
@@ -34,6 +36,9 @@ export default class Events {
34
36
  };
35
37
  }
36
38
 
39
+ /**
40
+ * Remove a listener
41
+ */
37
42
  remove(ev: string, fn: any) {
38
43
  const set = this.inner.get(ev);
39
44
  if (!set) return;
@@ -41,6 +46,12 @@ export default class Events {
41
46
  set.delete(fn);
42
47
  }
43
48
 
49
+ /**
50
+ * Trigger an event
51
+ */
52
+ trigger(ev: 'loadGlobalData', cr: CrelteRequest): Promise<any>[];
53
+ trigger(ev: 'loadData', cr: CrelteRequest, entry: any): Promise<any>[];
54
+ trigger(ev: 'beforeRender', cr: CrelteRequest): void[];
44
55
  trigger(ev: string, ...args: any[]): any[] {
45
56
  const set = this.inner.get(ev);
46
57
  if (!set) return [];
@@ -1,11 +1,32 @@
1
- import Crelte from '../Crelte.js';
1
+ import CrelteCore from '../Crelte.js';
2
2
 
3
+ /**
4
+ * A plugin
5
+ */
3
6
  export interface Plugin {
4
7
  name: string;
5
8
  }
6
9
 
7
- export type PluginCreator = (crelte: Crelte) => Plugin;
10
+ /**
11
+ * A plugin create function
12
+ *
13
+ * Each plugin needs to export a createPluginname function which will be called
14
+ * by crelte to create the plugin. If youre plugin has options you can create
15
+ * a configurePluginname function which will be called by youre user and should
16
+ * return a createPlugin function.
17
+ *
18
+ * ## Example App.svelte in module="context"
19
+ * ```
20
+ * import { createPlugin, configurePlugin } from 'some-plugin';
21
+ *
22
+ * export plugins = [createPlugin, configurePlugin({ enableFeature: true })];
23
+ * ```
24
+ */
25
+ export type PluginCreator = (crelte: CrelteCore) => Plugin;
8
26
 
27
+ /**
28
+ * A plugin manager
29
+ */
9
30
  export default class Plugins {
10
31
  plugins: Map<string, Plugin>;
11
32
 
@@ -13,6 +34,11 @@ export default class Plugins {
13
34
  this.plugins = new Map();
14
35
  }
15
36
 
37
+ /**
38
+ * @hidden
39
+ *
40
+ * Plugins should be added via App.svelte plugins export
41
+ */
16
42
  add(plugin: Plugin) {
17
43
  this.plugins.set(plugin.name, plugin);
18
44
  }
@@ -3,6 +3,7 @@ export default interface History {
3
3
  replaceState(data: any, url?: string): void;
4
4
  pushState(data: any, url: string): void;
5
5
  open(url: string): void;
6
+ back(): void;
6
7
  }
7
8
 
8
9
  export class ClientHistory implements History {
@@ -21,6 +22,10 @@ export class ClientHistory implements History {
21
22
  open(url: string): void {
22
23
  window.location.href = url;
23
24
  }
25
+
26
+ back(): void {
27
+ window.history.back();
28
+ }
24
29
  }
25
30
 
26
31
  export class ServerHistory implements History {
@@ -49,4 +54,8 @@ export class ServerHistory implements History {
49
54
  open(url: string): void {
50
55
  this.url = url;
51
56
  }
57
+
58
+ back(): void {
59
+ throw new Error('Cannot go back on the server');
60
+ }
52
61
  }
@@ -1,6 +1,8 @@
1
- import Route from './Route.js';
2
1
  import Site, { SiteFromGraphQl } from './Site.js';
3
- import History, { ClientHistory, ServerHistory } from './History.js';
2
+ import History from './History.js';
3
+ import { ClientHistory, ServerHistory } from './History.js';
4
+ import Request, { isRequest } from './Request.js';
5
+ import Route from './Route.js';
4
6
 
5
7
  export type InnerRouterOpts = {
6
8
  preloadOnMouseOver: boolean;
@@ -19,8 +21,8 @@ export default class InnerRouter {
19
21
  * @param changeHistory returns a function you need to call when you are ready to
20
22
  update the window history (note do not call this after another onRoute call was made)
21
23
  */
22
- onRoute: (route: Route, site: Site, changeHistory: () => void) => void;
23
- onPreload: (route: Route, site: Site) => void;
24
+ onRoute: (route: Request, site: Site, changeHistory: () => void) => void;
25
+ onPreload: (route: Request, site: Site) => void;
24
26
 
25
27
  private scrollDebounceTimeout: any | null;
26
28
 
@@ -56,7 +58,7 @@ export default class InnerRouter {
56
58
  this.listen();
57
59
 
58
60
  // let's first try to load from the state
59
- const route = this.targetToRoute(window.location.href);
61
+ const route = this.targetToRequest(window.location.href);
60
62
  route._fillFromState(window.history.state);
61
63
 
62
64
  route.origin = 'init';
@@ -139,7 +141,7 @@ export default class InnerRouter {
139
141
  * @param target
140
142
  * @return Returns null if the url does not match our host (the protocol get's ignored)
141
143
  */
142
- targetToRoute(target: string | URL | Route): Route {
144
+ targetToRequest(target: string | URL | Route | Request): Request {
143
145
  if (typeof target === 'string') {
144
146
  if (target.startsWith('/')) {
145
147
  const site = this.site;
@@ -150,7 +152,11 @@ export default class InnerRouter {
150
152
  }
151
153
 
152
154
  if (target instanceof URL) {
153
- return this.routeFromUrl(target);
155
+ target = this.routeFromUrl(target);
156
+ }
157
+
158
+ if (!isRequest(target)) {
159
+ return Request.fromRoute(target);
154
160
  }
155
161
 
156
162
  return target;
@@ -269,7 +275,7 @@ export default class InnerRouter {
269
275
  window.addEventListener('popstate', async e => {
270
276
  if (!('route' in e.state)) return;
271
277
 
272
- const route = this.targetToRoute(window.location.href);
278
+ const route = this.targetToRequest(window.location.href);
273
279
  route._fillFromState(e.state);
274
280
  route.origin = 'pop';
275
281
 
@@ -288,12 +294,12 @@ export default class InnerRouter {
288
294
  * @param route a route object or an url or uri, never input the same route object again
289
295
  * @param pushState if true pushed the state to the window.history
290
296
  */
291
- open(target: string | URL | Route, pushState: boolean = true) {
292
- const route = this.targetToRoute(target);
297
+ open(target: string | URL | Route | Request, pushState: boolean = true) {
298
+ const req = this.targetToRequest(target);
293
299
 
294
300
  const current = this.route;
295
301
  if (current) {
296
- // if the scrollY will still be updated we clear the timeout
302
+ // if the scrollY would still be updated we clear the timeout
297
303
  // since we should have the latest scrollY
298
304
  if (this.scrollDebounceTimeout) {
299
305
  clearTimeout(this.scrollDebounceTimeout);
@@ -311,20 +317,21 @@ export default class InnerRouter {
311
317
  // if the domain of the current site is different than the domain of the
312
318
  // new site we need to do a window.location.href call
313
319
  if (
314
- (current && current.url.origin !== route.url.origin) ||
320
+ (current && current.url.origin !== req.url.origin) ||
321
+ // @ts-ignore
315
322
  import.meta.env.SSR
316
323
  ) {
317
- this.history.open(route.url.href);
324
+ this.history.open(req.url.href);
318
325
  return;
319
326
  }
320
327
 
321
328
  if (pushState) {
322
- route.index = (current?.index ?? 0) + 1;
323
- this.onRoute(route, route.site ?? this.site, () => {
324
- this.pushState(route);
329
+ req.index = (current?.index ?? 0) + 1;
330
+ this.onRoute(req, req.site ?? this.site, () => {
331
+ this.pushState(req.toRoute());
325
332
  });
326
333
  } else {
327
- this.setRoute(route);
334
+ this.setRoute(req);
328
335
  }
329
336
  }
330
337
 
@@ -334,13 +341,13 @@ export default class InnerRouter {
334
341
  * Will trigger an onRoute event but will not store any scroll progress
335
342
  * or modify the history
336
343
  *
337
- * @param route
344
+ * @param req
338
345
  */
339
- setRoute(route: Route) {
340
- this.route = route;
341
- if (route.site) this.site = route.site;
346
+ setRoute(req: Request) {
347
+ this.route = req.toRoute();
348
+ if (req.site) this.site = req.site;
342
349
 
343
- this.onRoute(route, this.site, () => {});
350
+ this.onRoute(req, this.site, () => {});
344
351
  }
345
352
 
346
353
  /**
@@ -389,26 +396,29 @@ export default class InnerRouter {
389
396
  *
390
397
  * @param url
391
398
  */
392
- preload(target: string | URL | Route) {
393
- const route = this.targetToRoute(target);
399
+ preload(target: string | URL | Route | Request) {
400
+ const req = this.targetToRequest(target);
394
401
 
402
+ // todo, don't think this makes any sense
395
403
  // if the domain of the current site is different than the domain of the
396
404
  // new site id does not make sense to preload
397
- if (this.site.url.origin !== route.url.origin) {
405
+ if (this.site.url.origin !== req.url.origin) {
398
406
  return;
399
407
  }
400
408
 
401
409
  const current = this.route;
402
- const site = route.site ?? this.site;
410
+ const site = req.site ?? this.site;
403
411
 
404
412
  // if the origin matches, the route will be able to be load
405
413
  // so let's preload it
406
- if (current && current.url.origin === route.url.origin) {
407
- this.onPreload(route, site);
414
+ if (current && current.url.origin === req.url.origin) {
415
+ this.onPreload(req, site);
408
416
  }
409
417
  }
410
418
 
411
- domReady(route: Route) {
419
+ domReady(req: Request) {
420
+ if (req.disableScroll) return;
421
+
412
422
  // scroll to target
413
423
  let scrollTo:
414
424
  | { top: number; behavior: ScrollBehavior }
@@ -417,7 +427,7 @@ export default class InnerRouter {
417
427
 
418
428
  // if the route is a live preview init and we have a scrollY stored
419
429
  // scroll to that
420
- if (route.origin === 'live-preview-init') {
430
+ if (req.origin === 'live-preview-init') {
421
431
  const scrollY = sessionStorage.getItem('live-preview-scroll');
422
432
  if (scrollY) {
423
433
  scrollTo = {
@@ -427,11 +437,11 @@ export default class InnerRouter {
427
437
  }
428
438
  // if we have a hash and the route was not visited
429
439
  } else if (
430
- route.hash &&
431
- ((route.origin === 'init' && typeof route.scrollY !== 'number') ||
432
- route.origin === 'click')
440
+ req.hash &&
441
+ ((req.origin === 'init' && typeof req.scrollY !== 'number') ||
442
+ req.origin === 'click')
433
443
  ) {
434
- const el = document.getElementById(route.hash.substring(1));
444
+ const el = document.getElementById(req.hash.substring(1));
435
445
  if (el) {
436
446
  scrollTo = {
437
447
  intoView: el,
@@ -443,11 +453,11 @@ export default class InnerRouter {
443
453
  // restore scroll position
444
454
  if (
445
455
  !scrollTo &&
446
- route.origin !== 'click' &&
447
- typeof route.scrollY === 'number'
456
+ req.origin !== 'click' &&
457
+ typeof req.scrollY === 'number'
448
458
  ) {
449
459
  scrollTo = {
450
- top: route.scrollY,
460
+ top: req.scrollY,
451
461
  behavior: 'instant',
452
462
  };
453
463
  }
@@ -1,4 +1,4 @@
1
- import Route from './Route.js';
1
+ import Request from './Request.js';
2
2
  import Site from './Site.js';
3
3
 
4
4
  export type PageLoaderOptions = {
@@ -11,7 +11,7 @@ export type LoadResponse = {
11
11
  };
12
12
 
13
13
  export type LoadFn = (
14
- route: Route,
14
+ req: Request,
15
15
  site: Site,
16
16
  opts: LoadOptions,
17
17
  ) => Promise<any> | any;
@@ -31,7 +31,7 @@ export default class PageLoader<More> {
31
31
 
32
32
  onLoaded: (
33
33
  resp: LoadResponse,
34
- route: Route,
34
+ req: Request,
35
35
  site: Site,
36
36
  more: More,
37
37
  ) => void;
@@ -62,7 +62,7 @@ export default class PageLoader<More> {
62
62
  this.onProgress(false);
63
63
  }
64
64
 
65
- async load(route: Route, site: Site, more: More) {
65
+ async load(req: Request, site: Site, more: More) {
66
66
  this.onProgress(true);
67
67
 
68
68
  const version = ++this.loadingVersion;
@@ -76,7 +76,7 @@ export default class PageLoader<More> {
76
76
 
77
77
  const resp: LoadResponse = { success: false, data: null };
78
78
  try {
79
- resp.data = await this.loadFn(route, site, { setProgress });
79
+ resp.data = await this.loadFn(req, site, { setProgress });
80
80
  resp.success = true;
81
81
  } catch (e) {
82
82
  resp.success = false;
@@ -91,19 +91,19 @@ export default class PageLoader<More> {
91
91
  return console.log('route changed quickly, ignoring response');
92
92
 
93
93
  this.onProgress(false);
94
- this.onLoaded(resp, route, site, more);
94
+ this.onLoaded(resp, req, site, more);
95
95
  }
96
96
 
97
97
  // you don't need to wait on this call
98
- async preload(route: Route, site: Site) {
99
- const url = route.url.origin + route.url.pathname;
98
+ async preload(req: Request, site: Site) {
99
+ const url = req.url.origin + req.url.pathname;
100
100
  if (this.preloadedUrls.has(url)) return;
101
101
 
102
102
  this.preloadedUrls.add(url);
103
103
 
104
104
  try {
105
- await this.loadFn(route, site, { setProgress: () => null });
106
- } catch (e) {
105
+ await this.loadFn(req, site, { setProgress: () => null });
106
+ } catch (_e) {
107
107
  console.log('preload failed');
108
108
  // retry at another time
109
109
  this.preloadedUrls.delete(url);