@player-devtools/basic-plugin 0.0.2-next.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.
@@ -0,0 +1,59 @@
1
+ import { ExpressionEvaluator } from "@player-ui/player";
2
+ import { generateUUID } from "@player-devtools/plugin";
3
+ import { Evaluation } from "../types";
4
+
5
+ /**
6
+ * Creates a function to evaluate expressions using an nullable Player-UI's ExpressionEvaluator.
7
+ *
8
+ * This function factory takes an nullable WeakRef to an ExpressionEvaluator and returns
9
+ * a new function that can be used to evaluate expressions. If the ExpressionEvaluator is
10
+ * not available, it returns an error Evaluation. Otherwise, it attempts to evaluate the
11
+ * expression. If the evaluation is successful, it returns the result. If there's an error
12
+ * during evaluation, it captures the error and returns it as part of the Evaluation object.
13
+ */
14
+ export const getEvaluateExpression =
15
+ (expressionEvaluator?: WeakRef<ExpressionEvaluator>) =>
16
+ (expression: string): Evaluation => {
17
+ if (!expressionEvaluator) {
18
+ return {
19
+ id: generateUUID(),
20
+ severity: "error",
21
+ result: "Expression evaluator not available",
22
+ expression,
23
+ };
24
+ }
25
+
26
+ let result: Evaluation = {
27
+ id: generateUUID(),
28
+ severity: "error",
29
+ result: "Something went wrong",
30
+ expression,
31
+ };
32
+
33
+ try {
34
+ expressionEvaluator.deref()?.hooks.onError.intercept({
35
+ call: (error: Error) => {
36
+ throw error;
37
+ },
38
+ });
39
+
40
+ const evaluatorResult = expressionEvaluator.deref()?.evaluate(expression);
41
+
42
+ result = {
43
+ id: generateUUID(),
44
+ result: evaluatorResult,
45
+ expression,
46
+ };
47
+ } catch (error) {
48
+ if (error instanceof Error) {
49
+ result = {
50
+ id: generateUUID(),
51
+ severity: "error",
52
+ result: error.message,
53
+ expression,
54
+ };
55
+ }
56
+ }
57
+
58
+ return result;
59
+ };
@@ -0,0 +1 @@
1
+ export { getEvaluateExpression } from "./getEvaluateExpression";
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { BasicDevtoolsPlugin } from "./plugin";
package/src/plugin.ts ADDED
@@ -0,0 +1,194 @@
1
+ import {
2
+ INTERACTIONS,
3
+ BasicPluginData,
4
+ } from "@player-devtools/basic-plugin-content";
5
+ import {
6
+ DevtoolsPlugin,
7
+ DevtoolsPluginOptions,
8
+ generateUUID,
9
+ } from "@player-devtools/plugin";
10
+ import type { DevtoolsPluginInteractionEvent } from "@player-devtools/types";
11
+ import { dsetAssign } from "@player-devtools/utils";
12
+ import type {
13
+ DataController,
14
+ ExpressionEvaluator,
15
+ Flow,
16
+ Player,
17
+ ViewInstance,
18
+ Logger,
19
+ } from "@player-ui/player";
20
+ import { produce } from "immer";
21
+
22
+ import { Evaluation } from "./types";
23
+
24
+ /** Taps into the Player and ReactPlayer hooks and leverage the WrapperComponent to define and process the content. */
25
+ export class BasicDevtoolsPlugin extends DevtoolsPlugin {
26
+ constructor(options: Omit<DevtoolsPluginOptions, "pluginData">) {
27
+ super({
28
+ ...options,
29
+ pluginData: BasicPluginData,
30
+ });
31
+ }
32
+
33
+ name = "BasicDevtoolsPlugin";
34
+
35
+ data: Record<string, unknown> = {};
36
+
37
+ playerConfig: Record<string, unknown> = {};
38
+
39
+ logs: {
40
+ severity: string;
41
+ message: unknown;
42
+ }[] = [];
43
+
44
+ flow?: Flow;
45
+
46
+ logger?: WeakRef<Logger>;
47
+
48
+ expressionEvaluator?: WeakRef<ExpressionEvaluator>;
49
+
50
+ view?: WeakRef<ViewInstance>;
51
+
52
+ dataController?: WeakRef<DataController>;
53
+
54
+ overrideFlow?: Player["start"];
55
+
56
+ apply(player: Player): void {
57
+ this.logger = new WeakRef(player.logger);
58
+
59
+ if (!this.checkIfDevtoolsIsActive()) return;
60
+
61
+ this.options.pluginData.flow.data!.playerConfig = {
62
+ version: player.getVersion(),
63
+ plugins: player.getPlugins().map((plugin) => plugin.name),
64
+ };
65
+
66
+ super.apply(player);
67
+
68
+ // Config
69
+ this.playerConfig = {
70
+ version: player.getVersion(),
71
+ plugins: player.getPlugins().map((plugin) => plugin.name),
72
+ };
73
+
74
+ this.dispatchDataUpdate({ playerConfig: this.playerConfig });
75
+
76
+ // Data
77
+ player.hooks.dataController.tap(this.name, (dataController) => {
78
+ dataController.hooks.onUpdate.tap(this.name, (updates) => {
79
+ this.data = produce(this.data, (draft) => {
80
+ updates.forEach(({ binding, newValue }) => {
81
+ dsetAssign(draft, ["data", ...binding.asArray()], newValue);
82
+ });
83
+ });
84
+
85
+ this.dispatchDataUpdate({ data: this.data });
86
+ });
87
+ });
88
+
89
+ player.logger.hooks.log.tap(this.name, (severity, message) => {
90
+ this.logs = [...this.logs, { severity, message }];
91
+
92
+ this.dispatchDataUpdate({ logs: this.logs });
93
+ });
94
+
95
+ // Flow
96
+ player.hooks.onStart.tap(this.name, (f) => {
97
+ this.flow = JSON.parse(JSON.stringify(f));
98
+
99
+ this.dispatchDataUpdate({ flow: this.flow });
100
+ });
101
+
102
+ // View
103
+ player.hooks.view.tap(this.name, (view) => {
104
+ this.view = new WeakRef(view);
105
+ });
106
+
107
+ // Expression evaluator
108
+ player.hooks.expressionEvaluator.tap(this.name, (evaluator) => {
109
+ this.expressionEvaluator = new WeakRef(evaluator);
110
+ });
111
+
112
+ // Override flow
113
+ this.overrideFlow = player.start.bind(player);
114
+ }
115
+
116
+ private evaluateExpression(expression: string): Evaluation {
117
+ const evaluator = this.expressionEvaluator?.deref();
118
+
119
+ if (!evaluator) {
120
+ return {
121
+ id: generateUUID(),
122
+ severity: "error",
123
+ result: "Expression evaluator not available",
124
+ expression,
125
+ };
126
+ }
127
+
128
+ try {
129
+ evaluator.hooks.onError.intercept({
130
+ call: (error: Error) => {
131
+ throw error;
132
+ },
133
+ });
134
+
135
+ const evaluatorResult = evaluator.evaluate(expression);
136
+
137
+ return {
138
+ id: generateUUID(),
139
+ result: evaluatorResult,
140
+ expression,
141
+ };
142
+ } catch (error) {
143
+ const message =
144
+ error instanceof Error
145
+ ? error.message
146
+ : String(error ?? "Something went wrong");
147
+ return {
148
+ id: generateUUID(),
149
+ severity: "error",
150
+ result: message,
151
+ expression,
152
+ };
153
+ }
154
+ }
155
+
156
+ processInteraction(interaction: DevtoolsPluginInteractionEvent): void {
157
+ // invokes mobile specific handlers
158
+ super.processInteraction(interaction);
159
+
160
+ const {
161
+ payload: { type, payload },
162
+ } = interaction;
163
+ if (
164
+ type === INTERACTIONS.EVALUATE_EXPRESSION &&
165
+ this.expressionEvaluator &&
166
+ payload
167
+ ) {
168
+ const result = this.evaluateExpression(payload);
169
+ const current: Array<Evaluation> =
170
+ (this.store.getState()?.plugins?.[this.pluginID]?.flow?.data
171
+ ?.history as Array<Evaluation>) || [];
172
+
173
+ this.dispatchDataUpdate({ history: [...current, result] });
174
+
175
+ return;
176
+ }
177
+
178
+ if (type === INTERACTIONS.OVERRIDE_FLOW && payload && this.overrideFlow) {
179
+ let newFlow: Flow | undefined;
180
+
181
+ try {
182
+ newFlow = JSON.parse(payload);
183
+ } catch (e) {
184
+ this.logger?.deref()?.error(this.name, "Error parsing new flow", e);
185
+ }
186
+
187
+ if (newFlow) {
188
+ this.overrideFlow(newFlow);
189
+ }
190
+
191
+ return;
192
+ }
193
+ }
194
+ }
package/src/types.ts ADDED
@@ -0,0 +1,10 @@
1
+ export interface Evaluation {
2
+ /** A unique key for this expression */
3
+ id: string;
4
+ /** The expression itself */
5
+ expression: string;
6
+ /** The result for a given expression */
7
+ result?: unknown;
8
+ /** Whether there were any errors with the result */
9
+ severity?: "error" | "warning";
10
+ }
@@ -0,0 +1,13 @@
1
+ import { ExpressionEvaluator } from "@player-ui/player";
2
+ import { Evaluation } from "../types";
3
+ /**
4
+ * Creates a function to evaluate expressions using an nullable Player-UI's ExpressionEvaluator.
5
+ *
6
+ * This function factory takes an nullable WeakRef to an ExpressionEvaluator and returns
7
+ * a new function that can be used to evaluate expressions. If the ExpressionEvaluator is
8
+ * not available, it returns an error Evaluation. Otherwise, it attempts to evaluate the
9
+ * expression. If the evaluation is successful, it returns the result. If there's an error
10
+ * during evaluation, it captures the error and returns it as part of the Evaluation object.
11
+ */
12
+ export declare const getEvaluateExpression: (expressionEvaluator?: WeakRef<ExpressionEvaluator>) => (expression: string) => Evaluation;
13
+ //# sourceMappingURL=getEvaluateExpression.d.ts.map
@@ -0,0 +1,2 @@
1
+ export { getEvaluateExpression } from "./getEvaluateExpression";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ export { BasicDevtoolsPlugin } from "./plugin";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,24 @@
1
+ import { DevtoolsPlugin, DevtoolsPluginOptions } from "@player-devtools/plugin";
2
+ import type { DevtoolsPluginInteractionEvent } from "@player-devtools/types";
3
+ import type { DataController, ExpressionEvaluator, Flow, Player, ViewInstance, Logger } from "@player-ui/player";
4
+ /** Taps into the Player and ReactPlayer hooks and leverage the WrapperComponent to define and process the content. */
5
+ export declare class BasicDevtoolsPlugin extends DevtoolsPlugin {
6
+ constructor(options: Omit<DevtoolsPluginOptions, "pluginData">);
7
+ name: string;
8
+ data: Record<string, unknown>;
9
+ playerConfig: Record<string, unknown>;
10
+ logs: {
11
+ severity: string;
12
+ message: unknown;
13
+ }[];
14
+ flow?: Flow;
15
+ logger?: WeakRef<Logger>;
16
+ expressionEvaluator?: WeakRef<ExpressionEvaluator>;
17
+ view?: WeakRef<ViewInstance>;
18
+ dataController?: WeakRef<DataController>;
19
+ overrideFlow?: Player["start"];
20
+ apply(player: Player): void;
21
+ private evaluateExpression;
22
+ processInteraction(interaction: DevtoolsPluginInteractionEvent): void;
23
+ }
24
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1,11 @@
1
+ export interface Evaluation {
2
+ /** A unique key for this expression */
3
+ id: string;
4
+ /** The expression itself */
5
+ expression: string;
6
+ /** The result for a given expression */
7
+ result?: unknown;
8
+ /** Whether there were any errors with the result */
9
+ severity?: "error" | "warning";
10
+ }
11
+ //# sourceMappingURL=types.d.ts.map