crelte 0.3.0 → 0.3.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.
- package/dist/Crelte.d.ts +12 -0
- package/dist/Crelte.d.ts.map +1 -1
- package/dist/Crelte.js +12 -0
- package/dist/CrelteRequest.d.ts +0 -4
- package/dist/CrelteRequest.d.ts.map +1 -1
- package/dist/CrelteRequest.js +0 -4
- package/dist/entry/EntryRouter.d.ts +30 -0
- package/dist/entry/EntryRouter.d.ts.map +1 -0
- package/dist/entry/EntryRouter.js +45 -0
- package/dist/entry/index.d.ts +32 -0
- package/dist/entry/index.d.ts.map +1 -0
- package/dist/entry/index.js +31 -0
- package/dist/index.d.ts +2 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -6
- package/dist/init/client.d.ts +1 -1
- package/dist/init/client.d.ts.map +1 -1
- package/dist/init/client.js +4 -3
- package/dist/init/server.d.ts.map +1 -1
- package/dist/init/server.js +3 -2
- package/dist/init/shared.d.ts +3 -1
- package/dist/init/shared.d.ts.map +1 -1
- package/dist/init/shared.js +47 -26
- package/dist/routing/InnerRouter.d.ts +1 -10
- package/dist/routing/InnerRouter.d.ts.map +1 -1
- package/dist/routing/InnerRouter.js +20 -21
- package/dist/routing/Request.d.ts +2 -0
- package/dist/routing/Request.d.ts.map +1 -1
- package/dist/routing/Request.js +9 -0
- package/dist/routing/Route.d.ts +67 -1
- package/dist/routing/Route.d.ts.map +1 -1
- package/dist/routing/Route.js +98 -2
- package/dist/routing/Router.d.ts +49 -12
- package/dist/routing/Router.d.ts.map +1 -1
- package/dist/routing/Router.js +82 -28
- package/dist/routing/index.d.ts +2 -2
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/utils.d.ts +2 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +8 -0
- package/package.json +9 -4
- package/src/Crelte.ts +15 -0
- package/src/CrelteRequest.ts +0 -4
- package/src/entry/EntryRouter.ts +71 -0
- package/src/entry/index.ts +48 -0
- package/src/index.ts +2 -11
- package/src/init/client.ts +10 -3
- package/src/init/server.ts +9 -2
- package/src/init/shared.ts +78 -28
- package/src/routing/InnerRouter.ts +29 -30
- package/src/routing/Request.ts +11 -0
- package/src/routing/Route.ts +107 -2
- package/src/routing/Router.ts +110 -31
- package/src/routing/index.ts +2 -1
- package/src/utils.ts +10 -0
package/dist/routing/Router.js
CHANGED
|
@@ -54,6 +54,8 @@ export default class Router {
|
|
|
54
54
|
this._loading = new Writable(false);
|
|
55
55
|
this._loadingProgress = new Writable(0);
|
|
56
56
|
this._onRequest = new Listeners();
|
|
57
|
+
// these functions are exposed to the init "module"
|
|
58
|
+
// but should not be used by anybody else
|
|
57
59
|
this._internal = {
|
|
58
60
|
onLoaded: () => { },
|
|
59
61
|
onNothingLoaded: () => { },
|
|
@@ -130,24 +132,35 @@ export default class Router {
|
|
|
130
132
|
* ```
|
|
131
133
|
*/
|
|
132
134
|
open(target, opts = {}) {
|
|
133
|
-
const req = this.
|
|
134
|
-
...opts,
|
|
135
|
+
const req = this.targetOrUpdateToRequest(target, opts, {
|
|
135
136
|
origin: 'manual',
|
|
136
137
|
});
|
|
138
|
+
if (!req)
|
|
139
|
+
return;
|
|
137
140
|
this.inner.open(req);
|
|
138
141
|
}
|
|
139
142
|
/**
|
|
140
143
|
* This pushes the new route without triggering a new pageload
|
|
141
144
|
*
|
|
142
145
|
* You can use this when using pagination for example change the route object
|
|
143
|
-
* (search argument) and then call
|
|
146
|
+
* (search argument) and then call push
|
|
144
147
|
*
|
|
145
148
|
* ## Note
|
|
146
149
|
* This will always set the origin to 'push'
|
|
147
150
|
* And will clear the scrollY value if you not provide a new one via the `opts`
|
|
148
151
|
* This will disableLoadData by default if you not provide an override via the `opts`
|
|
149
152
|
*
|
|
150
|
-
* ## Example
|
|
153
|
+
* ## Example using the update function
|
|
154
|
+
* ```
|
|
155
|
+
* import { getRouter } from 'crelte';
|
|
156
|
+
*
|
|
157
|
+
* const router = getRouter();
|
|
158
|
+
*
|
|
159
|
+
* const page = 1;
|
|
160
|
+
* router.push(req => req.setSearchParam('page', page || null));
|
|
161
|
+
* ```
|
|
162
|
+
*
|
|
163
|
+
* ## Example using the route object
|
|
151
164
|
* ```
|
|
152
165
|
* import { getRouter } from 'crelte';
|
|
153
166
|
*
|
|
@@ -156,21 +169,20 @@ export default class Router {
|
|
|
156
169
|
* const page = 1;
|
|
157
170
|
* const route = router.route.get();
|
|
158
171
|
* route.setSearchParam('page', page > 0 ? page : null);
|
|
159
|
-
* router.
|
|
172
|
+
* router.push(route);
|
|
160
173
|
* ```
|
|
161
174
|
*/
|
|
162
175
|
push(route, opts = {}) {
|
|
163
|
-
//
|
|
164
|
-
|
|
165
|
-
const req = this.
|
|
166
|
-
...opts,
|
|
176
|
+
// theoretically string and URL also work but we might
|
|
177
|
+
// change that in the future
|
|
178
|
+
const req = this.targetOrUpdateToRequest(route, opts, {
|
|
167
179
|
origin: 'push',
|
|
168
180
|
scrollY: opts.scrollY ?? undefined,
|
|
169
181
|
disableLoadData: opts.disableLoadData ?? true,
|
|
170
182
|
});
|
|
183
|
+
if (!req)
|
|
184
|
+
return;
|
|
171
185
|
this.inner.push(req);
|
|
172
|
-
this.destroyRequest();
|
|
173
|
-
this.setNewRoute(route);
|
|
174
186
|
}
|
|
175
187
|
/**
|
|
176
188
|
* @deprecated use push instead
|
|
@@ -180,16 +192,26 @@ export default class Router {
|
|
|
180
192
|
this.push(route);
|
|
181
193
|
}
|
|
182
194
|
/**
|
|
183
|
-
* This replaces the state of the route without triggering
|
|
195
|
+
* This replaces the state of the route without triggering a new pageload
|
|
184
196
|
*
|
|
185
197
|
* You can use this when using some filters for example a search filter
|
|
186
198
|
*
|
|
187
199
|
* ## Note
|
|
188
200
|
* This will always set the origin to 'replace'
|
|
189
|
-
* And will clear the scrollY value if you
|
|
190
|
-
* This will disableLoadData by default if you
|
|
201
|
+
* And will clear the scrollY value if you don't provide a new one via the `opts`
|
|
202
|
+
* This will disableLoadData by default if you don't provide an override via the `opts`
|
|
191
203
|
*
|
|
192
|
-
* ## Example
|
|
204
|
+
* ## Example using the update function
|
|
205
|
+
* ```
|
|
206
|
+
* import { getRouter } from 'crelte';
|
|
207
|
+
*
|
|
208
|
+
* const router = getRouter();
|
|
209
|
+
*
|
|
210
|
+
* const search = 'foo';
|
|
211
|
+
* router.replace(req => req.setSearchParam('search', search));
|
|
212
|
+
* ```
|
|
213
|
+
*
|
|
214
|
+
* ## Example using the route object
|
|
193
215
|
* ```
|
|
194
216
|
* import { getRouter } from 'crelte';
|
|
195
217
|
*
|
|
@@ -197,21 +219,21 @@ export default class Router {
|
|
|
197
219
|
*
|
|
198
220
|
* const search = 'foo';
|
|
199
221
|
* const route = router.route.get();
|
|
200
|
-
* route.setSearchParam('search', search
|
|
201
|
-
* router.
|
|
222
|
+
* route.setSearchParam('search', search);
|
|
223
|
+
* router.replace(route);
|
|
202
224
|
* ```
|
|
203
225
|
*/
|
|
204
226
|
replace(route, opts = {}) {
|
|
205
|
-
//
|
|
206
|
-
|
|
207
|
-
const req = this.
|
|
227
|
+
// theoretically string and URL also work but we might
|
|
228
|
+
// change that in the future
|
|
229
|
+
const req = this.targetOrUpdateToRequest(route, opts, {
|
|
208
230
|
origin: 'replace',
|
|
209
231
|
scrollY: opts.scrollY ?? undefined,
|
|
210
232
|
disableLoadData: opts.disableLoadData ?? true,
|
|
211
233
|
});
|
|
234
|
+
if (!req)
|
|
235
|
+
return;
|
|
212
236
|
this.inner.replace(req);
|
|
213
|
-
this.destroyRequest();
|
|
214
|
-
this.setNewRoute(req);
|
|
215
237
|
}
|
|
216
238
|
/**
|
|
217
239
|
* @deprecated use replace instead
|
|
@@ -299,11 +321,11 @@ export default class Router {
|
|
|
299
321
|
});
|
|
300
322
|
};
|
|
301
323
|
});
|
|
302
|
-
const
|
|
303
|
-
|
|
324
|
+
const req = this.inner.targetToRequest(url);
|
|
325
|
+
req.origin = 'init';
|
|
304
326
|
// let's see if the url matches any route and site
|
|
305
327
|
// if not let's redirect to the site which matches the acceptLang
|
|
306
|
-
if (!
|
|
328
|
+
if (!req.siteMatches()) {
|
|
307
329
|
const site = this.inner.siteByAcceptLang(acceptLang);
|
|
308
330
|
return {
|
|
309
331
|
success: true,
|
|
@@ -312,12 +334,13 @@ export default class Router {
|
|
|
312
334
|
props: {},
|
|
313
335
|
};
|
|
314
336
|
}
|
|
315
|
-
this.inner.
|
|
337
|
+
this.inner.route = req.toRoute();
|
|
338
|
+
this.inner.onRoute(req, () => { });
|
|
316
339
|
const resp = await prom;
|
|
317
340
|
const hist = this.inner.history;
|
|
318
341
|
if (hist.url || hist.req) {
|
|
319
342
|
const nReq = this.inner.targetToRequest(hist.req ?? hist.url);
|
|
320
|
-
if (!
|
|
343
|
+
if (!req.eq(nReq)) {
|
|
321
344
|
return {
|
|
322
345
|
success: true,
|
|
323
346
|
redirect: true,
|
|
@@ -328,6 +351,7 @@ export default class Router {
|
|
|
328
351
|
}
|
|
329
352
|
return resp;
|
|
330
353
|
}
|
|
354
|
+
// gets called by the InnerRouter when a new route is requested
|
|
331
355
|
_onRoute(req, changeHistory) {
|
|
332
356
|
this.destroyRequest();
|
|
333
357
|
this._request = req;
|
|
@@ -341,6 +365,7 @@ export default class Router {
|
|
|
341
365
|
this.pageLoader.load(req, { changeHistory });
|
|
342
366
|
}
|
|
343
367
|
else {
|
|
368
|
+
this.pageLoader.discard();
|
|
344
369
|
this._onNothingLoaded(req, { changeHistory });
|
|
345
370
|
}
|
|
346
371
|
}
|
|
@@ -353,12 +378,13 @@ export default class Router {
|
|
|
353
378
|
_onPreload(req) {
|
|
354
379
|
this.pageLoader.preload(req);
|
|
355
380
|
}
|
|
381
|
+
// gets called by the pageLoader when teh loadData completes
|
|
356
382
|
async _onLoaded(resp, req, more) {
|
|
357
383
|
// check if the render was cancelled
|
|
358
384
|
if (await req._renderBarrier.ready())
|
|
359
385
|
return;
|
|
360
386
|
// when the data is loaded let's update the route of the inner
|
|
361
|
-
// this
|
|
387
|
+
// this will only happen if no other route has been requested
|
|
362
388
|
// in the meantime
|
|
363
389
|
more.changeHistory();
|
|
364
390
|
const route = req.toRoute();
|
|
@@ -368,6 +394,7 @@ export default class Router {
|
|
|
368
394
|
return resp.data;
|
|
369
395
|
});
|
|
370
396
|
}
|
|
397
|
+
// this gets called if loadData is not called
|
|
371
398
|
async _onNothingLoaded(req, more) {
|
|
372
399
|
// check if the render was cancelled
|
|
373
400
|
if (await req._renderBarrier.ready())
|
|
@@ -383,10 +410,37 @@ export default class Router {
|
|
|
383
410
|
this.setNewRoute(route);
|
|
384
411
|
});
|
|
385
412
|
}
|
|
413
|
+
// this is called by the pageLoader if we get a progress update
|
|
386
414
|
_onProgress(loading, progress) {
|
|
387
415
|
if (this._loading.get() !== loading)
|
|
388
416
|
this._loading.set(loading);
|
|
389
417
|
if (typeof progress === 'number')
|
|
390
418
|
this._loadingProgress.set(progress);
|
|
391
419
|
}
|
|
420
|
+
/**
|
|
421
|
+
* Transforms a target to a request
|
|
422
|
+
*
|
|
423
|
+
* returns null if the request was canceled by the update request
|
|
424
|
+
*/
|
|
425
|
+
targetOrUpdateToRequest(target, opts = {}, forcedOpts = {}) {
|
|
426
|
+
// we have an update request
|
|
427
|
+
if (typeof target === 'function') {
|
|
428
|
+
const route = this.route.get();
|
|
429
|
+
if (!route) {
|
|
430
|
+
throw new Error('route to update missing in first loadData call');
|
|
431
|
+
}
|
|
432
|
+
// first get a req
|
|
433
|
+
const req = this.inner.targetToRequest(route, opts);
|
|
434
|
+
// check if the request was canceled by the update request
|
|
435
|
+
if (target(req) === false)
|
|
436
|
+
return null;
|
|
437
|
+
// now we add the forcedOpts
|
|
438
|
+
req._updateOpts(forcedOpts);
|
|
439
|
+
return req;
|
|
440
|
+
}
|
|
441
|
+
return this.inner.targetToRequest(target, {
|
|
442
|
+
...opts,
|
|
443
|
+
...forcedOpts,
|
|
444
|
+
});
|
|
445
|
+
}
|
|
392
446
|
}
|
package/dist/routing/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import Router from './Router.js';
|
|
1
|
+
import Router, { type UpdateRequest } from './Router.js';
|
|
2
2
|
import Route, { type RouteOptions } from './Route.js';
|
|
3
3
|
import Request, { type RequestOptions, type DelayRender } from './Request.js';
|
|
4
4
|
import Site from './Site.js';
|
|
5
|
-
export { Router, Route, RouteOptions, Site, Request, DelayRender, RequestOptions, };
|
|
5
|
+
export { Router, UpdateRequest, Route, RouteOptions, Site, Request, DelayRender, RequestOptions, };
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/routing/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/routing/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,EAAE,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,KAAK,EAAE,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,OAAO,EAAE,EAAE,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EACN,MAAM,EACN,aAAa,EACb,KAAK,EACL,YAAY,EACZ,IAAI,EACJ,OAAO,EACP,WAAW,EACX,cAAc,GACd,CAAC"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/utils.ts"],"names":[],"mappings":"AAGA,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CAMtC"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// This are internal utils. Consider adding them to crelte-std instead
|
|
2
|
+
// this tries to do a structuredClone and else just uses JSON
|
|
3
|
+
export function objClone(obj) {
|
|
4
|
+
if (typeof structuredClone === 'function') {
|
|
5
|
+
return structuredClone(obj);
|
|
6
|
+
}
|
|
7
|
+
return JSON.parse(JSON.stringify(obj));
|
|
8
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "crelte",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"author": "Crelte <support@crelte.com>",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -44,6 +44,10 @@
|
|
|
44
44
|
"types": "./dist/routing/index.d.ts",
|
|
45
45
|
"default": "./dist/routing/index.js"
|
|
46
46
|
},
|
|
47
|
+
"./entry": {
|
|
48
|
+
"types": "./dist/entry/index.d.ts",
|
|
49
|
+
"default": "./dist/entry/index.js"
|
|
50
|
+
},
|
|
47
51
|
"./ssr": {
|
|
48
52
|
"types": "./dist/ssr/index.d.ts",
|
|
49
53
|
"default": "./dist/ssr/index.js"
|
|
@@ -71,14 +75,15 @@
|
|
|
71
75
|
},
|
|
72
76
|
"dependencies": {
|
|
73
77
|
"crelte-std": "^0.1.1",
|
|
74
|
-
"svelte": "^4.2.12"
|
|
78
|
+
"svelte": "^4.2.12",
|
|
79
|
+
"trouter": "^4.0.0"
|
|
75
80
|
},
|
|
76
81
|
"devDependencies": {
|
|
77
82
|
"@sveltejs/package": "^2.3.1",
|
|
78
83
|
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
|
79
84
|
"svelte-check": "^4.1.4",
|
|
80
85
|
"typescript-svelte-plugin": "^0.3.45",
|
|
81
|
-
"
|
|
82
|
-
"
|
|
86
|
+
"vite": "^5.0",
|
|
87
|
+
"vitest": "^2.0.0"
|
|
83
88
|
}
|
|
84
89
|
}
|
package/src/Crelte.ts
CHANGED
|
@@ -2,9 +2,12 @@ import ClientCookies from './cookies/ClientCookies.js';
|
|
|
2
2
|
import { Cookies } from './cookies/index.js';
|
|
3
3
|
import ServerCookies from './cookies/ServerCookies.js';
|
|
4
4
|
import GraphQl, { GraphQlQuery } from './graphql/GraphQl.js';
|
|
5
|
+
import { CrelteRequest } from './index.js';
|
|
5
6
|
import Globals, { Global } from './loadData/Globals.js';
|
|
6
7
|
import Events from './plugins/Events.js';
|
|
7
8
|
import Plugins, { Plugin } from './plugins/Plugins.js';
|
|
9
|
+
import type Route from './routing/Route.js';
|
|
10
|
+
import type Request from './routing/Request.js';
|
|
8
11
|
import Router from './routing/Router.js';
|
|
9
12
|
import { SiteFromGraphQl } from './routing/Site.js';
|
|
10
13
|
import SsrCache from './ssr/SsrCache.js';
|
|
@@ -243,6 +246,18 @@ export default class Crelte {
|
|
|
243
246
|
return this.globals.getStore(name) ?? null;
|
|
244
247
|
}
|
|
245
248
|
|
|
249
|
+
/**
|
|
250
|
+
* returns a new CrelteRequest instance either with the current
|
|
251
|
+
* route or a provided one
|
|
252
|
+
*
|
|
253
|
+
* ## Note
|
|
254
|
+
* This is useful if you want to create a stateful crelte
|
|
255
|
+
* to use in loadData context
|
|
256
|
+
*/
|
|
257
|
+
toRequest(req?: Route | Request): CrelteRequest {
|
|
258
|
+
return CrelteRequest.fromCrelte(this, req);
|
|
259
|
+
}
|
|
260
|
+
|
|
246
261
|
/**
|
|
247
262
|
* Run a GraphQl Query
|
|
248
263
|
*
|
package/src/CrelteRequest.ts
CHANGED
|
@@ -21,10 +21,6 @@ export default class CrelteRequest extends Crelte {
|
|
|
21
21
|
*
|
|
22
22
|
* If you don't provide a route or request the current route
|
|
23
23
|
* will be used.
|
|
24
|
-
*
|
|
25
|
-
* ## Note
|
|
26
|
-
* If you provide a route it must contain a site or you must
|
|
27
|
-
* provide one,
|
|
28
24
|
*/
|
|
29
25
|
static fromCrelte(
|
|
30
26
|
inner: Crelte | CrelteRequest,
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Pattern, Trouter } from 'trouter';
|
|
2
|
+
import { Crelte, CrelteRequest, Entry, QueryOptions } from '../index.js';
|
|
3
|
+
import { CrelteEntryRequest, EntryRequest } from './index.js';
|
|
4
|
+
import { GraphQlQuery } from '../graphql/GraphQl.js';
|
|
5
|
+
|
|
6
|
+
export type EntryRouteHandler = (
|
|
7
|
+
cr: CrelteEntryRequest,
|
|
8
|
+
) => Promise<Entry | null | undefined> | Entry | null | undefined | void;
|
|
9
|
+
|
|
10
|
+
export type EntryRoutes = (router: EntryRouter) => Promise<void> | void;
|
|
11
|
+
|
|
12
|
+
export default class EntryRouter {
|
|
13
|
+
private _crelte: Crelte;
|
|
14
|
+
private inner: Trouter<EntryRouteHandler>;
|
|
15
|
+
|
|
16
|
+
constructor(crelte: Crelte) {
|
|
17
|
+
this._crelte = crelte;
|
|
18
|
+
this.inner = new Trouter();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
add(pattern: Pattern, ...handlers: EntryRouteHandler[]): this {
|
|
22
|
+
this.inner.add('GET', pattern, ...handlers);
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* returns an env variable from the craft/.env file.
|
|
28
|
+
*/
|
|
29
|
+
getEnv(name: 'ENDPOINT_URL'): string;
|
|
30
|
+
getEnv(name: 'CRAFT_WEB_URL'): string;
|
|
31
|
+
getEnv(name: string): string | null;
|
|
32
|
+
getEnv(name: string): string | null {
|
|
33
|
+
return this._crelte.getEnv(name);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Run a GraphQl Query
|
|
38
|
+
*
|
|
39
|
+
* @param query the default export from a graphql file or the gql`query {}`
|
|
40
|
+
* function
|
|
41
|
+
* @param variables variables that should be passed to the
|
|
42
|
+
* graphql query
|
|
43
|
+
*/
|
|
44
|
+
async query(
|
|
45
|
+
query: GraphQlQuery,
|
|
46
|
+
variables: Record<string, unknown> = {},
|
|
47
|
+
opts: QueryOptions = {},
|
|
48
|
+
): Promise<unknown> {
|
|
49
|
+
// this function is added as convenience
|
|
50
|
+
return this._crelte.graphQl.query(query, variables, opts);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** @hidden */
|
|
54
|
+
async _handle(cr: CrelteRequest): Promise<Entry | null> {
|
|
55
|
+
const { params, handlers } = this.inner.find('GET', cr.req.uri);
|
|
56
|
+
|
|
57
|
+
if (!handlers.length) return null;
|
|
58
|
+
|
|
59
|
+
const er = new EntryRequest(cr.req.url, cr.req.site, {
|
|
60
|
+
params: new Map(Object.entries(params)),
|
|
61
|
+
});
|
|
62
|
+
const cer = new CrelteEntryRequest(cr, er);
|
|
63
|
+
|
|
64
|
+
for (const handler of handlers) {
|
|
65
|
+
const res = await handler(cer);
|
|
66
|
+
if (res) return res;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Crelte, CrelteRequest } from '../index.js';
|
|
2
|
+
import { Request, RequestOptions, Site } from '../routing/index.js';
|
|
3
|
+
import EntryRouter, { EntryRouteHandler, EntryRoutes } from './EntryRouter.js';
|
|
4
|
+
|
|
5
|
+
export { EntryRouter, type EntryRouteHandler, type EntryRoutes };
|
|
6
|
+
|
|
7
|
+
export type Entry = {
|
|
8
|
+
sectionHandle: string;
|
|
9
|
+
typeHandle: string;
|
|
10
|
+
[key: string]: any;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type EntryRequestOptions = RequestOptions & {
|
|
14
|
+
params?: Map<string, string>;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export class EntryRequest extends Request {
|
|
18
|
+
private params: Map<string, string>;
|
|
19
|
+
|
|
20
|
+
constructor(url: string | URL, site: Site, opts: EntryRequestOptions = {}) {
|
|
21
|
+
super(url, site, opts);
|
|
22
|
+
|
|
23
|
+
this.params = opts.params ?? new Map();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* returns the url params from the request
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```js
|
|
31
|
+
* router.get('/blog/:slug', async (cs, req) => {
|
|
32
|
+
* return Response.json({ slug: cs.getParam('slug') });
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
getParam(name: string): string | null {
|
|
37
|
+
return this.params.get(name) ?? null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export class CrelteEntryRequest extends CrelteRequest {
|
|
42
|
+
req: EntryRequest;
|
|
43
|
+
|
|
44
|
+
constructor(inner: Crelte, req: EntryRequest) {
|
|
45
|
+
super(inner, req);
|
|
46
|
+
this.req = req;
|
|
47
|
+
}
|
|
48
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { getContext, onDestroy } from 'svelte';
|
|
2
2
|
import type Route from './routing/Route.js';
|
|
3
|
-
import type Request from './routing/Request.js';
|
|
4
3
|
import type Router from './routing/Router.js';
|
|
5
4
|
import type SsrCache from './ssr/SsrCache.js';
|
|
6
5
|
import type Site from './routing/Site.js';
|
|
@@ -16,6 +15,7 @@ import {
|
|
|
16
15
|
LoadDataFn,
|
|
17
16
|
LoadDataObj,
|
|
18
17
|
} from './loadData/index.js';
|
|
18
|
+
import { Entry } from './entry/index.js';
|
|
19
19
|
|
|
20
20
|
export {
|
|
21
21
|
Crelte,
|
|
@@ -26,6 +26,7 @@ export {
|
|
|
26
26
|
type LoadDataFn,
|
|
27
27
|
type LoadDataObj,
|
|
28
28
|
type LoadDataArray,
|
|
29
|
+
type Entry,
|
|
29
30
|
};
|
|
30
31
|
|
|
31
32
|
/**
|
|
@@ -149,16 +150,6 @@ export function getCookies(): Cookies {
|
|
|
149
150
|
return getCrelte().cookies;
|
|
150
151
|
}
|
|
151
152
|
|
|
152
|
-
/**
|
|
153
|
-
* A function to make sure you have a CrelteRequest
|
|
154
|
-
*/
|
|
155
|
-
export function toCrelteRequest(
|
|
156
|
-
crelte: Crelte | CrelteRequest,
|
|
157
|
-
req?: Route | Request,
|
|
158
|
-
): CrelteRequest {
|
|
159
|
-
return CrelteRequest.fromCrelte(crelte, req);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
153
|
/**
|
|
163
154
|
* Listen for route changes
|
|
164
155
|
*
|
package/src/init/client.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { CrelteBuilder } from '../Crelte.js';
|
|
|
2
2
|
import CrelteRequest from '../CrelteRequest.js';
|
|
3
3
|
import { GraphQlQuery } from '../graphql/GraphQl.js';
|
|
4
4
|
import { SiteFromGraphQl } from '../routing/Site.js';
|
|
5
|
-
import {
|
|
5
|
+
import { pluginsBeforeRender, prepareLoadFn, setupPlugins } from './shared.js';
|
|
6
6
|
import { tick } from 'svelte';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -49,7 +49,7 @@ const mainDataDefault = {
|
|
|
49
49
|
* });
|
|
50
50
|
* ```
|
|
51
51
|
*/
|
|
52
|
-
export function main(data: MainData) {
|
|
52
|
+
export async function main(data: MainData) {
|
|
53
53
|
data = { ...mainDataDefault, ...data };
|
|
54
54
|
|
|
55
55
|
// rendering steps
|
|
@@ -97,11 +97,18 @@ export function main(data: MainData) {
|
|
|
97
97
|
// setup plugins
|
|
98
98
|
setupPlugins(crelte, data.app.plugins ?? []);
|
|
99
99
|
|
|
100
|
+
const loadFn = await prepareLoadFn(
|
|
101
|
+
crelte,
|
|
102
|
+
data.app,
|
|
103
|
+
data.entryQuery,
|
|
104
|
+
data.globalQuery,
|
|
105
|
+
);
|
|
106
|
+
|
|
100
107
|
// setup load Data
|
|
101
108
|
|
|
102
109
|
crelte.router._internal.onLoad = (req, opts) => {
|
|
103
110
|
const cr = new CrelteRequest(crelte, req);
|
|
104
|
-
return loadFn(cr,
|
|
111
|
+
return loadFn(cr, opts);
|
|
105
112
|
};
|
|
106
113
|
|
|
107
114
|
// render Space
|
package/src/init/server.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CrelteBuilder } from '../Crelte.js';
|
|
2
2
|
import { SiteFromGraphQl } from '../routing/Site.js';
|
|
3
|
-
import {
|
|
3
|
+
import { pluginsBeforeRender, prepareLoadFn, setupPlugins } from './shared.js';
|
|
4
4
|
import SsrComponents from '../ssr/SsrComponents.js';
|
|
5
5
|
import SsrCache from '../ssr/SsrCache.js';
|
|
6
6
|
import ServerCookies from '../cookies/ServerCookies.js';
|
|
@@ -85,11 +85,18 @@ export async function main(data: MainData): Promise<{
|
|
|
85
85
|
// setup plugins
|
|
86
86
|
setupPlugins(crelte, data.app.plugins ?? []);
|
|
87
87
|
|
|
88
|
+
const loadFn = await prepareLoadFn(
|
|
89
|
+
crelte,
|
|
90
|
+
data.app,
|
|
91
|
+
data.entryQuery,
|
|
92
|
+
data.globalQuery,
|
|
93
|
+
);
|
|
94
|
+
|
|
88
95
|
// setup load Data
|
|
89
96
|
|
|
90
97
|
crelte.router._internal.onLoad = req => {
|
|
91
98
|
const cr = new CrelteRequest(crelte, req);
|
|
92
|
-
return loadFn(cr
|
|
99
|
+
return loadFn(cr);
|
|
93
100
|
};
|
|
94
101
|
|
|
95
102
|
const { success, redirect, req, props } =
|