diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 6d5079309131d7e5cd22acd9cc5be28073d88770..f74c19bf7b2d2e39ed67b1e699ba05e552ab9689 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -4,7 +4,7 @@ Eventually this will document the architecture of Samizdat. ## Plugins -There are two kinds of plugins: +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). @@ -12,13 +12,17 @@ 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) -* **Stashing plugins** +- **Stashing plugins** Plugins that *stash* content locally (e.g., in the [browser cache](https://developer.mozilla.org/en-US/docs/Web/API/Cache)) for displaying when no *transport plugin* works, or before content is received via one of them. Methods these plugins implement: - `fetch` - fetch the locally stored content (e.g., from cache) - `stash` - stash the content locally (e.g., in cache) - `unstash` - clear the content from the local store (e.g., clear the cache) +- **Composing plugins** + 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 `SamizdatConfig`. + Any plugin needs to add itself to the SamizdatPlugins global variable, using a data structure as follows: ```javascript @@ -27,7 +31,16 @@ self.SamizdatPlugins.push({ description: 'Plugin description. Just a few words, ideally.', version: 'any relevant plugin version information', fetch: functionImplementingFetch, - publish|stash|unstash: functionsImplementingRelevantFunctionality + publish|stash|unstash: functionsImplementingRelevantFunctionality, + uses: { + composed-plugin-1: { + configKey1: "whatever-data-here" + }, + composed-plugin-2: { + configKey2: "whatever-data-here" + }, + {...} + } }) ``` @@ -45,6 +58,22 @@ Transport plugins *must* add `X-Samizdat-Method` and `X-Samizdat-ETag` headers t Stashing plugins *must* stash the request along with the `X-Samizdat-Method` and `X-Samizdat-ETag` headers. +### 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 `SamizdatPlugins`. 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" + }, + {...} +} +``` + ## Fetching a resource via Samizdat Whenever a resource is being fetched on a Samizdat-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: