crelte 0.2.0 → 0.2.2

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.
@@ -1,10 +1,7 @@
1
1
  import { trimSlashEnd } from './utils.js';
2
2
  /**
3
3
  * A Route contains information about the current page for example the url and
4
- * the site id
5
- *
6
- * ## Note
7
- * Never update the route directly, clone it before
4
+ * the site
8
5
  */
9
6
  export default class Route {
10
7
  /**
@@ -24,6 +21,13 @@ export default class Route {
24
21
  site;
25
22
  /**
26
23
  * The scroll position of the current route
24
+ *
25
+ * ## Note
26
+ * This does not have to represent the current scroll position
27
+ * should more be used internally.
28
+ *
29
+ * It might be useful for a new request to specify the wanted
30
+ * scroll position
27
31
  */
28
32
  scrollY;
29
33
  /**
@@ -115,43 +119,6 @@ export default class Route {
115
119
  get hash() {
116
120
  return this.url.hash;
117
121
  }
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
- }
131
- /**
132
- * Checks if the route is equal to another route
133
- *
134
- * This checks all properties of the url but search params do not have to be
135
- * in the same order
136
- */
137
- eq(route) {
138
- const searchEq = (a, b) => {
139
- if (a.size !== b.size)
140
- return false;
141
- a.sort();
142
- b.sort();
143
- const aEntries = Array.from(a.entries());
144
- const bEntries = Array.from(b.entries());
145
- return aEntries
146
- .map((a, i) => [a, bEntries[i]])
147
- .every(([[ak, av], [bk, bv]]) => ak === bk && av === bv);
148
- };
149
- return (route &&
150
- this.url.pathname === route.url.pathname &&
151
- this.url.origin === route.url.origin &&
152
- searchEq(this.search, route.search) &&
153
- this.hash === route.hash);
154
- }
155
122
  /**
156
123
  * Checks if there are previous routes which would allow it to go back
157
124
  */
@@ -191,6 +158,67 @@ export default class Route {
191
158
  this.search.delete(key);
192
159
  }
193
160
  }
161
+ inLivePreview() {
162
+ return !!this.search.get('x-craft-live-preview');
163
+ }
164
+ /**
165
+ * Returns if the site matches the url
166
+ */
167
+ siteMatches() {
168
+ if (this.url.origin !== this.site.url.origin)
169
+ return false;
170
+ // now we need to validate the pathname we should make sure both end with a slash
171
+ // todo can we do this better?
172
+ // make sure that urls like pathname: /abcbc and site: /abc don't match
173
+ return (this.url.pathname + '/').startsWith(
174
+ // uri never returns a slash at the end
175
+ this.site.uri + '/');
176
+ }
177
+ /**
178
+ * Checks if the route is equal to another route
179
+ *
180
+ * This checks all properties of the url but search params do not have to be
181
+ * in the same order
182
+ */
183
+ eq(route) {
184
+ return (route &&
185
+ this.eqUrl(route) &&
186
+ this.eqSearch(route) &&
187
+ this.eqHash(route));
188
+ }
189
+ /**
190
+ * Checks if the route is equal to another route
191
+ *
192
+ * This does not check the search params or hash
193
+ */
194
+ eqUrl(route) {
195
+ return (route &&
196
+ this.url.pathname === route.url.pathname &&
197
+ this.url.origin === route.url.origin);
198
+ }
199
+ /**
200
+ * Checks if the search params are equal to another route
201
+ */
202
+ eqSearch(route) {
203
+ const searchEq = (a, b) => {
204
+ if (a.size !== b.size)
205
+ return false;
206
+ a.sort();
207
+ b.sort();
208
+ const aEntries = Array.from(a.entries());
209
+ const bEntries = Array.from(b.entries());
210
+ return aEntries
211
+ .map((a, i) => [a, bEntries[i]])
212
+ .every(([[ak, av], [bk, bv]]) => ak === bk && av === bv);
213
+ };
214
+ return route && searchEq(this.search, route.search);
215
+ }
216
+ /**
217
+ * Checks if the hash is equal to another route
218
+ */
219
+ eqHash(route) {
220
+ return route && this.hash === route.hash;
221
+ }
194
222
  /**
195
223
  * Create a copy of the request
196
224
  */
