Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plugin API #598

Merged
merged 6 commits into from
Jun 27, 2021
Merged

plugin API #598

merged 6 commits into from
Jun 27, 2021

Conversation

Yuyz0112
Copy link
Member

@Yuyz0112 Yuyz0112 commented Jun 26, 2021

There are some long-term feature-requested in our issue list, including:

  • console record/replay
  • network record/replay
  • record more user interactions that do not have an impact on the view but useful for analytic scenarios.

And we also get some feedback from users who want rrweb to keep the minimal implementation of record and replay the web, which is stable and performant.

The plugin API is the solution to these questions.

Interface

Same to with other functionality in rrweb, a plugin can implement record or replay or both features.

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

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'
  }
}

In this example, the record plugin will emit events like this:

{
  type: 6,
  data: {
    plugin: 'my-scope/example@1',
    payload: {
      foo: 'bar',
      timestamp: 1624693882345,
    },
  },
  timestamp: 1624693882345,
}

replay plugin

const exampleReplayPlugin: ReplayPlugin = {
  handler(event, isSync, context) {
    if (event.type === EventType.Plugin) {
      // do something with event.data.payload
    }
  }
}

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.

bundling

The plugins will be bundled into the all-in-one entry and also have a standalone version for iife, CommonJS, and ESmodule.

breaking changes

In this PR, we migrated the log recording feature into the new plugin API, which introduces some breaking changes.

The record option recordLog has been removed, the new API is:

rrweb.record({
  emit(e) {
    events.push(e);
  },
- recordLog: true,
+ plugins: [rrwebConsoleRecord.getRecordConsolePlugin()],
});

The replay option logConfig has been removed, the new API is:

new rrweb.Replayer(events, {
- logConfig: {}
+ plugins: [replayConsole.getReplayConsolePlugin()],
});

And data recorded by the legacy log recording feature will replay correctly with any extra work.

Copy link
Member

@YunFeng0817 YunFeng0817 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The plugin mechanism looks great to me!
And I did a little change to the replay code.

@YunFeng0817 YunFeng0817 marked this pull request as ready for review June 27, 2021 11:23
@Yuyz0112 Yuyz0112 changed the title temp: plugin API plugin API Jun 27, 2021
@Yuyz0112
Copy link
Member Author

@Mark-Fenng I've updated several commits and add the description in this PR.

@Yuyz0112 Yuyz0112 merged commit 5fc6c19 into master Jun 27, 2021
@Yuyz0112 Yuyz0112 deleted the plugin-api branch June 27, 2021 16:09
@eoghanmurray eoghanmurray mentioned this pull request Jul 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants