@podium/client
Advanced tools
Comparing version 4.5.35 to 4.6.0
@@ -0,1 +1,8 @@ | ||
# [4.6.0](https://github.com/podium-lib/client/compare/v4.5.35...v4.6.0) (2023-11-16) | ||
### Features | ||
* use manifest asset scope field to filter assets ([fd83d64](https://github.com/podium-lib/client/commit/fd83d6486f9454f4fef2cdbcf3a05b86c81205c5)) | ||
## [4.5.35](https://github.com/podium-lib/client/compare/v4.5.34...v4.5.35) (2023-10-19) | ||
@@ -2,0 +9,0 @@ |
@@ -27,2 +27,3 @@ /* eslint-disable no-underscore-dangle */ | ||
const _uri = Symbol('podium:httpoutgoing:uri'); | ||
const _isfallback = Symbol('podium:httpoutgoing:isfallback'); | ||
@@ -118,2 +119,5 @@ const PodletClientHttpOutgoing = class PodletClientHttpOutgoing extends PassThrough { | ||
this[_redirect] = null; | ||
// When isfallback is true, content fetch has failed and fallback will be served instead | ||
this[_isfallback] = false; | ||
} | ||
@@ -245,7 +249,19 @@ | ||
/** | ||
* Boolean getter that indicates whether the client is responding with a content or fallback payload. | ||
* @example | ||
* ``` | ||
* if (outgoing.isFallback) console.log("Fallback!"); | ||
* ``` | ||
*/ | ||
get isFallback() { | ||
return this[_isfallback]; | ||
} | ||
pushFallback() { | ||
this.push(this[_manifest]._fallback); | ||
this.push(null); | ||
this[_isfallback] = true; | ||
} | ||
}; | ||
module.exports = PodletClientHttpOutgoing; |
@@ -84,2 +84,9 @@ /* eslint-disable no-param-reassign */ | ||
outgoing.pushFallback(); | ||
outgoing.emit( | ||
'beforeStream', | ||
new Response({ | ||
js: utils.filterAssets("fallback", outgoing.manifest.js), | ||
css: utils.filterAssets("fallback", outgoing.manifest.css), | ||
}), | ||
); | ||
resolve(outgoing); | ||
@@ -105,2 +112,9 @@ return; | ||
outgoing.pushFallback(); | ||
outgoing.emit( | ||
'beforeStream', | ||
new Response({ | ||
js: utils.filterAssets("fallback", outgoing.manifest.js), | ||
css: utils.filterAssets("fallback", outgoing.manifest.css), | ||
}), | ||
); | ||
resolve(outgoing); | ||
@@ -186,2 +200,10 @@ return; | ||
outgoing.pushFallback(); | ||
outgoing.emit( | ||
'beforeStream', | ||
new Response({ | ||
headers: outgoing.headers, | ||
js: utils.filterAssets("fallback", outgoing.manifest.js), | ||
css: utils.filterAssets("fallback", outgoing.manifest.css), | ||
}), | ||
); | ||
resolve(outgoing); | ||
@@ -234,4 +256,4 @@ return; | ||
headers: outgoing.headers, | ||
js: outgoing.manifest.js, | ||
css: outgoing.manifest.css, | ||
js: utils.filterAssets("content", outgoing.manifest.js), | ||
css: utils.filterAssets("content", outgoing.manifest.css), | ||
redirect: outgoing.redirect, | ||
@@ -280,4 +302,11 @@ }), | ||
outgoing.success = true; | ||
outgoing.pushFallback(); | ||
outgoing.emit( | ||
'beforeStream', | ||
new Response({ | ||
js: utils.filterAssets('fallback', outgoing.manifest.js), | ||
css: utils.filterAssets('fallback', outgoing.manifest.css), | ||
}), | ||
); | ||
outgoing.pushFallback(); | ||
resolve(outgoing); | ||
@@ -284,0 +313,0 @@ }); |
@@ -15,2 +15,3 @@ /* eslint-disable no-underscore-dangle */ | ||
const Resolver = require('./resolver'); | ||
const utils = require('./utils'); | ||
@@ -78,3 +79,3 @@ const _resolver = Symbol('podium:client:resource:resolver'); | ||
const { manifest, headers, redirect } = await this[_resolver].resolve( | ||
const { manifest, headers, redirect, isFallback } = await this[_resolver].resolve( | ||
outgoing, | ||
@@ -90,4 +91,4 @@ ); | ||
content, | ||
css: manifest.css, | ||
js: manifest.js, | ||
css: utils.filterAssets(isFallback ? "fallback" : "content", manifest.css), | ||
js: utils.filterAssets(isFallback ? "fallback" : "content", manifest.js), | ||
redirect, | ||
@@ -94,0 +95,0 @@ }); |
@@ -74,1 +74,32 @@ 'use strict'; | ||
}; | ||
/** | ||
* @typedef {import("@podium/utils").AssetCss | import("@podium/utils").AssetJs} Asset | ||
*/ | ||
/** | ||
* Filter assets array based on scope. | ||
* If scope property is not present, asset will be included (backwards compatibility) | ||
* If scope property is set to "all", asset will be included. | ||
* If scope is set to "content" and asset scope property is set to "fallback", asset will not be included | ||
* If scope is set to "fallback" and asset scope property is set to "content", asset will not be included | ||
* @param {"content" | "fallback" | "all"} scope | ||
* @param {Asset[]} assets | ||
* @returns {Asset[]} | ||
* | ||
* @example | ||
* ``` | ||
* // plain objects work | ||
* const assets = filterAssets("content", [{..., scope: "content"}, {..., scope: "fallback"}]); | ||
* // as do AssetJs and AssetCSS objects | ||
* const assets = filterAssets("content", [new AssetCss(), new AssetCss()]); | ||
* ``` | ||
*/ | ||
module.exports.filterAssets = (scope, assets) => { | ||
// if undefined or null, passthrough | ||
if (!assets) return assets; | ||
// if a non array value is given, throw | ||
if (!Array.isArray(assets)) throw new TypeError(`Asset definition must be of type array. Got ${typeof assets}`); | ||
// filter the array of asset definitions to matchin scope or anything with all. Treat no scope the same as "all" for backwards compatibility. | ||
return assets.filter(asset => !asset.scope || asset.scope === scope || asset.scope === "all"); | ||
}; |
{ | ||
"name": "@podium/client", | ||
"version": "4.5.35", | ||
"version": "4.6.0", | ||
"main": "lib/client.js", | ||
@@ -40,4 +40,4 @@ "license": "MIT", | ||
"@metrics/client": "2.5.2", | ||
"@podium/schemas": "4.1.34", | ||
"@podium/utils": "4.4.41", | ||
"@podium/schemas": "4.2.0", | ||
"@podium/utils": "4.5.0", | ||
"abslog": "2.4.0", | ||
@@ -44,0 +44,0 @@ "http-cache-semantics": "^4.0.3", |
@@ -387,2 +387,4 @@ # @podium/client | ||
**Note:** If the podlet is unavailable, the client will not receive `headers` and therefore will not set `headers` on the response. | ||
#### incoming (required) | ||
@@ -432,2 +434,22 @@ | ||
**Note:** If the podlet is unavailable, the client will not receive `headers` and therefore `data.headers` will be undefined. | ||
### Asset Scope | ||
Both the .fetch() method and the .stream() method give you access to podlet asset objects and these CSS and JS asset objects will be filtered if the asset objects contain a `scope` property and that `scope` property matches the current response type (either content or fallback). | ||
For example, if the podlet manifest contains a JavaScript asset definition of the form: | ||
``` | ||
{ | ||
js: [{ value: "https://assets.com/path/to/file.js", scope: "content" }], | ||
} | ||
``` | ||
And the client performs a fetch like so: | ||
```js | ||
const result = await component.fetch(); | ||
``` | ||
Then, if the podlet successfully responds from its content route, the `result.js` property will contain the asset defined above. If, however, the podlet's content route errors and the client is forced to use the podlet's fallback content, then `result.js` property will be an empty array. | ||
Possible `scope` values are `content`, `fallback` and `all`. For backwards compatibility reasons, when assets do not provide a `scope` property, they will always be included in both `content` and `fallback` responses. | ||
## Controlling caching of the manifest | ||
@@ -434,0 +456,0 @@ |
110986
1703
663
+ Added@podium/schemas@4.2.0(transitive)
+ Added@podium/utils@4.5.0(transitive)
- Removed@podium/schemas@4.1.34(transitive)
- Removed@podium/utils@4.4.41(transitive)
Updated@podium/schemas@4.2.0
Updated@podium/utils@4.5.0