causal-inspector 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/CausalInspector.css +124 -0
  2. package/dist/CausalInspector.d.ts +13 -0
  3. package/dist/CausalInspector.js +257 -0
  4. package/dist/components/CopyablePayload.d.ts +4 -0
  5. package/dist/components/CopyablePayload.js +44 -0
  6. package/dist/components/FilterBar.d.ts +1 -0
  7. package/dist/components/FilterBar.js +23 -0
  8. package/dist/components/GlobalScrubber.d.ts +1 -0
  9. package/dist/components/GlobalScrubber.js +148 -0
  10. package/dist/components/JsonSyntax.d.ts +3 -0
  11. package/dist/components/JsonSyntax.js +40 -0
  12. package/dist/context.d.ts +26 -0
  13. package/dist/context.js +28 -0
  14. package/dist/engines/index.d.ts +22 -0
  15. package/dist/engines/index.js +29 -0
  16. package/dist/engines/query.d.ts +14 -0
  17. package/dist/engines/query.js +241 -0
  18. package/dist/engines/scrubber.d.ts +12 -0
  19. package/dist/engines/scrubber.js +69 -0
  20. package/dist/engines/storage.d.ts +15 -0
  21. package/dist/engines/storage.js +16 -0
  22. package/dist/engines/subscription.d.ts +17 -0
  23. package/dist/engines/subscription.js +44 -0
  24. package/dist/engines/url.d.ts +13 -0
  25. package/dist/engines/url.js +64 -0
  26. package/dist/events.d.ts +77 -0
  27. package/dist/events.js +1 -0
  28. package/dist/index.d.ts +30 -0
  29. package/dist/index.js +29 -0
  30. package/dist/machine/core.d.ts +22 -0
  31. package/dist/machine/core.js +34 -0
  32. package/dist/machine/engine.d.ts +17 -0
  33. package/dist/machine/engine.js +21 -0
  34. package/dist/machine/events.d.ts +18 -0
  35. package/dist/machine/events.js +1 -0
  36. package/dist/machine/hooks.d.ts +23 -0
  37. package/dist/machine/hooks.js +52 -0
  38. package/dist/machine/index.d.ts +5 -0
  39. package/dist/machine/index.js +4 -0
  40. package/dist/machine/store.d.ts +27 -0
  41. package/dist/machine/store.js +42 -0
  42. package/dist/panes/AggregateTimelinePane.d.ts +2 -0
  43. package/dist/panes/AggregateTimelinePane.js +224 -0
  44. package/dist/panes/CausalFlowPane.d.ts +7 -0
  45. package/dist/panes/CausalFlowPane.js +596 -0
  46. package/dist/panes/CausalTreePane.d.ts +5 -0
  47. package/dist/panes/CausalTreePane.js +158 -0
  48. package/dist/panes/CorrelationExplorerPane.d.ts +2 -0
  49. package/dist/panes/CorrelationExplorerPane.js +46 -0
  50. package/dist/panes/LogsPane.d.ts +6 -0
  51. package/dist/panes/LogsPane.js +65 -0
  52. package/dist/panes/TimelinePane.d.ts +6 -0
  53. package/dist/panes/TimelinePane.js +121 -0
  54. package/dist/panes/WaterfallPane.d.ts +2 -0
  55. package/dist/panes/WaterfallPane.js +202 -0
  56. package/dist/queries.d.ts +15 -0
  57. package/dist/queries.js +175 -0
  58. package/dist/reducer.d.ts +4 -0
  59. package/dist/reducer.js +177 -0
  60. package/dist/state.d.ts +34 -0
  61. package/dist/state.js +39 -0
  62. package/dist/theme.d.ts +7 -0
  63. package/dist/theme.js +34 -0
  64. package/dist/types.d.ts +140 -0
  65. package/dist/types.js +1 -0
  66. package/dist/utils.d.ts +14 -0
  67. package/dist/utils.js +91 -0
  68. package/package.json +43 -0
