@player-tools/devtools-desktop-plugins-common 0.5.3--canary.90.2515

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.
@@ -0,0 +1,219 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // ../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/devtools/plugins/desktop/common/src/index.ts
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ reducer: () => reducer,
34
+ startFlipperConnection: () => startFlipperConnection,
35
+ useCommunicationLayer: () => useCommunicationLayer,
36
+ usePluginState: () => usePluginState
37
+ });
38
+ module.exports = __toCommonJS(src_exports);
39
+
40
+ // ../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/devtools/plugins/desktop/common/src/communication-layer/index.ts
41
+ var import_react = require("react");
42
+ var import_js_flipper = require("js-flipper");
43
+ var flipperConnection = null;
44
+ var startFlipperConnection = (setLayerCallbacks) => {
45
+ const listeners = [];
46
+ if (!flipperConnection) {
47
+ import_js_flipper.flipperClient.start("player-ui-devtools").then(() => {
48
+ import_js_flipper.flipperClient.addPlugin({
49
+ getId() {
50
+ return "player-ui-devtools";
51
+ },
52
+ onConnect(conn) {
53
+ flipperConnection = conn;
54
+ conn.receive("message::flipper", (message) => {
55
+ listeners.forEach((listener) => listener(message));
56
+ });
57
+ },
58
+ onDisconnect() {
59
+ console.log("Flipper client disconnected");
60
+ flipperConnection = null;
61
+ }
62
+ });
63
+ }).catch((error) => {
64
+ console.error("Failed to start Flipper client", error);
65
+ });
66
+ }
67
+ const sendMessage = async (message) => {
68
+ flipperConnection?.send("message::plugin", message);
69
+ };
70
+ const addListener = (listener) => {
71
+ listeners.push(listener);
72
+ };
73
+ setLayerCallbacks((current) => ({
74
+ sendMessage: [...current.sendMessage, sendMessage],
75
+ addListener: [...current.addListener, addListener],
76
+ removeListener: current.removeListener
77
+ }));
78
+ };
79
+ var useCommunicationLayer = () => {
80
+ const [layerCallbacks, setLayerCallbacks] = (0, import_react.useState)({
81
+ sendMessage: [],
82
+ addListener: [],
83
+ removeListener: []
84
+ });
85
+ (0, import_react.useEffect)(() => {
86
+ startFlipperConnection(setLayerCallbacks);
87
+ let windowListener = null;
88
+ setLayerCallbacks((current) => ({
89
+ sendMessage: [
90
+ ...current.sendMessage,
91
+ async (message) => {
92
+ window.postMessage(message, "*");
93
+ }
94
+ ],
95
+ addListener: [
96
+ ...current.addListener,
97
+ (listener) => {
98
+ windowListener = (event) => listener(event.data);
99
+ window.addEventListener("message", windowListener);
100
+ }
101
+ ],
102
+ removeListener: [
103
+ ...current.removeListener,
104
+ () => {
105
+ if (windowListener) {
106
+ window.removeEventListener("message", windowListener);
107
+ }
108
+ }
109
+ ]
110
+ }));
111
+ }, []);
112
+ const layer = {
113
+ sendMessage: async (message) => {
114
+ layerCallbacks.sendMessage.forEach((callback) => callback(message));
115
+ },
116
+ addListener: (listener) => {
117
+ layerCallbacks.addListener.forEach((callback) => callback(listener));
118
+ },
119
+ removeListener: (listener) => {
120
+ layerCallbacks.removeListener.forEach((callback) => callback(listener));
121
+ }
122
+ };
123
+ return layer;
124
+ };
125
+
126
+ // ../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/devtools/plugins/desktop/common/src/state/reducer.ts
127
+ var import_immer = require("immer");
128
+ var import_merge = require("dset/merge");
129
+ var import_dequal = require("dequal");
130
+ var containsInteraction = (interactions, interaction) => {
131
+ return interactions.filter((i) => (0, import_dequal.dequal)(i, interaction)).length > 0;
132
+ };
133
+ var reducer = (state, transaction) => {
134
+ switch (transaction.type) {
135
+ case "PLAYER_DEVTOOLS_PLAYER_INIT":
136
+ return (0, import_immer.produce)(state, (draft) => {
137
+ const { payload } = transaction;
138
+ (0, import_merge.dset)(draft, "plugins", payload.plugins);
139
+ const message = {
140
+ type: "PLAYER_DEVTOOLS_PLAYER_INIT",
141
+ payload
142
+ };
143
+ draft.messages.push(message);
144
+ });
145
+ case "PLAYER_DEVTOOLS_PLUGIN_DATA_CHANGE":
146
+ return (0, import_immer.produce)(state, (draft) => {
147
+ const { payload } = transaction;
148
+ if (!payload.data)
149
+ return state;
150
+ (0, import_merge.dset)(
151
+ draft.plugins,
152
+ [transaction.payload.pluginID, "flow", "data"],
153
+ transaction.payload.data
154
+ );
155
+ const message = {
156
+ type: "PLAYER_DEVTOOLS_PLUGIN_DATA_CHANGE",
157
+ payload
158
+ };
159
+ draft.messages.push(message);
160
+ });
161
+ case "PLAYER_DEVTOOLS_PLUGIN_INTERACTION":
162
+ return (0, import_immer.produce)(state, (draft) => {
163
+ if (containsInteraction(draft.interactions, transaction))
164
+ return state;
165
+ (0, import_merge.dset)(draft, ["interactions"], [...draft.interactions, transaction]);
166
+ });
167
+ default:
168
+ return state;
169
+ }
170
+ };
171
+
172
+ // ../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/devtools/plugins/desktop/common/src/state/usePluginState.ts
173
+ var import_devtools_messenger = require("@player-tools/devtools-messenger");
174
+ var import_react2 = require("react");
175
+ var import_tiny_uid = __toESM(require("tiny-uid"));
176
+ var playerID = (0, import_tiny_uid.default)();
177
+ var INITIAL_STATE = {
178
+ messages: [],
179
+ plugins: {},
180
+ interactions: []
181
+ };
182
+ var usePluginState = () => {
183
+ const [state, dispatch] = (0, import_react2.useReducer)(reducer, INITIAL_STATE);
184
+ const lastMessageIndex = (0, import_react2.useRef)(-1);
185
+ const { sendMessage, addListener, removeListener } = useCommunicationLayer();
186
+ const messenger = (0, import_react2.useMemo)(() => {
187
+ const options = {
188
+ id: playerID,
189
+ context: "player",
190
+ messageCallback: (message) => dispatch(message),
191
+ sendMessage,
192
+ addListener,
193
+ removeListener,
194
+ logger: console
195
+ };
196
+ return new import_devtools_messenger.Messenger(options);
197
+ }, [addListener, removeListener, sendMessage]);
198
+ (0, import_react2.useEffect)(() => {
199
+ if (state.messages.length > lastMessageIndex.current + 1) {
200
+ const messages = state.messages.slice(
201
+ lastMessageIndex.current + 1,
202
+ state.messages.length
203
+ );
204
+ lastMessageIndex.current = state.messages.length - 1;
205
+ messages.forEach((message) => {
206
+ messenger.sendMessage(message);
207
+ });
208
+ }
209
+ }, [state.messages, messenger]);
210
+ return [state, playerID, dispatch];
211
+ };
212
+ // Annotate the CommonJS export names for ESM import in node:
213
+ 0 && (module.exports = {
214
+ reducer,
215
+ startFlipperConnection,
216
+ useCommunicationLayer,
217
+ usePluginState
218
+ });
219
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/devtools/plugins/desktop/common/src/index.ts","../../../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/devtools/plugins/desktop/common/src/communication-layer/index.ts","../../../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/devtools/plugins/desktop/common/src/state/reducer.ts","../../../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/devtools/plugins/desktop/common/src/state/usePluginState.ts"],"sourcesContent":["export * from \"./communication-layer\";\nexport * from \"./state\";\n","import type {\n ExtensionSupportedEvents,\n MessengerEvent,\n MessengerOptions,\n TransactionMetadata,\n} from \"@player-tools/devtools-types\";\nimport { useEffect, useState } from \"react\";\nimport { type FlipperPluginConnection, flipperClient } from \"js-flipper\";\n\ntype IntoArrays<T> = {\n [P in keyof T]: T[P][];\n};\n\ntype CommunicationLayerMethods = Pick<\n MessengerOptions<ExtensionSupportedEvents>,\n \"sendMessage\" | \"addListener\" | \"removeListener\"\n>;\n\ntype Callbacks = IntoArrays<CommunicationLayerMethods>;\n\n// keep track of the Flipper connection between React renders\nlet flipperConnection: FlipperPluginConnection | null = null;\n\nexport const startFlipperConnection = (\n setLayerCallbacks: (\n value: React.SetStateAction<IntoArrays<CommunicationLayerMethods>>\n ) => void\n) => {\n const listeners: Array<\n (\n message: TransactionMetadata & MessengerEvent<ExtensionSupportedEvents>\n ) => void\n > = [];\n\n if (!flipperConnection) {\n flipperClient\n .start(\"player-ui-devtools\")\n .then(() => {\n flipperClient.addPlugin({\n getId() {\n return \"player-ui-devtools\";\n },\n onConnect(conn) {\n flipperConnection = conn;\n\n conn.receive(\"message::flipper\", (message) => {\n listeners.forEach((listener) => listener(message));\n });\n },\n onDisconnect() {\n console.log(\"Flipper client disconnected\");\n flipperConnection = null;\n },\n });\n })\n .catch((error) => {\n console.error(\"Failed to start Flipper client\", error);\n });\n }\n\n const sendMessage: CommunicationLayerMethods[\"sendMessage\"] = async (\n message\n ) => {\n flipperConnection?.send(\"message::plugin\", message);\n };\n\n const addListener: CommunicationLayerMethods[\"addListener\"] = (listener) => {\n listeners.push(listener);\n };\n\n setLayerCallbacks((current) => ({\n sendMessage: [...current.sendMessage, sendMessage],\n addListener: [...current.addListener, addListener],\n removeListener: current.removeListener,\n }));\n};\n\n/** Web extension communication layer leverage by the @player-tools/devtools-messenger */\nexport const useCommunicationLayer = (): Pick<\n MessengerOptions<ExtensionSupportedEvents>,\n \"sendMessage\" | \"addListener\" | \"removeListener\"\n> => {\n const [layerCallbacks, setLayerCallbacks] = useState<Callbacks>({\n sendMessage: [],\n addListener: [],\n removeListener: [],\n });\n\n useEffect(() => {\n startFlipperConnection(setLayerCallbacks);\n\n let windowListener: null | ((event: MessageEvent) => void) = null;\n\n setLayerCallbacks((current) => ({\n sendMessage: [\n ...current.sendMessage,\n async (message) => {\n window.postMessage(message, \"*\");\n },\n ],\n addListener: [\n ...current.addListener,\n (listener) => {\n windowListener = (event: MessageEvent) => listener(event.data);\n window.addEventListener(\"message\", windowListener);\n },\n ],\n removeListener: [\n ...current.removeListener,\n () => {\n if (windowListener) {\n window.removeEventListener(\"message\", windowListener);\n }\n },\n ],\n }));\n }, []);\n\n const layer: Pick<\n MessengerOptions<ExtensionSupportedEvents>,\n \"sendMessage\" | \"addListener\" | \"removeListener\"\n > = {\n sendMessage: async (message) => {\n layerCallbacks.sendMessage.forEach((callback) => callback(message));\n },\n addListener: (listener) => {\n layerCallbacks.addListener.forEach((callback) => callback(listener));\n },\n removeListener: (listener) => {\n layerCallbacks.removeListener.forEach((callback) => callback(listener));\n },\n };\n\n return layer;\n};\n","import { produce } from \"immer\";\nimport { dset } from \"dset/merge\";\nimport { dequal } from \"dequal\";\nimport type {\n DevtoolsDataChangeEvent,\n DevtoolsPluginsStore,\n ExtensionSupportedEvents,\n PlayerInitEvent,\n Transaction,\n} from \"@player-tools/devtools-types\";\n\nconst containsInteraction = (\n interactions: DevtoolsPluginsStore[\"interactions\"],\n interaction: DevtoolsPluginsStore[\"interactions\"][number]\n) => {\n return interactions.filter((i) => dequal(i, interaction)).length > 0;\n};\n\n/** devtools plugin state reducer */\nexport const reducer = (\n state: DevtoolsPluginsStore,\n transaction: Transaction<ExtensionSupportedEvents>\n): DevtoolsPluginsStore => {\n switch (transaction.type) {\n case \"PLAYER_DEVTOOLS_PLAYER_INIT\":\n return produce(state, (draft) => {\n const { payload } = transaction;\n dset(draft, \"plugins\", payload.plugins);\n\n const message: PlayerInitEvent = {\n type: \"PLAYER_DEVTOOLS_PLAYER_INIT\",\n payload,\n };\n\n draft.messages.push(message);\n });\n case \"PLAYER_DEVTOOLS_PLUGIN_DATA_CHANGE\":\n return produce(state, (draft) => {\n const { payload } = transaction;\n\n if (!payload.data) return state;\n\n dset(\n draft.plugins,\n [transaction.payload.pluginID, \"flow\", \"data\"],\n transaction.payload.data\n );\n\n const message: DevtoolsDataChangeEvent = {\n type: \"PLAYER_DEVTOOLS_PLUGIN_DATA_CHANGE\",\n payload,\n };\n\n draft.messages.push(message);\n });\n case \"PLAYER_DEVTOOLS_PLUGIN_INTERACTION\":\n return produce(state, (draft) => {\n if (containsInteraction(draft.interactions, transaction)) return state;\n\n dset(draft, [\"interactions\"], [...draft.interactions, transaction]);\n });\n default:\n return state;\n }\n};\n","import { Messenger } from \"@player-tools/devtools-messenger\";\nimport type {\n DevtoolsPluginsStore,\n ExtensionSupportedEvents,\n MessengerOptions,\n Transaction,\n} from \"@player-tools/devtools-types\";\nimport { useEffect, useMemo, useReducer, useRef } from \"react\";\nimport uid from \"tiny-uid\";\nimport { useCommunicationLayer } from \"../communication-layer\";\nimport { reducer } from \"./reducer\";\n\nconst playerID = uid();\n\nconst INITIAL_STATE: DevtoolsPluginsStore = {\n messages: [],\n plugins: {},\n interactions: [],\n};\n\n/** devtools plugin state */\nexport const usePluginState = (): [\n DevtoolsPluginsStore,\n string,\n React.Dispatch<Transaction<ExtensionSupportedEvents>>\n] => {\n const [state, dispatch] = useReducer(reducer, INITIAL_STATE);\n const lastMessageIndex = useRef<number>(-1);\n const { sendMessage, addListener, removeListener } = useCommunicationLayer();\n\n const messenger = useMemo(() => {\n const options: MessengerOptions<ExtensionSupportedEvents> = {\n id: playerID,\n context: \"player\",\n messageCallback: (message) =>\n dispatch(message as Parameters<typeof dispatch>[0]),\n sendMessage,\n addListener,\n removeListener,\n logger: console,\n };\n\n return new Messenger(options);\n }, [addListener, removeListener, sendMessage]);\n\n useEffect(() => {\n if (state.messages.length > lastMessageIndex.current + 1) {\n const messages = state.messages.slice(\n lastMessageIndex.current + 1,\n state.messages.length\n );\n lastMessageIndex.current = state.messages.length - 1;\n messages.forEach((message) => {\n messenger.sendMessage(message);\n });\n }\n }, [state.messages, messenger]);\n\n return [state, playerID, dispatch];\n};\n"],"mappings":"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","names":["import_react","uid"]}
@@ -0,0 +1,179 @@
1
+ // ../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/devtools/plugins/desktop/common/src/communication-layer/index.ts
2
+ import { useEffect, useState } from "react";
3
+ import { flipperClient } from "js-flipper";
4
+ var flipperConnection = null;
5
+ var startFlipperConnection = (setLayerCallbacks) => {
6
+ const listeners = [];
7
+ if (!flipperConnection) {
8
+ flipperClient.start("player-ui-devtools").then(() => {
9
+ flipperClient.addPlugin({
10
+ getId() {
11
+ return "player-ui-devtools";
12
+ },
13
+ onConnect(conn) {
14
+ flipperConnection = conn;
15
+ conn.receive("message::flipper", (message) => {
16
+ listeners.forEach((listener) => listener(message));
17
+ });
18
+ },
19
+ onDisconnect() {
20
+ console.log("Flipper client disconnected");
21
+ flipperConnection = null;
22
+ }
23
+ });
24
+ }).catch((error) => {
25
+ console.error("Failed to start Flipper client", error);
26
+ });
27
+ }
28
+ const sendMessage = async (message) => {
29
+ flipperConnection?.send("message::plugin", message);
30
+ };
31
+ const addListener = (listener) => {
32
+ listeners.push(listener);
33
+ };
34
+ setLayerCallbacks((current) => ({
35
+ sendMessage: [...current.sendMessage, sendMessage],
36
+ addListener: [...current.addListener, addListener],
37
+ removeListener: current.removeListener
38
+ }));
39
+ };
40
+ var useCommunicationLayer = () => {
41
+ const [layerCallbacks, setLayerCallbacks] = useState({
42
+ sendMessage: [],
43
+ addListener: [],
44
+ removeListener: []
45
+ });
46
+ useEffect(() => {
47
+ startFlipperConnection(setLayerCallbacks);
48
+ let windowListener = null;
49
+ setLayerCallbacks((current) => ({
50
+ sendMessage: [
51
+ ...current.sendMessage,
52
+ async (message) => {
53
+ window.postMessage(message, "*");
54
+ }
55
+ ],
56
+ addListener: [
57
+ ...current.addListener,
58
+ (listener) => {
59
+ windowListener = (event) => listener(event.data);
60
+ window.addEventListener("message", windowListener);
61
+ }
62
+ ],
63
+ removeListener: [
64
+ ...current.removeListener,
65
+ () => {
66
+ if (windowListener) {
67
+ window.removeEventListener("message", windowListener);
68
+ }
69
+ }
70
+ ]
71
+ }));
72
+ }, []);
73
+ const layer = {
74
+ sendMessage: async (message) => {
75
+ layerCallbacks.sendMessage.forEach((callback) => callback(message));
76
+ },
77
+ addListener: (listener) => {
78
+ layerCallbacks.addListener.forEach((callback) => callback(listener));
79
+ },
80
+ removeListener: (listener) => {
81
+ layerCallbacks.removeListener.forEach((callback) => callback(listener));
82
+ }
83
+ };
84
+ return layer;
85
+ };
86
+
87
+ // ../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/devtools/plugins/desktop/common/src/state/reducer.ts
88
+ import { produce } from "immer";
89
+ import { dset } from "dset/merge";
90
+ import { dequal } from "dequal";
91
+ var containsInteraction = (interactions, interaction) => {
92
+ return interactions.filter((i) => dequal(i, interaction)).length > 0;
93
+ };
94
+ var reducer = (state, transaction) => {
95
+ switch (transaction.type) {
96
+ case "PLAYER_DEVTOOLS_PLAYER_INIT":
97
+ return produce(state, (draft) => {
98
+ const { payload } = transaction;
99
+ dset(draft, "plugins", payload.plugins);
100
+ const message = {
101
+ type: "PLAYER_DEVTOOLS_PLAYER_INIT",
102
+ payload
103
+ };
104
+ draft.messages.push(message);
105
+ });
106
+ case "PLAYER_DEVTOOLS_PLUGIN_DATA_CHANGE":
107
+ return produce(state, (draft) => {
108
+ const { payload } = transaction;
109
+ if (!payload.data)
110
+ return state;
111
+ dset(
112
+ draft.plugins,
113
+ [transaction.payload.pluginID, "flow", "data"],
114
+ transaction.payload.data
115
+ );
116
+ const message = {
117
+ type: "PLAYER_DEVTOOLS_PLUGIN_DATA_CHANGE",
118
+ payload
119
+ };
120
+ draft.messages.push(message);
121
+ });
122
+ case "PLAYER_DEVTOOLS_PLUGIN_INTERACTION":
123
+ return produce(state, (draft) => {
124
+ if (containsInteraction(draft.interactions, transaction))
125
+ return state;
126
+ dset(draft, ["interactions"], [...draft.interactions, transaction]);
127
+ });
128
+ default:
129
+ return state;
130
+ }
131
+ };
132
+
133
+ // ../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/devtools/plugins/desktop/common/src/state/usePluginState.ts
134
+ import { Messenger } from "@player-tools/devtools-messenger";
135
+ import { useEffect as useEffect2, useMemo, useReducer, useRef } from "react";
136
+ import uid from "tiny-uid";
137
+ var playerID = uid();
138
+ var INITIAL_STATE = {
139
+ messages: [],
140
+ plugins: {},
141
+ interactions: []
142
+ };
143
+ var usePluginState = () => {
144
+ const [state, dispatch] = useReducer(reducer, INITIAL_STATE);
145
+ const lastMessageIndex = useRef(-1);
146
+ const { sendMessage, addListener, removeListener } = useCommunicationLayer();
147
+ const messenger = useMemo(() => {
148
+ const options = {
149
+ id: playerID,
150
+ context: "player",
151
+ messageCallback: (message) => dispatch(message),
152
+ sendMessage,
153
+ addListener,
154
+ removeListener,
155
+ logger: console
156
+ };
157
+ return new Messenger(options);
158
+ }, [addListener, removeListener, sendMessage]);
159
+ useEffect2(() => {
160
+ if (state.messages.length > lastMessageIndex.current + 1) {
161
+ const messages = state.messages.slice(
162
+ lastMessageIndex.current + 1,
163
+ state.messages.length
164
+ );
165
+ lastMessageIndex.current = state.messages.length - 1;
166
+ messages.forEach((message) => {
167
+ messenger.sendMessage(message);
168
+ });
169
+ }
170
+ }, [state.messages, messenger]);
171
+ return [state, playerID, dispatch];
172
+ };
173
+ export {
174
+ reducer,
175
+ startFlipperConnection,
176
+ useCommunicationLayer,
177
+ usePluginState
178
+ };
179
+ //# sourceMappingURL=index.mjs.map
package/dist/index.mjs ADDED
@@ -0,0 +1,179 @@
1
+ // ../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/devtools/plugins/desktop/common/src/communication-layer/index.ts
2
+ import { useEffect, useState } from "react";
3
+ import { flipperClient } from "js-flipper";
4
+ var flipperConnection = null;
5
+ var startFlipperConnection = (setLayerCallbacks) => {
6
+ const listeners = [];
7
+ if (!flipperConnection) {
8
+ flipperClient.start("player-ui-devtools").then(() => {
9
+ flipperClient.addPlugin({
10
+ getId() {
11
+ return "player-ui-devtools";
12
+ },
13
+ onConnect(conn) {
14
+ flipperConnection = conn;
15
+ conn.receive("message::flipper", (message) => {
16
+ listeners.forEach((listener) => listener(message));
17
+ });
18
+ },
19
+ onDisconnect() {
20
+ console.log("Flipper client disconnected");
21
+ flipperConnection = null;
22
+ }
23
+ });
24
+ }).catch((error) => {
25
+ console.error("Failed to start Flipper client", error);
26
+ });
27
+ }
28
+ const sendMessage = async (message) => {
29
+ flipperConnection?.send("message::plugin", message);
30
+ };
31
+ const addListener = (listener) => {
32
+ listeners.push(listener);
33
+ };
34
+ setLayerCallbacks((current) => ({
35
+ sendMessage: [...current.sendMessage, sendMessage],
36
+ addListener: [...current.addListener, addListener],
37
+ removeListener: current.removeListener
38
+ }));
39
+ };
40
+ var useCommunicationLayer = () => {
41
+ const [layerCallbacks, setLayerCallbacks] = useState({
42
+ sendMessage: [],
43
+ addListener: [],
44
+ removeListener: []
45
+ });
46
+ useEffect(() => {
47
+ startFlipperConnection(setLayerCallbacks);
48
+ let windowListener = null;
49
+ setLayerCallbacks((current) => ({
50
+ sendMessage: [
51
+ ...current.sendMessage,
52
+ async (message) => {
53
+ window.postMessage(message, "*");
54
+ }
55
+ ],
56
+ addListener: [
57
+ ...current.addListener,
58
+ (listener) => {
59
+ windowListener = (event) => listener(event.data);
60
+ window.addEventListener("message", windowListener);
61
+ }
62
+ ],
63
+ removeListener: [
64
+ ...current.removeListener,
65
+ () => {
66
+ if (windowListener) {
67
+ window.removeEventListener("message", windowListener);
68
+ }
69
+ }
70
+ ]
71
+ }));
72
+ }, []);
73
+ const layer = {
74
+ sendMessage: async (message) => {
75
+ layerCallbacks.sendMessage.forEach((callback) => callback(message));
76
+ },
77
+ addListener: (listener) => {
78
+ layerCallbacks.addListener.forEach((callback) => callback(listener));
79
+ },
80
+ removeListener: (listener) => {
81
+ layerCallbacks.removeListener.forEach((callback) => callback(listener));
82
+ }
83
+ };
84
+ return layer;
85
+ };
86
+
87
+ // ../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/devtools/plugins/desktop/common/src/state/reducer.ts
88
+ import { produce } from "immer";
89
+ import { dset } from "dset/merge";
90
+ import { dequal } from "dequal";
91
+ var containsInteraction = (interactions, interaction) => {
92
+ return interactions.filter((i) => dequal(i, interaction)).length > 0;
93
+ };
94
+ var reducer = (state, transaction) => {
95
+ switch (transaction.type) {
96
+ case "PLAYER_DEVTOOLS_PLAYER_INIT":
97
+ return produce(state, (draft) => {
98
+ const { payload } = transaction;
99
+ dset(draft, "plugins", payload.plugins);
100
+ const message = {
101
+ type: "PLAYER_DEVTOOLS_PLAYER_INIT",
102
+ payload
103
+ };
104
+ draft.messages.push(message);
105
+ });
106
+ case "PLAYER_DEVTOOLS_PLUGIN_DATA_CHANGE":
107
+ return produce(state, (draft) => {
108
+ const { payload } = transaction;
109
+ if (!payload.data)
110
+ return state;
111
+ dset(
112
+ draft.plugins,
113
+ [transaction.payload.pluginID, "flow", "data"],
114
+ transaction.payload.data
115
+ );
116
+ const message = {
117
+ type: "PLAYER_DEVTOOLS_PLUGIN_DATA_CHANGE",
118
+ payload
119
+ };
120
+ draft.messages.push(message);
121
+ });
122
+ case "PLAYER_DEVTOOLS_PLUGIN_INTERACTION":
123
+ return produce(state, (draft) => {
124
+ if (containsInteraction(draft.interactions, transaction))
125
+ return state;
126
+ dset(draft, ["interactions"], [...draft.interactions, transaction]);
127
+ });
128
+ default:
129
+ return state;
130
+ }
131
+ };
132
+
133
+ // ../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/devtools/plugins/desktop/common/src/state/usePluginState.ts
134
+ import { Messenger } from "@player-tools/devtools-messenger";
135
+ import { useEffect as useEffect2, useMemo, useReducer, useRef } from "react";
136
+ import uid from "tiny-uid";
137
+ var playerID = uid();
138
+ var INITIAL_STATE = {
139
+ messages: [],
140
+ plugins: {},
141
+ interactions: []
142
+ };
143
+ var usePluginState = () => {
144
+ const [state, dispatch] = useReducer(reducer, INITIAL_STATE);
145
+ const lastMessageIndex = useRef(-1);
146
+ const { sendMessage, addListener, removeListener } = useCommunicationLayer();
147
+ const messenger = useMemo(() => {
148
+ const options = {
149
+ id: playerID,
150
+ context: "player",
151
+ messageCallback: (message) => dispatch(message),
152
+ sendMessage,
153
+ addListener,
154
+ removeListener,
155
+ logger: console
156
+ };
157
+ return new Messenger(options);
158
+ }, [addListener, removeListener, sendMessage]);
159
+ useEffect2(() => {
160
+ if (state.messages.length > lastMessageIndex.current + 1) {
161
+ const messages = state.messages.slice(
162
+ lastMessageIndex.current + 1,
163
+ state.messages.length
164
+ );
165
+ lastMessageIndex.current = state.messages.length - 1;
166
+ messages.forEach((message) => {
167
+ messenger.sendMessage(message);
168
+ });
169
+ }
170
+ }, [state.messages, messenger]);
171
+ return [state, playerID, dispatch];
172
+ };
173
+ export {
174
+ reducer,
175
+ startFlipperConnection,
176
+ useCommunicationLayer,
177
+ usePluginState
178
+ };
179
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/devtools/plugins/desktop/common/src/communication-layer/index.ts","../../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/devtools/plugins/desktop/common/src/state/reducer.ts","../../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/devtools/plugins/desktop/common/src/state/usePluginState.ts"],"sourcesContent":["import type {\n ExtensionSupportedEvents,\n MessengerEvent,\n MessengerOptions,\n TransactionMetadata,\n} from \"@player-tools/devtools-types\";\nimport { useEffect, useState } from \"react\";\nimport { type FlipperPluginConnection, flipperClient } from \"js-flipper\";\n\ntype IntoArrays<T> = {\n [P in keyof T]: T[P][];\n};\n\ntype CommunicationLayerMethods = Pick<\n MessengerOptions<ExtensionSupportedEvents>,\n \"sendMessage\" | \"addListener\" | \"removeListener\"\n>;\n\ntype Callbacks = IntoArrays<CommunicationLayerMethods>;\n\n// keep track of the Flipper connection between React renders\nlet flipperConnection: FlipperPluginConnection | null = null;\n\nexport const startFlipperConnection = (\n setLayerCallbacks: (\n value: React.SetStateAction<IntoArrays<CommunicationLayerMethods>>\n ) => void\n) => {\n const listeners: Array<\n (\n message: TransactionMetadata & MessengerEvent<ExtensionSupportedEvents>\n ) => void\n > = [];\n\n if (!flipperConnection) {\n flipperClient\n .start(\"player-ui-devtools\")\n .then(() => {\n flipperClient.addPlugin({\n getId() {\n return \"player-ui-devtools\";\n },\n onConnect(conn) {\n flipperConnection = conn;\n\n conn.receive(\"message::flipper\", (message) => {\n listeners.forEach((listener) => listener(message));\n });\n },\n onDisconnect() {\n console.log(\"Flipper client disconnected\");\n flipperConnection = null;\n },\n });\n })\n .catch((error) => {\n console.error(\"Failed to start Flipper client\", error);\n });\n }\n\n const sendMessage: CommunicationLayerMethods[\"sendMessage\"] = async (\n message\n ) => {\n flipperConnection?.send(\"message::plugin\", message);\n };\n\n const addListener: CommunicationLayerMethods[\"addListener\"] = (listener) => {\n listeners.push(listener);\n };\n\n setLayerCallbacks((current) => ({\n sendMessage: [...current.sendMessage, sendMessage],\n addListener: [...current.addListener, addListener],\n removeListener: current.removeListener,\n }));\n};\n\n/** Web extension communication layer leverage by the @player-tools/devtools-messenger */\nexport const useCommunicationLayer = (): Pick<\n MessengerOptions<ExtensionSupportedEvents>,\n \"sendMessage\" | \"addListener\" | \"removeListener\"\n> => {\n const [layerCallbacks, setLayerCallbacks] = useState<Callbacks>({\n sendMessage: [],\n addListener: [],\n removeListener: [],\n });\n\n useEffect(() => {\n startFlipperConnection(setLayerCallbacks);\n\n let windowListener: null | ((event: MessageEvent) => void) = null;\n\n setLayerCallbacks((current) => ({\n sendMessage: [\n ...current.sendMessage,\n async (message) => {\n window.postMessage(message, \"*\");\n },\n ],\n addListener: [\n ...current.addListener,\n (listener) => {\n windowListener = (event: MessageEvent) => listener(event.data);\n window.addEventListener(\"message\", windowListener);\n },\n ],\n removeListener: [\n ...current.removeListener,\n () => {\n if (windowListener) {\n window.removeEventListener(\"message\", windowListener);\n }\n },\n ],\n }));\n }, []);\n\n const layer: Pick<\n MessengerOptions<ExtensionSupportedEvents>,\n \"sendMessage\" | \"addListener\" | \"removeListener\"\n > = {\n sendMessage: async (message) => {\n layerCallbacks.sendMessage.forEach((callback) => callback(message));\n },\n addListener: (listener) => {\n layerCallbacks.addListener.forEach((callback) => callback(listener));\n },\n removeListener: (listener) => {\n layerCallbacks.removeListener.forEach((callback) => callback(listener));\n },\n };\n\n return layer;\n};\n","import { produce } from \"immer\";\nimport { dset } from \"dset/merge\";\nimport { dequal } from \"dequal\";\nimport type {\n DevtoolsDataChangeEvent,\n DevtoolsPluginsStore,\n ExtensionSupportedEvents,\n PlayerInitEvent,\n Transaction,\n} from \"@player-tools/devtools-types\";\n\nconst containsInteraction = (\n interactions: DevtoolsPluginsStore[\"interactions\"],\n interaction: DevtoolsPluginsStore[\"interactions\"][number]\n) => {\n return interactions.filter((i) => dequal(i, interaction)).length > 0;\n};\n\n/** devtools plugin state reducer */\nexport const reducer = (\n state: DevtoolsPluginsStore,\n transaction: Transaction<ExtensionSupportedEvents>\n): DevtoolsPluginsStore => {\n switch (transaction.type) {\n case \"PLAYER_DEVTOOLS_PLAYER_INIT\":\n return produce(state, (draft) => {\n const { payload } = transaction;\n dset(draft, \"plugins\", payload.plugins);\n\n const message: PlayerInitEvent = {\n type: \"PLAYER_DEVTOOLS_PLAYER_INIT\",\n payload,\n };\n\n draft.messages.push(message);\n });\n case \"PLAYER_DEVTOOLS_PLUGIN_DATA_CHANGE\":\n return produce(state, (draft) => {\n const { payload } = transaction;\n\n if (!payload.data) return state;\n\n dset(\n draft.plugins,\n [transaction.payload.pluginID, \"flow\", \"data\"],\n transaction.payload.data\n );\n\n const message: DevtoolsDataChangeEvent = {\n type: \"PLAYER_DEVTOOLS_PLUGIN_DATA_CHANGE\",\n payload,\n };\n\n draft.messages.push(message);\n });\n case \"PLAYER_DEVTOOLS_PLUGIN_INTERACTION\":\n return produce(state, (draft) => {\n if (containsInteraction(draft.interactions, transaction)) return state;\n\n dset(draft, [\"interactions\"], [...draft.interactions, transaction]);\n });\n default:\n return state;\n }\n};\n","import { Messenger } from \"@player-tools/devtools-messenger\";\nimport type {\n DevtoolsPluginsStore,\n ExtensionSupportedEvents,\n MessengerOptions,\n Transaction,\n} from \"@player-tools/devtools-types\";\nimport { useEffect, useMemo, useReducer, useRef } from \"react\";\nimport uid from \"tiny-uid\";\nimport { useCommunicationLayer } from \"../communication-layer\";\nimport { reducer } from \"./reducer\";\n\nconst playerID = uid();\n\nconst INITIAL_STATE: DevtoolsPluginsStore = {\n messages: [],\n plugins: {},\n interactions: [],\n};\n\n/** devtools plugin state */\nexport const usePluginState = (): [\n DevtoolsPluginsStore,\n string,\n React.Dispatch<Transaction<ExtensionSupportedEvents>>\n] => {\n const [state, dispatch] = useReducer(reducer, INITIAL_STATE);\n const lastMessageIndex = useRef<number>(-1);\n const { sendMessage, addListener, removeListener } = useCommunicationLayer();\n\n const messenger = useMemo(() => {\n const options: MessengerOptions<ExtensionSupportedEvents> = {\n id: playerID,\n context: \"player\",\n messageCallback: (message) =>\n dispatch(message as Parameters<typeof dispatch>[0]),\n sendMessage,\n addListener,\n removeListener,\n logger: console,\n };\n\n return new Messenger(options);\n }, [addListener, removeListener, sendMessage]);\n\n useEffect(() => {\n if (state.messages.length > lastMessageIndex.current + 1) {\n const messages = state.messages.slice(\n lastMessageIndex.current + 1,\n state.messages.length\n );\n lastMessageIndex.current = state.messages.length - 1;\n messages.forEach((message) => {\n messenger.sendMessage(message);\n });\n }\n }, [state.messages, messenger]);\n\n return [state, playerID, dispatch];\n};\n"],"mappings":";AAMA,SAAS,WAAW,gBAAgB;AACpC,SAAuC,qBAAqB;AAc5D,IAAI,oBAAoD;AAEjD,IAAM,yBAAyB,CACpC,sBAGG;AACH,QAAM,YAIF,CAAC;AAEL,MAAI,CAAC,mBAAmB;AACtB,kBACG,MAAM,oBAAoB,EAC1B,KAAK,MAAM;AACV,oBAAc,UAAU;AAAA,QACtB,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,QACA,UAAU,MAAM;AACd,8BAAoB;AAEpB,eAAK,QAAQ,oBAAoB,CAAC,YAAY;AAC5C,sBAAU,QAAQ,CAAC,aAAa,SAAS,OAAO,CAAC;AAAA,UACnD,CAAC;AAAA,QACH;AAAA,QACA,eAAe;AACb,kBAAQ,IAAI,6BAA6B;AACzC,8BAAoB;AAAA,QACtB;AAAA,MACF,CAAC;AAAA,IACH,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,cAAQ,MAAM,kCAAkC,KAAK;AAAA,IACvD,CAAC;AAAA,EACL;AAEA,QAAM,cAAwD,OAC5D,YACG;AACH,uBAAmB,KAAK,mBAAmB,OAAO;AAAA,EACpD;AAEA,QAAM,cAAwD,CAAC,aAAa;AAC1E,cAAU,KAAK,QAAQ;AAAA,EACzB;AAEA,oBAAkB,CAAC,aAAa;AAAA,IAC9B,aAAa,CAAC,GAAG,QAAQ,aAAa,WAAW;AAAA,IACjD,aAAa,CAAC,GAAG,QAAQ,aAAa,WAAW;AAAA,IACjD,gBAAgB,QAAQ;AAAA,EAC1B,EAAE;AACJ;AAGO,IAAM,wBAAwB,MAGhC;AACH,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAoB;AAAA,IAC9D,aAAa,CAAC;AAAA,IACd,aAAa,CAAC;AAAA,IACd,gBAAgB,CAAC;AAAA,EACnB,CAAC;AAED,YAAU,MAAM;AACd,2BAAuB,iBAAiB;AAExC,QAAI,iBAAyD;AAE7D,sBAAkB,CAAC,aAAa;AAAA,MAC9B,aAAa;AAAA,QACX,GAAG,QAAQ;AAAA,QACX,OAAO,YAAY;AACjB,iBAAO,YAAY,SAAS,GAAG;AAAA,QACjC;AAAA,MACF;AAAA,MACA,aAAa;AAAA,QACX,GAAG,QAAQ;AAAA,QACX,CAAC,aAAa;AACZ,2BAAiB,CAAC,UAAwB,SAAS,MAAM,IAAI;AAC7D,iBAAO,iBAAiB,WAAW,cAAc;AAAA,QACnD;AAAA,MACF;AAAA,MACA,gBAAgB;AAAA,QACd,GAAG,QAAQ;AAAA,QACX,MAAM;AACJ,cAAI,gBAAgB;AAClB,mBAAO,oBAAoB,WAAW,cAAc;AAAA,UACtD;AAAA,QACF;AAAA,MACF;AAAA,IACF,EAAE;AAAA,EACJ,GAAG,CAAC,CAAC;AAEL,QAAM,QAGF;AAAA,IACF,aAAa,OAAO,YAAY;AAC9B,qBAAe,YAAY,QAAQ,CAAC,aAAa,SAAS,OAAO,CAAC;AAAA,IACpE;AAAA,IACA,aAAa,CAAC,aAAa;AACzB,qBAAe,YAAY,QAAQ,CAAC,aAAa,SAAS,QAAQ,CAAC;AAAA,IACrE;AAAA,IACA,gBAAgB,CAAC,aAAa;AAC5B,qBAAe,eAAe,QAAQ,CAAC,aAAa,SAAS,QAAQ,CAAC;AAAA,IACxE;AAAA,EACF;AAEA,SAAO;AACT;;;ACtIA,SAAS,eAAe;AACxB,SAAS,YAAY;AACrB,SAAS,cAAc;AASvB,IAAM,sBAAsB,CAC1B,cACA,gBACG;AACH,SAAO,aAAa,OAAO,CAAC,MAAM,OAAO,GAAG,WAAW,CAAC,EAAE,SAAS;AACrE;AAGO,IAAM,UAAU,CACrB,OACA,gBACyB;AACzB,UAAQ,YAAY,MAAM;AAAA,IACxB,KAAK;AACH,aAAO,QAAQ,OAAO,CAAC,UAAU;AAC/B,cAAM,EAAE,QAAQ,IAAI;AACpB,aAAK,OAAO,WAAW,QAAQ,OAAO;AAEtC,cAAM,UAA2B;AAAA,UAC/B,MAAM;AAAA,UACN;AAAA,QACF;AAEA,cAAM,SAAS,KAAK,OAAO;AAAA,MAC7B,CAAC;AAAA,IACH,KAAK;AACH,aAAO,QAAQ,OAAO,CAAC,UAAU;AAC/B,cAAM,EAAE,QAAQ,IAAI;AAEpB,YAAI,CAAC,QAAQ;AAAM,iBAAO;AAE1B;AAAA,UACE,MAAM;AAAA,UACN,CAAC,YAAY,QAAQ,UAAU,QAAQ,MAAM;AAAA,UAC7C,YAAY,QAAQ;AAAA,QACtB;AAEA,cAAM,UAAmC;AAAA,UACvC,MAAM;AAAA,UACN;AAAA,QACF;AAEA,cAAM,SAAS,KAAK,OAAO;AAAA,MAC7B,CAAC;AAAA,IACH,KAAK;AACH,aAAO,QAAQ,OAAO,CAAC,UAAU;AAC/B,YAAI,oBAAoB,MAAM,cAAc,WAAW;AAAG,iBAAO;AAEjE,aAAK,OAAO,CAAC,cAAc,GAAG,CAAC,GAAG,MAAM,cAAc,WAAW,CAAC;AAAA,MACpE,CAAC;AAAA,IACH;AACE,aAAO;AAAA,EACX;AACF;;;AChEA,SAAS,iBAAiB;AAO1B,SAAS,aAAAA,YAAW,SAAS,YAAY,cAAc;AACvD,OAAO,SAAS;AAIhB,IAAM,WAAW,IAAI;AAErB,IAAM,gBAAsC;AAAA,EAC1C,UAAU,CAAC;AAAA,EACX,SAAS,CAAC;AAAA,EACV,cAAc,CAAC;AACjB;AAGO,IAAM,iBAAiB,MAIzB;AACH,QAAM,CAAC,OAAO,QAAQ,IAAI,WAAW,SAAS,aAAa;AAC3D,QAAM,mBAAmB,OAAe,EAAE;AAC1C,QAAM,EAAE,aAAa,aAAa,eAAe,IAAI,sBAAsB;AAE3E,QAAM,YAAY,QAAQ,MAAM;AAC9B,UAAM,UAAsD;AAAA,MAC1D,IAAI;AAAA,MACJ,SAAS;AAAA,MACT,iBAAiB,CAAC,YAChB,SAAS,OAAyC;AAAA,MACpD;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,IACV;AAEA,WAAO,IAAI,UAAU,OAAO;AAAA,EAC9B,GAAG,CAAC,aAAa,gBAAgB,WAAW,CAAC;AAE7C,EAAAC,WAAU,MAAM;AACd,QAAI,MAAM,SAAS,SAAS,iBAAiB,UAAU,GAAG;AACxD,YAAM,WAAW,MAAM,SAAS;AAAA,QAC9B,iBAAiB,UAAU;AAAA,QAC3B,MAAM,SAAS;AAAA,MACjB;AACA,uBAAiB,UAAU,MAAM,SAAS,SAAS;AACnD,eAAS,QAAQ,CAAC,YAAY;AAC5B,kBAAU,YAAY,OAAO;AAAA,MAC/B,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,MAAM,UAAU,SAAS,CAAC;AAE9B,SAAO,CAAC,OAAO,UAAU,QAAQ;AACnC;","names":["useEffect","useEffect"]}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@player-tools/devtools-desktop-plugins-common",
3
+ "version": "0.5.3--canary.90.2515",
4
+ "main": "dist/cjs/index.cjs",
5
+ "dependencies": {
6
+ "@player-tools/devtools-messenger": "0.5.3--canary.90.2515",
7
+ "@player-tools/devtools-types": "0.5.3--canary.90.2515",
8
+ "dset": "^3.1.3",
9
+ "dequal": "^2.0.2",
10
+ "immer": "^10.0.3",
11
+ "js-flipper": "^0.212.0",
12
+ "tiny-uid": "^1.1.2",
13
+ "tslib": "^2.6.2"
14
+ },
15
+ "module": "dist/index.legacy-esm.js",
16
+ "types": "types/index.d.ts",
17
+ "sideEffects": false,
18
+ "exports": {
19
+ "./package.json": "./package.json",
20
+ "./dist/index.css": "./dist/index.css",
21
+ ".": {
22
+ "types": "./types/index.d.ts",
23
+ "import": "./dist/index.mjs",
24
+ "default": "./dist/cjs/index.cjs"
25
+ }
26
+ },
27
+ "files": [
28
+ "dist",
29
+ "src",
30
+ "types"
31
+ ],
32
+ "peerDependencies": {
33
+ "react": "^18.2.0",
34
+ "@types/react": "^18.2.51"
35
+ }
36
+ }
@@ -0,0 +1,135 @@
1
+ import type {
2
+ ExtensionSupportedEvents,
3
+ MessengerEvent,
4
+ MessengerOptions,
5
+ TransactionMetadata,
6
+ } from "@player-tools/devtools-types";
7
+ import { useEffect, useState } from "react";
8
+ import { type FlipperPluginConnection, flipperClient } from "js-flipper";
9
+
10
+ type IntoArrays<T> = {
11
+ [P in keyof T]: T[P][];
12
+ };
13
+
14
+ type CommunicationLayerMethods = Pick<
15
+ MessengerOptions<ExtensionSupportedEvents>,
16
+ "sendMessage" | "addListener" | "removeListener"
17
+ >;
18
+
19
+ type Callbacks = IntoArrays<CommunicationLayerMethods>;
20
+
21
+ // keep track of the Flipper connection between React renders
22
+ let flipperConnection: FlipperPluginConnection | null = null;
23
+
24
+ export const startFlipperConnection = (
25
+ setLayerCallbacks: (
26
+ value: React.SetStateAction<IntoArrays<CommunicationLayerMethods>>
27
+ ) => void
28
+ ) => {
29
+ const listeners: Array<
30
+ (
31
+ message: TransactionMetadata & MessengerEvent<ExtensionSupportedEvents>
32
+ ) => void
33
+ > = [];
34
+
35
+ if (!flipperConnection) {
36
+ flipperClient
37
+ .start("player-ui-devtools")
38
+ .then(() => {
39
+ flipperClient.addPlugin({
40
+ getId() {
41
+ return "player-ui-devtools";
42
+ },
43
+ onConnect(conn) {
44
+ flipperConnection = conn;
45
+
46
+ conn.receive("message::flipper", (message) => {
47
+ listeners.forEach((listener) => listener(message));
48
+ });
49
+ },
50
+ onDisconnect() {
51
+ console.log("Flipper client disconnected");
52
+ flipperConnection = null;
53
+ },
54
+ });
55
+ })
56
+ .catch((error) => {
57
+ console.error("Failed to start Flipper client", error);
58
+ });
59
+ }
60
+
61
+ const sendMessage: CommunicationLayerMethods["sendMessage"] = async (
62
+ message
63
+ ) => {
64
+ flipperConnection?.send("message::plugin", message);
65
+ };
66
+
67
+ const addListener: CommunicationLayerMethods["addListener"] = (listener) => {
68
+ listeners.push(listener);
69
+ };
70
+
71
+ setLayerCallbacks((current) => ({
72
+ sendMessage: [...current.sendMessage, sendMessage],
73
+ addListener: [...current.addListener, addListener],
74
+ removeListener: current.removeListener,
75
+ }));
76
+ };
77
+
78
+ /** Web extension communication layer leverage by the @player-tools/devtools-messenger */
79
+ export const useCommunicationLayer = (): Pick<
80
+ MessengerOptions<ExtensionSupportedEvents>,
81
+ "sendMessage" | "addListener" | "removeListener"
82
+ > => {
83
+ const [layerCallbacks, setLayerCallbacks] = useState<Callbacks>({
84
+ sendMessage: [],
85
+ addListener: [],
86
+ removeListener: [],
87
+ });
88
+
89
+ useEffect(() => {
90
+ startFlipperConnection(setLayerCallbacks);
91
+
92
+ let windowListener: null | ((event: MessageEvent) => void) = null;
93
+
94
+ setLayerCallbacks((current) => ({
95
+ sendMessage: [
96
+ ...current.sendMessage,
97
+ async (message) => {
98
+ window.postMessage(message, "*");
99
+ },
100
+ ],
101
+ addListener: [
102
+ ...current.addListener,
103
+ (listener) => {
104
+ windowListener = (event: MessageEvent) => listener(event.data);
105
+ window.addEventListener("message", windowListener);
106
+ },
107
+ ],
108
+ removeListener: [
109
+ ...current.removeListener,
110
+ () => {
111
+ if (windowListener) {
112
+ window.removeEventListener("message", windowListener);
113
+ }
114
+ },
115
+ ],
116
+ }));
117
+ }, []);
118
+
119
+ const layer: Pick<
120
+ MessengerOptions<ExtensionSupportedEvents>,
121
+ "sendMessage" | "addListener" | "removeListener"
122
+ > = {
123
+ sendMessage: async (message) => {
124
+ layerCallbacks.sendMessage.forEach((callback) => callback(message));
125
+ },
126
+ addListener: (listener) => {
127
+ layerCallbacks.addListener.forEach((callback) => callback(listener));
128
+ },
129
+ removeListener: (listener) => {
130
+ layerCallbacks.removeListener.forEach((callback) => callback(listener));
131
+ },
132
+ };
133
+
134
+ return layer;
135
+ };
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./communication-layer";
2
+ export * from "./state";
@@ -0,0 +1,168 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import { reducer } from "../reducer";
3
+ import {
4
+ DevtoolsPluginsStore,
5
+ Transaction,
6
+ DevtoolsDataChangeEvent,
7
+ PlayerInitEvent,
8
+ DevtoolsPluginInteractionEvent,
9
+ } from "@player-tools/devtools-types";
10
+
11
+ const INITIAL_STATE: DevtoolsPluginsStore = {
12
+ messages: [],
13
+ plugins: {},
14
+ interactions: [],
15
+ };
16
+
17
+ let mockTransactionID = 1;
18
+
19
+ const mockTransactionMetadata = {
20
+ timestamp: 0,
21
+ sender: "senderID",
22
+ target: "player",
23
+ context: "devtools",
24
+ _messenger_: true,
25
+ } as const;
26
+
27
+ const mockPlayerInitTransaction: Transaction<PlayerInitEvent> = {
28
+ ...mockTransactionMetadata,
29
+ type: "PLAYER_DEVTOOLS_PLAYER_INIT",
30
+ id: mockTransactionID++,
31
+ payload: {
32
+ plugins: {
33
+ test: {
34
+ id: "test",
35
+ version: "0.0.1",
36
+ name: "Test",
37
+ description: "Test Plugin",
38
+ flow: {
39
+ id: "TestFlow",
40
+ navigation: {
41
+ BEGIN: "TestFlow",
42
+ },
43
+ },
44
+ },
45
+ },
46
+ },
47
+ };
48
+
49
+ const mockPluginDataChangeTransaction: Transaction<DevtoolsDataChangeEvent> = {
50
+ ...mockTransactionMetadata,
51
+ type: "PLAYER_DEVTOOLS_PLUGIN_DATA_CHANGE",
52
+ id: mockTransactionID++,
53
+ payload: {
54
+ data: { foo: "bar" },
55
+ pluginID: "test",
56
+ },
57
+ };
58
+
59
+ const mockPluginInteractionTransaction: Transaction<DevtoolsPluginInteractionEvent> =
60
+ {
61
+ ...mockTransactionMetadata,
62
+ type: "PLAYER_DEVTOOLS_PLUGIN_INTERACTION",
63
+ id: mockTransactionID++,
64
+ payload: {
65
+ type: "evaluate-expression",
66
+ payload: '{"expression": "{{foo.bar}}"}',
67
+ },
68
+ };
69
+
70
+ describe("reducer", () => {
71
+ test("handles PLAYER_DEVTOOLS_PLAYER_INIT", () => {
72
+ const newState = reducer(INITIAL_STATE, mockPlayerInitTransaction);
73
+ expect(newState).toMatchInlineSnapshot(`
74
+ {
75
+ "interactions": [],
76
+ "messages": [
77
+ {
78
+ "payload": {
79
+ "plugins": {
80
+ "test": {
81
+ "description": "Test Plugin",
82
+ "flow": {
83
+ "id": "TestFlow",
84
+ "navigation": {
85
+ "BEGIN": "TestFlow",
86
+ },
87
+ },
88
+ "id": "test",
89
+ "name": "Test",
90
+ "version": "0.0.1",
91
+ },
92
+ },
93
+ },
94
+ "type": "PLAYER_DEVTOOLS_PLAYER_INIT",
95
+ },
96
+ ],
97
+ "plugins": {
98
+ "test": {
99
+ "description": "Test Plugin",
100
+ "flow": {
101
+ "id": "TestFlow",
102
+ "navigation": {
103
+ "BEGIN": "TestFlow",
104
+ },
105
+ },
106
+ "id": "test",
107
+ "name": "Test",
108
+ "version": "0.0.1",
109
+ },
110
+ },
111
+ }
112
+ `);
113
+ });
114
+
115
+ test("handles PLAYER_DEVTOOLS_PLUGIN_DATA_CHANGE", () => {
116
+ const newState = reducer(INITIAL_STATE, mockPluginDataChangeTransaction);
117
+ expect(newState).toMatchInlineSnapshot(`
118
+ {
119
+ "interactions": [],
120
+ "messages": [
121
+ {
122
+ "payload": {
123
+ "data": {
124
+ "foo": "bar",
125
+ },
126
+ "pluginID": "test",
127
+ },
128
+ "type": "PLAYER_DEVTOOLS_PLUGIN_DATA_CHANGE",
129
+ },
130
+ ],
131
+ "plugins": {
132
+ "test": {
133
+ "flow": {
134
+ "data": {
135
+ "foo": "bar",
136
+ },
137
+ },
138
+ },
139
+ },
140
+ }
141
+ `);
142
+ });
143
+
144
+ test("handles PLAYER_DEVTOOLS_PLUGIN_INTERACTION", () => {
145
+ const newState = reducer(INITIAL_STATE, mockPluginInteractionTransaction);
146
+ expect(newState).toMatchInlineSnapshot(`
147
+ {
148
+ "interactions": [
149
+ {
150
+ "_messenger_": true,
151
+ "context": "devtools",
152
+ "id": 3,
153
+ "payload": {
154
+ "payload": "{"expression": "{{foo.bar}}"}",
155
+ "type": "evaluate-expression",
156
+ },
157
+ "sender": "senderID",
158
+ "target": "player",
159
+ "timestamp": 0,
160
+ "type": "PLAYER_DEVTOOLS_PLUGIN_INTERACTION",
161
+ },
162
+ ],
163
+ "messages": [],
164
+ "plugins": {},
165
+ }
166
+ `);
167
+ });
168
+ });
@@ -0,0 +1,2 @@
1
+ export * from "./reducer";
2
+ export * from "./usePluginState";
@@ -0,0 +1,65 @@
1
+ import { produce } from "immer";
2
+ import { dset } from "dset/merge";
3
+ import { dequal } from "dequal";
4
+ import type {
5
+ DevtoolsDataChangeEvent,
6
+ DevtoolsPluginsStore,
7
+ ExtensionSupportedEvents,
8
+ PlayerInitEvent,
9
+ Transaction,
10
+ } from "@player-tools/devtools-types";
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
+ dset(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
+ dset(
44
+ draft.plugins,
45
+ [transaction.payload.pluginID, "flow", "data"],
46
+ transaction.payload.data
47
+ );
48
+
49
+ const message: DevtoolsDataChangeEvent = {
50
+ type: "PLAYER_DEVTOOLS_PLUGIN_DATA_CHANGE",
51
+ payload,
52
+ };
53
+
54
+ draft.messages.push(message);
55
+ });
56
+ case "PLAYER_DEVTOOLS_PLUGIN_INTERACTION":
57
+ return produce(state, (draft) => {
58
+ if (containsInteraction(draft.interactions, transaction)) return state;
59
+
60
+ dset(draft, ["interactions"], [...draft.interactions, transaction]);
61
+ });
62
+ default:
63
+ return state;
64
+ }
65
+ };
@@ -0,0 +1,60 @@
1
+ import { Messenger } from "@player-tools/devtools-messenger";
2
+ import type {
3
+ DevtoolsPluginsStore,
4
+ ExtensionSupportedEvents,
5
+ MessengerOptions,
6
+ Transaction,
7
+ } from "@player-tools/devtools-types";
8
+ import { useEffect, useMemo, useReducer, useRef } from "react";
9
+ import uid from "tiny-uid";
10
+ import { useCommunicationLayer } from "../communication-layer";
11
+ import { reducer } from "./reducer";
12
+
13
+ const playerID = uid();
14
+
15
+ const INITIAL_STATE: DevtoolsPluginsStore = {
16
+ messages: [],
17
+ plugins: {},
18
+ interactions: [],
19
+ };
20
+
21
+ /** devtools plugin state */
22
+ export const usePluginState = (): [
23
+ DevtoolsPluginsStore,
24
+ string,
25
+ React.Dispatch<Transaction<ExtensionSupportedEvents>>
26
+ ] => {
27
+ const [state, dispatch] = useReducer(reducer, INITIAL_STATE);
28
+ const lastMessageIndex = useRef<number>(-1);
29
+ const { sendMessage, addListener, removeListener } = useCommunicationLayer();
30
+
31
+ const messenger = useMemo(() => {
32
+ const options: MessengerOptions<ExtensionSupportedEvents> = {
33
+ id: playerID,
34
+ context: "player",
35
+ messageCallback: (message) =>
36
+ dispatch(message as Parameters<typeof dispatch>[0]),
37
+ sendMessage,
38
+ addListener,
39
+ removeListener,
40
+ logger: console,
41
+ };
42
+
43
+ return new Messenger(options);
44
+ }, [addListener, removeListener, sendMessage]);
45
+
46
+ useEffect(() => {
47
+ if (state.messages.length > lastMessageIndex.current + 1) {
48
+ const messages = state.messages.slice(
49
+ lastMessageIndex.current + 1,
50
+ state.messages.length
51
+ );
52
+ lastMessageIndex.current = state.messages.length - 1;
53
+ messages.forEach((message) => {
54
+ messenger.sendMessage(message);
55
+ });
56
+ }
57
+ }, [state.messages, messenger]);
58
+
59
+ return [state, playerID, dispatch];
60
+ };
@@ -0,0 +1,10 @@
1
+ import type { ExtensionSupportedEvents, MessengerOptions } from "@player-tools/devtools-types";
2
+ type IntoArrays<T> = {
3
+ [P in keyof T]: T[P][];
4
+ };
5
+ type CommunicationLayerMethods = Pick<MessengerOptions<ExtensionSupportedEvents>, "sendMessage" | "addListener" | "removeListener">;
6
+ export declare const startFlipperConnection: (setLayerCallbacks: (value: React.SetStateAction<IntoArrays<CommunicationLayerMethods>>) => void) => void;
7
+ /** Web extension communication layer leverage by the @player-tools/devtools-messenger */
8
+ export declare const useCommunicationLayer: () => Pick<MessengerOptions<ExtensionSupportedEvents>, "sendMessage" | "addListener" | "removeListener">;
9
+ export {};
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,3 @@
1
+ export * from "./communication-layer";
2
+ export * from "./state";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,3 @@
1
+ export * from "./reducer";
2
+ export * from "./usePluginState";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,4 @@
1
+ import type { DevtoolsPluginsStore, ExtensionSupportedEvents, Transaction } from "@player-tools/devtools-types";
2
+ /** devtools plugin state reducer */
3
+ export declare const reducer: (state: DevtoolsPluginsStore, transaction: Transaction<ExtensionSupportedEvents>) => DevtoolsPluginsStore;
4
+ //# sourceMappingURL=reducer.d.ts.map
@@ -0,0 +1,8 @@
1
+ import type { DevtoolsPluginsStore, ExtensionSupportedEvents, Transaction } from "@player-tools/devtools-types";
2
+ /** devtools plugin state */
3
+ export declare const usePluginState: () => [
4
+ DevtoolsPluginsStore,
5
+ string,
6
+ React.Dispatch<Transaction<ExtensionSupportedEvents>>
7
+ ];
8
+ //# sourceMappingURL=usePluginState.d.ts.map