Skip to content

Commit ab6e21d

Browse files
authored
feat(docs): add documentation (#53)
* docs(ui): update documentation * feat(docs): add documentation * Create big-badgers-invite.md
1 parent db21a06 commit ab6e21d

File tree

17 files changed

+2946
-137
lines changed

17 files changed

+2946
-137
lines changed

.changeset/big-badgers-invite.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@composite-fetcher/docs": patch
3+
"@composite-fetcher/core": patch
4+
"@composite-fetcher/with-caching": patch
5+
"@composite-fetcher/with-logging": patch
6+
---
7+
8+
feat(docs): add documentation

apps/docs/next.config.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1-
module.exports = {
2-
reactStrictMode: true,
3-
};
1+
/* eslint-disable @typescript-eslint/no-var-requires */
2+
/* eslint-disable import/no-extraneous-dependencies */
3+
const withNextra = require('nextra')({
4+
theme: 'nextra-theme-docs',
5+
themeConfig: './theme.config.jsx',
6+
});
7+
8+
module.exports = withNextra();

apps/docs/package.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,10 @@
1111
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next"
1212
},
1313
"dependencies": {
14-
"@composite-fetcher/core": "workspace:^",
1514
"@composite-fetcher/utils": "workspace:*",
16-
"@composite-fetcher/with-caching": "workspace:^",
17-
"@composite-fetcher/with-logging": "workspace:^",
18-
"next": "^13.4.1",
15+
"next": "^13.4.19",
16+
"nextra": "^2.13.1",
17+
"nextra-theme-docs": "^2.13.1",
1918
"react": "^18.2.0",
2019
"react-dom": "^18.2.0"
2120
},

apps/docs/src/app/layout.tsx

Lines changed: 0 additions & 11 deletions
This file was deleted.

apps/docs/src/app/page.tsx

Lines changed: 0 additions & 19 deletions
This file was deleted.

apps/docs/src/lib/fetcher.ts

Lines changed: 0 additions & 12 deletions
This file was deleted.

apps/docs/src/pages/_meta.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"index": "Quick Start",
3+
"plugins": "Plugins",
4+
"github_link": {
5+
"title": "⭐ us on GitHub <3",
6+
"href": "https://github.com/teofanis/composite-fetcher",
7+
"newWindow": true
8+
}
9+
}

