@player-devtools/plugin 0.0.7--canary.8.483
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.
- package/dist/DevtoolsPlugin.native.js +1344 -0
- package/dist/DevtoolsPlugin.native.js.map +1 -0
- package/dist/cjs/index.cjs +282 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/index.legacy-esm.js +252 -0
- package/dist/index.mjs +252 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +34 -0
- package/src/constants.ts +6 -0
- package/src/helpers/__tests__/genDataChangeTransaction.test.ts +40 -0
- package/src/helpers/genDataChangeTransaction.ts +39 -0
- package/src/helpers/index.ts +2 -0
- package/src/helpers/uuid.ts +22 -0
- package/src/index.ts +8 -0
- package/src/plugin.ts +176 -0
- package/src/reducer.ts +80 -0
- package/src/state.ts +43 -0
- package/types/constants.d.ts +5 -0
- package/types/helpers/genDataChangeTransaction.d.ts +16 -0
- package/types/helpers/index.d.ts +3 -0
- package/types/helpers/uuid.d.ts +2 -0
- package/types/index.d.ts +4 -0
- package/types/plugin.d.ts +33 -0
- package/types/reducer.d.ts +4 -0
- package/types/state.d.ts +12 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
DevtoolsDataChangeEvent,
|
|
3
|
+
Transaction,
|
|
4
|
+
} from "@player-devtools/types";
|
|
5
|
+
import type { Flow } from "@player-ui/player";
|
|
6
|
+
|
|
7
|
+
const NOOP_ID = -1;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Generates a data change transaction for the player devtools plugin.
|
|
11
|
+
*
|
|
12
|
+
* This function creates a transaction object that represents a change in data
|
|
13
|
+
* within a player devtools plugin. The transaction includes details such as the
|
|
14
|
+
* plugin ID, the changed data, and the player ID. It is used to communicate
|
|
15
|
+
* changes between the plugin and devtools.
|
|
16
|
+
*/
|
|
17
|
+
export const genDataChangeTransaction = ({
|
|
18
|
+
playerID,
|
|
19
|
+
data,
|
|
20
|
+
pluginID,
|
|
21
|
+
}: {
|
|
22
|
+
playerID: string;
|
|
23
|
+
data: Flow["data"];
|
|
24
|
+
pluginID: string;
|
|
25
|
+
}): Transaction<DevtoolsDataChangeEvent> => {
|
|
26
|
+
return {
|
|
27
|
+
id: NOOP_ID,
|
|
28
|
+
type: "PLAYER_DEVTOOLS_PLUGIN_DATA_CHANGE",
|
|
29
|
+
payload: {
|
|
30
|
+
pluginID,
|
|
31
|
+
data,
|
|
32
|
+
},
|
|
33
|
+
sender: playerID,
|
|
34
|
+
context: "player",
|
|
35
|
+
target: "player",
|
|
36
|
+
timestamp: Date.now(),
|
|
37
|
+
_messenger_: true,
|
|
38
|
+
};
|
|
39
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export function generateUUID(): string {
|
|
2
|
+
// Public Domain/MIT
|
|
3
|
+
let d = new Date().getTime(); //Timestamp
|
|
4
|
+
let d2 =
|
|
5
|
+
(typeof performance !== "undefined" &&
|
|
6
|
+
performance.now &&
|
|
7
|
+
performance.now() * 1000) ||
|
|
8
|
+
0; //Time in microseconds since page-load or 0 if unsupported
|
|
9
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
|
|
10
|
+
let r = Math.random() * 16; //random number between 0 and 16
|
|
11
|
+
if (d > 0) {
|
|
12
|
+
//Use timestamp until depleted
|
|
13
|
+
r = (d + r) % 16 | 0;
|
|
14
|
+
d = Math.floor(d / 16);
|
|
15
|
+
} else {
|
|
16
|
+
//Use microseconds since page-load if supported
|
|
17
|
+
r = (d2 + r) % 16 | 0;
|
|
18
|
+
d2 = Math.floor(d2 / 16);
|
|
19
|
+
}
|
|
20
|
+
return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
|
|
21
|
+
});
|
|
22
|
+
}
|
package/src/index.ts
ADDED
package/src/plugin.ts
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import type { Messenger } from "@player-devtools/messenger";
|
|
2
|
+
import {
|
|
3
|
+
PluginData,
|
|
4
|
+
DevtoolsPluginsStore,
|
|
5
|
+
PlayerInitEvent,
|
|
6
|
+
ExtensionSupportedEvents,
|
|
7
|
+
Transaction,
|
|
8
|
+
DevtoolsPluginInteractionEvent,
|
|
9
|
+
} from "@player-devtools/types";
|
|
10
|
+
import { dsetAssign } from "@player-devtools/utils";
|
|
11
|
+
import type { DataModel, Player, PlayerPlugin } from "@player-ui/player";
|
|
12
|
+
import { produce } from "immer";
|
|
13
|
+
import { useStateReducer, type Store, type Unsubscribe } from "./state";
|
|
14
|
+
import { reducer } from "./reducer";
|
|
15
|
+
import { PLUGIN_INACTIVE_WARNING, INTERACTIONS } from "./constants";
|
|
16
|
+
import { genDataChangeTransaction } from "./helpers";
|
|
17
|
+
import { dequal } from "dequal";
|
|
18
|
+
|
|
19
|
+
export interface DevtoolsHandler {
|
|
20
|
+
// TODO: Could return bool to signifiy handled to avoid double processing?
|
|
21
|
+
processInteraction(interaction: DevtoolsPluginInteractionEvent): void;
|
|
22
|
+
checkIfDevtoolsIsActive(): boolean;
|
|
23
|
+
log?(message: string): void;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface DevtoolsPluginOptions {
|
|
27
|
+
playerID: string;
|
|
28
|
+
pluginData: PluginData;
|
|
29
|
+
handler: DevtoolsHandler;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const INITIAL_STATE: DevtoolsPluginsStore = {
|
|
33
|
+
messages: [],
|
|
34
|
+
plugins: {},
|
|
35
|
+
interactions: [],
|
|
36
|
+
currentPlayer: "",
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// TODO: Rename to DevtoolsPluginStore? Need to rename DevtoolsPluginsStore to DevtoolsPluginState
|
|
40
|
+
export type PluginStore = Store<
|
|
41
|
+
DevtoolsPluginsStore,
|
|
42
|
+
Transaction<ExtensionSupportedEvents>
|
|
43
|
+
>;
|
|
44
|
+
|
|
45
|
+
/** Entrypoint for devtools plugins with platform-agnostic components */
|
|
46
|
+
export class DevtoolsPlugin implements PlayerPlugin, DevtoolsHandler {
|
|
47
|
+
name: string = "DevtoolsPlugin";
|
|
48
|
+
|
|
49
|
+
private loggedWarning = false;
|
|
50
|
+
|
|
51
|
+
store: PluginStore = useStateReducer(reducer, INITIAL_STATE);
|
|
52
|
+
protected lastProcessedInteraction = 0;
|
|
53
|
+
|
|
54
|
+
get pluginID(): string {
|
|
55
|
+
return this.options.pluginData.id;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get playerID(): string {
|
|
59
|
+
return this.options.playerID;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
constructor(protected options: DevtoolsPluginOptions) {
|
|
63
|
+
this.store.subscribe(({ interactions }) => {
|
|
64
|
+
if (this.lastProcessedInteraction < (interactions.length ?? 0)) {
|
|
65
|
+
interactions
|
|
66
|
+
.slice(this.lastProcessedInteraction)
|
|
67
|
+
.forEach(this.processInteraction.bind(this));
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
registerMessenger(
|
|
73
|
+
messenger: Messenger<ExtensionSupportedEvents>,
|
|
74
|
+
): Unsubscribe {
|
|
75
|
+
// Propagate new messages from state to devtools via the messenger
|
|
76
|
+
let lastMessageIndex = -1;
|
|
77
|
+
return this.store.subscribe(({ messages }) => {
|
|
78
|
+
const start = lastMessageIndex + 1;
|
|
79
|
+
if (messages.length > start) {
|
|
80
|
+
const newlyAdded = messages.slice(start);
|
|
81
|
+
lastMessageIndex = messages.length - 1;
|
|
82
|
+
for (const msg of newlyAdded) {
|
|
83
|
+
messenger.sendMessage(msg);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
protected dispatchPlayerInit(): void {
|
|
90
|
+
// Initial plugin content
|
|
91
|
+
const transaction: Transaction<PlayerInitEvent> = {
|
|
92
|
+
id: -1,
|
|
93
|
+
type: "PLAYER_DEVTOOLS_PLAYER_INIT",
|
|
94
|
+
payload: {
|
|
95
|
+
plugins: {
|
|
96
|
+
[this.pluginID]: this.options.pluginData,
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
sender: this.options.playerID,
|
|
100
|
+
context: "player",
|
|
101
|
+
target: "player",
|
|
102
|
+
timestamp: Date.now(),
|
|
103
|
+
_messenger_: true,
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
this.store.dispatch(transaction);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// By default, we'll only write to the keys defined in data -- if undefined, data will be cleared
|
|
110
|
+
protected dispatchDataUpdate(data?: DataModel): void {
|
|
111
|
+
const state = this.store.getState();
|
|
112
|
+
|
|
113
|
+
const { plugins } = produce(this.store.getState(), (draft) => {
|
|
114
|
+
if (!data)
|
|
115
|
+
dsetAssign(draft, ["plugins", this.pluginID, "flow", "data"], data);
|
|
116
|
+
else
|
|
117
|
+
Object.entries(data).forEach(([key, value]) => {
|
|
118
|
+
dsetAssign(
|
|
119
|
+
draft,
|
|
120
|
+
["plugins", this.pluginID, "flow", "data", key],
|
|
121
|
+
value,
|
|
122
|
+
);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const newData = plugins[this.pluginID]!.flow.data;
|
|
127
|
+
if (dequal(state.plugins[this.pluginID]?.flow?.data, newData)) return;
|
|
128
|
+
|
|
129
|
+
const transaction = genDataChangeTransaction({
|
|
130
|
+
playerID: this.playerID,
|
|
131
|
+
pluginID: this.pluginID,
|
|
132
|
+
data: newData,
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
this.store.dispatch(transaction);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
checkIfDevtoolsIsActive(): boolean {
|
|
139
|
+
const isActive = this.options.handler.checkIfDevtoolsIsActive();
|
|
140
|
+
if (!isActive && !this.loggedWarning) {
|
|
141
|
+
this.options.handler.log?.(PLUGIN_INACTIVE_WARNING);
|
|
142
|
+
this.loggedWarning = true;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return isActive;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
processInteraction(interaction: DevtoolsPluginInteractionEvent): void {
|
|
149
|
+
this.options.handler.processInteraction(interaction);
|
|
150
|
+
|
|
151
|
+
const {
|
|
152
|
+
payload: { type, payload },
|
|
153
|
+
} = interaction;
|
|
154
|
+
|
|
155
|
+
if (type === INTERACTIONS.PLAYER_SELECTED && payload) {
|
|
156
|
+
this.store.dispatch({
|
|
157
|
+
id: -1,
|
|
158
|
+
type: "PLAYER_DEVTOOLS_SELECTED_PLAYER_CHANGE",
|
|
159
|
+
payload: { playerID: payload },
|
|
160
|
+
sender: this.playerID,
|
|
161
|
+
context: "player",
|
|
162
|
+
target: this.playerID,
|
|
163
|
+
timestamp: Date.now(),
|
|
164
|
+
_messenger_: true,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
this.lastProcessedInteraction += 1;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
apply(player: Player): void {
|
|
172
|
+
if (!this.checkIfDevtoolsIsActive()) return;
|
|
173
|
+
|
|
174
|
+
this.dispatchPlayerInit();
|
|
175
|
+
}
|
|
176
|
+
}
|
package/src/reducer.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { produce } from "immer";
|
|
2
|
+
import { dequal } from "dequal";
|
|
3
|
+
import type {
|
|
4
|
+
DevtoolsDataChangeEvent,
|
|
5
|
+
DevtoolsPluginsStore,
|
|
6
|
+
ExtensionSupportedEvents,
|
|
7
|
+
PlayerInitEvent,
|
|
8
|
+
Transaction,
|
|
9
|
+
} from "@player-devtools/types";
|
|
10
|
+
import { dsetAssign } from "@player-devtools/utils";
|
|
11
|
+
|
|
12
|
+
const containsInteraction = (
|
|
13
|
+
interactions: DevtoolsPluginsStore["interactions"],
|
|
14
|
+
interaction: DevtoolsPluginsStore["interactions"][number],
|
|
15
|
+
) => {
|
|
16
|
+
return interactions.filter((i) => dequal(i, interaction)).length > 0;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/** devtools plugin state reducer */
|
|
20
|
+
export const reducer = (
|
|
21
|
+
state: DevtoolsPluginsStore,
|
|
22
|
+
transaction: Transaction<ExtensionSupportedEvents>,
|
|
23
|
+
): DevtoolsPluginsStore => {
|
|
24
|
+
switch (transaction.type) {
|
|
25
|
+
case "PLAYER_DEVTOOLS_PLAYER_INIT":
|
|
26
|
+
return produce(state, (draft) => {
|
|
27
|
+
const { payload } = transaction;
|
|
28
|
+
dsetAssign(draft, ["plugins"], payload.plugins);
|
|
29
|
+
|
|
30
|
+
const message: PlayerInitEvent = {
|
|
31
|
+
type: "PLAYER_DEVTOOLS_PLAYER_INIT",
|
|
32
|
+
payload,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
draft.messages.push(message);
|
|
36
|
+
});
|
|
37
|
+
case "PLAYER_DEVTOOLS_PLUGIN_DATA_CHANGE":
|
|
38
|
+
return produce(state, (draft) => {
|
|
39
|
+
const { payload } = transaction;
|
|
40
|
+
|
|
41
|
+
if (!payload.data) return state;
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
dsetAssign(
|
|
45
|
+
draft,
|
|
46
|
+
["plugins", transaction.payload.pluginID, "flow", "data"],
|
|
47
|
+
transaction.payload.data,
|
|
48
|
+
);
|
|
49
|
+
} catch {
|
|
50
|
+
console.error("error setting data:", transaction.payload.data);
|
|
51
|
+
}
|
|
52
|
+
const message: DevtoolsDataChangeEvent = {
|
|
53
|
+
type: "PLAYER_DEVTOOLS_PLUGIN_DATA_CHANGE",
|
|
54
|
+
payload,
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
draft.messages.push(message);
|
|
58
|
+
});
|
|
59
|
+
case "PLAYER_DEVTOOLS_PLUGIN_INTERACTION":
|
|
60
|
+
return produce(state, (draft) => {
|
|
61
|
+
if (containsInteraction(draft.interactions, transaction)) return state;
|
|
62
|
+
|
|
63
|
+
dsetAssign(
|
|
64
|
+
draft,
|
|
65
|
+
["interactions"],
|
|
66
|
+
[...draft.interactions, transaction],
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
case "PLAYER_DEVTOOLS_SELECTED_PLAYER_CHANGE": {
|
|
70
|
+
const { playerID } = transaction.payload;
|
|
71
|
+
|
|
72
|
+
if (!playerID) return state;
|
|
73
|
+
return produce(state, (draft) => {
|
|
74
|
+
dsetAssign(draft, ["currentPlayer"], playerID);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
default:
|
|
78
|
+
return state;
|
|
79
|
+
}
|
|
80
|
+
};
|
package/src/state.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export type Reducer<T, A> = (state: T, action: A) => T;
|
|
2
|
+
export type Dispatch<A> = (action: A) => void;
|
|
3
|
+
export type Subscriber<T> = (state: T) => void;
|
|
4
|
+
export type Subscribe<T> = (subscriber: Subscriber<T>) => Unsubscribe;
|
|
5
|
+
export type Unsubscribe = () => void;
|
|
6
|
+
|
|
7
|
+
export interface Store<State, Action> {
|
|
8
|
+
getState: () => State;
|
|
9
|
+
subscribe: Subscribe<State>;
|
|
10
|
+
dispatch: Dispatch<Action>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const useStateReducer = <State, Action>(
|
|
14
|
+
reducer: Reducer<State, Action>,
|
|
15
|
+
initialState: State,
|
|
16
|
+
): Store<State, Action> => {
|
|
17
|
+
let state = initialState;
|
|
18
|
+
const subscribers = new Set<Subscriber<State>>();
|
|
19
|
+
return {
|
|
20
|
+
getState: () => state,
|
|
21
|
+
|
|
22
|
+
/** Subscribe to state changes; returns an unsubscribe function. */
|
|
23
|
+
subscribe(subscriber: Subscriber<State>): Unsubscribe {
|
|
24
|
+
subscribers.add(subscriber);
|
|
25
|
+
subscriber(state);
|
|
26
|
+
return () => subscribers.delete(subscriber);
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
/** Dispatch an action through the reducer, then run side-effects. */
|
|
30
|
+
dispatch(action: Action): void {
|
|
31
|
+
const prevState = state;
|
|
32
|
+
const nextState = reducer(prevState, action);
|
|
33
|
+
|
|
34
|
+
// Only proceed if state actually changed by reference
|
|
35
|
+
if (nextState !== prevState) {
|
|
36
|
+
state = nextState;
|
|
37
|
+
|
|
38
|
+
// Notify subscribers
|
|
39
|
+
for (const sub of subscribers) sub(state);
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const INTERACTIONS: {
|
|
2
|
+
PLAYER_SELECTED: string;
|
|
3
|
+
};
|
|
4
|
+
export declare const PLUGIN_INACTIVE_WARNING = "The plugin has been registered, but the Player development tools are not active. If you are working in a production environment, it is recommended to remove the plugin. To activate, enable through the browser extension popup for web or configure the FlipperClient for mobile.";
|
|
5
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { DevtoolsDataChangeEvent, Transaction } from "@player-devtools/types";
|
|
2
|
+
import type { Flow } from "@player-ui/player";
|
|
3
|
+
/**
|
|
4
|
+
* Generates a data change transaction for the player devtools plugin.
|
|
5
|
+
*
|
|
6
|
+
* This function creates a transaction object that represents a change in data
|
|
7
|
+
* within a player devtools plugin. The transaction includes details such as the
|
|
8
|
+
* plugin ID, the changed data, and the player ID. It is used to communicate
|
|
9
|
+
* changes between the plugin and devtools.
|
|
10
|
+
*/
|
|
11
|
+
export declare const genDataChangeTransaction: ({ playerID, data, pluginID, }: {
|
|
12
|
+
playerID: string;
|
|
13
|
+
data: Flow["data"];
|
|
14
|
+
pluginID: string;
|
|
15
|
+
}) => Transaction<DevtoolsDataChangeEvent>;
|
|
16
|
+
//# sourceMappingURL=genDataChangeTransaction.d.ts.map
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Messenger } from "@player-devtools/messenger";
|
|
2
|
+
import { PluginData, DevtoolsPluginsStore, ExtensionSupportedEvents, Transaction, DevtoolsPluginInteractionEvent } from "@player-devtools/types";
|
|
3
|
+
import type { DataModel, Player, PlayerPlugin } from "@player-ui/player";
|
|
4
|
+
import { type Store, type Unsubscribe } from "./state";
|
|
5
|
+
export interface DevtoolsHandler {
|
|
6
|
+
processInteraction(interaction: DevtoolsPluginInteractionEvent): void;
|
|
7
|
+
checkIfDevtoolsIsActive(): boolean;
|
|
8
|
+
log?(message: string): void;
|
|
9
|
+
}
|
|
10
|
+
export interface DevtoolsPluginOptions {
|
|
11
|
+
playerID: string;
|
|
12
|
+
pluginData: PluginData;
|
|
13
|
+
handler: DevtoolsHandler;
|
|
14
|
+
}
|
|
15
|
+
export type PluginStore = Store<DevtoolsPluginsStore, Transaction<ExtensionSupportedEvents>>;
|
|
16
|
+
/** Entrypoint for devtools plugins with platform-agnostic components */
|
|
17
|
+
export declare class DevtoolsPlugin implements PlayerPlugin, DevtoolsHandler {
|
|
18
|
+
protected options: DevtoolsPluginOptions;
|
|
19
|
+
name: string;
|
|
20
|
+
private loggedWarning;
|
|
21
|
+
store: PluginStore;
|
|
22
|
+
protected lastProcessedInteraction: number;
|
|
23
|
+
get pluginID(): string;
|
|
24
|
+
get playerID(): string;
|
|
25
|
+
constructor(options: DevtoolsPluginOptions);
|
|
26
|
+
registerMessenger(messenger: Messenger<ExtensionSupportedEvents>): Unsubscribe;
|
|
27
|
+
protected dispatchPlayerInit(): void;
|
|
28
|
+
protected dispatchDataUpdate(data?: DataModel): void;
|
|
29
|
+
checkIfDevtoolsIsActive(): boolean;
|
|
30
|
+
processInteraction(interaction: DevtoolsPluginInteractionEvent): void;
|
|
31
|
+
apply(player: Player): void;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { DevtoolsPluginsStore, ExtensionSupportedEvents, Transaction } from "@player-devtools/types";
|
|
2
|
+
/** devtools plugin state reducer */
|
|
3
|
+
export declare const reducer: (state: DevtoolsPluginsStore, transaction: Transaction<ExtensionSupportedEvents>) => DevtoolsPluginsStore;
|
|
4
|
+
//# sourceMappingURL=reducer.d.ts.map
|
package/types/state.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type Reducer<T, A> = (state: T, action: A) => T;
|
|
2
|
+
export type Dispatch<A> = (action: A) => void;
|
|
3
|
+
export type Subscriber<T> = (state: T) => void;
|
|
4
|
+
export type Subscribe<T> = (subscriber: Subscriber<T>) => Unsubscribe;
|
|
5
|
+
export type Unsubscribe = () => void;
|
|
6
|
+
export interface Store<State, Action> {
|
|
7
|
+
getState: () => State;
|
|
8
|
+
subscribe: Subscribe<State>;
|
|
9
|
+
dispatch: Dispatch<Action>;
|
|
10
|
+
}
|
|
11
|
+
export declare const useStateReducer: <State, Action>(reducer: Reducer<State, Action>, initialState: State) => Store<State, Action>;
|
|
12
|
+
//# sourceMappingURL=state.d.ts.map
|