UNPKG

2.15 kBPlain TextView Raw
1import { IComputedDidChange } from "./computedvalue"
2import { IValueDidChange, IBoxDidChange } from "./../types/observablevalue"
3import { IObjectDidChange } from "./../types/observableobject"
4import { IArrayDidChange } from "./../types/observablearray"
5import { Lambda, globalState, once, ISetDidChange, IMapDidChange } from "../internal"
6
7export function isSpyEnabled() {
8 return __DEV__ && !!globalState.spyListeners.length
9}
10
11export type PureSpyEvent =
12 | { type: "action"; name: string; object: unknown; arguments: unknown[] }
13 | { type: "scheduled-reaction"; name: string }
14 | { type: "reaction"; name: string }
15 | { type: "error"; name: string; message: string; error: string }
16 | IComputedDidChange<unknown>
17 | IObjectDidChange<unknown>
18 | IArrayDidChange<unknown>
19 | IMapDidChange<unknown, unknown>
20 | ISetDidChange<unknown>
21 | IValueDidChange<unknown>
22 | IBoxDidChange<unknown>
23 | { type: "report-end"; spyReportEnd: true; time?: number }
24
25type SpyEvent = PureSpyEvent & { spyReportStart?: true }
26
27export function spyReport(event: SpyEvent) {
28 if (!__DEV__) return // dead code elimination can do the rest
29 if (!globalState.spyListeners.length) return
30 const listeners = globalState.spyListeners
31 for (let i = 0, l = listeners.length; i < l; i++) listeners[i](event)
32}
33
34export function spyReportStart(event: PureSpyEvent) {
35 if (!__DEV__) return
36 const change = { ...event, spyReportStart: true as const }
37 spyReport(change)
38}
39
40const END_EVENT: SpyEvent = { type: "report-end", spyReportEnd: true }
41
42export function spyReportEnd(change?: { time?: number }) {
43 if (!__DEV__) return
44 if (change) spyReport({ ...change, type: "report-end", spyReportEnd: true })
45 else spyReport(END_EVENT)
46}
47
48export function spy(listener: (change: SpyEvent) => void): Lambda {
49 if (!__DEV__) {
50 console.warn(`[mobx.spy] Is a no-op in production builds`)
51 return function () {}
52 } else {
53 globalState.spyListeners.push(listener)
54 return once(() => {
55 globalState.spyListeners = globalState.spyListeners.filter(l => l !== listener)
56 })
57 }
58}