apps/docs/src/pages/index.mdx

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
import { Callout } from 'nextra/components'
2+
3+
<Callout type="info" emoji="ℹ️">
4+
Thank you for taking the time to read this documentation. For any questions or requests, please open an issue on the repository [here](https://github.com/teofanis/composite-fetcher/issues/new/choose).
5+
</Callout>
6+
7+
# Composite-Fetcher Documentation
8+
9+
Welcome to the official documentation for Composite-Fetcher!
10+
11+
## What is Composite-Fetcher?
12+
13+
Composite-Fetcher is a dynamic and modular fetcher designed to simplify and streamline the process of making network requests. Instead of writing repetitive and error-prone fetch requests, Composite-Fetcher provides a structured and extensible platform, allowing developers to effortlessly manage, extend, and deduplicate their requests.
14+
15+
## Why does Composite-Fetcher exist?
16+
17+
During my journey as a developer, while working on various projects, I often encountered the need to wrap around requests for deduplication, error handling, and other concerns. This repetitive task sparked the idea for a tool that could handle these for me. In my current role, I had the opportunity to design a fetcher based on similar concepts. The results were impressive, and it significantly streamlined our development process. Recognizing its potential, I decided to modularize the concept and thus, Composite-Fetcher was born. My hope is that this repository can serve as a robust tool for developers everywhere, offering the flexibility to extend and adapt it according to their needs.
18+
19+
## Composite-Fetcher Basics
20+
21+
Composite-Fetcher is essentially a wrapper around the native fetch API. It retains the familiar fetch API structure, but enriches it with added functionalities, mainly via plugins.
22+
23+
### Basic Usage
24+
To kick things off, let's take a look at a straightforward use-case:
25+
26+
```js copy
27+
import { Fetcher } from '@composite-fetcher/core';
28+
29+
const fetcher = new Fetcher();
30+
fetcher.fetch('https://example.com/api/...')
31+
.then(response => { /* handle response */ })
32+
.catch(error => { /* handle error */ });
33+
34+
```
35+
36+
Here, you're simply using the fetcher instance as you would with the native fetch function.
37+
38+
### Enhancing with Plugins
39+
40+
One of the main attractions of Composite-Fetcher is the ability to apply plugins, which are essentially middlewares providing additional functionalities.
41+
42+
Plugin Usage
43+
Let's enhance our basic fetcher with some plugins:
44+
45+
```js copy
46+
import { Fetcher } from '@composite-fetcher/core';
47+
import { withCaching, SessionStorageDriver } from '@composite-fetcher/with-caching';
48+
import { withLogging } from '@composite-fetcher/with-logging';
49+
50+
const fetcher = new Fetcher();
51+
fetcher.use([
52+
new withLogging(),
53+
new withCaching({
54+
cacheDriver: new SessionStorageDriver()
55+
})
56+
]);
57+
58+
fetcher.fetch('https://example.com/api/...')
59+
.then(response => { /* handle response */ })
60+
.catch(error => { /* handle error */ });
61+
62+
```
63+
64+
In the above example, we've applied both logging and caching plugins. It's important to remember that the sequence of the plugins matters. They will execute in the order they're added.
65+
66+
### How Do Plugins Work?
67+
68+
Each plugin might consist of hooks that are triggered at different stages of the request lifecycle. The primary stages are:
69+
70+
1. Pre-Request: Before the actual request is made.
71+
2. Actual Request: Where the fetch action occurs.
72+
3. Post-Request: After receiving the response.
73+
74+
A plugin can provide:
75+
76+
- onPreRequestHook: Triggered during the pre-request phase.
77+
- onPostRequestHook: Triggered during the post-request phase.
78+
- Or both.
79+
80+
### Lifecycle Example
81+
Consider the earlier code where we added the logging and caching plugins. Here's the execution sequence:
82+
83+
1. Logging pre-request hook
84+
2. Caching pre-request hook
85+
3. Actual request
86+
4. Logging post-request hook
87+
5. Caching post-request hook
88+
89+
### Plugin Hook Context
90+
91+
Hooks have access to a certain context:
92+
93+
#### Pre-Request Hook
94+
95+
- request: Current state of the Request object.
96+
- originalRequest: Initial unmodified Request.
97+
- pluginManager: Manager handling the plugins.
98+
99+
#### Post-Request Hook
100+
101+
- response: Response object.
102+
- originalRequest: Initial unmodified Request.
103+
- pluginManager: Manager handling the plugins.
104+
105+
It's important to note that plugins can directly modify the request or response object without returning it. The changes will still be reflected. Owing to the internal lifecycle management by the pluginManager, hooks are expected to either return void (no value) or a Response object if they intend to exit the lifecycle early.
106+
107+
108+
With these fundamentals, you're now equipped to make the most of Composite-Fetcher. Delve into the sections ahead to understand more about individual plugins and their options.
109+
110+
## Extending Composite-Fetcher / Creating Plugins
111+
112+
The Plugin Structure
113+
At the heart of creating a custom plugin lies the foundational structure you'll be working with. Here's the recommended way to define a plugin:
114+
115+
Create a class that either extends the BasePlugin abstract class:
116+
117+
```js copy copy
118+
import { BasePlugin, PluginHandlerContext, PluginLifecycleHook } from '@composite-fetcher/core';
119+
120+
export default class CustomPlugin extends BasePlugin {
121+
async onPreRequest(
122+
context: PluginHandlerContext<PluginLifecycleHook.PRE_REQUEST>,
123+
): Promise<void | Response> {
124+
// Your pre-request logic here
125+
}
126+
127+
async onPostRequest(
128+
context: PluginHandlerContext<PluginLifecycleHook.POST_REQUEST>,
129+
): Promise<void | Response> {
130+
// Your post-request logic here
131+
}
132+
}
133+
134+
```
135+
136+
### Writing Your Logic
137+
138+
Now that the foundational structure is set up, let's add logic to our custom plugin. Consider an example where you want to add a custom header to each request:
139+
```js copy
140+
export default class CustomHeaderPlugin extends BasePlugin {
141+
async onPreRequest(
142+
context: PluginHandlerContext<PluginLifecycleHook.PRE_REQUEST>,
143+
): Promise<void | Response> {
144+
context.request.headers.append('X-Custom-Header', 'CustomValue');
145+
}
146+
}
147+
```
148+
In this example, the CustomHeaderPlugin appends a custom header before each request is made. The context.request provides access to the current state of the request, allowing you to modify it as needed.
149+
150+
### Using Your Custom Plugin
151+
Once your custom plugin is ready, integrating it with the Fetcher is a breeze:
152+
153+
```js copy
154+
import { Fetcher } from '@composite-fetcher/core';
155+
import CustomHeaderPlugin from './path-to-your-custom-plugin';
156+
157+
const fetcher = new Fetcher();
158+
fetcher.use([new CustomHeaderPlugin()]);
159+
160+
fetcher.fetch('https://example.com/api/...')
161+
.then(response => { /* handle response */ })
162+
.catch(error => { /* handle error */ });
163+
164+
```
165+
{/*
166+
## Explore More
167+
168+
Ready to dive deeper? Explore the submenus to learn about the plugins, their functionalities, options, and how to make the most out of Composite-Fetcher:
169+
170+
- [Plugin Documentation](./plugins)
171+
- [Configuration Options](./configuration)
172+
- ... [Add links to other sub-sections] */}
173+
174+
Thank you for using Composite-Fetcher !
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"with-caching": "withCaching",
3+
"with-logging": "withLogging"
4+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# WithCaching Plugin
2+
The `withCaching` plugin is designed to enhance the efficiency of your fetch operations by leveraging caching mechanisms. By caching responses, it significantly reduces the number of redundant requests, making your applications faster and more responsive.
3+
4+
## How it Works
5+
The withCaching plugin checks the cache before dispatching a request.
6+
If a cached response for the request exists and hasn't expired, it returns the cached response, skipping the network request.
7+
Otherwise, it will cache the response after the call.
8+
9+
## Lifecycle:
10+
- onPreRequest: Before a request is dispatched, it checks the cache for a corresponding response.
11+
- onPostRequest: After receiving a response, it caches the response for future use.
12+
13+
## Plugin Options
14+
15+
The `withCaching` plugin offers several options to customize its behavior:
16+
17+
- `cacheDriver`: Specifies the caching mechanism to use. E.g., SessionStorageDriver, or a custom driver - InMemoryDriver is used by default.
18+
- `defaultTTL`: Determines how long a response should be stored in cache (time in milliseconds). Default is 10 minutes.
19+
20+
You can use the following custom headers for more granual control per request.
21+
- `x-fetcher-no-cache`: Specifies whether to use the cache or not. If present cache will be skipped.
22+
- `x-fetcher-cache-ttl`: Specifies the TTL for the cached response (time in milliseconds).
23+
24+
## Usage:
25+
26+
```js copy
27+
import { Fetcher } from '@composite-fetcher/core';
28+
import { withCaching, SessionStorageDriver } from '@composite-fetcher/with-caching';
29+
30+
const fetcher = new Fetcher();
31+
32+
const cachingPlugin = new withCaching({
33+
cacheDriver: new SessionStorageDriver(),
34+
cacheExpiration: 600000, // cache for 10 minutes
35+
});
36+
fetcher.use([cachingPlugin]);
37+
38+
fetcher.fetch('https://example.com/api/...')
39+
.then(response => { /* handle response */ })
40+
.catch(error => { /* handle error */ });
41+
```
42+
43+
## Custom Cache Driver
44+
45+
You can create your own cache driver by implementing the [`CacheDriver`](https://github.com/teofanis/composite-fetcher/blob/db21a060522b21c693f3d2c0fa0ea2453f0e052d/packages/with-caching/src/interfaces/index.ts#L1) interface.

0 commit comments

Comments
 (0)