Updated docs/ARCHITECTURE.md to reflect the current code

merge-requests/4/merge
Michał "rysiek" Woźniak 2021-11-02 00:27:43 +00:00
rodzic 736675fa06
commit 4798ba0a42
2 zmienionych plików z 49 dodań i 28 usunięć

Wyświetl plik

@ -13,7 +13,7 @@ self.LibResilientConfig.plugins = [{
name: 'cache'
},{
name: 'any-of',
plugins: [{
uses: [{
name: 'alt-fetch',
// configuring the alternate endpoints plugin to use IPNS gateways
//

Wyświetl plik

@ -7,7 +7,7 @@ Eventually this will document the architecture of LibResilient.
There are three kinds of plugins:
- **Transport plugins**
Plugins that *retrieve* website content, e.g. by using regular HTTPS [`fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API), or by going through [IPFS](https://js.ipfs.io/). They *should* also offer a way to *publish* content by website admins (if relevant credentials or encryption keys are provided, depending on the method).
Plugins that *retrieve* website content, for example by using regular HTTPS [`fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API), or by going through [IPFS](https://js.ipfs.io/). They *should* also offer a way to *publish* content by website admins (if relevant credentials or encryption keys are provided, depending on the method).
Methods these plugins implement:
- `fetch` - fetch content from an external source (e.g., from IPFS)
- `publish` - publish the content to the external source (e.g., to IPFS)
@ -23,25 +23,19 @@ Methods these plugins implement:
Plugins that *compose* other plugins, for example by running them simultaneously to retrieve content from whichever succeeds first.
Methods these plugins implement depend on which plugins they compose. Additionally, plugins being composed the `uses` key, providing the configuration for them the same way configuration is provided for plugins in the `plugins` key of `LibResilientConfig`.
Any plugin needs to add itself to the LibResilientPlugins global variable, using a data structure as follows:
Every plugin needs to be implemented as a constructor function that is added to the `LibResilientPluginConstructors` [Map()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) object for later instantiation.
The constructor function should return a structure as follows (fields depending on the plugin type):
```javascript
self.LibResilientPlugins.push({
{
name: 'plugin-name',
description: 'Plugin description. Just a few words, ideally.',
version: 'any relevant plugin version information',
fetch: functionImplementingFetch,
publish|stash|unstash: functionsImplementingRelevantFunctionality,
uses: {
composed-plugin-1: {
configKey1: "whatever-data-here"
},
composed-plugin-2: {
configKey2: "whatever-data-here"
},
{...}
}
})
uses: []
}
```
### Transport plugins
@ -60,29 +54,56 @@ Stashing plugins *must* stash the request along with the `X-LibResilient-Method`
### Composing plugins
Composing plugins work by composing other plugins, for example to run them simultaneously and retrieve content from the first one that succeeds. A composing plugin needs to set the `uses` key in it's `LibResilientPlugins`. The key should contain mappings from plugin names to configuration:
Composing plugins work by composing other plugins, for example to: run them simultaneously and retrieve content from the first one that succeeds; or to run them in a particular order. A composing plugin needs to set the `uses` key in the object returned by it's constructor. The key should contain mappings from plugin names to configuration:
```javascript
uses: {
composed-plugin-1: {
configKey1: "whatever-data-here"
},
composed-plugin-2: {
configKey2: "whatever-data-here"
},
{...}
}
uses: [{
name: "composed-plugin-1",
configKey1: "whatever-data-here"
},{
name: "composed-plugin-2",
configKey2: "whatever-data-here"
},
{...}
}]
```
If these mappings are to be configured via the global configuration file, the `uses` key should instead point to `config.uses`:
```javascript
uses: config.uses
```
## Fetching a resource via LibResilient
Whenever a resource is being fetched on a LibResilient-enabled site, the `service-worker.js` script dispatches plugins in the set order. Currently this order is hard-coded in `service-worker.js`, and is:
Whenever a resource is being fetched on a LibResilient-enabled site, the `service-worker.js` script dispatches plugins in the set order. This order is configured via the `plugins` key of the `LibResilientConfig` variable, usually set in `config.js` config file.
A minimal default configuration is hard-coded in case no site-specific configuration is provided. This default configuration runs these plugins:
1. `fetch`, to use the upstream site directly if it is available,
1. `cache`, to display the site immediately from the cache in case regular `fetch` fails,
1. `gun-ipfs`, in the background if `cache` call succeeded, otherwise as the active fetch handler.
1. `cache`, to display the site immediately from the cache in case regular `fetch` fails (if content is already cached from previous visit).
If a background plugin `fetch()` succeeds, the result is added to the cache and will be immediately available on page reload.
A more robust configuration could look like this:
```javascript
self.LibResilientConfig.plugins = [{
name: 'fetch'
},{
name: 'cache'
},{
name: 'alt-fetch',
endpoints: [
'https://fallback-endpoint.example.com'
]}
}]
```
For each resource, such a config would:
1. Perform a regular `fetch()` to the main site domain first; if that succeeds, content is added to cache and displayed to the user.
1. If the `fetch()` failed, the cache would be checked.
1. If the resource was cached, it would be displayed; at the same time, a background request for that resource would be made to `fallback-endpoint.example.com` instead of the (failing) main domain; if that succeeded, the new version of the resource would be cached.
1. If the resource was not cached, a request for that resource would be made to `fallback-endpoint.example.com`; if that succeded, the resource would be displayed and cached.
## Stashed versions invalidation