crelte 0.1.0 → 0.1.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 +89 -25
- package/dist/Crelte.d.ts.map +1 -1
- package/dist/Crelte.js +79 -38
- package/dist/CrelteRequest.d.ts +63 -0
- package/dist/CrelteRequest.d.ts.map +1 -0
- package/dist/CrelteRequest.js +94 -0
- package/dist/blocks/Blocks.d.ts +27 -3
- package/dist/blocks/Blocks.d.ts.map +1 -1
- package/dist/blocks/Blocks.js +8 -0
- package/dist/blocks/Blocks.svelte +1 -1
- package/dist/blocks/Blocks.svelte.d.ts +36 -4
- package/dist/blocks/Blocks.svelte.d.ts.map +1 -1
- package/dist/blocks/index.d.ts +6 -3
- package/dist/blocks/index.d.ts.map +1 -1
- package/dist/blocks/index.js +3 -2
- package/dist/cookies/ServerCookies.d.ts +1 -1
- package/dist/cookies/ServerCookies.d.ts.map +1 -1
- package/dist/cookies/index.d.ts +7 -0
- package/dist/cookies/index.d.ts.map +1 -1
- package/dist/graphql/GraphQl.d.ts +53 -14
- package/dist/graphql/GraphQl.d.ts.map +1 -1
- package/dist/graphql/GraphQl.js +44 -23
- package/dist/graphql/index.d.ts +1 -1
- package/dist/graphql/index.d.ts.map +1 -1
- package/dist/graphql/index.js +2 -2
- package/dist/index.d.ts +55 -22
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +50 -23
- package/dist/init/client.d.ts +43 -2
- package/dist/init/client.d.ts.map +1 -1
- package/dist/init/client.js +26 -6
- package/dist/init/server.d.ts +49 -2
- package/dist/init/server.d.ts.map +1 -1
- package/dist/init/server.js +56 -6
- package/dist/init/shared.d.ts +5 -4
- package/dist/init/shared.d.ts.map +1 -1
- package/dist/init/shared.js +3 -3
- package/dist/loadData/Globals.d.ts +41 -2
- package/dist/loadData/Globals.d.ts.map +1 -1
- package/dist/loadData/Globals.js +33 -5
- package/dist/loadData/index.d.ts +74 -11
- package/dist/loadData/index.d.ts.map +1 -1
- package/dist/loadData/index.js +5 -8
- package/dist/plugins/Events.d.ts +18 -5
- package/dist/plugins/Events.d.ts.map +1 -1
- package/dist/plugins/Events.js +3 -0
- package/dist/plugins/Plugins.d.ts +28 -2
- package/dist/plugins/Plugins.d.ts.map +1 -1
- package/dist/plugins/Plugins.js +8 -0
- package/dist/routing/History.d.ts +6 -3
- package/dist/routing/History.d.ts.map +1 -1
- package/dist/routing/History.js +7 -1
- package/dist/routing/InnerRouter.d.ts +10 -9
- package/dist/routing/InnerRouter.d.ts.map +1 -1
- package/dist/routing/InnerRouter.js +47 -35
- package/dist/routing/PageLoader.d.ts +5 -5
- package/dist/routing/PageLoader.d.ts.map +1 -1
- package/dist/routing/PageLoader.js +7 -7
- package/dist/routing/Request.d.ts +102 -0
- package/dist/routing/Request.d.ts.map +1 -0
- package/dist/routing/Request.js +128 -0
- package/dist/routing/Route.d.ts +73 -5
- package/dist/routing/Route.d.ts.map +1 -1
- package/dist/routing/Route.js +71 -6
- package/dist/routing/Router.d.ts +59 -52
- package/dist/routing/Router.d.ts.map +1 -1
- package/dist/routing/Router.js +95 -116
- package/dist/routing/Site.d.ts +1 -1
- package/dist/routing/Site.js +1 -1
- package/dist/routing/index.d.ts +4 -3
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/index.js +2 -1
- package/dist/ssr/SsrCache.d.ts +17 -0
- package/dist/ssr/SsrCache.d.ts.map +1 -1
- package/dist/ssr/SsrCache.js +17 -4
- package/dist/ssr/SsrComponents.d.ts +1 -0
- package/dist/ssr/SsrComponents.d.ts.map +1 -1
- package/dist/ssr/SsrComponents.js +1 -0
- package/package.json +6 -6
- package/src/Crelte.ts +124 -52
- package/src/CrelteRequest.ts +124 -0
- package/src/blocks/Blocks.svelte +35 -18
- package/src/blocks/Blocks.ts +38 -6
- package/src/blocks/index.ts +19 -10
- package/src/cookies/ServerCookies.ts +1 -1
- package/src/cookies/index.ts +7 -1
- package/src/graphql/GraphQl.ts +79 -27
- package/src/graphql/index.ts +7 -1
- package/src/index.ts +65 -29
- package/src/init/client.ts +55 -10
- package/src/init/server.ts +70 -10
- package/src/init/shared.ts +8 -7
- package/src/loadData/Globals.ts +43 -7
- package/src/loadData/index.ts +76 -13
- package/src/plugins/Events.ts +16 -5
- package/src/plugins/Plugins.ts +28 -2
- package/src/routing/History.ts +13 -4
- package/src/routing/InnerRouter.ts +55 -39
- package/src/routing/PageLoader.ts +10 -10
- package/src/routing/Request.ts +175 -0
- package/src/routing/Route.ts +73 -8
- package/src/routing/Router.ts +108 -162
- package/src/routing/Site.ts +1 -1
- package/src/routing/index.ts +12 -3
- package/src/ssr/SsrCache.ts +17 -4
- package/src/ssr/SsrComponents.ts +1 -0
- package/dist/CrelteBase.d.ts +0 -16
- package/dist/CrelteBase.d.ts.map +0 -1
- package/dist/CrelteBase.js +0 -1
- package/dist/CrelteRouted.d.ts +0 -50
- package/dist/CrelteRouted.d.ts.map +0 -1
- package/dist/CrelteRouted.js +0 -88
- package/src/CrelteBase.ts +0 -24
- package/src/CrelteRouted.ts +0 -128
package/src/graphql/GraphQl.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import Route from '../routing/Route.js';
|
|
1
2
|
import SsrCache, { calcKey as ssrCacheCalcKey } from '../ssr/SsrCache.js';
|
|
2
3
|
|
|
3
4
|
export type GraphQlErrorResponse = {
|
|
@@ -5,7 +6,21 @@ export type GraphQlErrorResponse = {
|
|
|
5
6
|
body?: string;
|
|
6
7
|
};
|
|
7
8
|
|
|
9
|
+
/**
|
|
10
|
+
* A GraphQL query
|
|
11
|
+
*
|
|
12
|
+
* You should almost never create this object directly
|
|
13
|
+
* but instead import a graphql file or use the gql template.
|
|
14
|
+
*/
|
|
15
|
+
export interface GraphQlQuery {
|
|
16
|
+
path?: string;
|
|
17
|
+
query: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
8
20
|
// todo improve this
|
|
21
|
+
/**
|
|
22
|
+
* A GraphQL error
|
|
23
|
+
*/
|
|
9
24
|
export class GraphQlError extends Error {
|
|
10
25
|
resp: GraphQlErrorResponse;
|
|
11
26
|
ctx: any;
|
|
@@ -18,24 +33,44 @@ export class GraphQlError extends Error {
|
|
|
18
33
|
this.ctx = ctx;
|
|
19
34
|
}
|
|
20
35
|
|
|
36
|
+
/**
|
|
37
|
+
* The status code of the response
|
|
38
|
+
*/
|
|
21
39
|
status(): number {
|
|
22
40
|
return this.resp?.status ?? 500;
|
|
23
41
|
}
|
|
24
42
|
|
|
25
43
|
__isGraphQlError__() {}
|
|
26
44
|
|
|
45
|
+
/**
|
|
46
|
+
* The error message in string form
|
|
47
|
+
*/
|
|
27
48
|
get message(): string {
|
|
28
49
|
return 'GraphqlError: ' + JSON.stringify(this.resp);
|
|
29
50
|
}
|
|
30
51
|
}
|
|
31
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Options for the GraphQl class
|
|
55
|
+
*/
|
|
32
56
|
export type GraphQlOptions = {
|
|
33
57
|
debug?: boolean;
|
|
34
58
|
debugTiming?: boolean;
|
|
35
59
|
};
|
|
36
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Options to configure the request
|
|
63
|
+
*
|
|
64
|
+
* If you use `Crelte*.query` the following options
|
|
65
|
+
* will be set automatically:
|
|
66
|
+
* - path
|
|
67
|
+
* - route
|
|
68
|
+
* - previewToken
|
|
69
|
+
* - siteToken
|
|
70
|
+
*/
|
|
37
71
|
export type GraphQlRequestOptions = {
|
|
38
72
|
path?: string;
|
|
73
|
+
route?: Route;
|
|
39
74
|
ignoreStatusCode?: boolean;
|
|
40
75
|
previewToken?: string;
|
|
41
76
|
siteToken?: string;
|
|
@@ -45,6 +80,9 @@ export type GraphQlRequestOptions = {
|
|
|
45
80
|
status?: number;
|
|
46
81
|
};
|
|
47
82
|
|
|
83
|
+
/**
|
|
84
|
+
* A GraphQL client
|
|
85
|
+
*/
|
|
48
86
|
export default class GraphQl {
|
|
49
87
|
private endpoint: string;
|
|
50
88
|
private ssrCache: SsrCache;
|
|
@@ -57,9 +95,7 @@ export default class GraphQl {
|
|
|
57
95
|
private loggingTiming: boolean;
|
|
58
96
|
|
|
59
97
|
/**
|
|
60
|
-
* Create a new GraphQL
|
|
61
|
-
*
|
|
62
|
-
* @param {Object} [opts={}] opts `{ debug: false, debugTiming: false }`
|
|
98
|
+
* Create a new GraphQL client
|
|
63
99
|
*/
|
|
64
100
|
constructor(
|
|
65
101
|
endpoint: string,
|
|
@@ -74,9 +110,41 @@ export default class GraphQl {
|
|
|
74
110
|
this.loggingTiming = opts?.debugTiming ?? false;
|
|
75
111
|
}
|
|
76
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Run a GraphQl Query
|
|
115
|
+
*
|
|
116
|
+
* @param query the default export from a graphql file or the gql`query {}`
|
|
117
|
+
* function
|
|
118
|
+
* @param variables variables that should be passed to the
|
|
119
|
+
* graphql query
|
|
120
|
+
*/
|
|
121
|
+
async query(
|
|
122
|
+
query: GraphQlQuery,
|
|
123
|
+
variables: Record<string, unknown> = {},
|
|
124
|
+
opts: GraphQlRequestOptions = {},
|
|
125
|
+
): Promise<unknown> {
|
|
126
|
+
if (opts.route) {
|
|
127
|
+
const search = opts.route.search;
|
|
128
|
+
|
|
129
|
+
// todo should variables contain siteId
|
|
130
|
+
// or maybe gql should detect loadData and add it there
|
|
131
|
+
// it might make export const loadData = query; easier
|
|
132
|
+
|
|
133
|
+
if (search.has('token') && search.get('x-craft-live-preview')) {
|
|
134
|
+
opts.previewToken = search.get('token')!;
|
|
135
|
+
} else if (search.has('siteToken')) {
|
|
136
|
+
opts.siteToken = search.get('siteToken')!;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
opts.path = query.path;
|
|
141
|
+
|
|
142
|
+
return await this.request(query.query, variables, opts);
|
|
143
|
+
}
|
|
144
|
+
|
|
77
145
|
// returns {} or throws
|
|
78
146
|
// options: {ignoreStatusCode, previewToken, caching, headers}
|
|
79
|
-
async request(
|
|
147
|
+
private async request(
|
|
80
148
|
query: string,
|
|
81
149
|
variables: Record<string, unknown> = {},
|
|
82
150
|
options: GraphQlRequestOptions = {},
|
|
@@ -219,38 +287,22 @@ export default class GraphQl {
|
|
|
219
287
|
}
|
|
220
288
|
}
|
|
221
289
|
|
|
222
|
-
export class GraphQlQuery {
|
|
223
|
-
query: string;
|
|
224
|
-
path: string;
|
|
225
|
-
|
|
226
|
-
constructor(query: string, path: string) {
|
|
227
|
-
this.query = query;
|
|
228
|
-
this.path = path;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/// doc hidden
|
|
232
|
-
__GraphQlQuery__() {
|
|
233
|
-
return true;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
290
|
/** Returns true if the passed object is a GraphQlQuery */
|
|
238
291
|
export function isGraphQlQuery(obj: any): obj is GraphQlQuery {
|
|
239
292
|
return (
|
|
240
|
-
typeof obj === 'object' &&
|
|
241
|
-
obj !== null &&
|
|
242
|
-
typeof obj.__GraphQlQuery__ === 'function'
|
|
293
|
+
typeof obj === 'object' && obj !== null && typeof obj.query === 'string'
|
|
243
294
|
);
|
|
244
295
|
}
|
|
245
296
|
|
|
246
297
|
/**
|
|
247
|
-
*
|
|
298
|
+
* Create a GraphQL query string with variables.
|
|
248
299
|
* @param strings
|
|
249
300
|
* @param keys
|
|
250
301
|
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
* const query = gql`query ($id: ID!) { page(id: $id) { id } }
|
|
302
|
+
* ## Example
|
|
303
|
+
* ```
|
|
304
|
+
* const query = gql`query ($id: ID!) { page(id: $id) { id } }`;
|
|
305
|
+
* ```
|
|
254
306
|
*/
|
|
255
307
|
export function gql(
|
|
256
308
|
strings: TemplateStringsArray | string[] | string,
|
|
@@ -277,5 +329,5 @@ export function gql(
|
|
|
277
329
|
}
|
|
278
330
|
});
|
|
279
331
|
|
|
280
|
-
return
|
|
332
|
+
return { query, path: import.meta.url };
|
|
281
333
|
}
|
package/src/graphql/index.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
import { getContext } from 'svelte';
|
|
1
|
+
import { getContext, onDestroy } from 'svelte';
|
|
2
2
|
import type Route from './routing/Route.js';
|
|
3
3
|
import type Router from './routing/Router.js';
|
|
4
4
|
import type SsrCache from './ssr/SsrCache.js';
|
|
5
5
|
import type Site from './routing/Site.js';
|
|
6
6
|
import type GraphQl from './graphql/GraphQl.js';
|
|
7
|
-
import Crelte from './Crelte.js';
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { Readable } from 'crelte-std/stores';
|
|
7
|
+
import Crelte, { type QueryOptions } from './Crelte.js';
|
|
8
|
+
import CrelteRequest from './CrelteRequest.js';
|
|
9
|
+
import type { Global, GlobalData } from './loadData/Globals.js';
|
|
10
|
+
import type { Cookies } from './cookies/index.js';
|
|
11
|
+
import type { Readable } from 'crelte-std/stores';
|
|
13
12
|
|
|
14
|
-
export { Crelte,
|
|
15
|
-
export type { CrelteBase };
|
|
13
|
+
export { Crelte, CrelteRequest, type QueryOptions };
|
|
16
14
|
|
|
17
15
|
/**
|
|
18
|
-
* Get
|
|
16
|
+
* Get Crelte from the current context
|
|
17
|
+
*
|
|
18
|
+
* ## Note
|
|
19
|
+
* This only works during component initialisation.
|
|
19
20
|
*/
|
|
20
21
|
export function getCrelte(): Crelte {
|
|
21
22
|
return getContext('crelte');
|
|
@@ -23,6 +24,9 @@ export function getCrelte(): Crelte {
|
|
|
23
24
|
|
|
24
25
|
/**
|
|
25
26
|
* Get the router from the current context
|
|
27
|
+
*
|
|
28
|
+
* ## Note
|
|
29
|
+
* This only works during component initialisation.
|
|
26
30
|
*/
|
|
27
31
|
export function getRouter(): Router {
|
|
28
32
|
return getCrelte().router;
|
|
@@ -30,6 +34,9 @@ export function getRouter(): Router {
|
|
|
30
34
|
|
|
31
35
|
/**
|
|
32
36
|
* Get the SSR cache from the current context
|
|
37
|
+
*
|
|
38
|
+
* ## Note
|
|
39
|
+
* This only works during component initialisation.
|
|
33
40
|
*/
|
|
34
41
|
export function getSsrCache(): SsrCache {
|
|
35
42
|
return getCrelte().ssrCache;
|
|
@@ -37,56 +44,64 @@ export function getSsrCache(): SsrCache {
|
|
|
37
44
|
|
|
38
45
|
/**
|
|
39
46
|
* Get the GraphQl from the current context
|
|
47
|
+
*
|
|
48
|
+
* ## Note
|
|
49
|
+
* This only works during component initialisation.
|
|
40
50
|
*/
|
|
41
51
|
export function getGraphQl(): GraphQl {
|
|
42
52
|
return getCrelte().graphQl;
|
|
43
53
|
}
|
|
44
54
|
|
|
45
55
|
/**
|
|
46
|
-
* Get the current route
|
|
56
|
+
* Get a store with the current route
|
|
57
|
+
*
|
|
58
|
+
* ## Note
|
|
59
|
+
* This only works during component initialisation.
|
|
47
60
|
*/
|
|
48
61
|
export function getRoute(): Readable<Route> {
|
|
49
62
|
return getRouter().route;
|
|
50
63
|
}
|
|
51
64
|
|
|
52
65
|
/**
|
|
53
|
-
* Get the current site
|
|
66
|
+
* Get a store with the current site
|
|
67
|
+
*
|
|
68
|
+
* ## Note
|
|
69
|
+
* This only works during component initialisation.
|
|
54
70
|
*/
|
|
55
71
|
export function getSite(): Readable<Site> {
|
|
56
72
|
return getRouter().site;
|
|
57
73
|
}
|
|
58
74
|
|
|
59
75
|
/**
|
|
60
|
-
*
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Get the next site
|
|
68
|
-
*/
|
|
69
|
-
export function getNextSite(): Readable<Site> {
|
|
70
|
-
return getRouter().nextSite;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* returns an env Variables, always needs to be prefixed VITE_
|
|
75
|
-
* Except ENDPOINT_URL and CRAFT_WEB_URL
|
|
76
|
+
* returns an env variable from the craft/.env file.
|
|
77
|
+
* All env variables need to start with VITE_
|
|
78
|
+
* except ENDPOINT_URL and CRAFT_WEB_URL
|
|
79
|
+
*
|
|
80
|
+
* ## Note
|
|
81
|
+
* This only works during component initialisation.
|
|
76
82
|
*/
|
|
83
|
+
export function getEnv(name: 'ENDPOINT_URL'): string;
|
|
84
|
+
export function getEnv(name: 'CRAFT_WEB_URL'): string;
|
|
85
|
+
export function getEnv(name: string): string | null;
|
|
77
86
|
export function getEnv(name: string): string | null {
|
|
78
87
|
return getCrelte().getEnv(name);
|
|
79
88
|
}
|
|
80
89
|
|
|
81
90
|
/**
|
|
82
91
|
* returns a store which indicates if the a page is loading
|
|
92
|
+
*
|
|
93
|
+
* ## Note
|
|
94
|
+
* This only works during component initialisation.
|
|
83
95
|
*/
|
|
84
96
|
export function getLoading(): Readable<boolean> {
|
|
85
97
|
return getRouter().loading;
|
|
86
98
|
}
|
|
87
99
|
|
|
88
100
|
/**
|
|
89
|
-
* returns a store which indicates the loading progress
|
|
101
|
+
* returns a store which indicates the loading progress between 0 and 1
|
|
102
|
+
*
|
|
103
|
+
* ## Note
|
|
104
|
+
* This only works during component initialisation.
|
|
90
105
|
*/
|
|
91
106
|
export function getLoadingProgress(): Readable<number> {
|
|
92
107
|
return getRouter().loadingProgress;
|
|
@@ -94,6 +109,9 @@ export function getLoadingProgress(): Readable<number> {
|
|
|
94
109
|
|
|
95
110
|
/**
|
|
96
111
|
* returns a store which contains a globalSet
|
|
112
|
+
*
|
|
113
|
+
* ## Note
|
|
114
|
+
* This only works during component initialisation.
|
|
97
115
|
*/
|
|
98
116
|
export function getGlobal<T extends GlobalData>(
|
|
99
117
|
name: string,
|
|
@@ -103,7 +121,25 @@ export function getGlobal<T extends GlobalData>(
|
|
|
103
121
|
|
|
104
122
|
/**
|
|
105
123
|
* returns the cookies instance
|
|
124
|
+
*
|
|
125
|
+
* ## Note
|
|
126
|
+
* This only works during component initialisation.
|
|
106
127
|
*/
|
|
107
128
|
export function getCookies(): Cookies {
|
|
108
129
|
return getCrelte().cookies;
|
|
109
130
|
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Listen for requests
|
|
134
|
+
*
|
|
135
|
+
* ## Note
|
|
136
|
+
* This only works during component initialisation.
|
|
137
|
+
*/
|
|
138
|
+
export function onRequest(fn: (cr: CrelteRequest) => void) {
|
|
139
|
+
const crelte = getCrelte();
|
|
140
|
+
const rmListener = crelte.router.onRequest((req, site) => {
|
|
141
|
+
fn(new CrelteRequest(crelte, req, site));
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
onDestroy(rmListener);
|
|
145
|
+
}
|
package/src/init/client.ts
CHANGED
|
@@ -1,23 +1,49 @@
|
|
|
1
1
|
import { CrelteBuilder } from '../Crelte.js';
|
|
2
|
+
import CrelteRequest from '../CrelteRequest.js';
|
|
3
|
+
import { GraphQlQuery } from '../graphql/GraphQl.js';
|
|
2
4
|
import { SiteFromGraphQl } from '../routing/Site.js';
|
|
3
5
|
import { loadFn, pluginsBeforeRender, setupPlugins } from './shared.js';
|
|
4
6
|
import { tick } from 'svelte';
|
|
5
7
|
|
|
8
|
+
/**
|
|
9
|
+
* The main function to start the client side rendering
|
|
10
|
+
*/
|
|
6
11
|
export type MainData = {
|
|
7
|
-
|
|
12
|
+
/** The App.svelte module */
|
|
8
13
|
app: any;
|
|
9
|
-
|
|
14
|
+
/** The Error.svelte module */
|
|
10
15
|
errorPage: any;
|
|
11
|
-
|
|
12
|
-
|
|
16
|
+
/** The entry query from queries/entry.graphql */
|
|
17
|
+
entryQuery: GraphQlQuery;
|
|
18
|
+
/** The global query from queries/global.graphql */
|
|
19
|
+
globalQuery?: GraphQlQuery;
|
|
13
20
|
|
|
14
21
|
// options
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Preload pages on mouse over
|
|
25
|
+
* @default false
|
|
26
|
+
*/
|
|
15
27
|
preloadOnMouseOver?: boolean;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Use view transitions
|
|
31
|
+
* @default false
|
|
32
|
+
*/
|
|
16
33
|
viewTransition?: boolean;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Play the intro animation
|
|
37
|
+
* @default false
|
|
38
|
+
*/
|
|
17
39
|
playIntro?: boolean;
|
|
18
40
|
|
|
19
41
|
// debug
|
|
42
|
+
|
|
43
|
+
/** Enable graphql query debugging */
|
|
20
44
|
graphQlDebug?: boolean;
|
|
45
|
+
|
|
46
|
+
/** Enable request and render timing measurement */
|
|
21
47
|
debugTiming?: boolean;
|
|
22
48
|
};
|
|
23
49
|
|
|
@@ -31,6 +57,25 @@ const mainDataDefault = {
|
|
|
31
57
|
debugTiming: false,
|
|
32
58
|
};
|
|
33
59
|
|
|
60
|
+
/**
|
|
61
|
+
* The main function to start the client side rendering
|
|
62
|
+
*
|
|
63
|
+
* ## Example
|
|
64
|
+
* ```
|
|
65
|
+
* import * as app from './App.svelte';
|
|
66
|
+
* import * as errorPage from './Error.svelte';
|
|
67
|
+
* import entryQuery from './queries/entry.graphql';
|
|
68
|
+
* import globalQuery from './queries/global.graphql';
|
|
69
|
+
* import { main } from 'crelte/client';
|
|
70
|
+
*
|
|
71
|
+
* main({
|
|
72
|
+
* app,
|
|
73
|
+
* errorPage,
|
|
74
|
+
* entryQuery,
|
|
75
|
+
* globalQuery,
|
|
76
|
+
* });
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
34
79
|
export function main(data: MainData) {
|
|
35
80
|
data = { ...mainDataDefault, ...data };
|
|
36
81
|
|
|
@@ -57,7 +102,7 @@ export function main(data: MainData) {
|
|
|
57
102
|
debugTiming: data.debugTiming,
|
|
58
103
|
});
|
|
59
104
|
|
|
60
|
-
// on the client the cookies are always
|
|
105
|
+
// on the client the cookies are always coming from document.cookie
|
|
61
106
|
builder.setupCookies('');
|
|
62
107
|
|
|
63
108
|
const csites = builder.ssrCache.get('crelteSites') as SiteFromGraphQl[];
|
|
@@ -86,8 +131,8 @@ export function main(data: MainData) {
|
|
|
86
131
|
|
|
87
132
|
// setup load Data
|
|
88
133
|
|
|
89
|
-
crelte.router._internal.onLoad = (
|
|
90
|
-
const cr = crelte
|
|
134
|
+
crelte.router._internal.onLoad = (req, site, opts) => {
|
|
135
|
+
const cr = new CrelteRequest(crelte, req, site);
|
|
91
136
|
return loadFn(cr, data.app, data.entryQuery, data.globalQuery, opts);
|
|
92
137
|
};
|
|
93
138
|
|
|
@@ -111,7 +156,7 @@ export function main(data: MainData) {
|
|
|
111
156
|
let firstLoad = true;
|
|
112
157
|
crelte.router._internal.onLoaded = async (
|
|
113
158
|
success,
|
|
114
|
-
|
|
159
|
+
req,
|
|
115
160
|
site,
|
|
116
161
|
readyForProps,
|
|
117
162
|
) => {
|
|
@@ -132,7 +177,7 @@ export function main(data: MainData) {
|
|
|
132
177
|
return handleLoadError(readyForProps());
|
|
133
178
|
}
|
|
134
179
|
|
|
135
|
-
const cr = crelte
|
|
180
|
+
const cr = new CrelteRequest(crelte, req, site);
|
|
136
181
|
|
|
137
182
|
const startTime = data.debugTiming ? Date.now() : null;
|
|
138
183
|
let render = async () => {
|
|
@@ -149,7 +194,7 @@ export function main(data: MainData) {
|
|
|
149
194
|
);
|
|
150
195
|
}
|
|
151
196
|
|
|
152
|
-
crelte.router._internal.domReady(
|
|
197
|
+
crelte.router._internal.domReady(cr.req);
|
|
153
198
|
};
|
|
154
199
|
|
|
155
200
|
// render with view Transition if enabled and not in hydration
|
package/src/init/server.ts
CHANGED
|
@@ -4,6 +4,8 @@ import { loadFn, pluginsBeforeRender, 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';
|
|
7
|
+
import CrelteRequest from '../CrelteRequest.js';
|
|
8
|
+
import { gql, GraphQlQuery } from '../graphql/GraphQl.js';
|
|
7
9
|
|
|
8
10
|
export type ServerData = {
|
|
9
11
|
url: string;
|
|
@@ -16,19 +18,49 @@ export type ServerData = {
|
|
|
16
18
|
cookies?: string;
|
|
17
19
|
};
|
|
18
20
|
|
|
21
|
+
/**
|
|
22
|
+
* The main function to start the server side rendering
|
|
23
|
+
*/
|
|
19
24
|
export type MainData = {
|
|
20
|
-
|
|
25
|
+
/** The App.svelte module */
|
|
21
26
|
app: any;
|
|
22
|
-
|
|
23
|
-
|
|
27
|
+
/** The entry query from queries/entry.graphql */
|
|
28
|
+
entryQuery: GraphQlQuery;
|
|
29
|
+
/** The global query from queries/global.graphql */
|
|
30
|
+
globalQuery?: GraphQlQuery;
|
|
24
31
|
|
|
32
|
+
/** Server data provided by crelte-node */
|
|
25
33
|
serverData: ServerData;
|
|
26
34
|
|
|
27
35
|
// debug
|
|
36
|
+
|
|
37
|
+
/** Enable graphql query debugging */
|
|
28
38
|
graphQlDebug?: boolean;
|
|
39
|
+
|
|
40
|
+
/** Enable request and render timing measurement */
|
|
29
41
|
debugTiming?: boolean;
|
|
30
42
|
};
|
|
31
43
|
|
|
44
|
+
/**
|
|
45
|
+
* The main function to start the server side rendering
|
|
46
|
+
*
|
|
47
|
+
* ## Example
|
|
48
|
+
* ```
|
|
49
|
+
* import * as app from './App.svelte';
|
|
50
|
+
* import entryQuery from './queries/entry.graphql';
|
|
51
|
+
* import globalQuery from './queries/global.graphql';
|
|
52
|
+
* import { main } from 'crelte/server';
|
|
53
|
+
*
|
|
54
|
+
* export function render(serverData) {
|
|
55
|
+
* return main({
|
|
56
|
+
* app,
|
|
57
|
+
* entryQuery,
|
|
58
|
+
* globalQuery,
|
|
59
|
+
* serverData,
|
|
60
|
+
* });
|
|
61
|
+
* }
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
32
64
|
export async function main(data: MainData): Promise<{
|
|
33
65
|
status: number;
|
|
34
66
|
location?: string;
|
|
@@ -64,12 +96,12 @@ export async function main(data: MainData): Promise<{
|
|
|
64
96
|
|
|
65
97
|
// setup load Data
|
|
66
98
|
|
|
67
|
-
crelte.router._internal.onLoad = (
|
|
68
|
-
const cr = crelte
|
|
99
|
+
crelte.router._internal.onLoad = (req, site) => {
|
|
100
|
+
const cr = new CrelteRequest(crelte, req, site);
|
|
69
101
|
return loadFn(cr, data.app, data.entryQuery, data.globalQuery);
|
|
70
102
|
};
|
|
71
103
|
|
|
72
|
-
const { success, redirect,
|
|
104
|
+
const { success, redirect, req, site, props } =
|
|
73
105
|
await crelte.router._internal.initServer(
|
|
74
106
|
data.serverData.url,
|
|
75
107
|
data.serverData.acceptLang,
|
|
@@ -79,7 +111,7 @@ export async function main(data: MainData): Promise<{
|
|
|
79
111
|
if (redirect) {
|
|
80
112
|
return {
|
|
81
113
|
status: 302,
|
|
82
|
-
location:
|
|
114
|
+
location: req.url.toString(),
|
|
83
115
|
};
|
|
84
116
|
}
|
|
85
117
|
|
|
@@ -87,7 +119,7 @@ export async function main(data: MainData): Promise<{
|
|
|
87
119
|
const ssrComponents = new SsrComponents();
|
|
88
120
|
ssrComponents.addToContext(context);
|
|
89
121
|
|
|
90
|
-
pluginsBeforeRender(crelte
|
|
122
|
+
pluginsBeforeRender(new CrelteRequest(crelte, req, site));
|
|
91
123
|
crelte.globals._updateSiteId(site.id);
|
|
92
124
|
// eslint-disable-next-line prefer-const
|
|
93
125
|
let { html, head } = data.app.default.render(props, { context });
|
|
@@ -125,6 +157,23 @@ export type MainErrorData = {
|
|
|
125
157
|
serverData: ServerData;
|
|
126
158
|
};
|
|
127
159
|
|
|
160
|
+
/**
|
|
161
|
+
* The main function to start the server side rendering
|
|
162
|
+
* if there was an error
|
|
163
|
+
*
|
|
164
|
+
* ## Example
|
|
165
|
+
* ```
|
|
166
|
+
* import * as errorPage from './Error.svelte';
|
|
167
|
+
*
|
|
168
|
+
* export function renderError(error, serverData) {
|
|
169
|
+
* return mainError({
|
|
170
|
+
* error,
|
|
171
|
+
* errorPage,
|
|
172
|
+
* serverData
|
|
173
|
+
* });
|
|
174
|
+
* }
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
128
177
|
export async function mainError(
|
|
129
178
|
data: MainErrorData,
|
|
130
179
|
): Promise<{ status: number; html?: string }> {
|
|
@@ -164,8 +213,19 @@ async function loadSites(builder: CrelteBuilder): Promise<SiteFromGraphQl[]> {
|
|
|
164
213
|
return globalThis['CRAFT_SITES_CACHED'];
|
|
165
214
|
}
|
|
166
215
|
|
|
167
|
-
const resp = (await builder.graphQl.
|
|
168
|
-
|
|
216
|
+
const resp = (await builder.graphQl.query(
|
|
217
|
+
gql`
|
|
218
|
+
query {
|
|
219
|
+
crelteSites {
|
|
220
|
+
id
|
|
221
|
+
baseUrl
|
|
222
|
+
language
|
|
223
|
+
name
|
|
224
|
+
handle
|
|
225
|
+
primary
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
`,
|
|
169
229
|
{},
|
|
170
230
|
// don't cache since we cache ourself
|
|
171
231
|
{ caching: false },
|
package/src/init/shared.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import CrelteRouted, { GraphQlQuery } from '../CrelteRouted.js';
|
|
2
1
|
import Crelte from '../Crelte.js';
|
|
2
|
+
import CrelteRequest from '../CrelteRequest.js';
|
|
3
|
+
import { GraphQlQuery } from '../graphql/GraphQl.js';
|
|
3
4
|
import { LoadData, callLoadData } from '../loadData/index.js';
|
|
4
5
|
import { PluginCreator } from '../plugins/Plugins.js';
|
|
5
6
|
import { LoadOptions } from '../routing/PageLoader.js';
|
|
@@ -17,7 +18,7 @@ interface TemplateModule<E, T> {
|
|
|
17
18
|
// svelte component
|
|
18
19
|
default: any;
|
|
19
20
|
|
|
20
|
-
loadData?(cr:
|
|
21
|
+
loadData?(cr: CrelteRequest, entry: E): Promise<T>;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
type LazyTemplateModule<E, T> =
|
|
@@ -31,7 +32,7 @@ export function setupPlugins(crelte: Crelte, plugins: PluginCreator[]) {
|
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
export function pluginsBeforeRender(cr:
|
|
35
|
+
export function pluginsBeforeRender(cr: CrelteRequest): void {
|
|
35
36
|
cr.events.trigger('beforeRender', cr);
|
|
36
37
|
}
|
|
37
38
|
|
|
@@ -58,7 +59,7 @@ export function getEntry(page: any): any {
|
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
export async function loadFn<D, E, T>(
|
|
61
|
-
cr:
|
|
62
|
+
cr: CrelteRequest,
|
|
62
63
|
app: App<D, E, T>,
|
|
63
64
|
entryQuery: GraphQlQuery,
|
|
64
65
|
globalQuery?: GraphQlQuery,
|
|
@@ -91,14 +92,14 @@ export async function loadFn<D, E, T>(
|
|
|
91
92
|
}
|
|
92
93
|
|
|
93
94
|
let pageProm = null;
|
|
94
|
-
if (cr.
|
|
95
|
-
let uri = decodeURI(cr.
|
|
95
|
+
if (cr.req.site) {
|
|
96
|
+
let uri = decodeURI(cr.req.uri);
|
|
96
97
|
if (uri.startsWith('/')) uri = uri.substring(1);
|
|
97
98
|
if (uri === '' || uri === '/') uri = '__home__';
|
|
98
99
|
|
|
99
100
|
pageProm = cr.query(entryQuery, {
|
|
100
101
|
uri,
|
|
101
|
-
siteId: cr.
|
|
102
|
+
siteId: cr.req.site.id,
|
|
102
103
|
});
|
|
103
104
|
}
|
|
104
105
|
|