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:
Delirium 2023-05-24 11:56:40 +02:00 committed by GitHub
parent e6e138b967
commit ce4d625c36
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 73 additions and 97 deletions

View file

@ -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.

View file

@ -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"

View file

@ -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));
}
};
}

View file

@ -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
};