crelte 0.2.2 → 0.3.1

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 (55) hide show
  1. package/dist/Crelte.d.ts +61 -9
  2. package/dist/Crelte.d.ts.map +1 -1
  3. package/dist/Crelte.js +42 -10
  4. package/dist/CrelteRequest.d.ts +3 -11
  5. package/dist/CrelteRequest.d.ts.map +1 -1
  6. package/dist/CrelteRequest.js +9 -19
  7. package/dist/graphql/GraphQl.d.ts +7 -0
  8. package/dist/graphql/GraphQl.d.ts.map +1 -1
  9. package/dist/graphql/GraphQl.js +16 -3
  10. package/dist/index.d.ts +10 -4
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +13 -1
  13. package/dist/init/client.d.ts +0 -19
  14. package/dist/init/client.d.ts.map +1 -1
  15. package/dist/init/client.js +9 -12
  16. package/dist/init/server.d.ts +0 -4
  17. package/dist/init/server.d.ts.map +1 -1
  18. package/dist/init/server.js +2 -5
  19. package/dist/init/shared.d.ts.map +1 -1
  20. package/dist/init/shared.js +8 -8
  21. package/dist/loadData/Globals.d.ts +15 -31
  22. package/dist/loadData/Globals.d.ts.map +1 -1
  23. package/dist/loadData/Globals.js +65 -72
  24. package/dist/routing/InnerRouter.d.ts +1 -10
  25. package/dist/routing/InnerRouter.d.ts.map +1 -1
  26. package/dist/routing/InnerRouter.js +28 -23
  27. package/dist/routing/Request.d.ts +2 -0
  28. package/dist/routing/Request.d.ts.map +1 -1
  29. package/dist/routing/Request.js +9 -0
  30. package/dist/routing/Route.d.ts +56 -1
  31. package/dist/routing/Route.d.ts.map +1 -1
  32. package/dist/routing/Route.js +85 -2
  33. package/dist/routing/Router.d.ts +29 -4
  34. package/dist/routing/Router.d.ts.map +1 -1
  35. package/dist/routing/Router.js +39 -12
  36. package/dist/ssr/SsrCache.d.ts.map +1 -1
  37. package/dist/ssr/SsrCache.js +6 -1
  38. package/dist/utils.d.ts +2 -0
  39. package/dist/utils.d.ts.map +1 -0
  40. package/dist/utils.js +8 -0
  41. package/package.json +2 -2
  42. package/src/Crelte.ts +95 -13
  43. package/src/CrelteRequest.ts +14 -27
  44. package/src/graphql/GraphQl.ts +25 -6
  45. package/src/index.ts +19 -8
  46. package/src/init/client.ts +9 -40
  47. package/src/init/server.ts +2 -13
  48. package/src/init/shared.ts +8 -9
  49. package/src/loadData/Globals.ts +76 -93
  50. package/src/routing/InnerRouter.ts +38 -32
  51. package/src/routing/Request.ts +11 -0
  52. package/src/routing/Route.ts +93 -2
  53. package/src/routing/Router.ts +51 -20
  54. package/src/ssr/SsrCache.ts +6 -1
  55. package/src/utils.ts +10 -0
