fix(tracker): fix mobx plugin for prod builds (#1269)
* fix(tracker): fix mobx plugin for prod builds * fix(tracker): fix mobx tracking
This commit is contained in:
parent
e6e138b967
commit
ce4d625c36
4 changed files with 73 additions and 97 deletions
|
|
@ -13,75 +13,31 @@ Then put the generated middleware into your Redux chain.
|
|||
```js
|
||||
import Tracker from '@openreplay/tracker';
|
||||
import trackerMobX from '@openreplay/tracker-mobx';
|
||||
import { observe } from 'mobx';
|
||||
|
||||
const tracker = new Tracker({
|
||||
projectKey: YOUR_PROJECT_KEY,
|
||||
});
|
||||
|
||||
tracker.plugin(trackerMobX());
|
||||
const mobxTrackerInstance = tracker.use(trackerMobX(options)); // look below for available options
|
||||
observe(yourMobxStore, mobxTrackerInstance)
|
||||
```
|
||||
|
||||
This plugin is inspired by [mobx-logger](https://github.com/winterbe/mobx-logger), hence it has similar configurations.
|
||||
|
||||
The default configurations are following
|
||||
Options:
|
||||
|
||||
```js
|
||||
interface Options {
|
||||
predicate?: (ev: { type: string; name: string; object: any; debugObjectName: string }) => boolean;
|
||||
sanitize?: (ev: { state: any; type: string; property: string }) => { state: any; type: string; property: string };
|
||||
update?: boolean;
|
||||
add?: boolean;
|
||||
delete?: boolean;
|
||||
}
|
||||
|
||||
trackerMobX({
|
||||
predicate: () => true,
|
||||
action: true,
|
||||
reaction: true,
|
||||
transaction: true,
|
||||
compute: true
|
||||
sanitize: (event) => event
|
||||
})
|
||||
```
|
||||
|
||||
You can disable logging for actions and computed properties by providing a static `trackerMobXConfig`. This is useful to protect the private user data and keep your logs clean.
|
||||
|
||||
Here's an example of how to disable logging for all actions and computed properties for a given class:
|
||||
|
||||
```js
|
||||
class MyModel {
|
||||
static trackerMobXConfig: {
|
||||
enabled: false
|
||||
};
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively you can disable logging for particular class methods:
|
||||
|
||||
```js
|
||||
class MyStore {
|
||||
static trackerMobXConfig: {
|
||||
methods: {
|
||||
myAction: false
|
||||
}
|
||||
};
|
||||
|
||||
@action myAction() {
|
||||
// calls to this method won't be logged
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can combine the above examples to whitelist certain actions for being logged:
|
||||
|
||||
```js
|
||||
class MyStore {
|
||||
static trackerMobXConfig: {
|
||||
enabled: false,
|
||||
methods: {
|
||||
myAction: true
|
||||
}
|
||||
};
|
||||
|
||||
@action myAction() {
|
||||
// only calls to this method are being logged
|
||||
}
|
||||
|
||||
// other methods won't be logged ...
|
||||
}
|
||||
```
|
||||
|
||||
> Please keep in mind that at this point `trackerMobXConfig` is only available for actions (`@action`) and computed properties (`@computed`).
|
||||
Where `predicate` can be used to dynamically turn off capturing and `sanitize` can be used to modify the payload before sending it to backend.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@openreplay/tracker-mobx",
|
||||
"description": "Tracker plugin for MobX events recording",
|
||||
"version": "3.0.1",
|
||||
"version": "4.0.0",
|
||||
"keywords": [
|
||||
"mobx",
|
||||
"logging",
|
||||
|
|
@ -23,12 +23,10 @@
|
|||
},
|
||||
"dependencies": {},
|
||||
"peerDependencies": {
|
||||
"@openreplay/tracker": ">=3.0.0",
|
||||
"mobx": "^4.15.7"
|
||||
"@openreplay/tracker": ">=3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@openreplay/tracker": "file:../tracker",
|
||||
"mobx": "^4.15.7",
|
||||
"prettier": "^1.18.2",
|
||||
"replace-in-files-cli": "^1.0.0",
|
||||
"typescript": "^3.6.4"
|
||||
|
|
|
|||
|
|
@ -1,25 +1,24 @@
|
|||
import { spy } from 'mobx';
|
||||
import { App, Messages } from '@openreplay/tracker';
|
||||
|
||||
import log from './log';
|
||||
import { Encoder, sha1 } from './syncod';
|
||||
import log from './log.js';
|
||||
import { Encoder, sha1 } from './syncod/index.js';
|
||||
|
||||
export interface Options {
|
||||
predicate: (ev: any) => boolean,
|
||||
action: boolean;
|
||||
reaction: boolean;
|
||||
transaction: boolean;
|
||||
compute: boolean;
|
||||
predicate: (ev: { type: string; name: string; object: any; debugObjectName: string }) => boolean;
|
||||
sanitize: (ev: { state: any; type: string; property: string }) => { state: any; type: string; property: string };
|
||||
update: boolean;
|
||||
delete: boolean;
|
||||
add: boolean;
|
||||
}
|
||||
|
||||
export default function(opts: Partial<Options> = {}) {
|
||||
export default function (opts: Partial<Options> = {}) {
|
||||
const options: Options = Object.assign(
|
||||
{
|
||||
predicate: () => true,
|
||||
action: true,
|
||||
reaction: true,
|
||||
transaction: true,
|
||||
compute: true,
|
||||
sanitize: (ev) => ev,
|
||||
update: true,
|
||||
delete: true,
|
||||
add: true,
|
||||
},
|
||||
opts,
|
||||
);
|
||||
|
|
@ -28,20 +27,23 @@ export default function(opts: Partial<Options> = {}) {
|
|||
return;
|
||||
}
|
||||
const encoder = new Encoder(sha1, 50);
|
||||
spy(app.safe(ev => {
|
||||
if (!options.predicate(ev)) return;
|
||||
const { type } = ev;
|
||||
ev = options[type] && log[type] && log[type](ev);
|
||||
if (!ev) return;
|
||||
if (typeof ev.name === 'string' && ev.name) {
|
||||
app.send(Messages.StateAction(ev.name));
|
||||
}
|
||||
|
||||
const payload = encoder.encode(ev);
|
||||
const table = encoder.commit();
|
||||
for (let key in table) app.send(Messages.OTable(key, table[key]));
|
||||
app.send(Messages.MobX(type, payload));
|
||||
}),
|
||||
);
|
||||
return (ev: { type: string; name: string; object: any; debugObjectName: string }) => {
|
||||
if (!options.predicate(ev)) return;
|
||||
const { type } = ev;
|
||||
const event = options[type] && log[type] && log[type](ev);
|
||||
if (!event) return;
|
||||
const sanitizedEvent = options.sanitize(event);
|
||||
const evType = ev.debugObjectName?.split('@')[0] || ev.type;
|
||||
if (evType) {
|
||||
app.send(Messages.StateAction(evType));
|
||||
}
|
||||
|
||||
const payload = encoder.encode(sanitizedEvent);
|
||||
const table = encoder.commit();
|
||||
|
||||
for (let key in table) app.send(Messages.OTable(key, table[key]));
|
||||
app.send(Messages.MobX(evType, payload));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
// Based on https://github.com/winterbe/mobx-logger/blob/master/src/log.js
|
||||
// though it is not used anymore due to spy() being no op in production
|
||||
|
||||
interface TrackerMobXConfig {
|
||||
enabled?: boolean;
|
||||
|
|
@ -36,13 +37,6 @@ const getPropName = ev => {
|
|||
);
|
||||
};
|
||||
|
||||
const action = ev => {
|
||||
if (!isLoggingEnabled(ev)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return { name: ev.name, arguments: ev.arguments, object: ev.object };
|
||||
};
|
||||
|
||||
const reaction = ev => {
|
||||
const name = ev.name.replace('#null', '');
|
||||
|
|
@ -65,4 +59,30 @@ const compute = ev => {
|
|||
return { name };
|
||||
};
|
||||
|
||||
export default { action, reaction, transaction, compute };
|
||||
|
||||
const observeAction = ev => {
|
||||
return {
|
||||
state: ev.object,
|
||||
type: ev.type,
|
||||
property: ev.name,
|
||||
}
|
||||
}
|
||||
|
||||
const action = ev => {
|
||||
if (!isLoggingEnabled(ev)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return { name: ev.name, arguments: ev.arguments, object: ev.object };
|
||||
};
|
||||
|
||||
|
||||
export default {
|
||||
// action,
|
||||
// reaction,
|
||||
// transaction,
|
||||
// compute,
|
||||
update: observeAction,
|
||||
delete: observeAction,
|
||||
add: observeAction
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue