add plugin API recipe

This commit is contained in:
Yanzhen Yu
2021-07-05 22:52:52 +08:00
parent 65a45202d7
commit dbbb20f5e5
4 changed files with 215 additions and 5 deletions

99
docs/recipes/plugin.md Normal file
View File

@@ -0,0 +1,99 @@
# Plugin
The plugin API is designed to extend the function of rrweb without bump the size and complexity of rrweb's core part.
## Interface
Same to with other functionality in rrweb, a plugin can implement record or replay or both features.
```ts
export type RecordPlugin<TOptions = unknown> = {
name: string;
observer: (cb: Function, options: TOptions) => listenerHandler;
options: TOptions;
};
export type ReplayPlugin = {
handler: (
event: eventWithTime,
isSync: boolean,
context: { replayer: Replayer },
) => void;
};
```
Both record and replay plugins have a type interface.
### example
#### record plugin
```ts
const exampleRecordPlugin: RecordPlugin<{ foo: string }> = {
name: 'my-scope/example@1',
observer(cb, options) {
const timer = setInterval(() => {
cb({
foo: options.foo,
timestamp: Date.now(),
});
}, 1000);
return () => clearInterval(timer);
},
options: {
foo: 'bar',
},
};
rrweb.record({
emit: emit(event) {},
plugins: [exampleRecordPlugin],
});
```
In this example, the record plugin will emit events like this:
```js
{
type: 6,
data: {
plugin: 'my-scope/example@1',
payload: {
foo: 'bar',
timestamp: 1624693882345,
},
},
timestamp: 1624693882345,
}
```
#### replay plugin
```ts
const exampleReplayPlugin: ReplayPlugin = {
handler(event, isSync, context) {
if (event.type === EventType.Plugin) {
// do something with event.data.payload
if (event.data.plugin === 'my-scope/example@1') {
// handle example plugin data
}
}
},
};
const replayer = new rrweb.Replayer(events, {
plugins: [exampleReplayPlugin],
});
```
A replay plugin can interact with the replayer by using `context.replayer`.
## naming a plugin
A record plugin should have a unique name, and it will be stored in the event it emits.
**Since we will have both plugins in the rrweb repo and plugins in users' own codebase, which may cause naming conflicts in the future, we strongly recommended users naming their own plugins in this way:**
> scope/name@version
For example `rrweb/console@1` or `github/pr@2`.