@@ -12,6 +12,7 @@ export type RouterOptions = {
12
12
  */
13
13
  type Internal = {
14
14
  onLoaded: (success: boolean, req: Request, ready: () => any) => void;
15
+ onNothingLoaded: (req: Request, ready: () => void) => void;
15
16
  onLoad: LoadFn;
16
17
  domReady: (req: Request) => void;
17
18
  initClient: () => void;
@@ -42,7 +43,6 @@ export default class Router {
42
43
  * The loading progress, the value is between 0 and 1
43
44
  */
44
45
  private _loadingProgress;
45
- private _onRouteEv;
46
46
  private _onRequest;
47
47
  /** @hidden */
48
48
  _internal: Internal;
@@ -72,10 +72,13 @@ export default class Router {
72
72
  /**
73
73
  * Open a new route
74
74
  *
75
- * @param target the target to open can be an url or a route
75
+ * @param target the target to open can be an url, a route or a request
76
76
  * the url needs to start with http or with a / which will be considered as
77
77
  * the site baseUrl
78
78
  *
79
+ * ## Note
80
+ * The origin will always be set to 'manual'
81
+ *
79
82
  * ## Example
80
83
  * ```
81
84
  * import { getRouter } from 'crelte';
@@ -87,13 +90,18 @@ export default class Router {
87
90
  * // the following page will be opened https://example.com/de/foo/bar
88
91
  * ```
89
92
  */
90
- open(target: string | URL | Route, opts?: RequestOptions): void;
93
+ open(target: string | URL | Route | Request, opts?: RequestOptions): void;
91
94
  /**
92
- * This pushes the state of the route without triggering an event
95
+ * This pushes the new route without triggering a new pageload
93
96
  *
94
97
  * You can use this when using pagination for example change the route object
95
98
  * (search argument) and then call pushState
96
99
  *
100
+ * ## Note
101
+ * This will always set the origin to 'push'
102
+ * And will clear the scrollY value if you not provide a new one via the `opts`
103
+ * This will disableLoadData by default if you not provide an override via the `opts`
104
+ *
97
105
  * ## Example
98
106
  * ```
99
107
  * import { getRouter } from 'crelte';
@@ -106,12 +114,21 @@ export default class Router {
106
114
  * router.pushState(route);
107
115
  * ```
108
116
  */
109
- pushState(route: Route): void;
117
+ push(route: Route | Request, opts?: RequestOptions): void;
118
+ /**
119
+ * @deprecated use push instead
120
+ */
121
+ pushState(route: Route | Request): void;
110
122
  /**
111
123
  * This replaces the state of the route without triggering an event
112
124
  *
113
125
  * You can use this when using some filters for example a search filter
114
126
  *
127
+ * ## Note
128
+ * This will always set the origin to 'replace'
129
+ * And will clear the scrollY value if you not provide a new one via the `opts`
130
+ * This will disableLoadData by default if you not provide an override via the `opts`
131
+ *
115
132
  * ## Example
116
133
  * ```
117
134
  * import { getRouter } from 'crelte';
@@ -124,7 +141,11 @@ export default class Router {
124
141
  * router.replaceState(route);
125
142
  * ```
126
143
  */
127
- replaceState(route: Route): void;
144
+ replace(route: Route | Request, opts?: RequestOptions): void;
145
+ /**
146
+ * @deprecated use replace instead
147
+ */
148
+ replaceState(route: Route | Request): void;
128
149
  /**
129
150
  * Checks if there are previous routes which would allow it to go back
130
151
  */
@@ -140,8 +161,8 @@ export default class Router {
140
161
  /**
141
162
  * Add a listener for the onRoute event
142
163
  *
143
- * This differs from router.route.subscribe in the way that
144
- * it will only trigger if a new render / load will occur
164
+ * This will trigger every time a new route is set
165
+ * and is equivalent to router.route.subscribe(fn)
145
166
  *
146
167
  * @returns a function to remove the listener
147
168
  */
@@ -161,6 +182,7 @@ export default class Router {
161
182
  private destroyRequest;
162
183
  private _onPreload;
163
184
  private _onLoaded;
185
+ private _onNothingLoaded;
164
186
  private _onProgress;
165
187
  }
166
188
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"Router.d.ts","sourceRoot":"","sources":["../../../../src/routing/Router.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Router.d.ts","sourceRoot":"","sources":["../../../../src/routing/Router.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@ import { Listeners } from 'crelte-std/sync';
5
5
  import Request from './Request.js';
6
6
  const defaultRouterOpts = {
7
7
  preloadOnMouseOver: false,
8
- deubgTiming: false,
8
+ debugTiming: false,
9
9
  };
10
10
  // Make sure route and nextRoute are not the same object as _inner.route
11
11
  export default class Router {
@@ -28,7 +28,6 @@ export default class Router {
28
28
  * The loading progress, the value is between 0 and 1
29
29
  */
30
30
  _loadingProgress;
31
- _onRouteEv;
32
31
  _onRequest;
33
32
  /** @hidden */
34
33
  _internal;
@@ -48,10 +47,10 @@ export default class Router {
48
47
  this._request = null;
49
48
  this._loading = new Writable(false);
50
49
  this._loadingProgress = new Writable(0);
51
- this._onRouteEv = new Listeners();
52
50
  this._onRequest = new Listeners();
53
51
  this._internal = {
54
52
  onLoaded: () => { },
53
+ onNothingLoaded: () => { },
55
54
  onLoad: () => { },
56
55
  domReady: req => this.inner.domReady(req),
57
56
  initClient: () => this._initClient(),
@@ -96,10 +95,13 @@ export default class Router {
96
95
  /**
97
96
  * Open a new route
98
97
  *
99
- * @param target the target to open can be an url or a route
98
+ * @param target the target to open can be an url, a route or a request
100
99
  * the url needs to start with http or with a / which will be considered as
101
100
  * the site baseUrl
102
101
  *
102
+ * ## Note
103
+ * The origin will always be set to 'manual'
104
+ *
103
105
  * ## Example
104
106
  * ```
105
107
  * import { getRouter } from 'crelte';
@@ -112,14 +114,23 @@ export default class Router {
112
114
  * ```
113
115
  */
114
116
  open(target, opts = {}) {
115
- this.inner.open(target, opts);
117
+ const req = this.inner.targetToRequest(target, {
118
+ ...opts,
119
+ origin: 'manual',
120
+ });
121
+ this.inner.open(req);
116
122
  }
117
123
  /**
118
- * This pushes the state of the route without triggering an event
124
+ * This pushes the new route without triggering a new pageload
119
125
  *
120
126
  * You can use this when using pagination for example change the route object
121
127
  * (search argument) and then call pushState
122
128
  *
129
+ * ## Note
130
+ * This will always set the origin to 'push'
131
+ * And will clear the scrollY value if you not provide a new one via the `opts`
132
+ * This will disableLoadData by default if you not provide an override via the `opts`
133
+ *
123
134
  * ## Example
124
135
  * ```
125
136
  * import { getRouter } from 'crelte';
@@ -132,17 +143,35 @@ export default class Router {
132
143
  * router.pushState(route);
133
144
  * ```
134
145
  */
135
- pushState(route) {
146
+ push(route, opts = {}) {
147
+ // cancel previous request
136
148
  this.pageLoader.discard();
137
- this.inner.pushState(route);
149
+ const req = this.inner.targetToRequest(route, {
150
+ ...opts,
151
+ origin: 'push',
152
+ scrollY: opts.scrollY ?? undefined,
153
+ disableLoadData: opts.disableLoadData ?? true,
154
+ });
155
+ this.inner.push(req);
138
156
  this.destroyRequest();
139
157
  this.setNewRoute(route);
140
158
  }
159
+ /**
160
+ * @deprecated use push instead
161
+ */
162
+ pushState(route) {
163
+ this.push(route);
164
+ }
141
165
  /**
142
166
  * This replaces the state of the route without triggering an event
143
167
  *
144
168
  * You can use this when using some filters for example a search filter
145
169
  *
170
+ * ## Note
171
+ * This will always set the origin to 'replace'
172
+ * And will clear the scrollY value if you not provide a new one via the `opts`
173
+ * This will disableLoadData by default if you not provide an override via the `opts`
174
+ *
146
175
  * ## Example
147
176
  * ```
148
177
  * import { getRouter } from 'crelte';
@@ -155,11 +184,23 @@ export default class Router {
155
184
  * router.replaceState(route);
156
185
  * ```
157
186
  */
158
- replaceState(route) {
187
+ replace(route, opts = {}) {
188
+ // cancel previous request
159
189
  this.pageLoader.discard();
160
- this.inner.replaceState(route);
190
+ const req = this.inner.targetToRequest(route, {
191
+ origin: 'replace',
192
+ scrollY: opts.scrollY ?? undefined,
193
+ disableLoadData: opts.disableLoadData ?? true,
194
+ });
195
+ this.inner.replace(req);
161
196
  this.destroyRequest();
162
- this.setNewRoute(route);
197
+ this.setNewRoute(req);
198
+ }
199
+ /**
200
+ * @deprecated use replace instead
201
+ */
202
+ replaceState(route) {
203
+ this.replace(route);
163
204
  }
164
205
  /**
165
206
  * Checks if there are previous routes which would allow it to go back
@@ -182,13 +223,13 @@ export default class Router {
182
223
  /**
183
224
  * Add a listener for the onRoute event
184
225
  *
185
- * This differs from router.route.subscribe in the way that
186
- * it will only trigger if a new render / load will occur
226
+ * This will trigger every time a new route is set
227
+ * and is equivalent to router.route.subscribe(fn)
187
228
  *
188
229
  * @returns a function to remove the listener
189
230
  */
190
231
  onRoute(fn) {
191
- return this._onRouteEv.add(fn);
232
+ return this.route.subscribe(fn);
192
233
  }
193
234
  /**
194
235
  * Add a listener for the onRequest event
@@ -213,6 +254,9 @@ export default class Router {
213
254
  }
214
255
  async _initServer(url, acceptLang) {
215
256
  this.inner.initServer();
257
+ this._internal.onNothingLoaded = (_req, ready) => {
258
+ ready();
259
+ };
216
260
  const prom = new Promise(resolve => {
217
261
  this._internal.onLoaded = (success, req, ready) => {
218
262
  const props = ready();
@@ -263,7 +307,12 @@ export default class Router {
263
307
  }
264
308
  this._onRequest.trigger(req);
265
309
  // route prepared
266
- this.pageLoader.load(req, { changeHistory });
310
+ if (!req.disableLoadData) {
311
+ this.pageLoader.load(req, { changeHistory });
312
+ }
313
+ else {
314
+ this._onNothingLoaded(req, { changeHistory });
315
+ }
267
316
  }
268
317
  destroyRequest() {
269
318
  if (!this._request)
@@ -283,15 +332,27 @@ export default class Router {
283
332
  // in the meantime
284
333
  more.changeHistory();
285
334
  const route = req.toRoute();
286
- const updateRoute = () => {
287
- this.setNewRoute(route);
288
- this._onRouteEv.trigger(route.clone());
289
- };
335
+ // call the client or server saying we are ready for a new render
290
336
  this._internal.onLoaded(resp.success, req, () => {
291
- updateRoute();
337
+ this.setNewRoute(route);
292
338
  return resp.data;
293
339
  });
294
340
  }
341
+ async _onNothingLoaded(req, more) {
342
+ // check if the render was cancelled
343
+ if (await req._renderBarrier.ready())
344
+ return;
345
+ // when the data is loaded let's update the route of the inner
346
+ // this is will only happen if no other route has been requested
347
+ // in the meantime
348
+ more.changeHistory();
349
+ const route = req.toRoute();
350
+ // call the client or server saying there was an update in the route
351
+ // but no new data was loaded so no render should happen
352
+ this._internal.onNothingLoaded(req, () => {
353
+ this.setNewRoute(route);
354
+ });
355
+ }
295
356
  _onProgress(loading, progress) {
296
357
  if (this._loading.get() !== loading)
297
358
  this._loading.set(loading);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "crelte",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "author": "Crelte <support@crelte.com>",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -60,6 +60,10 @@
60
60
  "types": "./dist/cookies/index.d.ts",
61
61
  "default": "./dist/cookies/index.js"
62
62
  },
63
+ "./cookies/internal": {
64
+ "types": "./dist/cookies/internal.d.ts",
65
+ "default": "./dist/cookies/internal.js"
66
+ },
63
67
  "./blocks": {
64
68
  "types": "./dist/blocks/index.d.ts",
65
69
  "default": "./dist/blocks/index.js"
@@ -1,6 +1,10 @@
1
1
  import { Cookies, SetOptions } from './index.js';
2
2
  import { parseCookies, type SetCookie, setCookieToString } from './utils.js';
3
3
 
4
+ /**
5
+ * ## Warning
6
+ * This is not stable and should only be used internally by crelte
7
+ */
4
8
  export default class ServerCookies implements Cookies {
5
9
  requestCookies: Map<string, string>;
6
10
  setCookies: Map<string, SetCookie>;
@@ -0,0 +1,3 @@
1
+ import ServerCookies from './ServerCookies.js';
2
+
3
+ export { ServerCookies };
package/src/index.ts CHANGED
@@ -143,6 +143,15 @@ export function getCookies(): Cookies {
143
143
  return getCrelte().cookies;
144
144
  }
145
145
 
146
+ export function onRoute(fn: (route: Route, crelte: Crelte) => void) {
147
+ const crelte = getCrelte();
148
+ const rmListener = crelte.router.onRoute(route => {
149
+ fn(route, crelte);
150
+ });
151
+
152
+ onDestroy(rmListener);
153
+ }
154
+
146
155
  /**
147
156
  * Listen for requests
148
157
  *
@@ -204,6 +204,15 @@ export function main(data: MainData) {
204
204
  await render();
205
205
  };
206
206
 
207
+ crelte.router._internal.onNothingLoaded = async (req, ready) => {
208
+ crelte.globals._updateSiteId(req.site.id);
209
+ ready();
210
+
211
+ await tick();
212
+
213
+ crelte.router._internal.domReady(req);
214
+ };
215
+
207
216
  crelte.router._internal.initClient();
208
217
  }
209
218