@@ -0,0 +1,77 @@
1
+ import type { BaseEvent } from "./machine";
2
+ import type { InspectorEvent, CorrelationSummary, ReactorDependency, AggregateLifecycleEntry, FilterState, FlowSelection, ReactorDescription, ReactorDescriptionSnapshot, AggregateTimelineEntry, ReactorLog, ReactorOutcome, PaneLayout } from "./types";
3
+ type EventsReceived = BaseEvent<"events/received", InspectorEvent[]>;
4
+ type SubscriptionConnected = BaseEvent<"events/subscription_connected">;
5
+ type SubscriptionError = BaseEvent<"events/subscription_error", {
6
+ message: string;
7
+ }>;
8
+ type PageLoaded = BaseEvent<"events/page_loaded", {
9
+ events: InspectorEvent[];
10
+ hasMore: boolean;
11
+ }>;
12
+ type CausalTreeLoaded = BaseEvent<"events/causal_tree_loaded", {
13
+ events: InspectorEvent[];
14
+ rootSeq: number;
15
+ }>;
16
+ type FlowLoaded = BaseEvent<"events/flow_loaded", InspectorEvent[]>;
17
+ type LogsLoaded = BaseEvent<"events/logs_loaded", ReactorLog[]>;
18
+ type DescriptionsLoaded = BaseEvent<"events/descriptions_loaded", {
19
+ correlationId: string;
20
+ descriptions: ReactorDescription[];
21
+ }>;
22
+ type DescriptionSnapshotsLoaded = BaseEvent<"events/description_snapshots_loaded", {
23
+ correlationId: string;
24
+ snapshots: ReactorDescriptionSnapshot[];
25
+ }>;
26
+ type AggregateTimelineLoaded = BaseEvent<"events/aggregate_timeline_loaded", {
27
+ correlationId: string;
28
+ entries: AggregateTimelineEntry[];
29
+ }>;
30
+ type OutcomesLoaded = BaseEvent<"events/outcomes_loaded", {
31
+ correlationId: string;
32
+ outcomes: ReactorOutcome[];
33
+ }>;
34
+ type CorrelationsLoaded = BaseEvent<"events/correlations_loaded", CorrelationSummary[]>;
35
+ type ReactorDependenciesLoaded = BaseEvent<"events/reactor_dependencies_loaded", ReactorDependency[]>;
36
+ type AggregateKeysLoaded = BaseEvent<"events/aggregate_keys_loaded", string[]>;
37
+ type AggregateLifecycleLoaded = BaseEvent<"events/aggregate_lifecycle_loaded", {
38
+ key: string;
39
+ entries: AggregateLifecycleEntry[];
40
+ }>;
41
+ type EventSelected = BaseEvent<"ui/event_selected", {
42
+ seq: number;
43
+ }>;
44
+ type EventDeselected = BaseEvent<"ui/event_deselected">;
45
+ type FlowOpened = BaseEvent<"ui/flow_opened", {
46
+ correlationId: string;
47
+ }>;
48
+ type FlowClosed = BaseEvent<"ui/flow_closed">;
49
+ type FlowNodeSelected = BaseEvent<"ui/flow_node_selected", FlowSelection>;
50
+ type FilterChanged = BaseEvent<"ui/filter_changed", Partial<FilterState>>;
51
+ type LoadMoreRequested = BaseEvent<"ui/load_more_requested">;
52
+ type LayoutChanged = BaseEvent<"ui/layout_changed", PaneLayout>;
53
+ type ScrubberStartChanged = BaseEvent<"ui/scrubber_start_changed", {
54
+ start: number | null;
55
+ }>;
56
+ type ScrubberEndChanged = BaseEvent<"ui/scrubber_end_changed", {
57
+ end: number | null;
58
+ }>;
59
+ type ScrubberPlayToggled = BaseEvent<"ui/scrubber_play_toggled">;
60
+ type ScrubberSpeedChanged = BaseEvent<"ui/scrubber_speed_changed", {
61
+ speed: number;
62
+ }>;
63
+ type CorrelationsRequested = BaseEvent<"ui/correlations_requested", {
64
+ search?: string;
65
+ }>;
66
+ type HandlerSelected = BaseEvent<"ui/handler_selected", {
67
+ reactorId: string;
68
+ }>;
69
+ type AggregateLifecycleRequested = BaseEvent<"ui/aggregate_lifecycle_requested", {
70
+ aggregateKey: string;
71
+ }>;
72
+ type LocationChanged = BaseEvent<"location/changed", {
73
+ correlationId: string | null;
74
+ handler: string | null;
75
+ }>;
76
+ export type InspectorMachineEvent = EventsReceived | SubscriptionConnected | SubscriptionError | PageLoaded | CausalTreeLoaded | FlowLoaded | LogsLoaded | DescriptionsLoaded | DescriptionSnapshotsLoaded | AggregateTimelineLoaded | OutcomesLoaded | CorrelationsLoaded | EventSelected | EventDeselected | FlowOpened | FlowClosed | FlowNodeSelected | FilterChanged | LoadMoreRequested | LayoutChanged | ScrubberStartChanged | ScrubberEndChanged | ScrubberPlayToggled | ScrubberSpeedChanged | CorrelationsRequested | ReactorDependenciesLoaded | AggregateKeysLoaded | HandlerSelected | LocationChanged | AggregateLifecycleLoaded | AggregateLifecycleRequested;
77
+ export {};
package/dist/events.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,30 @@
1
+ export { Machine, Store, combineEngineCreators, MachineContext, useSelector, useDispatch, useInlineMachine, } from "./machine";
2
+ export type { Reducer, Engine, EngineCreator, BaseEvent, Dispatch, } from "./machine";
3
+ export { CausalInspectorProvider } from "./context";
4
+ export { reducer } from "./reducer";
5
+ export { initialState } from "./state";
6
+ export type { InspectorState } from "./state";
7
+ export type { InspectorMachineEvent } from "./events";
8
+ export type { InspectorEvent, InspectorEventsPage, InspectorCausalTree, InspectorCausalFlow, CorrelationSummary, ReactorDependency, AggregateLifecycleEntry, Block, ReactorLog, ReactorDescription, ReactorDescriptionSnapshot, AggregateStateEntry, AggregateTimelineEntry, ReactorOutcome, FilterState, LogsFilter, FlowSelection, PaneLayout, } from "./types";
9
+ export { createInspectorEngine, createSubscriptionEngine, createQueryEngine, createStorageEngine, } from "./engines";
10
+ export type { InspectorTransport, SubscriptionTransport, QueryTransport, StorageTransport, } from "./engines";
11
+ export { EVENTS_SUBSCRIPTION, INSPECTOR_EVENTS, INSPECTOR_CAUSAL_TREE, INSPECTOR_CAUSAL_FLOW, INSPECTOR_CORRELATIONS, INSPECTOR_REACTOR_LOGS, INSPECTOR_REACTOR_LOGS_BY_CORRELATION, INSPECTOR_REACTOR_DESCRIPTIONS, INSPECTOR_REACTOR_DESCRIPTION_SNAPSHOTS, INSPECTOR_AGGREGATE_TIMELINE, INSPECTOR_REACTOR_OUTCOMES, INSPECTOR_REACTOR_DEPENDENCIES, INSPECTOR_AGGREGATE_KEYS, INSPECTOR_AGGREGATE_LIFECYCLE, } from "./queries";
12
+ export { eventHue, eventBg, eventBorder, eventTextColor, LOG_LEVEL_COLORS, } from "./theme";
13
+ export { formatTs, compactPayload, copyToClipboard } from "./utils";
14
+ export { CausalInspector } from "./CausalInspector";
15
+ export type { CausalInspectorProps } from "./CausalInspector";
16
+ export { FilterBar } from "./components/FilterBar";
17
+ export { CopyablePayload } from "./components/CopyablePayload";
18
+ export { JsonSyntax } from "./components/JsonSyntax";
19
+ export { GlobalScrubber } from "./components/GlobalScrubber";
20
+ export { TimelinePane } from "./panes/TimelinePane";
21
+ export type { TimelinePaneProps } from "./panes/TimelinePane";
22
+ export { CausalTreePane } from "./panes/CausalTreePane";
23
+ export type { CausalTreePaneProps } from "./panes/CausalTreePane";
24
+ export { LogsPane } from "./panes/LogsPane";
25
+ export type { LogsPaneProps } from "./panes/LogsPane";
26
+ export { CausalFlowPane } from "./panes/CausalFlowPane";
27
+ export type { CausalFlowPaneProps } from "./panes/CausalFlowPane";
28
+ export { AggregateTimelinePane } from "./panes/AggregateTimelinePane";
29
+ export { WaterfallPane } from "./panes/WaterfallPane";
30
+ export { CorrelationExplorerPane } from "./panes/CorrelationExplorerPane";
package/dist/index.js ADDED
@@ -0,0 +1,29 @@
1
+ // ── Machine infra (generic, reusable) ──
2
+ export { Machine, Store, combineEngineCreators, MachineContext, useSelector, useDispatch, useInlineMachine, } from "./machine";
3
+ // ── Causal Inspector domain ──
4
+ export { CausalInspectorProvider } from "./context";
5
+ export { reducer } from "./reducer";
6
+ export { initialState } from "./state";
7
+ // ── Engines ──
8
+ export { createInspectorEngine, createSubscriptionEngine, createQueryEngine, createStorageEngine, } from "./engines";
9
+ // ── Queries ──
10
+ export { EVENTS_SUBSCRIPTION, INSPECTOR_EVENTS, INSPECTOR_CAUSAL_TREE, INSPECTOR_CAUSAL_FLOW, INSPECTOR_CORRELATIONS, INSPECTOR_REACTOR_LOGS, INSPECTOR_REACTOR_LOGS_BY_CORRELATION, INSPECTOR_REACTOR_DESCRIPTIONS, INSPECTOR_REACTOR_DESCRIPTION_SNAPSHOTS, INSPECTOR_AGGREGATE_TIMELINE, INSPECTOR_REACTOR_OUTCOMES, INSPECTOR_REACTOR_DEPENDENCIES, INSPECTOR_AGGREGATE_KEYS, INSPECTOR_AGGREGATE_LIFECYCLE, } from "./queries";
11
+ // ── Theme ──
12
+ export { eventHue, eventBg, eventBorder, eventTextColor, LOG_LEVEL_COLORS, } from "./theme";
13
+ // ── Utilities ──
14
+ export { formatTs, compactPayload, copyToClipboard } from "./utils";
15
+ // ── Drop-in component ──
16
+ export { CausalInspector } from "./CausalInspector";
17
+ // ── Components ──
18
+ export { FilterBar } from "./components/FilterBar";
19
+ export { CopyablePayload } from "./components/CopyablePayload";
20
+ export { JsonSyntax } from "./components/JsonSyntax";
21
+ export { GlobalScrubber } from "./components/GlobalScrubber";
22
+ // ── Panes ──
23
+ export { TimelinePane } from "./panes/TimelinePane";
24
+ export { CausalTreePane } from "./panes/CausalTreePane";
25
+ export { LogsPane } from "./panes/LogsPane";
26
+ export { CausalFlowPane } from "./panes/CausalFlowPane";
27
+ export { AggregateTimelinePane } from "./panes/AggregateTimelinePane";
28
+ export { WaterfallPane } from "./panes/WaterfallPane";
29
+ export { CorrelationExplorerPane } from "./panes/CorrelationExplorerPane";
@@ -0,0 +1,22 @@
1
+ import { EngineCreator } from "./engine";
2
+ import { Reducer } from "./store";
3
+ /**
4
+ * Machine = Store (pure state) + Engine (side effects).
5
+ *
6
+ * Dispatch flow:
7
+ * UI dispatches event
8
+ * → Store reduces (sync, via Immer)
9
+ * → Engine handles event with (curr, prev) state
10
+ * → Engine may dispatch new events (async reactions)
11
+ */
12
+ export declare class Machine<TState, TEvent extends {
13
+ type: string;
14
+ }> {
15
+ private _engine;
16
+ private _store;
17
+ constructor(reducer: Reducer<TState, TEvent>, createEngine: EngineCreator<TState, TEvent>, initialState: TState);
18
+ getState: () => TState;
19
+ dispatch: (event: TEvent) => void;
20
+ onStateChange(listener: (newState: TState, oldState: TState) => void): () => void;
21
+ dispose(): void;
22
+ }
@@ -0,0 +1,34 @@
1
+ import { Store } from "./store";
2
+ /**
3
+ * Machine = Store (pure state) + Engine (side effects).
4
+ *
5
+ * Dispatch flow:
6
+ * UI dispatches event
7
+ * → Store reduces (sync, via Immer)
8
+ * → Engine handles event with (curr, prev) state
9
+ * → Engine may dispatch new events (async reactions)
10
+ */
11
+ export class Machine {
12
+ _engine;
13
+ _store;
14
+ constructor(reducer, createEngine, initialState) {
15
+ this._store = new Store(reducer, initialState);
16
+ this._engine = createEngine(this.dispatch, this.getState);
17
+ }
18
+ getState = () => {
19
+ return this._store.getState();
20
+ };
21
+ dispatch = (event) => {
22
+ const prevState = this._store.getState();
23
+ this._store.dispatch(event);
24
+ const currState = this._store.getState();
25
+ this._engine.handleEvent?.(event, currState, prevState);
26
+ };
27
+ onStateChange(listener) {
28
+ return this._store.onStateChange(listener);
29
+ }
30
+ dispose() {
31
+ this._engine.dispose();
32
+ this._store.dispose();
33
+ }
34
+ }
@@ -0,0 +1,17 @@
1
+ import { Dispatch } from "./events";
2
+ export type Engine<TState, TEvent extends {
3
+ type: string;
4
+ }> = {
5
+ handleEvent?: (event: TEvent, currState: TState, prevState: TState) => void;
6
+ dispose: () => void;
7
+ };
8
+ export type EngineCreator<TState, TEvent extends {
9
+ type: string;
10
+ }> = (dispatch: Dispatch<TEvent>, getState: () => TState) => Engine<TState, TEvent>;
11
+ /**
12
+ * Compose multiple engine creators into one.
13
+ * Each engine receives every event — fan-out pattern.
14
+ */
15
+ export declare const combineEngineCreators: <TState, TEvent extends {
16
+ type: string;
17
+ }>(...creators: EngineCreator<TState, TEvent>[]) => EngineCreator<TState, TEvent>;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Compose multiple engine creators into one.
3
+ * Each engine receives every event — fan-out pattern.
4
+ */
5
+ export const combineEngineCreators = (...creators) => {
6
+ return (dispatch, getState) => {
7
+ const engines = creators.map((create) => create(dispatch, getState));
8
+ return {
9
+ handleEvent: (event, currState, prevState) => {
10
+ for (const engine of engines) {
11
+ engine.handleEvent?.(event, currState, prevState);
12
+ }
13
+ },
14
+ dispose: () => {
15
+ for (const engine of engines) {
16
+ engine.dispose();
17
+ }
18
+ },
19
+ };
20
+ };
21
+ };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Base event type — discriminated union foundation.
3
+ *
4
+ * When no payload type is given, the event has no `payload` property.
5
+ * When a payload type IS given, `payload` is required.
6
+ * This prevents accidentally omitting required payloads at dispatch sites.
7
+ */
8
+ export type BaseEvent<TType extends string, TPayload = void> = [
9
+ TPayload
10
+ ] extends [void] ? {
11
+ type: TType;
12
+ } : {
13
+ type: TType;
14
+ payload: TPayload;
15
+ };
16
+ export type Dispatch<TEvent extends {
17
+ type: string;
18
+ }> = (event: TEvent) => void;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,23 @@
1
+ import { Machine } from "./core";
2
+ import { Dispatch } from "./events";
3
+ import { EngineCreator } from "./engine";
4
+ import { Reducer } from "./store";
5
+ export declare const MachineContext: import("react").Context<Machine<any, any> | null>;
6
+ /**
7
+ * Select a slice of state. Only re-renders when the selected value changes
8
+ * (reference equality).
9
+ */
10
+ export declare const useSelector: <TState, TSelected>(selector: (state: TState) => TSelected) => TSelected;
11
+ /**
12
+ * Get the dispatch function. Stable reference — never causes re-renders.
13
+ */
14
+ export declare const useDispatch: <TEvent extends {
15
+ type: string;
16
+ }>() => Dispatch<TEvent>;
17
+ /**
18
+ * Create and manage a machine inline within a component.
19
+ * Useful for self-contained widgets.
20
+ */
21
+ export declare const useInlineMachine: <TState, TEvent extends {
22
+ type: string;
23
+ }>(reducer: Reducer<TState, TEvent>, createEngine: EngineCreator<TState, TEvent>, initialState: TState) => [TState, Dispatch<TEvent>];
@@ -0,0 +1,52 @@
1
+ import { createContext, useContext, useEffect, useMemo, useRef, useState } from "react";
2
+ import { Machine } from "./core";
3
+ export const MachineContext = createContext(null);
4
+ const useMachine = () => {
5
+ const machine = useContext(MachineContext);
6
+ if (!machine) {
7
+ throw new Error("useMachine must be used within a MachineContext.Provider");
8
+ }
9
+ return machine;
10
+ };
11
+ /**
12
+ * Select a slice of state. Only re-renders when the selected value changes
13
+ * (reference equality).
14
+ */
15
+ export const useSelector = (selector) => {
16
+ const machine = useMachine();
17
+ const [value, setValue] = useState(() => selector(machine.getState()));
18
+ const selectorRef = useRef(selector);
19
+ selectorRef.current = selector;
20
+ useEffect(() => {
21
+ // Sync in case state changed between render and effect
22
+ setValue(selectorRef.current(machine.getState()));
23
+ return machine.onStateChange((newState) => {
24
+ setValue(selectorRef.current(newState));
25
+ });
26
+ }, [machine]);
27
+ return value;
28
+ };
29
+ /**
30
+ * Get the dispatch function. Stable reference — never causes re-renders.
31
+ */
32
+ export const useDispatch = () => {
33
+ return useMachine().dispatch;
34
+ };
35
+ /**
36
+ * Create and manage a machine inline within a component.
37
+ * Useful for self-contained widgets.
38
+ */
39
+ export const useInlineMachine = (reducer, createEngine, initialState) => {
40
+ const machine = useMemo(() => new Machine(reducer, createEngine, initialState),
41
+ // eslint-disable-next-line react-hooks/exhaustive-deps
42
+ []);
43
+ const [state, setState] = useState(machine.getState());
44
+ useEffect(() => {
45
+ const unsub = machine.onStateChange((newState) => setState(newState));
46
+ return () => {
47
+ unsub();
48
+ machine.dispose();
49
+ };
50
+ }, [machine]);
51
+ return [state, machine.dispatch];
52
+ };
@@ -0,0 +1,5 @@
1
+ export { Machine } from "./core";
2
+ export { Store, type Reducer } from "./store";
3
+ export { type Engine, type EngineCreator, combineEngineCreators } from "./engine";
4
+ export { type BaseEvent, type Dispatch } from "./events";
5
+ export { MachineContext, useSelector, useDispatch, useInlineMachine } from "./hooks";
@@ -0,0 +1,4 @@
1
+ export { Machine } from "./core";
2
+ export { Store } from "./store";
3
+ export { combineEngineCreators } from "./engine";
4
+ export { MachineContext, useSelector, useDispatch, useInlineMachine } from "./hooks";
@@ -0,0 +1,27 @@
1
+ import { type Draft } from "immer";
2
+ type ChangeListener<TState> = (newState: TState, oldState: TState) => void;
3
+ export type Reducer<TState, TEvent extends {
4
+ type: string;
5
+ }> = (draft: Draft<TState>, event: TEvent) => void;
6
+ /**
7
+ * Immutable state store powered by Immer.
8
+ *
9
+ * Reducer receives a mutable draft (Immer proxy) — mutations are
10
+ * automatically converted to structural sharing under the hood.
11
+ */
12
+ export declare class Store<TState, TEvent extends {
13
+ type: string;
14
+ }> {
15
+ private _reduce;
16
+ private _state;
17
+ private _listeners;
18
+ constructor(_reduce: Reducer<TState, TEvent>, initialState: TState);
19
+ getState(): TState;
20
+ dispatch(event: TEvent): void;
21
+ /**
22
+ * Subscribe to state changes. Returns an unsubscribe function.
23
+ */
24
+ onStateChange(listener: ChangeListener<TState>): () => void;
25
+ dispose(): void;
26
+ }
27
+ export {};
@@ -0,0 +1,42 @@
1
+ import { produce } from "immer";
2
+ /**
3
+ * Immutable state store powered by Immer.
4
+ *
5
+ * Reducer receives a mutable draft (Immer proxy) — mutations are
6
+ * automatically converted to structural sharing under the hood.
7
+ */
8
+ export class Store {
9
+ _reduce;
10
+ _state;
11
+ _listeners = new Set();
12
+ constructor(_reduce, initialState) {
13
+ this._reduce = _reduce;
14
+ this._state = initialState;
15
+ }
16
+ getState() {
17
+ return this._state;
18
+ }
19
+ dispatch(event) {
20
+ const oldState = this._state;
21
+ this._state = produce(oldState, (draft) => {
22
+ this._reduce(draft, event);
23
+ });
24
+ if (this._state !== oldState) {
25
+ for (const listener of this._listeners) {
26
+ listener(this._state, oldState);
27
+ }
28
+ }
29
+ }
30
+ /**
31
+ * Subscribe to state changes. Returns an unsubscribe function.
32
+ */
33
+ onStateChange(listener) {
34
+ this._listeners.add(listener);
35
+ return () => {
36
+ this._listeners.delete(listener);
37
+ };
38
+ }
39
+ dispose() {
40
+ this._listeners.clear();
41
+ }
42
+ }
@@ -0,0 +1,2 @@
1
+ export type AggregateTimelinePaneProps = Record<string, never>;
2
+ export declare function AggregateTimelinePane(): import("react/jsx-runtime").JSX.Element;