@podium/podlet 5.1.12 → 5.2.0-next.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/CHANGELOG.md CHANGED
@@ -1,3 +1,129 @@
1
+ # [5.2.0-next.2](https://github.com/podium-lib/podlet/compare/v5.2.0-next.1...v5.2.0-next.2) (2024-09-06)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * force release 5.2.0-next.2 ([b2fc84c](https://github.com/podium-lib/podlet/commit/b2fc84cd6ced3716aa0964d76f55063db5c37fce))
7
+ * force release 5.2.0-next.2 ([84223e8](https://github.com/podium-lib/podlet/commit/84223e823125544eb40cbd50b2558bcb78ba9ce6))
8
+ * force release 5.2.0-next.2 ([4f5f19d](https://github.com/podium-lib/podlet/commit/4f5f19d9e486461b822dddf4bf278207927c63be))
9
+ * force release 5.2.0-next.2 ([a5a1953](https://github.com/podium-lib/podlet/commit/a5a19536aab17130e79f14b2a8d7e7f58e61d0f0))
10
+ * update @podium/utils ([719c1e0](https://github.com/podium-lib/podlet/commit/719c1e0ae4e06144e084e8b95bd04d94313b116e))
11
+
12
+ # [5.2.0-next.1](https://github.com/podium-lib/podlet/compare/v5.1.12...v5.2.0-next.1) (2024-09-05)
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * ensure both key/value and object conversion are supported for JS data attributes ([f243d60](https://github.com/podium-lib/podlet/commit/f243d607356166cd77c83eb72ef7ea84f4b95d80))
18
+ * force release 5.2.0-next.2 ([84223e8](https://github.com/podium-lib/podlet/commit/84223e823125544eb40cbd50b2558bcb78ba9ce6))
19
+ * force release 5.2.0-next.2 ([4f5f19d](https://github.com/podium-lib/podlet/commit/4f5f19d9e486461b822dddf4bf278207927c63be))
20
+ * force release 5.2.0-next.2 ([a5a1953](https://github.com/podium-lib/podlet/commit/a5a19536aab17130e79f14b2a8d7e7f58e61d0f0))
21
+ * **types:** fix AssetJsLike type ([19494f5](https://github.com/podium-lib/podlet/commit/19494f51c338468c362668678654c119993795db))
22
+ * update @podium/utils ([719c1e0](https://github.com/podium-lib/podlet/commit/719c1e0ae4e06144e084e8b95bd04d94313b116e))
23
+
24
+
25
+ ### Features
26
+
27
+ * automatically send assets with content/fallback requests as 103 early hints ([c4c8c88](https://github.com/podium-lib/podlet/commit/c4c8c889bc491b8a3c4a896220d1205164e6fde4))
28
+
29
+ # [5.2.0-next.1](https://github.com/podium-lib/podlet/compare/v5.1.12...v5.2.0-next.1) (2024-09-05)
30
+
31
+
32
+ ### Bug Fixes
33
+
34
+ * ensure both key/value and object conversion are supported for JS data attributes ([f243d60](https://github.com/podium-lib/podlet/commit/f243d607356166cd77c83eb72ef7ea84f4b95d80))
35
+ * force release 5.2.0-next.2 ([4f5f19d](https://github.com/podium-lib/podlet/commit/4f5f19d9e486461b822dddf4bf278207927c63be))
36
+ * force release 5.2.0-next.2 ([a5a1953](https://github.com/podium-lib/podlet/commit/a5a19536aab17130e79f14b2a8d7e7f58e61d0f0))
37
+ * **types:** fix AssetJsLike type ([19494f5](https://github.com/podium-lib/podlet/commit/19494f51c338468c362668678654c119993795db))
38
+ * update @podium/utils ([719c1e0](https://github.com/podium-lib/podlet/commit/719c1e0ae4e06144e084e8b95bd04d94313b116e))
39
+
40
+
41
+ ### Features
42
+
43
+ * automatically send assets with content/fallback requests as 103 early hints ([c4c8c88](https://github.com/podium-lib/podlet/commit/c4c8c889bc491b8a3c4a896220d1205164e6fde4))
44
+
45
+ # [5.2.0-next.1](https://github.com/podium-lib/podlet/compare/v5.1.12...v5.2.0-next.1) (2024-09-05)
46
+
47
+
48
+ ### Bug Fixes
49
+
50
+ * ensure both key/value and object conversion are supported for JS data attributes ([f243d60](https://github.com/podium-lib/podlet/commit/f243d607356166cd77c83eb72ef7ea84f4b95d80))
51
+ * force release 5.2.0-next.2 ([a5a1953](https://github.com/podium-lib/podlet/commit/a5a19536aab17130e79f14b2a8d7e7f58e61d0f0))
52
+ * **types:** fix AssetJsLike type ([19494f5](https://github.com/podium-lib/podlet/commit/19494f51c338468c362668678654c119993795db))
53
+ * update @podium/utils ([719c1e0](https://github.com/podium-lib/podlet/commit/719c1e0ae4e06144e084e8b95bd04d94313b116e))
54
+
55
+
56
+ ### Features
57
+
58
+ * automatically send assets with content/fallback requests as 103 early hints ([c4c8c88](https://github.com/podium-lib/podlet/commit/c4c8c889bc491b8a3c4a896220d1205164e6fde4))
59
+
60
+ # [5.2.0-next.1](https://github.com/podium-lib/podlet/compare/v5.1.12...v5.2.0-next.1) (2024-09-05)
61
+
62
+
63
+ ### Bug Fixes
64
+
65
+ * ensure both key/value and object conversion are supported for JS data attributes ([f243d60](https://github.com/podium-lib/podlet/commit/f243d607356166cd77c83eb72ef7ea84f4b95d80))
66
+ * **types:** fix AssetJsLike type ([19494f5](https://github.com/podium-lib/podlet/commit/19494f51c338468c362668678654c119993795db))
67
+ * update @podium/utils ([719c1e0](https://github.com/podium-lib/podlet/commit/719c1e0ae4e06144e084e8b95bd04d94313b116e))
68
+
69
+
70
+ ### Features
71
+
72
+ * automatically send assets with content/fallback requests as 103 early hints ([c4c8c88](https://github.com/podium-lib/podlet/commit/c4c8c889bc491b8a3c4a896220d1205164e6fde4))
73
+
74
+ # [5.2.0-next.1](https://github.com/podium-lib/podlet/compare/v5.1.12...v5.2.0-next.1) (2024-09-05)
75
+
76
+
77
+ ### Bug Fixes
78
+
79
+ * ensure both key/value and object conversion are supported for JS data attributes ([f243d60](https://github.com/podium-lib/podlet/commit/f243d607356166cd77c83eb72ef7ea84f4b95d80))
80
+ * **types:** fix AssetJsLike type ([19494f5](https://github.com/podium-lib/podlet/commit/19494f51c338468c362668678654c119993795db))
81
+ * update @podium/utils ([719c1e0](https://github.com/podium-lib/podlet/commit/719c1e0ae4e06144e084e8b95bd04d94313b116e))
82
+
83
+
84
+ ### Features
85
+
86
+ * automatically send assets with content/fallback requests as 103 early hints ([c4c8c88](https://github.com/podium-lib/podlet/commit/c4c8c889bc491b8a3c4a896220d1205164e6fde4))
87
+
88
+ # [5.2.0-next.1](https://github.com/podium-lib/podlet/compare/v5.1.12...v5.2.0-next.1) (2024-09-05)
89
+
90
+
91
+ ### Bug Fixes
92
+
93
+ * ensure both key/value and object conversion are supported for JS data attributes ([f243d60](https://github.com/podium-lib/podlet/commit/f243d607356166cd77c83eb72ef7ea84f4b95d80))
94
+ * **types:** fix AssetJsLike type ([19494f5](https://github.com/podium-lib/podlet/commit/19494f51c338468c362668678654c119993795db))
95
+
96
+
97
+ ### Features
98
+
99
+ * automatically send assets with content/fallback requests as 103 early hints ([c4c8c88](https://github.com/podium-lib/podlet/commit/c4c8c889bc491b8a3c4a896220d1205164e6fde4))
100
+
101
+ # [5.2.0-next.1](https://github.com/podium-lib/podlet/compare/v5.1.12...v5.2.0-next.1) (2024-09-03)
102
+
103
+
104
+ ### Bug Fixes
105
+
106
+ * ensure both key/value and object conversion are supported for JS data attributes ([f243d60](https://github.com/podium-lib/podlet/commit/f243d607356166cd77c83eb72ef7ea84f4b95d80))
107
+ * **types:** fix AssetJsLike type ([19494f5](https://github.com/podium-lib/podlet/commit/19494f51c338468c362668678654c119993795db))
108
+
109
+
110
+ ### Features
111
+
112
+ * automatically send assets with content/fallback requests as 103 early hints ([c4c8c88](https://github.com/podium-lib/podlet/commit/c4c8c889bc491b8a3c4a896220d1205164e6fde4))
113
+
114
+ # [5.2.0-next.1](https://github.com/podium-lib/podlet/compare/v5.1.12...v5.2.0-next.1) (2024-08-19)
115
+
116
+
117
+ ### Bug Fixes
118
+
119
+ * ensure both key/value and object conversion are supported for JS data attributes ([ccdfd1e](https://github.com/podium-lib/podlet/commit/ccdfd1e791c81b4c5aed045b47a316683911d929))
120
+ * **types:** fix AssetJsLike type ([1c29350](https://github.com/podium-lib/podlet/commit/1c29350a9f0682df675b44cf4c5e88468ab24043))
121
+
122
+
123
+ ### Features
124
+
125
+ * add res.assets for request bound, early hinted asset sending ([caca302](https://github.com/podium-lib/podlet/commit/caca302a2d80144e24d2078c3ae8f7a8f423b1dd))
126
+
1
127
  ## [5.1.12](https://github.com/podium-lib/podlet/compare/v5.1.11...v5.1.12) (2024-08-19)
2
128
 
3
129
 
package/README.md CHANGED
@@ -551,6 +551,8 @@ Sets the pathname for a podlet's javascript assets.
551
551
  When a value is set it will be internally kept and used when the podlet
552
552
  instance is serialized into a manifest JSON string.
553
553
 
554
+ In addition, JS information will be serialized into a Link header and sent as an HTTP 103 early hint with content and fallback responses so that the layout client can get access to assets before the main podlet body. The layout can use this information to generate 103 early hints for the browser so that the browser can begin downloading asset files while still waiting for the podlet and layout bodys.
555
+
554
556
  ### options
555
557
 
556
558
  | option | type | default | required |
@@ -647,6 +649,8 @@ Sets the options for a podlet's CSS assets.
647
649
  When a value is set it will be internally kept and used when the podlet
648
650
  instance is serialized into a manifest JSON string.
649
651
 
652
+ In addition, CSS information will be serialized into a Link header and sent as an HTTP 103 early hint with content and fallback responses so that the layout client can get access to assets before the main podlet body. The layout can use this information to generate 103 early hints for the browser so that the browser can begin downloading asset files while still waiting for the podlet and layout bodys.
653
+
650
654
  ### options
651
655
 
652
656
  | option | type | default | required |
package/lib/podlet.js CHANGED
@@ -7,11 +7,13 @@ import {
7
7
  import * as schema from '@podium/schemas';
8
8
  import Metrics from '@metrics/client';
9
9
  import abslog from 'abslog';
10
+ // @ts-ignore
10
11
  import objobj from 'objobj';
11
12
  import * as utils from '@podium/utils';
12
13
  import Proxy from '@podium/proxy';
13
14
  import { join, dirname } from 'node:path';
14
15
  import { fileURLToPath } from 'node:url';
16
+ // @ts-ignore
15
17
  import fs from 'node:fs';
16
18
 
17
19
  const currentDirectory = dirname(fileURLToPath(import.meta.url));
@@ -36,8 +38,8 @@ const { template } = utils;
36
38
  * @property {import("@podium/proxy").PodiumProxyOptions} [proxy] - options that can be provided to configure the @podium/proxy instance used by the podlet. See that module for details.
37
39
  *
38
40
  * @typedef {{ debug: 'true' | 'false', locale: string, deviceType: string, requestedBy: string, mountOrigin: string, mountPathname: string, publicPathname: string }} PodletContext
39
- * @typedef {{ as?: string | false | null, crossorigin?: string | null | boolean, disabled?: boolean | '' | null, hreflang?: string | false | null, title?: string | false | null, media?: string | false | null, rel?: string | false | null, type?: string | false | null, value: string | false | null, data?: Array<{ key: string; value: string }>, strategy?: "beforeInteractive" | "afterInteractive" | "lazy", scope?: "content" | "fallback" | "all", [key: string]: any }} AssetCssLike
40
- * @typedef {{ value: string | null, crossorigin?: string | null | boolean, type?: string | null | false, integrity?: string | null | false, referrerpolicy?: string | null | false, nomodule?: boolean | null | '', async?: boolean | null | '', defer?: boolean | null | '', data?: Array<{ key: string; value: string }>, strategy?: "beforeInteractive" | "afterInteractive" | "lazy", scope?: "content" | "fallback" | "all", [key: string]: any }} AssetJsLike
41
+ * @typedef {{ as?: string | false | null, crossorigin?: string | null | boolean, disabled?: boolean | '' | null, hreflang?: string | false | null, title?: string | false | null, media?: string | false | null, rel?: string | false | null, type?: string | false | null, value: string | false | null, strategy?: "beforeInteractive" | "afterInteractive" | "lazy", scope?: "content" | "fallback" | "all", [key: string]: any }} AssetCssLike
42
+ * @typedef {{ value: string | null, crossorigin?: string | null | boolean, type?: string | null | false, integrity?: string | null | false, referrerpolicy?: string | null | false, nomodule?: boolean | null | '', async?: boolean | null | '', defer?: boolean | null | '', data?: {[key: string]: string} | Array<{ key: string; value: string }>, strategy?: "beforeInteractive" | "afterInteractive" | "lazy", scope?: "content" | "fallback" | "all", [key: string]: any }} AssetJsLike
41
43
  */
42
44
 
43
45
  export default class PodiumPodlet {
@@ -515,9 +517,9 @@ export default class PodiumPodlet {
515
517
  * Takes an AssetCss instance or an object with equivalent properties, converts it to an AssetCss instance if necessary and adds it to the
516
518
  * cssRoute array.
517
519
  * @param { AssetCss | AssetCssLike } options
518
- * @returns {void}
520
+ * @returns {AssetCss}
519
521
  */
520
- #addCssAsset(options) {
522
+ #cssAsset(options) {
521
523
  const clonedOptions = JSON.parse(JSON.stringify(options));
522
524
  clonedOptions.value = this.#sanitize(
523
525
  clonedOptions.value,
@@ -528,7 +530,7 @@ export default class PodiumPodlet {
528
530
  ...clonedOptions,
529
531
  pathname: this.#pathname,
530
532
  };
531
- this.cssRoute.push(new AssetCss(args));
533
+ return new AssetCss(args);
532
534
  }
533
535
 
534
536
  /**
@@ -553,20 +555,19 @@ export default class PodiumPodlet {
553
555
  css(options) {
554
556
  if (Array.isArray(options)) {
555
557
  for (const opts of options) {
556
- this.#addCssAsset(opts);
558
+ this.cssRoute.push(this.#cssAsset(opts));
557
559
  }
558
560
  return;
559
561
  }
560
- this.#addCssAsset(options);
562
+ this.cssRoute.push(this.#cssAsset(options));
561
563
  }
562
564
 
563
565
  /**
564
- * Takes an AssetJs instance or an object with equivalent properties, converts it to an AssetJs instance if necessary and adds it to the
565
- * jsRoute array.
566
+ * Takes an AssetJs instance or an object with equivalent properties, converts it to an AssetJs instance if necessary and returns it.
566
567
  * @param { AssetJs | AssetJsLike } options
567
- * @returns {void}
568
+ * @returns {AssetJs}
568
569
  */
569
- #addJsAsset(options) {
570
+ #jsAsset(options) {
570
571
  const clonedOptions = JSON.parse(JSON.stringify(options));
571
572
  clonedOptions.value = this.#sanitize(
572
573
  clonedOptions.value,
@@ -579,19 +580,31 @@ export default class PodiumPodlet {
579
580
  pathname: this.#pathname,
580
581
  };
581
582
 
582
- // Convert data attribute object structure to array of key value objects
583
- if (typeof args.data === 'object' && args.data !== null) {
584
- const data = [];
585
- Object.keys(args.data).forEach((key) => {
586
- data.push({
587
- value: args.data[key],
588
- key,
583
+ if (args.data) {
584
+ // validate that key value objects provided are compliant
585
+ if (Array.isArray(args.data)) {
586
+ for (const data of args.data) {
587
+ if (!data.key || !data.value) {
588
+ throw new TypeError(
589
+ `JS Asset data object "${JSON.stringify(data)}" must contain both a 'key' and a 'value' attribute.`,
590
+ );
591
+ }
592
+ }
593
+ }
594
+ // Convert data attribute object structure to array of key value objects
595
+ else if (typeof args.data === 'object') {
596
+ const data = [];
597
+ Object.keys(args.data).forEach((key) => {
598
+ data.push({
599
+ value: args.data[key],
600
+ key,
601
+ });
589
602
  });
590
- });
591
- args.data = data;
603
+ args.data = data;
604
+ }
592
605
  }
593
606
 
594
- this.jsRoute.push(new AssetJs(args));
607
+ return new AssetJs(args);
595
608
  }
596
609
 
597
610
  /**
@@ -616,11 +629,11 @@ export default class PodiumPodlet {
616
629
  js(options) {
617
630
  if (Array.isArray(options)) {
618
631
  for (const opts of options) {
619
- this.#addJsAsset(opts);
632
+ this.jsRoute.push(this.#jsAsset(opts));
620
633
  }
621
634
  return;
622
635
  }
623
- this.#addJsAsset(options);
636
+ this.jsRoute.push(this.#jsAsset(options));
624
637
  }
625
638
 
626
639
  /**
@@ -863,11 +876,26 @@ export default class PodiumPodlet {
863
876
  );
864
877
  }
865
878
 
866
- // Determin if the request should be proxied and do if so
879
+ // Determine if the request should be proxied and do if so
867
880
  if (incoming.development && proxy) {
881
+ // @ts-ignore
868
882
  await this.httpProxy.process(incoming);
869
883
  }
870
884
 
885
+ // @ts-ignore
886
+ const js = incoming.js.map((asset) => asset.toHeader());
887
+
888
+ // @ts-ignore
889
+ const css = incoming.css.map((asset) => asset.toHeader());
890
+
891
+ // Send early hints to layout client in the form of a 103 status code and a link header with js/css asset information.
892
+ // Always send this. If no assets present, send an empty string.
893
+ if (incoming.response.writeEarlyHints) {
894
+ incoming.response.writeEarlyHints({
895
+ link: [...js, ...css],
896
+ });
897
+ }
898
+
871
899
  return incoming;
872
900
  }
873
901
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@podium/podlet",
3
- "version": "5.1.12",
3
+ "version": "5.2.0-next.2",
4
4
  "type": "module",
5
5
  "description": "Module for building page fragment servers in a micro frontend architecture.",
6
6
  "license": "MIT",
@@ -37,13 +37,13 @@
37
37
  "@metrics/client": "2.5.3",
38
38
  "@podium/proxy": "5.0.24",
39
39
  "@podium/schemas": "5.0.6",
40
- "@podium/utils": "5.1.0",
40
+ "@podium/utils": "5.2.0",
41
41
  "abslog": "2.4.4",
42
42
  "ajv": "8.17.1",
43
43
  "objobj": "1.0.0"
44
44
  },
45
45
  "devDependencies": {
46
- "@babel/eslint-parser": "7.24.7",
46
+ "@babel/eslint-parser": "7.25.1",
47
47
  "@podium/test-utils": "2.5.2",
48
48
  "@semantic-release/changelog": "6.0.3",
49
49
  "@semantic-release/commit-analyzer": "11.1.0",
@@ -53,16 +53,17 @@
53
53
  "@semantic-release/release-notes-generator": "12.1.0",
54
54
  "@types/node": "^20.10.3",
55
55
  "@types/readable-stream": "4.0.15",
56
- "eslint": "9.6.0",
56
+ "eslint": "9.9.1",
57
57
  "eslint-config-prettier": "9.1.0",
58
- "eslint-plugin-prettier": "5.1.3",
58
+ "eslint-plugin-prettier": "5.2.1",
59
59
  "express": "4.19.2",
60
- "globals": "15.8.0",
60
+ "globals": "15.9.0",
61
61
  "json-stringify-safe": "5.0.1",
62
62
  "npm-run-all2": "5.0.2",
63
- "prettier": "3.3.2",
63
+ "prettier": "3.3.3",
64
64
  "semantic-release": "23.1.1",
65
65
  "tap": "18.8.0",
66
- "typescript": "5.5.4"
66
+ "typescript": "5.5.4",
67
+ "undici": "^6.19.7"
67
68
  }
68
69
  }
package/types/podlet.d.ts CHANGED
@@ -38,8 +38,8 @@ declare global {
38
38
  * @property {import("@podium/proxy").PodiumProxyOptions} [proxy] - options that can be provided to configure the @podium/proxy instance used by the podlet. See that module for details.
39
39
  *
40
40
  * @typedef {{ debug: 'true' | 'false', locale: string, deviceType: string, requestedBy: string, mountOrigin: string, mountPathname: string, publicPathname: string }} PodletContext
41
- * @typedef {{ as?: string | false | null, crossorigin?: string | null | boolean, disabled?: boolean | '' | null, hreflang?: string | false | null, title?: string | false | null, media?: string | false | null, rel?: string | false | null, type?: string | false | null, value: string | false | null, data?: Array<{ key: string; value: string }>, strategy?: "beforeInteractive" | "afterInteractive" | "lazy", scope?: "content" | "fallback" | "all", [key: string]: any }} AssetCssLike
42
- * @typedef {{ value: string | null, crossorigin?: string | null | boolean, type?: string | null | false, integrity?: string | null | false, referrerpolicy?: string | null | false, nomodule?: boolean | null | '', async?: boolean | null | '', defer?: boolean | null | '', data?: Array<{ key: string; value: string }>, strategy?: "beforeInteractive" | "afterInteractive" | "lazy", scope?: "content" | "fallback" | "all", [key: string]: any }} AssetJsLike
41
+ * @typedef {{ as?: string | false | null, crossorigin?: string | null | boolean, disabled?: boolean | '' | null, hreflang?: string | false | null, title?: string | false | null, media?: string | false | null, rel?: string | false | null, type?: string | false | null, value: string | false | null, strategy?: "beforeInteractive" | "afterInteractive" | "lazy", scope?: "content" | "fallback" | "all", [key: string]: any }} AssetCssLike
42
+ * @typedef {{ value: string | null, crossorigin?: string | null | boolean, type?: string | null | false, integrity?: string | null | false, referrerpolicy?: string | null | false, nomodule?: boolean | null | '', async?: boolean | null | '', defer?: boolean | null | '', data?: {[key: string]: string} | Array<{ key: string; value: string }>, strategy?: "beforeInteractive" | "afterInteractive" | "lazy", scope?: "content" | "fallback" | "all", [key: string]: any }} AssetJsLike
43
43
  */
44
44
  export default class PodiumPodlet {
45
45
  /**
@@ -639,10 +639,6 @@ export type AssetCssLike = {
639
639
  rel?: string | false | null;
640
640
  type?: string | false | null;
641
641
  value: string | false | null;
642
- data?: Array<{
643
- key: string;
644
- value: string;
645
- }>;
646
642
  strategy?: "beforeInteractive" | "afterInteractive" | "lazy";
647
643
  scope?: "content" | "fallback" | "all";
648
644
  [key: string]: any;
@@ -656,7 +652,9 @@ export type AssetJsLike = {
656
652
  nomodule?: boolean | null | "";
657
653
  async?: boolean | null | "";
658
654
  defer?: boolean | null | "";
659
- data?: Array<{
655
+ data?: {
656
+ [key: string]: string;
657
+ } | Array<{
660
658
  key: string;
661
659
  value: string;
662
660
  }>;