@@ -25,7 +25,7 @@ import { gql } from '../graphql/GraphQl.js';
25
25
  * ```
26
26
  */
27
27
  export async function main(data) {
28
- const builder = new CrelteBuilder();
28
+ const builder = new CrelteBuilder(data.app.config ?? {});
29
29
  // setup viteEnv
30
30
  data.serverData.viteEnv.forEach((v, k) => {
31
31
  builder.ssrCache.set(k, v);
@@ -33,10 +33,7 @@ export async function main(data) {
33
33
  const endpoint = data.serverData.endpoint;
34
34
  builder.ssrCache.set('ENDPOINT_URL', endpoint);
35
35
  builder.ssrCache.set('CRAFT_WEB_URL', data.serverData.craftWeb);
36
- builder.setupGraphQl(endpoint, {
37
- debug: data.graphQlDebug,
38
- debugTiming: data.debugTiming,
39
- });
36
+ builder.setupGraphQl(endpoint);
40
37
  const cookies = data.serverData.cookies ?? '';
41
38
  builder.setupCookies(cookies);
42
39
  const csites = await loadSites(builder, data.serverData);
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../../src/init/shared.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,cAAc,CAAC;AAClC,OAAO,aAAa,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAgB,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,UAAU,GAAG,CAAC,CAAC,EAAE,CAAC;IACjB,cAAc,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IAGhC,aAAa,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;IAE9B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;CACrD;AAED,UAAU,cAAc,CAAC,CAAC,EAAE,CAAC;IAE5B,OAAO,EAAE,GAAG,CAAC;IAEb,QAAQ,CAAC,CAAC,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACnD;AAED,KAAK,kBAAkB,CAAC,CAAC,EAAE,CAAC,IACzB,CAAC,MAAM,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GACrC,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAExB,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,QAKpE;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,aAAa,GAAG,IAAI,CAE3D;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,GAAG,GAAG,GAAG,CAYvC;AAED,wBAAsB,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACnC,EAAE,EAAE,aAAa,EACjB,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,EACd,UAAU,EAAE,YAAY,EACxB,WAAW,CAAC,EAAE,YAAY,EAC1B,QAAQ,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,GAAG,CAAC,CAsGd"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../../src/init/shared.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,cAAc,CAAC;AAClC,OAAO,aAAa,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAgB,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,UAAU,GAAG,CAAC,CAAC,EAAE,CAAC;IACjB,cAAc,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IAGhC,aAAa,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;IAE9B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;CACrD;AAED,UAAU,cAAc,CAAC,CAAC,EAAE,CAAC;IAE5B,OAAO,EAAE,GAAG,CAAC;IAEb,QAAQ,CAAC,CAAC,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACnD;AAED,KAAK,kBAAkB,CAAC,CAAC,EAAE,CAAC,IACzB,CAAC,MAAM,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GACrC,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAExB,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,QAKpE;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,aAAa,GAAG,IAAI,CAE3D;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,GAAG,GAAG,GAAG,CAYvC;AAED,wBAAsB,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACnC,EAAE,EAAE,aAAa,EACjB,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,EACd,UAAU,EAAE,YAAY,EACxB,WAAW,CAAC,EAAE,YAAY,EAC1B,QAAQ,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,GAAG,CAAC,CAqGd"}
@@ -40,19 +40,21 @@ export async function loadFn(cr, app, entryQuery, globalQuery, loadOpts) {
40
40
  dataProm = callLoadData(app.loadGlobalData, cr, null);
41
41
  }
42
42
  let globalProm = null;
43
- if (globalQuery && !cr.globals._wasLoaded()) {
43
+ if (globalQuery && !cr.globals._wasLoaded(cr.site.id)) {
44
44
  globalProm = (async () => {
45
- const res = await cr.query(globalQuery);
45
+ const res = await cr.query(globalQuery, {
46
+ siteId: cr.site.id,
47
+ });
46
48
  // we need to do this sorcery here and can't wait until all
47
49
  // globals functions are done, because some global function
48
50
  // might want to use globals, and for that the function
49
- // getOrWait exists on Globals
51
+ // getAsync exists on Globals
50
52
  cr.globals._setData(cr.site.id, res);
51
53
  return res;
52
54
  })();
53
55
  }
54
56
  let pageProm = null;
55
- if (cr.req.site) {
57
+ if (cr.req.siteMatches()) {
56
58
  let uri = decodeURI(cr.req.uri);
57
59
  if (uri.startsWith('/'))
58
60
  uri = uri.substring(1);
@@ -60,7 +62,7 @@ export async function loadFn(cr, app, entryQuery, globalQuery, loadOpts) {
60
62
  uri = '__home__';
61
63
  pageProm = cr.query(entryQuery, {
62
64
  uri,
63
- siteId: cr.req.site.id,
65
+ siteId: cr.site.id,
64
66
  });
65
67
  }
66
68
  const pluginsLoadGlobalData = cr.events.trigger('loadGlobalData', cr);
@@ -75,13 +77,11 @@ export async function loadFn(cr, app, entryQuery, globalQuery, loadOpts) {
75
77
  if (global) {
76
78
  cr.globals._setData(cr.site.id, global);
77
79
  }
78
- else if (!cr.globals._wasLoaded()) {
80
+ else if (!cr.globals._wasLoaded(cr.site.id)) {
79
81
  // we need to set the global data to an empty object
80
82
  // so any waiters get's triggered
81
83
  cr.globals._setData(cr.site.id, {});
82
84
  }
83
- // allow cr to get the global data
84
- cr._globalDataLoaded();
85
85
  const entry = getEntry(page);
86
86
  let template;
87
87
  if (app.templates) {
@@ -1,19 +1,20 @@
1
- export type GlobalWaiters = [(g: Global<any> | null) => void];
1
+ export type GlobalWaiters<T> = [(g: T | null) => void];
2
2
  export default class Globals {
3
3
  private waiters;
4
- private entries;
5
- private loaded;
6
- private prevSiteId;
4
+ private data;
5
+ private stores;
6
+ private currentSiteId;
7
7
  constructor();
8
+ get<T = any>(name: string, siteId: number): T | null;
8
9
  /**
9
10
  * returns a store which contains a globalSet
10
11
  *
11
12
  * ## Note
12
13
  * This only works in loadData, in loadGlobalData this will
13
14
  * always return null. In that context you should use
14
- * `.getGlobalAsync`
15
+ * `.getAsync`
15
16
  */
16
- get<T extends GlobalData>(name: string): Global<T> | null;
17
+ getStore<T = any>(name: string): Global<T> | null;
17
18
  /**
18
19
  * Get a store which contains a globalSet and wait until it is loaded
19
20
  *
@@ -21,32 +22,21 @@ export default class Globals {
21
22
  * This is only useful in loadGlobalData in all other cases
22
23
  * you can use `.getGlobal` which does return a Promise
23
24
  */
24
- getAsync<T extends GlobalData>(name: string): Promise<Global<T> | null> | Global<T> | null;
25
+ getAsync<T = any>(name: string, siteId: number): Promise<T | null>;
25
26
  /** @hidden */
26
- _wasLoaded(): boolean;
27
+ _wasLoaded(siteId: number): boolean;
27
28
  /** @hidden */
28
29
  _setData(siteId: number, data: any): void;
29
30
  /** @hidden */
30
- _globalsBySite(siteId: number): Map<string, any>;
31
- /** @hidden */
32
31
  _updateSiteId(siteId: number): void;
33
32
  }
34
- /**
35
- * A globalSet Data
36
- *
37
- * Each global query should contain the siteId
38
- */
39
- export interface GlobalData {
40
- siteId?: number;
41
- [key: string]: any;
42
- }
43
33
  /**
44
34
  * A globalSet store
45
35
  */
46
- export declare class Global<T extends GlobalData> {
36
+ export declare class Global<T = any> {
37
+ /** @hidden */
47
38
  private inner;
48
- private languages;
49
- constructor(name: string, data: T[] | T, siteId: number);
39
+ constructor(name: string, data: T);
50
40
  /**
51
41
  * The function get's called once with the current value and then when the
52
42
  * values changes
@@ -58,15 +48,9 @@ export declare class Global<T extends GlobalData> {
58
48
  * The current value
59
49
  */
60
50
  get(): T;
61
- /**
62
- * Get the value based on the siteId
63
- *
64
- * ## Note
65
- * If you pass a siteId which comes from craft
66
- * you will never receive null
67
- */
68
- bySiteId(siteId: number): T | null;
69
51
  /** @hidden */
70
- _updateSiteId(siteId: number): void;
52
+ _setSilent(value: T): void;
53
+ /** @hidden */
54
+ _notify(): void;
71
55
  }
72
56
  //# sourceMappingURL=Globals.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Globals.d.ts","sourceRoot":"","sources":["../../../../src/loadData/Globals.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC;AAE9D,MAAM,CAAC,OAAO,OAAO,OAAO;IAG3B,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,UAAU,CAAgB;;IASlC;;;;;;;OAOG;IACH,GAAG,CAAC,CAAC,SAAS,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI;IAIzD;;;;;;OAMG;IACH,QAAQ,CAAC,CAAC,SAAS,UAAU,EAC5B,IAAI,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI;IAc/C,cAAc;IACd,UAAU,IAAI,OAAO;IAOrB,cAAc;IACd,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG;IAgBlC,cAAc;IACd,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC;IAUhD,cAAc;IACd,aAAa,CAAC,MAAM,EAAE,MAAM;CAM5B;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,MAAM,CAAC,CAAC,SAAS,UAAU;IACvC,OAAO,CAAC,KAAK,CAAc;IAE3B,OAAO,CAAC,SAAS,CAAa;gBAElB,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM;IAsBvD;;;;;OAKG;IACH,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI;IAI3C;;OAEG;IACH,GAAG,IAAI,CAAC;IAIR;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI;IAOlC,cAAc;IACd,aAAa,CAAC,MAAM,EAAE,MAAM;CAM5B"}
1
+ {"version":3,"file":"Globals.d.ts","sourceRoot":"","sources":["../../../../src/loadData/Globals.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC;AAEvD,MAAM,CAAC,OAAO,OAAO,OAAO;IAG3B,OAAO,CAAC,OAAO,CAA+C;IAC9D,OAAO,CAAC,IAAI,CAAgC;IAC5C,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,aAAa,CAAgB;;IASrC,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI;IAIpD;;;;;;;OAOG;IACH,QAAQ,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI;IAIjD;;;;;;OAMG;IACH,QAAQ,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAqBlE,cAAc;IACd,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAQnC,cAAc;IACd,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG;IAUlC,cAAc;IACd,aAAa,CAAC,MAAM,EAAE,MAAM;CAuB5B;AAED;;GAEG;AACH,qBAAa,MAAM,CAAC,CAAC,GAAG,GAAG;IAC1B,cAAc;IACd,OAAO,CAAC,KAAK,CAAc;gBAEf,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAiBjC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI;IAI3C;;OAEG;IACH,GAAG,IAAI,CAAC;IAIR,cAAc;IACd,UAAU,CAAC,KAAK,EAAE,CAAC;IAInB,cAAc;IACd,OAAO;CAGP"}
@@ -4,20 +4,24 @@ const emergency = getGlobal('emergency');
4
4
 
5
5
  // returns the data based on the current site (no store)
6
6
  cr.getGlobal('emergency')
7
+
7
8
  */
8
9
  import { Writable } from 'crelte-std/stores';
9
10
  export default class Globals {
10
11
  // while the globals are not loaded if somebody calls
11
- // getOrWait then we need to store the waiters
12
+ // getAsync then we need to store the waiters
12
13
  waiters;
13
- entries;
14
- loaded;
15
- prevSiteId;
14
+ data;
15
+ stores;
16
+ currentSiteId;
16
17
  constructor() {
17
18
  this.waiters = new Map();
18
- this.entries = new Map();
19
- this.loaded = false;
20
- this.prevSiteId = null;
19
+ this.data = new Map();
20
+ this.stores = new Map();
21
+ this.currentSiteId = null;
22
+ }
23
+ get(name, siteId) {
24
+ return this.data.get(siteId)?.get(name) ?? null;
21
25
  }
22
26
  /**
23
27
  * returns a store which contains a globalSet
@@ -25,10 +29,10 @@ export default class Globals {
25
29
  * ## Note
26
30
  * This only works in loadData, in loadGlobalData this will
27
31
  * always return null. In that context you should use
28
- * `.getGlobalAsync`
32
+ * `.getAsync`
29
33
  */
30
- get(name) {
31
- return this.entries.get(name) ?? null;
34
+ getStore(name) {
35
+ return this.stores.get(name) ?? null;
32
36
  }
33
37
  /**
34
38
  * Get a store which contains a globalSet and wait until it is loaded
@@ -37,78 +41,78 @@ export default class Globals {
37
41
  * This is only useful in loadGlobalData in all other cases
38
42
  * you can use `.getGlobal` which does return a Promise
39
43
  */
40
- getAsync(name) {
41
- if (this.loaded)
42
- return this.get(name);
43
- let waiter = this.waiters.get(name);
44
+ getAsync(name, siteId) {
45
+ if (this._wasLoaded(siteId))
46
+ return Promise.resolve(this.get(name, siteId));
47
+ let listeners = this.waiters.get(siteId);
48
+ if (!listeners) {
49
+ listeners = new Map();
50
+ this.waiters.set(siteId, listeners);
51
+ }
52
+ let waiter = listeners.get(name);
44
53
  if (!waiter) {
45
54
  waiter = [];
46
- this.waiters.set(name, waiter);
55
+ listeners.set(name, waiter);
47
56
  }
48
57
  return new Promise(resolve => {
49
58
  waiter.push(resolve);
50
59
  });
51
60
  }
52
61
  /** @hidden */
53
- _wasLoaded() {
54
- return this.loaded;
62
+ _wasLoaded(siteId) {
63
+ return this.data.has(siteId);
55
64
  }
56
65
  // data is the data from the global graphql
57
66
  // so it contains some keys and data which should be parsed
58
67
  // and created a store for each key
68
+ // do not call this if _wasLoaded returns true with the same siteId
59
69
  /** @hidden */
60
70
  _setData(siteId, data) {
61
- const wasLoaded = this.loaded;
62
- this.loaded = true;
63
- for (const [key, value] of Object.entries(data)) {
64
- this.entries.set(key, new Global(key, value, siteId));
65
- }
66
- if (!wasLoaded) {
67
- this.waiters.forEach((waiters, key) => {
68
- waiters.forEach(waiter => waiter(this.get(key)));
69
- });
70
- this.waiters.clear();
71
- }
72
- }
73
- /** @hidden */
74
- _globalsBySite(siteId) {
75
- const map = new Map();
76
- for (const [key, global] of this.entries) {
77
- map.set(key, global.bySiteId(siteId));
78
- }
79
- return map;
71
+ const map = new Map(Object.entries(data));
72
+ this.data.set(siteId, map);
73
+ this.waiters.get(siteId)?.forEach((waiters, key) => {
74
+ waiters.forEach(waiter => waiter(map.get(key)));
75
+ });
76
+ this.waiters.delete(siteId);
80
77
  }
81
78
  /** @hidden */
82
79
  _updateSiteId(siteId) {
83
- // todo we should only trigger
84
- if (this.prevSiteId === siteId)
80
+ if (this.currentSiteId === siteId)
85
81
  return;
86
- this.entries.forEach(global => global._updateSiteId(siteId));
82
+ const data = this.data.get(siteId) ?? new Map();
83
+ // we set all global data to null via setSilent
84
+ // then set them all with the new data
85
+ // and update all of them
86
+ this.stores.forEach(global => global._setSilent(null));
87
+ data.forEach((value, key) => {
88
+ let global = this.stores.get(key);
89
+ if (global) {
90
+ global._setSilent(value);
91
+ }
92
+ else {
93
+ global = new Global(key, value);
94
+ this.stores.set(key, global);
95
+ }
96
+ });
97
+ this.stores.forEach(global => global._notify());
87
98
  }
88
99
  }
89
100
  /**
90
101
  * A globalSet store
91
102
  */
92
103
  export class Global {
104
+ /** @hidden */
93
105
  inner;
94
- /// if languages is null this means we always have the same data
95
- languages;
96
- constructor(name, data, siteId) {
97
- this.languages = null;
98
- let inner;
99
- if (Array.isArray(data)) {
100
- // make sure the data contains an object with the property
101
- // siteId
102
- this.languages = data;
103
- inner = data.find(d => d.siteId === siteId);
104
- if (!inner?.siteId) {
105
- throw new Error(`The global query ${name} does not contain the required siteId property`);
106
- }
107
- }
108
- else {
109
- inner = data;
106
+ constructor(name, data) {
107
+ // todo remove in v1.0
108
+ // In v0.2, we queried the global data for all sites.
109
+ // We now check if the siteId is present and notify the user to remove it.
110
+ if (typeof data.siteId === 'number' ||
111
+ (Array.isArray(data) && typeof data[0]?.siteId === 'number')) {
112
+ throw new Error(`The global query ${name} should not include the siteId` +
113
+ ` property. Instead, use the siteId as a parameter.`);
110
114
  }
111
- this.inner = new Writable(inner);
115
+ this.inner = new Writable(data);
112
116
  }
113
117
  /**
114
118
  * The function get's called once with the current value and then when the
@@ -125,23 +129,12 @@ export class Global {
125
129
  get() {
126
130
  return this.inner.get();
127
131
  }
128
- /**
129
- * Get the value based on the siteId
130
- *
131
- * ## Note
132
- * If you pass a siteId which comes from craft
133
- * you will never receive null
134
- */
135
- bySiteId(siteId) {
136
- if (this.languages)
137
- return this.languages.find(d => d.siteId === siteId) ?? null;
138
- return this.inner.get();
132
+ /** @hidden */
133
+ _setSilent(value) {
134
+ this.inner.setSilent(value);
139
135
  }
140
136
  /** @hidden */
141
- _updateSiteId(siteId) {
142
- if (!this.languages)
143
- return;
144
- const inner = this.languages.find(d => d.siteId === siteId);
145
- this.inner.set(inner);
137
+ _notify() {
138
+ this.inner.notify();
146
139
  }
147
140
  }
@@ -82,15 +82,6 @@ export default class InnerRouter {
82
82
  * `push` and `replace` will cause this function to throw an error
83
83
  */
84
84
  open(req: Request): void;
85
- /**
86
- * Sets a route
87
- *
88
- * Will trigger an onRoute event but will not store any scroll progress
89
- * or modify the history
90
- *
91
- * @param req
92
- */
93
- setRoute(req: Request, preventOnRoute?: boolean): void;
94
85
  /**
95
86
  * This pushes a new route to the history
96
87
  *
@@ -99,7 +90,7 @@ export default class InnerRouter {
99
90
  * ## Important
100
91
  * Make sure the route has the correct origin
101
92
  */
102
- push(req: Request, preventOnRoute?: boolean): void;
93
+ push(req: Request): void;
103
94
  /**
104
95
  * This replaces the current route
105
96
  *
@@ -1 +1 @@
1
- {"version":3,"file":"InnerRouter.d.ts","sourceRoot":"","sources":["../../../../src/routing/InnerRouter.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,EAAE,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,OAAO,MAAM,cAAc,CAAC;AAEnC,OAAO,OAAO,EAAE,EAAa,cAAc,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,KAAK,MAAM,YAAY,CAAC;AAE/B,MAAM,MAAM,eAAe,GAAG;IAC7B,kBAAkB,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,WAAW;IAC/B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd;;;;;OAKG;IACH,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,kBAAkB,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAC7D,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAEpC,OAAO,CAAC,qBAAqB,CAAa;IAE1C;;;;;OAKG;gBACS,KAAK,EAAE,eAAe,EAAE,EAAE,IAAI,EAAE,eAAe;IAkB3D;;OAEG;IACH,UAAU;IAaV;;OAEG;IACH,UAAU;IAEV;;;;OAIG;IACH,gBAAgB,CAAC,UAAU,GAAE,MAAM,GAAG,IAAW,GAAG,IAAI;IAsCxD;;OAEG;IACH,WAAW,IAAI,IAAI;IAInB;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIjC;;;;;;OAMG;IACH,eAAe,CACd,MAAM,EAAE,MAAM,GAAG,GAAG,GAAG,KAAK,GAAG,OAAO,EACtC,IAAI,GAAE,cAAmB,GACvB,OAAO;IAwBV;;;;;OAKG;IACH,YAAY,CAAC,OAAO,EAAE,GAAG,GAAG,KAAK;IAgCjC,MAAM;IA6FN;;;;;;;;;OASG;IACH,IAAI,CAAC,GAAG,EAAE,OAAO;IAuCjB;;;;;;;OAOG;IACH,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,cAAc,UAAQ;IAM7C;;;;;;;OAOG;IACH,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,cAAc,UAAQ;IAsBzC;;;;;;;OAOG;IACH,OAAO,CAAC,GAAG,EAAE,OAAO;IAsBpB;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,GAAG,KAAK,GAAG,OAAO;IAW9C,QAAQ,CAAC,GAAG,EAAE,OAAO;CAsErB"}
1
+ {"version":3,"file":"InnerRouter.d.ts","sourceRoot":"","sources":["../../../../src/routing/InnerRouter.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,EAAE,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,OAAO,MAAM,cAAc,CAAC;AAEnC,OAAO,OAAO,EAAE,EAAa,cAAc,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,KAAK,MAAM,YAAY,CAAC;AAE/B,MAAM,MAAM,eAAe,GAAG;IAC7B,kBAAkB,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,WAAW;IAC/B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd;;;;;OAKG;IACH,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,kBAAkB,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAC7D,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAEpC,OAAO,CAAC,qBAAqB,CAAa;IAE1C;;;;;OAKG;gBACS,KAAK,EAAE,eAAe,EAAE,EAAE,IAAI,EAAE,eAAe;IAkB3D;;OAEG;IACH,UAAU;IAgBV;;OAEG;IACH,UAAU;IAEV;;;;OAIG;IACH,gBAAgB,CAAC,UAAU,GAAE,MAAM,GAAG,IAAW,GAAG,IAAI;IAsCxD;;OAEG;IACH,WAAW,IAAI,IAAI;IAInB;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAKjC;;;;;;OAMG;IACH,eAAe,CACd,MAAM,EAAE,MAAM,GAAG,GAAG,GAAG,KAAK,GAAG,OAAO,EACtC,IAAI,GAAE,cAAmB,GACvB,OAAO;IA0BV;;;;;OAKG;IACH,YAAY,CAAC,OAAO,EAAE,GAAG,GAAG,KAAK;IAgCjC,MAAM;IAoGN;;;;;;;;;OASG;IACH,IAAI,CAAC,GAAG,EAAE,OAAO;IA4CjB;;;;;;;OAOG;IACH,IAAI,CAAC,GAAG,EAAE,OAAO;IAuBjB;;;;;;;OAOG;IACH,OAAO,CAAC,GAAG,EAAE,OAAO;IAuBpB;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,GAAG,KAAK,GAAG,OAAO;IAW9C,QAAQ,CAAC,GAAG,EAAE,OAAO;CAsErB"}
@@ -52,7 +52,10 @@ export default class InnerRouter {
52
52
  req._fillFromState(window.history.state);
53
53
  req.origin = 'init';
54
54
  window.history.scrollRestoration = 'manual';
55
- this.setRoute(req);
55
+ // we set it now instead of waiting for the onRoute call
56
+ // because the window.history is already set
57
+ this.route = req.toRoute();
58
+ this.onRoute(req, () => { });
56
59
  }
57
60
  /**
58
61
  * Initializes the router when running on the server.
@@ -110,6 +113,7 @@ export default class InnerRouter {
110
113
  siteById(id) {
111
114
  return this.sites.find(s => s.id === id) ?? null;
112
115
  }
116
+ // keep this doc in sync with Router.targetToRequest
113
117
  /**
114
118
  * Resolve a url or Route and convert it to a Request
115
119
  *
@@ -125,6 +129,9 @@ export default class InnerRouter {
125
129
  const site = this.route?.site ?? this.defaultSite();
126
130
  target = new URL(site.uri + target, site.url);
127
131
  }
132
+ else if (!target) {
133
+ throw new Error('the url is not allowed to be empty');
134
+ }
128
135
  else {
129
136
  target = new URL(target);
130
137
  }
@@ -205,7 +212,9 @@ export default class InnerRouter {
205
212
  return;
206
213
  if (link && link.target.toLowerCase() === '_blank')
207
214
  return;
208
- if (link && !link.hasAttribute('data-no-preload')) {
215
+ if (link &&
216
+ !link.hasAttribute('data-no-preload') &&
217
+ link.href) {
209
218
  this.preload(link.href);
210
219
  }
211
220
  currentMouseOver = link;
@@ -243,12 +252,15 @@ export default class InnerRouter {
243
252
  });
244
253
  }
245
254
  window.addEventListener('popstate', async (e) => {
246
- if (!('route' in e.state))
255
+ if (!e.state?.route)
247
256
  return;
248
257
  const req = this.targetToRequest(window.location.href);
249
258
  req._fillFromState(e.state);
250
259
  req.origin = 'pop';
251
- this.setRoute(req);
260
+ // we set it now instead of waiting for the onRoute call
261
+ // because the window.history was already modified
262
+ this.route = req.toRoute();
263
+ this.onRoute(req, () => { });
252
264
  });
253
265
  }
254
266
  /**
@@ -290,22 +302,11 @@ export default class InnerRouter {
290
302
  }
291
303
  req.index = (current?.index ?? 0) + 1;
292
304
  this.onRoute(req, () => {
293
- this.push(req, true);
305
+ const url = req.url;
306
+ this.history.pushState(req._toState(), url.pathname + url.search + url.hash);
307
+ this.route = req.toRoute();
294
308
  });
295
309
  }
296
- /**
297
- * Sets a route
298
- *
299
- * Will trigger an onRoute event but will not store any scroll progress
300
- * or modify the history
301
- *
302
- * @param req
303
- */
304
- setRoute(req, preventOnRoute = false) {
305
- this.route = req.toRoute();
306
- if (!preventOnRoute)
307
- this.onRoute(req, () => { });
308
- }
309
310
  /**
310
311
  * This pushes a new route to the history
311
312
  *
@@ -314,7 +315,7 @@ export default class InnerRouter {
314
315
  * ## Important
315
316
  * Make sure the route has the correct origin
316
317
  */
317
- push(req, preventOnRoute = false) {
318
+ push(req) {
318
319
  const url = req.url;
319
320
  // todo a push should also store the previous scrollY
320
321
  let nReq = req;
@@ -326,8 +327,10 @@ export default class InnerRouter {
326
327
  nReq = req.clone();
327
328
  nReq.scrollY = this.history.scrollY();
328
329
  }
329
- this.history.pushState(nReq._toState(), url.pathname + url.search + url.hash);
330
- this.setRoute(req, preventOnRoute);
330
+ this.onRoute(req, () => {
331
+ this.history.pushState(req._toState(), url.pathname + url.search + url.hash);
332
+ this.route = req.toRoute();
333
+ });
331
334
  }
332
335
  /**
333
336
  * This replaces the current route
@@ -349,8 +352,10 @@ export default class InnerRouter {
349
352
  nReq = req.clone();
350
353
  nReq.scrollY = this.history.scrollY();
351
354
  }
352
- this.history.replaceState(nReq._toState(), url.pathname + url.search + url.hash);
353
- this.setRoute(req);
355
+ this.onRoute(req, () => {
356
+ this.history.replaceState(req._toState(), url.pathname + url.search + url.hash);
357
+ this.route = req.toRoute();
358
+ });
354
359
  }
355
360
  /**
356
361
  * Preload a url
@@ -8,6 +8,8 @@ export type RequestOptions = {
8
8
  scrollY?: number;
9
9
  index?: number;
10
10
  origin?: RouteOrigin;
11
+ state?: Record<string, any>;
12
+ context?: Record<string, any>;
11
13
  disableScroll?: boolean;
12
14
  disableLoadData?: boolean;
13
15
  statusCode?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"Request.d.ts","sourceRoot":"","sources":["../../../../src/routing/Request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,KAAK;IACzC;;;OAGG;IACH,aAAa,EAAE,OAAO,CAAC;IAEvB;;;OAGG;IACH,eAAe,EAAE,OAAO,CAAC;IAEzB;;OAEG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAE1B,cAAc;IACd,cAAc,EAAE,aAAa,CAAC;IAE9B;;OAEG;gBACS,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,GAAE,cAAmB;IASpE;;OAEG;IACH,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,GAAE,cAAmB;IASxD;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,WAAW,IAAI,WAAW;IAI1B;;OAEG;IACH,KAAK;IAUL;;OAEG;IACH,OAAO;IAQP,cAAc;IACd,WAAW,CAAC,IAAI,GAAE,cAAmB;CAOrC;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,OAAO,CAElD;AAED,cAAM,aAAa;IAClB,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,WAAW,CAAC;;IAQlB,MAAM,IAAI,OAAO;IAIjB,GAAG,IAAI,WAAW;IAclB,cAAc;IACd,MAAM;IAQN,cAAc;IACd,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;CAGzB;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACzB;;;;;OAKG;IACH,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAE9B;;OAEG;IACH,MAAM,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC"}
1
+ {"version":3,"file":"Request.d.ts","sourceRoot":"","sources":["../../../../src/routing/Request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,KAAK;IACzC;;;OAGG;IACH,aAAa,EAAE,OAAO,CAAC;IAEvB;;;OAGG;IACH,eAAe,EAAE,OAAO,CAAC;IAEzB;;OAEG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAE1B,cAAc;IACd,cAAc,EAAE,aAAa,CAAC;IAE9B;;OAEG;gBACS,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,GAAE,cAAmB;IASpE;;OAEG;IACH,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,GAAE,cAAmB;IAWxD;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,WAAW,IAAI,WAAW;IAI1B;;OAEG;IACH,KAAK;IAYL;;OAEG;IACH,OAAO;IAUP,cAAc;IACd,WAAW,CAAC,IAAI,GAAE,cAAmB;CASrC;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,OAAO,CAElD;AAED,cAAM,aAAa;IAClB,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,WAAW,CAAC;;IAQlB,MAAM,IAAI,OAAO;IAIjB,GAAG,IAAI,WAAW;IAclB,cAAc;IACd,MAAM;IAQN,cAAc;IACd,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;CAGzB;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACzB;;;;;OAKG;IACH,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAE9B;;OAEG;IACH,MAAM,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { Barrier } from 'crelte-std/sync';
2
2
  import Route from './Route.js';
3
+ import { objClone } from '../utils.js';
3
4
  /**
4
5
  * A Request is a Route with some extra options
5
6
  * you get a Request from the onRequest event or
@@ -40,6 +41,8 @@ export default class Request extends Route {
40
41
  scrollY: route.scrollY ?? undefined,
41
42
  index: route.index,
42
43
  origin: route.origin,
44
+ state: route._state,
45
+ context: route._context,
43
46
  ...opts,
44
47
  });
45
48
  }
@@ -82,6 +85,8 @@ export default class Request extends Route {
82
85
  scrollY: this.scrollY ?? undefined,
83
86
  index: this.index,
84
87
  origin: this.origin,
88
+ state: objClone(this._state),
89
+ context: this._context,
85
90
  disableScroll: this.disableScroll,
86
91
  statusCode: this.statusCode ?? undefined,
87
92
  });
@@ -94,6 +99,8 @@ export default class Request extends Route {
94
99
  scrollY: this.scrollY ?? undefined,
95
100
  index: this.index,
96
101
  origin: this.origin,
102
+ state: objClone(this._state),
103
+ context: this._context,
97
104
  });
98
105
  }
99
106
  /** @hidden */
@@ -101,6 +108,8 @@ export default class Request extends Route {
101
108
  this.scrollY = opts.scrollY ?? this.scrollY;
102
109
  this.index = opts.index ?? this.index;
103
110
  this.origin = opts.origin ?? this.origin;
111
+ this._state = opts.state ?? this._state;
112
+ this._context = opts.context ?? this._context;
104
113
  this.disableScroll = opts.disableScroll ?? this.disableScroll;
105
114
  this.statusCode = opts.statusCode ?? this.statusCode;
106
115
  }