1 | import { IComputedDidChange } from "./computedvalue"
|
2 | import { IValueDidChange, IBoxDidChange } from "./../types/observablevalue"
|
3 | import { IObjectDidChange } from "./../types/observableobject"
|
4 | import { IArrayDidChange } from "./../types/observablearray"
|
5 | import { Lambda, globalState, once, ISetDidChange, IMapDidChange } from "../internal"
|
6 |
|
7 | export function isSpyEnabled() {
|
8 | return __DEV__ && !!globalState.spyListeners.length
|
9 | }
|
10 |
|
11 | export 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 |
|
25 | type SpyEvent = PureSpyEvent & { spyReportStart?: true }
|
26 |
|
27 | export function spyReport(event: SpyEvent) {
|
28 | if (!__DEV__) return
|
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 |
|
34 | export function spyReportStart(event: PureSpyEvent) {
|
35 | if (!__DEV__) return
|
36 | const change = { ...event, spyReportStart: true as const }
|
37 | spyReport(change)
|
38 | }
|
39 |
|
40 | const END_EVENT: SpyEvent = { type: "report-end", spyReportEnd: true }
|
41 |
|
42 | export 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 |
|
48 | export 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 | }
|