kopia lustrzana https://gitlab.com/rysiekpl/libresilient
Merge branch 'modularize-alt-fetch-as-an-example' into 'master'
Draft: modularize alt fetch plugin as an example See merge request rysiekpl/libresilient!23merge-requests/23/merge
commit
1a4edee18b
|
@ -1,2 +1,5 @@
|
|||
coverage/
|
||||
junit.xml
|
||||
|
||||
dist
|
||||
node_modules
|
||||
|
|
|
@ -0,0 +1,422 @@
|
|||
{
|
||||
"name": "libresilient",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "libresilient",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"esbuild": "0.19.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.10.tgz",
|
||||
"integrity": "sha512-Q+mk96KJ+FZ30h9fsJl+67IjNJm3x2eX+GBWGmocAKgzp27cowCOOqSdscX80s0SpdFXZnIv/+1xD1EctFx96Q==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"aix"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.10.tgz",
|
||||
"integrity": "sha512-7W0bK7qfkw1fc2viBfrtAEkDKHatYfHzr/jKAHNr9BvkYDXPcC6bodtm8AyLJNNuqClLNaeTLuwURt4PRT9d7w==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.10.tgz",
|
||||
"integrity": "sha512-1X4CClKhDgC3by7k8aOWZeBXQX8dHT5QAMCAQDArCLaYfkppoARvh0fit3X2Qs+MXDngKcHv6XXyQCpY0hkK1Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.10.tgz",
|
||||
"integrity": "sha512-O/nO/g+/7NlitUxETkUv/IvADKuZXyH4BHf/g/7laqKC4i/7whLpB0gvpPc2zpF0q9Q6FXS3TS75QHac9MvVWw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.10.tgz",
|
||||
"integrity": "sha512-YSRRs2zOpwypck+6GL3wGXx2gNP7DXzetmo5pHXLrY/VIMsS59yKfjPizQ4lLt5vEI80M41gjm2BxrGZ5U+VMA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.10.tgz",
|
||||
"integrity": "sha512-alfGtT+IEICKtNE54hbvPg13xGBe4GkVxyGWtzr+yHO7HIiRJppPDhOKq3zstTcVf8msXb/t4eavW3jCDpMSmA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.10.tgz",
|
||||
"integrity": "sha512-dMtk1wc7FSH8CCkE854GyGuNKCewlh+7heYP/sclpOG6Cectzk14qdUIY5CrKDbkA/OczXq9WesqnPl09mj5dg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.10.tgz",
|
||||
"integrity": "sha512-G5UPPspryHu1T3uX8WiOEUa6q6OlQh6gNl4CO4Iw5PS+Kg5bVggVFehzXBJY6X6RSOMS8iXDv2330VzaObm4Ag==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.10.tgz",
|
||||
"integrity": "sha512-j6gUW5aAaPgD416Hk9FHxn27On28H4eVI9rJ4az7oCGTFW48+LcgNDBN+9f8rKZz7EEowo889CPKyeaD0iw9Kg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.10.tgz",
|
||||
"integrity": "sha512-QxaouHWZ+2KWEj7cGJmvTIHVALfhpGxo3WLmlYfJ+dA5fJB6lDEIg+oe/0//FuyVHuS3l79/wyBxbHr0NgtxJQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.10.tgz",
|
||||
"integrity": "sha512-4ub1YwXxYjj9h1UIZs2hYbnTZBtenPw5NfXCRgEkGb0b6OJ2gpkMvDqRDYIDRjRdWSe/TBiZltm3Y3Q8SN1xNg==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.10.tgz",
|
||||
"integrity": "sha512-lo3I9k+mbEKoxtoIbM0yC/MZ1i2wM0cIeOejlVdZ3D86LAcFXFRdeuZmh91QJvUTW51bOK5W2BznGNIl4+mDaA==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.10.tgz",
|
||||
"integrity": "sha512-J4gH3zhHNbdZN0Bcr1QUGVNkHTdpijgx5VMxeetSk6ntdt+vR1DqGmHxQYHRmNb77tP6GVvD+K0NyO4xjd7y4A==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.10.tgz",
|
||||
"integrity": "sha512-tgT/7u+QhV6ge8wFMzaklOY7KqiyitgT1AUHMApau32ZlvTB/+efeCtMk4eXS+uEymYK249JsoiklZN64xt6oQ==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.10.tgz",
|
||||
"integrity": "sha512-0f/spw0PfBMZBNqtKe5FLzBDGo0SKZKvMl5PHYQr3+eiSscfJ96XEknCe+JoOayybWUFQbcJTrk946i3j9uYZA==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.10.tgz",
|
||||
"integrity": "sha512-pZFe0OeskMHzHa9U38g+z8Yx5FNCLFtUnJtQMpwhS+r4S566aK2ci3t4NCP4tjt6d5j5uo4h7tExZMjeKoehAA==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.10.tgz",
|
||||
"integrity": "sha512-SpYNEqg/6pZYoc+1zLCjVOYvxfZVZj6w0KROZ3Fje/QrM3nfvT2llI+wmKSrWuX6wmZeTapbarvuNNK/qepSgA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.10.tgz",
|
||||
"integrity": "sha512-ACbZ0vXy9zksNArWlk2c38NdKg25+L9pr/mVaj9SUq6lHZu/35nx2xnQVRGLrC1KKQqJKRIB0q8GspiHI3J80Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.10.tgz",
|
||||
"integrity": "sha512-PxcgvjdSjtgPMiPQrM3pwSaG4kGphP+bLSb+cihuP0LYdZv1epbAIecHVl5sD3npkfYBZ0ZnOjR878I7MdJDFg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.10.tgz",
|
||||
"integrity": "sha512-ZkIOtrRL8SEJjr+VHjmW0znkPs+oJXhlJbNwfI37rvgeMtk3sxOQevXPXjmAPZPigVTncvFqLMd+uV0IBSEzqA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.10.tgz",
|
||||
"integrity": "sha512-+Sa4oTDbpBfGpl3Hn3XiUe4f8TU2JF7aX8cOfqFYMMjXp6ma6NJDztl5FDG8Ezx0OjwGikIHw+iA54YLDNNVfw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.10.tgz",
|
||||
"integrity": "sha512-EOGVLK1oWMBXgfttJdPHDTiivYSjX6jDNaATeNOaCOFEVcfMjtbx7WVQwPSE1eIfCp/CaSF2nSrDtzc4I9f8TQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.10.tgz",
|
||||
"integrity": "sha512-whqLG6Sc70AbU73fFYvuYzaE4MNMBIlR1Y/IrUeOXFrWHxBEjjbZaQ3IXIQS8wJdAzue2GwYZCjOrgrU1oUHoA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.10.tgz",
|
||||
"integrity": "sha512-S1Y27QGt/snkNYrRcswgRFqZjaTG5a5xM3EQo97uNBnH505pdzSNe/HLBq1v0RO7iK/ngdbhJB6mDAp0OK+iUA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/aix-ppc64": "0.19.10",
|
||||
"@esbuild/android-arm": "0.19.10",
|
||||
"@esbuild/android-arm64": "0.19.10",
|
||||
"@esbuild/android-x64": "0.19.10",
|
||||
"@esbuild/darwin-arm64": "0.19.10",
|
||||
"@esbuild/darwin-x64": "0.19.10",
|
||||
"@esbuild/freebsd-arm64": "0.19.10",
|
||||
"@esbuild/freebsd-x64": "0.19.10",
|
||||
"@esbuild/linux-arm": "0.19.10",
|
||||
"@esbuild/linux-arm64": "0.19.10",
|
||||
"@esbuild/linux-ia32": "0.19.10",
|
||||
"@esbuild/linux-loong64": "0.19.10",
|
||||
"@esbuild/linux-mips64el": "0.19.10",
|
||||
"@esbuild/linux-ppc64": "0.19.10",
|
||||
"@esbuild/linux-riscv64": "0.19.10",
|
||||
"@esbuild/linux-s390x": "0.19.10",
|
||||
"@esbuild/linux-x64": "0.19.10",
|
||||
"@esbuild/netbsd-x64": "0.19.10",
|
||||
"@esbuild/openbsd-x64": "0.19.10",
|
||||
"@esbuild/sunos-x64": "0.19.10",
|
||||
"@esbuild/win32-arm64": "0.19.10",
|
||||
"@esbuild/win32-ia32": "0.19.10",
|
||||
"@esbuild/win32-x64": "0.19.10"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"name": "libresilient",
|
||||
"version": "1.0.0",
|
||||
"description": "A browser-based decentralized content delivery network, implemented as a JavaScript library to be deployed easily on any website. LibResilient uses [ServiceWorkers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers) and a suite of unconventional in-browser delivery mechanisms, with a strong focus on decentralized tools like [IPFS](https://ipfs.io/).",
|
||||
"main": "libresilient.js",
|
||||
"directories": {
|
||||
"doc": "docs",
|
||||
"lib": "lib"
|
||||
},
|
||||
"scripts": {
|
||||
"prebuild": "rm -rf dist && mkdir -p dist/plugins/alt-fetch",
|
||||
"build": "cp -r plugins/alt-fetch/lib dist/plugins/alt-fetch/lib && esbuild plugins/alt-fetch/index.js --bundle --outfile=dist/plugins/alt-fetch/index.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://gitlab.com/Zamaneh-Media/libresilient.git"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://gitlab.com/Zamaneh-Media/libresilient/issues"
|
||||
},
|
||||
"homepage": "https://gitlab.com/Zamaneh-Media/libresilient#readme",
|
||||
"devDependencies": {
|
||||
"esbuild": "0.19.10"
|
||||
}
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
import { fetchContentFromAlternativeEndpoints } from "./lib/fetchContentFromAlternativeEndpoints";
|
||||
|
||||
/* ========================================================================= *\
|
||||
|* === HTTP(S) fetch() from alternative endpoints === *|
|
||||
\* ========================================================================= */
|
||||
|
@ -10,16 +12,12 @@
|
|||
* the polyfill is implemented in LibResilient's service-worker.js
|
||||
*/
|
||||
|
||||
// no polluting of the global namespace please
|
||||
(function(LRPC){
|
||||
// this never changes
|
||||
const pluginName = "alt-fetch"
|
||||
LRPC.set(pluginName, (LR, init={})=>{
|
||||
export const PLUGIN_NAME = 'alt-fetch';
|
||||
|
||||
/*
|
||||
* plugin config settings
|
||||
*/
|
||||
const LRPC = self.libResilientPluginConstructors;
|
||||
|
||||
let config = {};
|
||||
LRPC.set(PLUGIN_NAME, (LR, init={})=> {
|
||||
// sane defaults
|
||||
let defaultConfig = {
|
||||
// endpoints to use
|
||||
|
@ -46,116 +44,20 @@
|
|||
//
|
||||
// 3 seems to be a reasonable default
|
||||
concurrency: 3
|
||||
}
|
||||
|
||||
// merge the defaults with settings from the init var
|
||||
let config = {...defaultConfig, ...init}
|
||||
|
||||
// reality check: endpoints need to be set to an array of non-empty strings
|
||||
if (typeof(config.endpoints) !== "object" || !Array.isArray(config.endpoints)) {
|
||||
let err = new Error("endpoints not confgured")
|
||||
console.error(err)
|
||||
throw err
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* getting content using regular HTTP(S) fetch()
|
||||
*/
|
||||
let fetchContentFromAlternativeEndpoints = (url, init={}) => {
|
||||
|
||||
// remove the https://original.domain/ bit to get the relative path
|
||||
// TODO: this assumes that URLs we handle are always relative to the root
|
||||
// TODO: of the original domain, this needs to be documented
|
||||
var path = url.replace(/https?:\/\/[^/]+\//, '')
|
||||
|
||||
// we really want to make fetch happen, Regina!
|
||||
// TODO: this change should *probably* be handled on the Service Worker level
|
||||
init.cache = 'reload'
|
||||
|
||||
// we don't want to modify the original endpoints array
|
||||
var sourceEndpoints = [...config.endpoints]
|
||||
|
||||
// if we have fewer than the configured concurrency or just as many, use all of them
|
||||
if (sourceEndpoints.length <= config.concurrency) {
|
||||
var useEndpoints = sourceEndpoints
|
||||
|
||||
// otherwise get `config.concurrency` endpoints at random
|
||||
} else {
|
||||
var useEndpoints = new Array()
|
||||
while (useEndpoints.length < config.concurrency) {
|
||||
useEndpoints.push(
|
||||
sourceEndpoints
|
||||
.splice(Math.floor(Math.random() * sourceEndpoints.length), 1)[0]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// add the rest of the path to each endpoint
|
||||
useEndpoints.forEach((endpoint, index) => {
|
||||
useEndpoints[index] = endpoint + path;
|
||||
});
|
||||
|
||||
// debug log
|
||||
LR.log(pluginName, `fetching from alternative endpoints:\n ${useEndpoints.join('\n ')}`)
|
||||
|
||||
return Promise.any(
|
||||
useEndpoints.map(
|
||||
u=>fetch(u, init)
|
||||
))
|
||||
.then((response) => {
|
||||
// 4xx? 5xx? that's a paddlin'
|
||||
if (response.status >= 400) {
|
||||
// throw an Error to fall back to other plugins:
|
||||
throw new Error('HTTP Error: ' + response.status + ' ' + response.statusText);
|
||||
}
|
||||
// all good, it seems
|
||||
LR.log(pluginName, "fetched:", response.url);
|
||||
|
||||
// we need to create a new Response object
|
||||
// with all the headers added explicitly,
|
||||
// since response.headers is immutable
|
||||
var responseInit = {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
headers: {},
|
||||
url: url
|
||||
};
|
||||
response.headers.forEach(function(val, header){
|
||||
responseInit.headers[header] = val;
|
||||
});
|
||||
|
||||
// add the X-LibResilient-* headers to the mix
|
||||
responseInit.headers['X-LibResilient-Method'] = pluginName
|
||||
|
||||
// we will not have it most of the time, due to CORS rules:
|
||||
// https://developer.mozilla.org/en-US/docs/Glossary/CORS-safelisted_response_header
|
||||
responseInit.headers['X-LibResilient-ETag'] = response.headers.get('ETag')
|
||||
if (responseInit.headers['X-LibResilient-ETag'] === null) {
|
||||
// far from perfect, but what are we going to do, eh?
|
||||
responseInit.headers['X-LibResilient-ETag'] = response.headers.get('last-modified')
|
||||
config = { ...defaultConfig, ...init };
|
||||
// reality check: endpoints need to be set to an array of non-empty strings
|
||||
if (typeof (config.endpoints) !== 'object' || !Array.isArray(config.endpoints)) {
|
||||
let err = new Error('endpoints not confgured');
|
||||
console.error(err);
|
||||
throw err;
|
||||
}
|
||||
|
||||
// return the new response, using the Blob from the original one
|
||||
return response
|
||||
.blob()
|
||||
.then((blob) => {
|
||||
return new Response(
|
||||
blob,
|
||||
responseInit
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// return the plugin data structure
|
||||
return {
|
||||
name: pluginName,
|
||||
name: PLUGIN_NAME,
|
||||
description: 'HTTP(S) fetch() using preconfigured alternative endpoints',
|
||||
version: 'COMMIT_UNKNOWN',
|
||||
fetch: fetchContentFromAlternativeEndpoints
|
||||
}
|
||||
|
||||
})
|
||||
// done with not polluting the global namespace
|
||||
})(LibResilientPluginConstructors)
|
||||
fetch: (url, init) => fetchContentFromAlternativeEndpoints(url, init, config)
|
||||
};
|
||||
});
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
import { PLUGIN_NAME } from "../index";
|
||||
|
||||
export function fetchContentFromAlternativeEndpoints (url, init = {}, config) {
|
||||
// remove the https://original.domain/ bit to get the relative path
|
||||
// TODO: this assumes that URLs we handle are always relative to the root
|
||||
// TODO: of the original domain, this needs to be documented
|
||||
var path = url.replace(/https?:\/\/[^/]+\//, '');
|
||||
|
||||
// we really want to make fetch happen, Regina!
|
||||
// TODO: this change should *probably* be handled on the Service Worker level
|
||||
// init.cache = 'reload';
|
||||
|
||||
// we don't want to modify the original endpoints array
|
||||
var sourceEndpoints = [...config.endpoints];
|
||||
|
||||
let useEndpoints = [];
|
||||
// if we have fewer than the configured concurrency or just as many, use all of them
|
||||
if (sourceEndpoints.length <= config.concurrency) {
|
||||
useEndpoints = sourceEndpoints;
|
||||
|
||||
// otherwise get `config.concurrency` endpoints at random
|
||||
} else {
|
||||
while (useEndpoints.length < config.concurrency) {
|
||||
useEndpoints.push(
|
||||
sourceEndpoints
|
||||
.splice(Math.floor(Math.random() * sourceEndpoints.length), 1)[0]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// add the rest of the path to each endpoint
|
||||
useEndpoints.forEach((endpoint, index) => {
|
||||
useEndpoints[index] = endpoint + path;
|
||||
});
|
||||
|
||||
// debug log
|
||||
console.log(PLUGIN_NAME, `fetching from alternative endpoints:\n ${useEndpoints.join('\n ')}`);
|
||||
|
||||
return Promise.any(
|
||||
useEndpoints.map(
|
||||
u=>fetch(u, init)
|
||||
))
|
||||
.then((response) => {
|
||||
// 4xx? 5xx? that's a paddlin'
|
||||
if (response.status >= 400) {
|
||||
// throw an Error to fall back to other plugins:
|
||||
throw new Error('HTTP Error: ' + response.status + ' ' + response.statusText);
|
||||
}
|
||||
// all good, it seems
|
||||
console.log(PLUGIN_NAME, 'fetched:', response.url);
|
||||
|
||||
// we need to create a new Response object
|
||||
// with all the headers added explicitly,
|
||||
// since response.headers is immutable
|
||||
var responseInit = {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
headers: {},
|
||||
url: url
|
||||
};
|
||||
response.headers.forEach(function (val, header){
|
||||
responseInit.headers[header] = val;
|
||||
});
|
||||
|
||||
// add the X-LibResilient-* headers to the mix
|
||||
responseInit.headers['X-LibResilient-Method'] = PLUGIN_NAME;
|
||||
|
||||
// we will not have it most of the time, due to CORS rules:
|
||||
// https://developer.mozilla.org/en-US/docs/Glossary/CORS-safelisted_response_header
|
||||
responseInit.headers['X-LibResilient-ETag'] = response.headers.get('ETag');
|
||||
if (responseInit.headers['X-LibResilient-ETag'] === null) {
|
||||
// far from perfect, but what are we going to do, eh?
|
||||
responseInit.headers['X-LibResilient-ETag'] = response.headers.get('last-modified');
|
||||
}
|
||||
|
||||
// return the new response, using the Blob from the original one
|
||||
return response
|
||||
.blob()
|
||||
.then((blob) => {
|
||||
return new Response(
|
||||
blob,
|
||||
responseInit
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
Ładowanie…
Reference in New Issue