@podium/client 5.1.0-beta.1 → 5.1.0

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.
@@ -20,11 +20,24 @@ const pkg = JSON.parse(pkgJson);
20
20
 
21
21
  const UA_STRING = `${pkg.name} ${pkg.version}`;
22
22
 
23
+ /**
24
+ * @typedef {object} PodletClientManifestResolverOptions
25
+ * @property {string} clientName
26
+ * @property {import('abslog').AbstractLoggerOptions} [logger]
27
+ * @property {import('./http.js').default} [http]
28
+ */
29
+
23
30
  export default class PodletClientManifestResolver {
24
31
  #log;
25
32
  #metrics;
26
33
  #histogram;
27
34
  #http;
35
+
36
+ /**
37
+ * @constructor
38
+ * @param {PodletClientManifestResolverOptions} options
39
+ */
40
+ // @ts-expect-error Deliberate default empty options for better error messages
28
41
  constructor(options = {}) {
29
42
  this.#http = options.http || new HTTP();
30
43
  const name = options.clientName;
@@ -53,6 +66,10 @@ export default class PodletClientManifestResolver {
53
66
  return this.#metrics;
54
67
  }
55
68
 
69
+ /**
70
+ * @param {import('./http-outgoing.js').default} outgoing
71
+ * @returns {Promise<import('./http-outgoing.js').default>}
72
+ */
56
73
  async resolve(outgoing) {
57
74
  if (outgoing.status === 'cached') {
58
75
  return outgoing;
@@ -62,6 +79,7 @@ export default class PodletClientManifestResolver {
62
79
  'User-Agent': UA_STRING,
63
80
  };
64
81
 
82
+ /** @type {import('./http.js').PodiumHttpClientRequestOptions} */
65
83
  const reqOptions = {
66
84
  rejectUnauthorized: outgoing.rejectUnauthorized,
67
85
  timeout: outgoing.timeout,
@@ -81,11 +99,11 @@ export default class PodletClientManifestResolver {
81
99
  );
82
100
 
83
101
  try {
84
- const {
85
- statusCode,
86
- headers: hdrs,
87
- body,
88
- } = await this.#http.request(outgoing.manifestUri, reqOptions);
102
+ const response = await this.#http.request(
103
+ outgoing.manifestUri,
104
+ reqOptions,
105
+ );
106
+ const { statusCode, headers: hdrs, body } = response;
89
107
 
90
108
  // Remote responds but with an http error code
91
109
  const resError = statusCode !== 200;
@@ -105,7 +123,11 @@ export default class PodletClientManifestResolver {
105
123
  return outgoing;
106
124
  }
107
125
 
108
- const manifest = validateManifest(await body.json());
126
+ const manifest = validateManifest(
127
+ /** @type {import("@podium/schemas").PodletManifestSchema} */ (
128
+ await body.json()
129
+ ),
130
+ );
109
131
 
110
132
  // Manifest validation error
111
133
  if (manifest.error) {
@@ -158,6 +180,7 @@ export default class PodletClientManifestResolver {
158
180
  );
159
181
 
160
182
  // Construct css and js objects with absolute URIs
183
+ // @ts-expect-error We assign here what will end up as PodletManifest as defined in http-outgoing.js
161
184
  manifest.value.css = manifest.value.css.map((obj) => {
162
185
  obj.value = utils.uriRelativeToAbsolute(
163
186
  obj.value,
@@ -166,6 +189,7 @@ export default class PodletClientManifestResolver {
166
189
  return new utils.AssetCss(obj);
167
190
  });
168
191
 
192
+ // @ts-expect-error We assign here what will end up as PodletManifest as defined in http-outgoing.js
169
193
  manifest.value.js = manifest.value.js.map((obj) => {
170
194
  obj.value = utils.uriRelativeToAbsolute(
171
195
  obj.value,
@@ -179,9 +203,9 @@ export default class PodletClientManifestResolver {
179
203
 
180
204
  If .proxy is and Array, the podlet are of version 6 or newer. The Array is then an
181
205
  Array of proxy Objects ({ name: 'foo', target: '/' }) which is the new structure
182
- wanted from version 6 and onwards so leave this structure untouched.
206
+ wanted from version 6 and onwards so leave this structure untouched.
183
207
 
184
- If .proxy is an Object, the podlet are of version 5 or older where the key of the
208
+ If .proxy is an Object, the podlet are of version 5 or older where the key of the
185
209
  Object is the key of the target. If so, convert the structure to the new structure
186
210
  consisting of an Array of proxy Objects.
187
211
 
@@ -191,12 +215,12 @@ export default class PodletClientManifestResolver {
191
215
  if (Array.isArray(manifest.value.proxy)) {
192
216
  // Build absolute proxy URIs
193
217
  manifest.value.proxy = manifest.value.proxy.map((item) => ({
194
- target: utils.uriRelativeToAbsolute(
195
- item.target,
196
- outgoing.manifestUri,
197
- ),
198
- name: item.name,
199
- }));
218
+ target: utils.uriRelativeToAbsolute(
219
+ item.target,
220
+ outgoing.manifestUri,
221
+ ),
222
+ name: item.name,
223
+ }));
200
224
  } else {
201
225
  const proxies = [];
202
226
  // Build absolute proxy URIs
@@ -216,6 +240,7 @@ export default class PodletClientManifestResolver {
216
240
  END: Proxy backwards compabillity check and handling
217
241
  */
218
242
 
243
+ // @ts-expect-error We map to AssetCss and AssetJs above
219
244
  outgoing.manifest = manifest.value;
220
245
  outgoing.status = 'fresh';
221
246
 
package/lib/resource.js CHANGED
@@ -11,11 +11,42 @@ import * as utils from './utils.js';
11
11
 
12
12
  const inspect = Symbol.for('nodejs.util.inspect.custom');
13
13
 
14
+ /**
15
+ * @typedef {object} RequestFilterOptions
16
+ * @property {string[]} [deviceType] List of values for the `x-podium-device-type` HTTP request header.
17
+ */
18
+
19
+ /**
20
+ * @typedef {object} PodiumClientResourceOptions
21
+ * @property {import('abslog').AbstractLoggerOptions} [logger]
22
+ * @property {string} clientName
23
+ * @property {string} name
24
+ * @property {string} uri To the podlet's `manifest.json`
25
+ * @property {number} timeout In milliseconds
26
+ * @property {number} maxAge
27
+ * @property {number} [retries]
28
+ * @property {boolean} [throwable]
29
+ * @property {boolean} [redirectable]
30
+ * @property {boolean} [rejectUnauthorized]
31
+ * @property {import('http').Agent} [httpAgent]
32
+ * @property {import('https').Agent} [httpsAgent]
33
+ * @property {RequestFilterOptions} [excludeBy] Used by `fetch` to conditionally skip fetching the podlet content based on values on the request.
34
+ * @property {RequestFilterOptions} [includeBy] Used by `fetch` to conditionally skip fetching the podlet content based on values on the request.
35
+ */
36
+
14
37
  export default class PodiumClientResource {
15
38
  #resolver;
16
39
  #options;
17
40
  #metrics;
18
41
  #state;
42
+
43
+ /**
44
+ * @constructor
45
+ * @param {import('ttl-mem-cache').default} registry
46
+ * @param {import('./state.js').default} state
47
+ * @param {PodiumClientResourceOptions} options
48
+ */
49
+ // @ts-expect-error Deliberate for better error messages
19
50
  constructor(registry, state, options = {}) {
20
51
  assert(
21
52
  registry,
@@ -56,7 +87,22 @@ export default class PodiumClientResource {
56
87
  return this.#options.uri;
57
88
  }
58
89
 
59
- async fetch(incoming = {}, reqOptions = {}) {
90
+ /**
91
+ * Fetch the podlet's content, or fallback if the podlet is unavailable.
92
+ * The podlet response includes references to its CSS and JS assets which should be included in the final HTML document.
93
+ *
94
+ * @param {import('@podium/utils').HttpIncoming} incoming Instance of HttpIncoming
95
+ * @param {import('./http-outgoing.js').PodiumClientResourceOptions} [reqOptions={}] Optional parameters to the HTTP request, such as query parameters or HTTP request headers.
96
+ * @returns {Promise<import('./response.js').default>}
97
+ *
98
+ * @example
99
+ * ```js
100
+ * const incoming = res.locals.podium; // Express server example
101
+ * const header = await headerPodlet.fetch(incoming);
102
+ * incoming.podlets = [header]; // Register the podlet's JS and CSS assets with the layout's HTML template
103
+ * ```
104
+ */
105
+ async fetch(incoming, reqOptions = {}) {
60
106
  if (!utils.validateIncoming(incoming))
61
107
  throw new TypeError(
62
108
  'you must pass an instance of "HttpIncoming" as the first argument to the .fetch() method',
@@ -67,21 +113,21 @@ export default class PodiumClientResource {
67
113
  /**
68
114
  * @type {string[] | undefined}
69
115
  */
70
- const exclucedDeviceTypes = this.#options.excludeBy.deviceType;
71
- if (Array.isArray(exclucedDeviceTypes)) {
116
+ const excludedDeviceTypes = this.#options.excludeBy.deviceType;
117
+ if (Array.isArray(excludedDeviceTypes)) {
72
118
  const deviceTypeHeader =
73
119
  incoming.request.headers['x-podium-device-type'];
74
120
 
75
- for (let i = 0; i < exclucedDeviceTypes.length; i += 1) {
121
+ for (let i = 0; i < excludedDeviceTypes.length; i += 1) {
76
122
  const shouldSkip =
77
- exclucedDeviceTypes[i] === deviceTypeHeader;
123
+ excludedDeviceTypes[i] === deviceTypeHeader;
78
124
  if (shouldSkip) {
79
125
  return new Response({
80
126
  headers: {},
81
127
  content: '',
82
128
  css: [],
83
129
  js: [],
84
- redirect: '',
130
+ redirect: null,
85
131
  });
86
132
  }
87
133
  }
@@ -107,7 +153,7 @@ export default class PodiumClientResource {
107
153
  content: '',
108
154
  css: [],
109
155
  js: [],
110
- redirect: '',
156
+ redirect: null,
111
157
  });
112
158
  }
113
159
  }
@@ -143,7 +189,14 @@ export default class PodiumClientResource {
143
189
  });
144
190
  }
145
191
 
146
- stream(incoming = {}, reqOptions = {}) {
192
+ /**
193
+ * Stream the podlet's content, or fallback if the podlet is unavailable.
194
+ *
195
+ * @param {import('@podium/utils').HttpIncoming} incoming
196
+ * @param {import('./http-outgoing.js').PodiumClientResourceOptions} [reqOptions={}]
197
+ * @returns {import('./http-outgoing.js').default}
198
+ */
199
+ stream(incoming, reqOptions = {}) {
147
200
  if (!utils.validateIncoming(incoming))
148
201
  throw new TypeError(
149
202
  'you must pass an instance of "HttpIncoming" as the first argument to the .stream() method',
@@ -154,7 +207,14 @@ export default class PodiumClientResource {
154
207
  return outgoing;
155
208
  }
156
209
 
157
- refresh(incoming = {}, reqOptions = {}) {
210
+ /**
211
+ * Refresh the podlet's manifest and fallback in the cache.
212
+ *
213
+ * @param {import('@podium/utils').HttpIncoming} [incoming]
214
+ * @param {import('./http-outgoing.js').PodiumClientResourceOptions} [reqOptions={}]
215
+ * @returns {Promise<boolean>} `true` if succesful
216
+ */
217
+ refresh(incoming, reqOptions = {}) {
158
218
  const outgoing = new HttpOutgoing(this.#options, reqOptions, incoming);
159
219
  this.#state.setInitializingState();
160
220
  return this.#resolver.refresh(outgoing).then((obj) => obj);
package/lib/response.js CHANGED
@@ -1,11 +1,25 @@
1
1
  const inspect = Symbol.for('nodejs.util.inspect.custom');
2
2
 
3
+ /**
4
+ * @typedef {object} PodiumClientResponseOptions
5
+ * @property {string} [content]
6
+ * @property {object} [headers]
7
+ * @property {Array<import('@podium/utils').AssetJs>} [js]
8
+ * @property {Array<import('@podium/utils').AssetCss>} [css]
9
+ * @property {import('./http-outgoing.js').PodiumRedirect | null} [redirect]
10
+ */
11
+
3
12
  export default class PodiumClientResponse {
4
13
  #redirect;
5
14
  #content;
6
15
  #headers;
7
16
  #css;
8
17
  #js;
18
+
19
+ /**
20
+ * @constructor
21
+ * @param {PodiumClientResponseOptions} options
22
+ */
9
23
  constructor({
10
24
  content = '',
11
25
  headers = {},
@@ -45,8 +59,8 @@ export default class PodiumClientResponse {
45
59
  redirect: this.redirect,
46
60
  content: this.content,
47
61
  headers: this.headers,
48
- css: this.css,
49
- js: this.js,
62
+ css: this.css.map((a) => a.toJSON()),
63
+ js: this.js.map((a) => a.toJSON()),
50
64
  };
51
65
  }
52
66
 
@@ -71,4 +85,4 @@ export default class PodiumClientResponse {
71
85
  get [Symbol.toStringTag]() {
72
86
  return 'PodiumClientResponse';
73
87
  }
74
- };
88
+ }
package/lib/state.js CHANGED
@@ -2,12 +2,25 @@ import EventEmitter from 'events';
2
2
 
3
3
  const inspect = Symbol.for('nodejs.util.inspect.custom');
4
4
 
5
+ /**
6
+ * @typedef {object} PodiumClientStateOptions
7
+ * @property {number} [resolveThreshold=10000]
8
+ * @property {number} [resolveMax=240000]
9
+ */
10
+
5
11
  export default class PodiumClientState extends EventEmitter {
12
+ /** @type {NodeJS.Timeout | undefined} */
6
13
  #thresholdTimer;
7
14
  #threshold;
15
+ /** @type {NodeJS.Timeout | undefined} */
8
16
  #maxTimer;
17
+ /** @type {"instantiated" | "stable" | "initializing" | "unhealthy" | "unstable"} */
9
18
  #state;
10
19
  #max;
20
+
21
+ /**
22
+ * @param {PodiumClientStateOptions} [options]
23
+ */
11
24
  constructor({
12
25
  resolveThreshold = 10 * 1000,
13
26
  resolveMax = 4 * 60 * 1000,
@@ -113,4 +126,4 @@ export default class PodiumClientState extends EventEmitter {
113
126
  get [Symbol.toStringTag]() {
114
127
  return 'PodiumClientState';
115
128
  }
116
- };
129
+ }
package/lib/utils.js CHANGED
@@ -1,14 +1,12 @@
1
1
  /**
2
- * Checks if a header Oject has a header.
3
- * Will return true if the header exist and are not an empty
4
- * String or a String of whitespace.
2
+ * Checks if a header object has a header.
3
+ * Will return true if the header exist and is not an empty
4
+ * string or a string of whitespace.
5
5
  *
6
- * @param {Object} headers A headers object
7
- * @param {String} header A header value
8
- *
9
- * @returns {Boolean}
6
+ * @param {object} headers
7
+ * @param {string} header
8
+ * @returns {boolean}
10
9
  */
11
-
12
10
  export const isHeaderDefined = (headers, header) => {
13
11
  if (headers[header] === undefined || headers[header].trim() === '') {
14
12
  return false;
@@ -21,31 +19,24 @@ export const isHeaderDefined = (headers, header) => {
21
19
  * the changelog event object emitted from the internal
22
20
  * cache registry.
23
21
  *
24
- * @param {Object} item A changelog event object
25
- *
26
- * @returns {Boolean}
22
+ * @param {object} item A changelog event object
23
+ * @returns {boolean}
27
24
  */
28
-
29
- export const hasManifestChange = item => {
25
+ export const hasManifestChange = (item) => {
30
26
  const oldVersion = item.oldVal ? item.oldVal.version : '';
31
27
  const newVersion = item.newVal ? item.newVal.version : '';
32
28
  return oldVersion !== newVersion;
33
29
  };
34
30
 
35
-
36
31
  /**
37
- * Check if a value is a HttpIncoming object or not. If not, it
32
+ * Check if a value is a Podium HttpIncoming object or not. If not, it
38
33
  * assume the incoming value is a context
39
34
  *
40
- * @param {Object} incoming A object
41
- *
42
- * @returns {HttpIncoming}
43
- */
44
- export const validateIncoming = (incoming = {}) => (Object.prototype.toString.call(incoming) === '[object PodiumHttpIncoming]');
45
-
46
- /**
47
- * @typedef {import("@podium/utils").AssetCss | import("@podium/utils").AssetJs} Asset
35
+ * @param {object} incoming
36
+ * @returns {boolean}
48
37
  */
38
+ export const validateIncoming = (incoming = {}) =>
39
+ Object.prototype.toString.call(incoming) === '[object PodiumHttpIncoming]';
49
40
 
50
41
  /**
51
42
  * Filter assets array based on scope.
@@ -53,9 +44,10 @@ export const validateIncoming = (incoming = {}) => (Object.prototype.toString.ca
53
44
  * If scope property is set to "all", asset will be included.
54
45
  * If scope is set to "content" and asset scope property is set to "fallback", asset will not be included
55
46
  * If scope is set to "fallback" and asset scope property is set to "content", asset will not be included
47
+ * @template {import("@podium/utils").AssetCss | import("@podium/utils").AssetJs} T[]
56
48
  * @param {"content" | "fallback" | "all"} scope
57
- * @param {Asset[]} assets
58
- * @returns {Asset[]}
49
+ * @param {T[]} assets
50
+ * @returns {T[]}
59
51
  *
60
52
  * @example
61
53
  * ```
@@ -69,7 +61,13 @@ export const filterAssets = (scope, assets) => {
69
61
  // if undefined or null, passthrough
70
62
  if (!assets) return assets;
71
63
  // if a non array value is given, throw
72
- if (!Array.isArray(assets)) throw new TypeError(`Asset definition must be of type array. Got ${typeof assets}`);
64
+ if (!Array.isArray(assets))
65
+ throw new TypeError(
66
+ `Asset definition must be of type array. Got ${typeof assets}`,
67
+ );
73
68
  // filter the array of asset definitions to matchin scope or anything with all. Treat no scope the same as "all" for backwards compatibility.
74
- return assets.filter(asset => !asset.scope || asset.scope === scope || asset.scope === "all");
69
+ return assets.filter(
70
+ (asset) =>
71
+ !asset.scope || asset.scope === scope || asset.scope === 'all',
72
+ );
75
73
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@podium/client",
3
- "version": "5.1.0-beta.1",
3
+ "version": "5.1.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -21,51 +21,53 @@
21
21
  "files": [
22
22
  "package.json",
23
23
  "CHANGELOG.md",
24
- "client.d.ts",
25
24
  "README.md",
26
25
  "LICENSE",
27
- "dist",
28
- "lib"
26
+ "lib",
27
+ "types"
29
28
  ],
30
29
  "main": "./lib/client.js",
31
- "types": "client.d.ts",
30
+ "types": "./types/client.d.ts",
32
31
  "scripts": {
33
32
  "lint": "eslint .",
34
33
  "lint:fix": "eslint --fix .",
35
- "test": "tap --disable-coverage --allow-empty-coverage"
34
+ "test": "tap tests/*.js --disable-coverage --allow-empty-coverage && tsc --project tsconfig.test.json",
35
+ "types": "tsc --declaration --emitDeclarationOnly"
36
36
  },
37
37
  "dependencies": {
38
- "@hapi/boom": "^10.0.0",
38
+ "@hapi/boom": "10.0.1",
39
39
  "@metrics/client": "2.5.2",
40
- "@podium/schemas": "5.0.0",
41
- "@podium/utils": "5.0.2",
42
- "abslog": "2.4.0",
40
+ "@podium/schemas": "5.0.5",
41
+ "@podium/utils": "5.0.7",
42
+ "abslog": "2.4.4",
43
43
  "http-cache-semantics": "^4.0.3",
44
44
  "lodash.clonedeep": "^4.5.0",
45
45
  "ttl-mem-cache": "4.1.0",
46
- "undici": "^6.0.0"
46
+ "undici": "6.19.2"
47
47
  },
48
48
  "devDependencies": {
49
+ "@babel/eslint-parser": "7.24.7",
49
50
  "@podium/test-utils": "2.5.2",
50
51
  "@semantic-release/changelog": "6.0.3",
51
52
  "@semantic-release/git": "10.0.1",
52
- "@babel/eslint-parser": "7.23.10",
53
- "@semantic-release/github": "9.2.6",
54
- "@semantic-release/npm": "11.0.2",
55
- "@semantic-release/release-notes-generator": "12.1.0",
53
+ "@semantic-release/github": "10.0.6",
54
+ "@semantic-release/npm": "12.0.1",
55
+ "@semantic-release/release-notes-generator": "13.0.0",
56
56
  "@sinonjs/fake-timers": "11.2.2",
57
+ "@types/readable-stream": "4.0.14",
57
58
  "benchmark": "2.1.4",
58
59
  "eslint": "8.57.0",
59
60
  "eslint-config-airbnb-base": "15.0.0",
60
61
  "eslint-config-prettier": "9.1.0",
61
62
  "eslint-plugin-import": "2.29.1",
62
63
  "eslint-plugin-prettier": "5.1.3",
63
- "express": "4.18.3",
64
- "get-stream": "8.0.1",
64
+ "express": "4.19.2",
65
+ "get-stream": "9.0.1",
65
66
  "http-proxy": "1.18.1",
66
- "is-stream": "3.0.0",
67
- "prettier": "3.2.5",
68
- "semantic-release": "23.0.2",
69
- "tap": "18.7.0"
67
+ "is-stream": "4.0.1",
68
+ "prettier": "3.3.2",
69
+ "semantic-release": "23.1.1",
70
+ "tap": "18.7.2",
71
+ "typescript": "5.4.5"
70
72
  }
71
73
  }
@@ -0,0 +1,120 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ /**
3
+ * @typedef {import('./resource.js').default} PodiumClientResource
4
+ * @typedef {import('./resource.js').PodiumClientResourceOptions} PodiumClientResourceOptions
5
+ * @typedef {import('./response.js').default} PodiumClientResponse
6
+ * @typedef {import('./http-outgoing.js').PodiumRedirect} PodiumRedirect
7
+ * @typedef {import('@podium/schemas').PodletManifestSchema} PodletManifest
8
+ */
9
+ /**
10
+ * @typedef {object} PodiumClientOptions
11
+ * @property {string} name
12
+ * @property {import('abslog').AbstractLoggerOptions} [logger]
13
+ * @property {number} [retries=4]
14
+ * @property {number} [timeout=1000] In milliseconds
15
+ * @property {number} [maxAge=Infinity]
16
+ * @property {boolean} [rejectUnauthorized=true]
17
+ * @property {number} [resolveThreshold]
18
+ * @property {number} [resolveMax]
19
+ * @property {import('http').Agent} [httpAgent]
20
+ * @property {import('https').Agent} [httpsAgent]
21
+ */
22
+ /**
23
+ * @typedef {object} RegisterOptions
24
+ * @property {string} name A unique name for the podlet
25
+ * @property {string} uri URL to the podlet's `manifest.json`
26
+ * @property {number} [retries=4] Number of retries before serving fallback
27
+ * @property {number} [timeout=1000] In milliseconds, the amount of time to wait before serving fallback.
28
+ * @property {boolean} [throwable=false] Set to `true` and surround `fetch` in `try/catch` to serve different content in case podlet is unavailable. Will not server fallback content.
29
+ * @property {boolean} [redirectable=false] Set to `true` to allow podlet to respond with a redirect. You need to look for the redirect response from the podlet and return a redirect response to the browser yourself.
30
+ * @property {import('./resource.js').RequestFilterOptions} [excludeBy] Used by `fetch` to conditionally skip fetching the podlet content based on values on the request.
31
+ * @property {import('./resource.js').RequestFilterOptions} [includeBy] Used by `fetch` to conditionally skip fetching the podlet content based on values on the request.
32
+ */
33
+ export default class PodiumClient extends EventEmitter<[never]> {
34
+ /**
35
+ * @constructor
36
+ * @param {PodiumClientOptions} options
37
+ */
38
+ constructor(options?: PodiumClientOptions);
39
+ get registry(): any;
40
+ get metrics(): Metrics;
41
+ get state(): "instantiated" | "stable" | "initializing" | "unhealthy" | "unstable";
42
+ /**
43
+ * Register a podlet so you can fetch its contents later with {@link PodiumClientResource.fetch}.
44
+ *
45
+ * @param {RegisterOptions} options
46
+ * @returns {PodiumClientResource}
47
+ *
48
+ * @example
49
+ * ```js
50
+ * const headerPodlet = layout.client.register({
51
+ * name: 'header',
52
+ * uri: 'http://header/manifest.json',
53
+ * });
54
+ * ```
55
+ */
56
+ register(options: RegisterOptions): PodiumClientResource;
57
+ dump(): any;
58
+ load(dump: any): any;
59
+ /**
60
+ * Refreshes the cached podlet manifest for all {@link register}ed podlets.
61
+ */
62
+ refreshManifests(): Promise<void>;
63
+ #private;
64
+ }
65
+ export type PodiumClientResource = import('./resource.js').default;
66
+ export type PodiumClientResourceOptions = import('./resource.js').PodiumClientResourceOptions;
67
+ export type PodiumClientResponse = import('./response.js').default;
68
+ export type PodiumRedirect = import('./http-outgoing.js').PodiumRedirect;
69
+ export type PodletManifest = import('@podium/schemas').PodletManifestSchema;
70
+ export type PodiumClientOptions = {
71
+ name: string;
72
+ logger?: import('abslog').AbstractLoggerOptions;
73
+ retries?: number;
74
+ /**
75
+ * In milliseconds
76
+ */
77
+ timeout?: number;
78
+ maxAge?: number;
79
+ rejectUnauthorized?: boolean;
80
+ resolveThreshold?: number;
81
+ resolveMax?: number;
82
+ httpAgent?: import('http').Agent;
83
+ httpsAgent?: import('https').Agent;
84
+ };
85
+ export type RegisterOptions = {
86
+ /**
87
+ * A unique name for the podlet
88
+ */
89
+ name: string;
90
+ /**
91
+ * URL to the podlet's `manifest.json`
92
+ */
93
+ uri: string;
94
+ /**
95
+ * Number of retries before serving fallback
96
+ */
97
+ retries?: number;
98
+ /**
99
+ * In milliseconds, the amount of time to wait before serving fallback.
100
+ */
101
+ timeout?: number;
102
+ /**
103
+ * Set to `true` and surround `fetch` in `try/catch` to serve different content in case podlet is unavailable. Will not server fallback content.
104
+ */
105
+ throwable?: boolean;
106
+ /**
107
+ * Set to `true` to allow podlet to respond with a redirect. You need to look for the redirect response from the podlet and return a redirect response to the browser yourself.
108
+ */
109
+ redirectable?: boolean;
110
+ /**
111
+ * Used by `fetch` to conditionally skip fetching the podlet content based on values on the request.
112
+ */
113
+ excludeBy?: import('./resource.js').RequestFilterOptions;
114
+ /**
115
+ * Used by `fetch` to conditionally skip fetching the podlet content based on values on the request.
116
+ */
117
+ includeBy?: import('./resource.js').RequestFilterOptions;
118
+ };
119
+ import EventEmitter from 'events';
120
+ import Metrics from '@metrics/client';