feat(tracker): capture pinia state updates

This commit is contained in:
sylenien 2022-08-30 16:19:31 +02:00
parent bef74d5284
commit 4c4304a419

View file

@ -1,10 +1,35 @@
import { App, Messages } from '@openreplay/tracker';
import { App, Messages } from "@openreplay/tracker";
import { Encoder, sha1 } from "./syncod/index.js";
export interface Options {
filter: (mutation: any, state: any) => boolean;
transformer: (state: any) => any;
mutationTransformer: (mutation: any) => any;
storeName?: string;
}
function processMutationAndState(
app: App,
options: Options,
encoder: Encoder,
mutation: any,
state: any
) {
if (options.filter(mutation, state)) {
try {
const { type } = mutation;
if (typeof type === "string" && type) {
app.send(Messages.StateAction(type));
}
const _mutation = encoder.encode(options.mutationTransformer(mutation));
const _state = encoder.encode(options.transformer(state));
const _table = encoder.commit();
for (let key in _table) app.send(Messages.OTable(key, _table[key]));
app.send(Messages.Vuex(_mutation, _state));
} catch {
encoder.clear();
}
}
}
export default function(opts: Partial<Options> = {}) {
@ -12,7 +37,8 @@ export default function(opts: Partial<Options> = {}) {
{
filter: () => true,
transformer: state => state,
mutationTransformer: mutation => mutation
mutationTransformer: mutation => mutation,
storeName: undefined,
},
opts
);
@ -21,26 +47,32 @@ export default function(opts: Partial<Options> = {}) {
return Function.prototype;
}
const encoder = new Encoder(sha1, 50);
const state = {};
return store => {
store.subscribe((mutation, state) => {
if (options.filter(mutation, state)) {
// Vuex
if (store.subscribe) {
const randomId = Math.random().toString(36).substring(2, 9)
store.subscribe((mutation, storeState) => {
state[options.storeName || randomId] = state
processMutationAndState(app, options, encoder, mutation, storeState);
});
}
// Pinia
if (store.$onAction) {
store.$onAction(({ name, store, args }) => {
try {
const { type } = mutation;
if (typeof type === 'string' && type) {
app.send(Messages.StateAction(type));
}
const _mutation = encoder.encode(
options.mutationTransformer(mutation)
);
const _state = encoder.encode(options.transformer(state));
const _table = encoder.commit();
for (let key in _table) app.send(Messages.OTable(key, _table[key]));
app.send(Messages.Vuex(_mutation, _state));
} catch {
encoder.clear();
state[options.storeName || store.$id] = store.$state;
const mutation = {
type: name,
payload: args
};
processMutationAndState(app, options, encoder, mutation, state);
} catch (e) {
app.debug.error(e)
}
}
});
});
}
};
};
}