@sigmacomputing/plugin 1.1.1 → 1.2.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.
- package/CHANGELOG.md +0 -14
- package/LICENSE +1 -1
- package/README.md +19 -24
- package/dist/cjs/index.cjs +506 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/index.d.cts +438 -0
- package/dist/esm/index.d.ts +438 -0
- package/dist/esm/index.js +466 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/umd/sigmacomputing-plugin.umd.js +2 -0
- package/dist/umd/sigmacomputing-plugin.umd.js.map +1 -0
- package/package.json +69 -36
- package/src/client/initialize.ts +280 -0
- package/src/client.ts +3 -0
- package/src/globals.d.ts +2 -0
- package/{dist/index.d.ts → src/index.ts} +1 -1
- package/src/react/Context.ts +6 -0
- package/src/react/Provider.tsx +20 -0
- package/src/react/hooks.ts +298 -0
- package/src/react.ts +3 -0
- package/src/types.ts +412 -0
- package/src/utils/deepEqual.ts +23 -0
- package/src/utils/error.ts +10 -0
- package/src/utils/polyfillRequestAnimationFrame.ts +13 -0
- package/dist/client/initialize.d.ts +0 -3
- package/dist/client/initialize.d.ts.map +0 -1
- package/dist/client/initialize.js +0 -223
- package/dist/client.d.ts +0 -2
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -5
- package/dist/error.d.ts +0 -3
- package/dist/error.d.ts.map +0 -1
- package/dist/error.js +0 -9
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -22
- package/dist/react/Context.d.ts +0 -4
- package/dist/react/Context.d.ts.map +0 -1
- package/dist/react/Context.js +0 -6
- package/dist/react/Provider.d.ts +0 -8
- package/dist/react/Provider.d.ts.map +0 -1
- package/dist/react/Provider.js +0 -9
- package/dist/react/hooks.d.ts +0 -83
- package/dist/react/hooks.d.ts.map +0 -1
- package/dist/react/hooks.js +0 -231
- package/dist/react.d.ts +0 -3
- package/dist/react.d.ts.map +0 -1
- package/dist/react.js +0 -20
- package/dist/types.d.ts +0 -332
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/utils/deepEqual.d.ts +0 -2
- package/dist/utils/deepEqual.d.ts.map +0 -1
- package/dist/utils/deepEqual.js +0 -28
- package/dist/utils/polyfillRequestAnimationFrame.d.ts +0 -8
- package/dist/utils/polyfillRequestAnimationFrame.d.ts.map +0 -1
- package/dist/utils/polyfillRequestAnimationFrame.js +0 -16
package/CHANGELOG.md
CHANGED
|
@@ -9,17 +9,3 @@ request. Read our `CONTRIBUTING.md` guide to get started.
|
|
|
9
9
|
- `@sigmacomputing/plugin-types` has been merged with `@sigmacomputing/plugin`
|
|
10
10
|
and will no longer received updates in the future. Please use only
|
|
11
11
|
`@sigmacomputing/plugin` going forward.
|
|
12
|
-
|
|
13
|
-
- All `react` exports (`SigmaClientProvider` and all hooks) have been moved to
|
|
14
|
-
a separate explicit export. This will allow better bundle splitting by not
|
|
15
|
-
including `react` specific code for plugins that do not use `react`.
|
|
16
|
-
|
|
17
|
-
```ts
|
|
18
|
-
// before
|
|
19
|
-
import { SigmaClientProvider, usePlugin } from '@sigmacomputing/plugin';
|
|
20
|
-
|
|
21
|
-
// after
|
|
22
|
-
import { SigmaClientProvider, usePlugin } from '@sigmacomputing/plugin/react';
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
All types can be imported from either `@sigmacomputing/plugin` or `@sigmacomputing/plugin/react`
|
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -32,7 +32,6 @@ To test your plugin in Sigma Plugin Dev Playground, you must:
|
|
|
32
32
|
To test a development version of a registered plugin, you must:
|
|
33
33
|
|
|
34
34
|
- Have either:
|
|
35
|
-
|
|
36
35
|
- An Admin account type
|
|
37
36
|
- A custom account type that supports plugin developer feature permissions
|
|
38
37
|
|
|
@@ -106,7 +105,6 @@ and a React Hooks API.
|
|
|
106
105
|
```
|
|
107
106
|
|
|
108
107
|
7. Start developing:
|
|
109
|
-
|
|
110
108
|
- Get started with Sigma’s Plugin APIs.
|
|
111
109
|
- Test your plugin directly in a Sigma workbook using the Sigma Plugin Dev
|
|
112
110
|
Playground.
|
|
@@ -137,7 +135,7 @@ Before you start:
|
|
|
137
135
|
> following command in your terminal:
|
|
138
136
|
>
|
|
139
137
|
> ```sh
|
|
140
|
-
> yarn && yarn
|
|
138
|
+
> yarn && yarn dev
|
|
141
139
|
> ```
|
|
142
140
|
|
|
143
141
|
1. Create/open a workbook.
|
|
@@ -264,14 +262,14 @@ type CustomPluginConfigOptions =
|
|
|
264
262
|
label?: string;
|
|
265
263
|
}
|
|
266
264
|
| {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
265
|
+
type: 'action-effect';
|
|
266
|
+
name: string;
|
|
267
|
+
label?: string;
|
|
268
|
+
}
|
|
271
269
|
| {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
270
|
+
type: 'url-parameter';
|
|
271
|
+
name: string;
|
|
272
|
+
};
|
|
275
273
|
```
|
|
276
274
|
|
|
277
275
|
</details>
|
|
@@ -488,9 +486,9 @@ interface PluginInstance<T> {
|
|
|
488
486
|
registerEffect(configId: string, effect: Function): void;
|
|
489
487
|
|
|
490
488
|
/**
|
|
491
|
-
* Overrider function for Config
|
|
489
|
+
* Overrider function for Config loading state
|
|
492
490
|
*/
|
|
493
|
-
setLoadingState(
|
|
491
|
+
setLoadingState(isLoading: boolean): void;
|
|
494
492
|
|
|
495
493
|
/**
|
|
496
494
|
* Allows users to subscribe to changes in the passed in variable
|
|
@@ -655,8 +653,8 @@ Arguments
|
|
|
655
653
|
|
|
656
654
|
#### useLoadingState()
|
|
657
655
|
|
|
658
|
-
Gets the current plugin's loading
|
|
659
|
-
|
|
656
|
+
Gets the current plugin's loading state and a setter. Call the setter with
|
|
657
|
+
`false` when your plugin has finished loading
|
|
660
658
|
|
|
661
659
|
```ts
|
|
662
660
|
function useLoadingState(
|
|
@@ -666,7 +664,7 @@ function useLoadingState(
|
|
|
666
664
|
|
|
667
665
|
Arguments
|
|
668
666
|
|
|
669
|
-
- `initialState : boolean` - Initial
|
|
667
|
+
- `initialState : boolean` - Initial loading state (typically `true`; then set to `false` when ready)
|
|
670
668
|
|
|
671
669
|
#### useElementColumns()
|
|
672
670
|
|
|
@@ -814,9 +812,12 @@ console.log(urlParam?.value);
|
|
|
814
812
|
client.config.setUrlParameter('myParamId', 'new-value');
|
|
815
813
|
|
|
816
814
|
// Subscribe to changes
|
|
817
|
-
const unsubscribe = client.config.subscribeToUrlParameter(
|
|
818
|
-
|
|
819
|
-
|
|
815
|
+
const unsubscribe = client.config.subscribeToUrlParameter(
|
|
816
|
+
'myParamId',
|
|
817
|
+
urlParam => {
|
|
818
|
+
console.log('URL parameter updated:', urlParam.value);
|
|
819
|
+
},
|
|
820
|
+
);
|
|
820
821
|
```
|
|
821
822
|
|
|
822
823
|
#### useInteraction()
|
|
@@ -904,33 +905,27 @@ Github.
|
|
|
904
905
|
### Available Plugins
|
|
905
906
|
|
|
906
907
|
- **Recharts Bar Chart** - A basic bar chart built with the Recharts library.
|
|
907
|
-
|
|
908
908
|
- [Source Code](https://github.com/sigmacomputing/sigma-sample-plugins/tree/main/sample-plugin-bar-chart)
|
|
909
909
|
- Production URL: https://sigma-sample-bar-chart-54049.netlify.app/
|
|
910
910
|
|
|
911
911
|
- **D3 Candlestick** - A candlestick visualization built with D3.
|
|
912
|
-
|
|
913
912
|
- [Source Code](https://github.com/sigmacomputing/sigma-sample-plugins/tree/main/sample-plugin-bar-chart)
|
|
914
913
|
- Production URL: https://sigma-sample-candlestick-chart-1664e5.netlify.app/
|
|
915
914
|
|
|
916
915
|
- **Narrative Science Quill** - Demonstrates secure text entry.
|
|
917
|
-
|
|
918
916
|
- [Source Code]()
|
|
919
917
|
- Production URL: https://narrativescience-quill-3ee312.netlify.app/
|
|
920
918
|
|
|
921
919
|
- **D3 Graph** - Demonstrates usage of multiple data sources and in-memory
|
|
922
920
|
joins.
|
|
923
|
-
|
|
924
921
|
- [Source Code](https://github.com/sigmacomputing/sigma-sample-plugins/tree/main/d3-graph)
|
|
925
922
|
- Production URL: https://d3-graph-3a0d0f.netlify.app/
|
|
926
923
|
|
|
927
924
|
- **D3 Sunburst** - A sunburst visualization built with D3.
|
|
928
|
-
|
|
929
925
|
- [Source Code](https://github.com/sigmacomputing/sigma-sample-plugins/tree/main/d3-sunburst)
|
|
930
926
|
- Production URL: https://d3-sunburst-b97c7c.netlify.app/
|
|
931
927
|
|
|
932
928
|
- **Frappe Heatmap** - A basic Frappe visualization example.
|
|
933
|
-
|
|
934
929
|
- [Source Code](https://github.com/sigmacomputing/sigma-sample-plugins/tree/main/frappe-heatmap)
|
|
935
930
|
- Production URL: https://frappe-heatmap-9a4163.netlify.app/
|
|
936
931
|
|
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
+
get: ((k) => from[k]).bind(null, key),
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
20
|
+
value: mod,
|
|
21
|
+
enumerable: true
|
|
22
|
+
}) : target, mod));
|
|
23
|
+
//#endregion
|
|
24
|
+
let react = require("react");
|
|
25
|
+
let react$1 = __toESM(react, 1);
|
|
26
|
+
react = __toESM(react);
|
|
27
|
+
//#region src/utils/deepEqual.ts
|
|
28
|
+
function isObject(obj) {
|
|
29
|
+
if (typeof obj === "object" && obj != null) return true;
|
|
30
|
+
else return false;
|
|
31
|
+
}
|
|
32
|
+
function deepEqual(obj1, obj2) {
|
|
33
|
+
if (obj1 === obj2) return true;
|
|
34
|
+
else if (isObject(obj1) && isObject(obj2)) {
|
|
35
|
+
if (Object.keys(obj1).length !== Object.keys(obj2).length) return false;
|
|
36
|
+
for (const prop in obj1) if (!deepEqual(obj1[prop], obj2[prop])) return false;
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region src/utils/error.ts
|
|
42
|
+
function validateConfigId(configId, expectedConfigType) {
|
|
43
|
+
if (configId === void 0) console.warn(`Invalid config ${expectedConfigType}: ${configId}`);
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/client/initialize.ts
|
|
47
|
+
function initialize() {
|
|
48
|
+
const pluginConfig = { config: {} };
|
|
49
|
+
let subscribedInteractions = {};
|
|
50
|
+
let subscribedWorkbookVars = {};
|
|
51
|
+
let subscribedUrlParameters = {};
|
|
52
|
+
const registeredEffects = {};
|
|
53
|
+
const listeners = {};
|
|
54
|
+
const location = new URL(document.location.href);
|
|
55
|
+
for (const [key, value] of location.searchParams.entries()) try {
|
|
56
|
+
pluginConfig[key] = JSON.parse(value);
|
|
57
|
+
} catch (_err) {
|
|
58
|
+
console.error(`Failed to parse URL param ${key} with value ${value} as JSON.`);
|
|
59
|
+
}
|
|
60
|
+
const listener = (e) => {
|
|
61
|
+
emit(e.data.type, e.data.result, e.data.error);
|
|
62
|
+
};
|
|
63
|
+
window.addEventListener("message", listener, false);
|
|
64
|
+
window.addEventListener("click", () => execPromise("wb:plugin:focus"));
|
|
65
|
+
on("wb:plugin:config:update", (config) => {
|
|
66
|
+
Object.assign(pluginConfig, config);
|
|
67
|
+
emit("config", pluginConfig.config ?? {});
|
|
68
|
+
});
|
|
69
|
+
execPromise("wb:plugin:init", "1.2.0").then((config) => {
|
|
70
|
+
Object.assign(pluginConfig, config);
|
|
71
|
+
emit("init", pluginConfig);
|
|
72
|
+
emit("config", pluginConfig.config);
|
|
73
|
+
});
|
|
74
|
+
on("wb:plugin:variable:update", (updatedVariables) => {
|
|
75
|
+
subscribedWorkbookVars = {};
|
|
76
|
+
Object.assign(subscribedWorkbookVars, updatedVariables);
|
|
77
|
+
});
|
|
78
|
+
on("wb:plugin:selection:update", (updatedInteractions) => {
|
|
79
|
+
subscribedInteractions = {};
|
|
80
|
+
Object.assign(subscribedInteractions, updatedInteractions);
|
|
81
|
+
});
|
|
82
|
+
on("wb:plugin:url-parameter:update", (updatedUrlParameters) => {
|
|
83
|
+
subscribedUrlParameters = {};
|
|
84
|
+
Object.assign(subscribedUrlParameters, updatedUrlParameters);
|
|
85
|
+
});
|
|
86
|
+
on("wb:plugin:action-effect:invoke", (configId) => {
|
|
87
|
+
const effect = registeredEffects[configId];
|
|
88
|
+
if (!effect) throw new Error(`Unknown action effect with name: ${configId}`);
|
|
89
|
+
effect();
|
|
90
|
+
});
|
|
91
|
+
function on(event, listener) {
|
|
92
|
+
listeners[event] = listeners[event] || [];
|
|
93
|
+
listeners[event].push(listener);
|
|
94
|
+
}
|
|
95
|
+
function off(event, listener) {
|
|
96
|
+
if (listeners[event] == null) return;
|
|
97
|
+
listeners[event] = listeners[event].filter((a) => a !== listener);
|
|
98
|
+
}
|
|
99
|
+
function emit(event, ...args) {
|
|
100
|
+
Object.values(listeners[event] || []).forEach((fn) => fn(...args));
|
|
101
|
+
}
|
|
102
|
+
function execPromise(event, ...args) {
|
|
103
|
+
return new Promise((resolve, reject) => {
|
|
104
|
+
const callback = (data, error) => {
|
|
105
|
+
if (error) reject(error);
|
|
106
|
+
else resolve(data);
|
|
107
|
+
off(event, callback);
|
|
108
|
+
};
|
|
109
|
+
on(event, callback);
|
|
110
|
+
window.parent.postMessage({
|
|
111
|
+
type: event,
|
|
112
|
+
args,
|
|
113
|
+
elementId: pluginConfig.id
|
|
114
|
+
}, pluginConfig?.wbOrigin ?? "*");
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
get sigmaEnv() {
|
|
119
|
+
return pluginConfig.sigmaEnv;
|
|
120
|
+
},
|
|
121
|
+
get isScreenshot() {
|
|
122
|
+
return pluginConfig.screenshot;
|
|
123
|
+
},
|
|
124
|
+
config: {
|
|
125
|
+
getKey(key) {
|
|
126
|
+
return pluginConfig?.config?.[key];
|
|
127
|
+
},
|
|
128
|
+
get() {
|
|
129
|
+
return pluginConfig.config;
|
|
130
|
+
},
|
|
131
|
+
set(partialConfig) {
|
|
132
|
+
execPromise("wb:plugin:config:update", partialConfig);
|
|
133
|
+
},
|
|
134
|
+
setKey(key, value) {
|
|
135
|
+
execPromise("wb:plugin:config:update", { [key]: value });
|
|
136
|
+
},
|
|
137
|
+
subscribe(listener) {
|
|
138
|
+
on("config", listener);
|
|
139
|
+
return () => off("config", listener);
|
|
140
|
+
},
|
|
141
|
+
getVariable(configId) {
|
|
142
|
+
validateConfigId(configId, "variable");
|
|
143
|
+
return subscribedWorkbookVars[configId];
|
|
144
|
+
},
|
|
145
|
+
setVariable(configId, ...values) {
|
|
146
|
+
validateConfigId(configId, "variable");
|
|
147
|
+
execPromise("wb:plugin:variable:set", configId, ...values);
|
|
148
|
+
},
|
|
149
|
+
getInteraction(configId) {
|
|
150
|
+
validateConfigId(configId, "interaction");
|
|
151
|
+
return subscribedInteractions[configId];
|
|
152
|
+
},
|
|
153
|
+
setInteraction(configId, elementId, selection) {
|
|
154
|
+
validateConfigId(configId, "interaction");
|
|
155
|
+
execPromise("wb:plugin:selection:set", configId, elementId, selection);
|
|
156
|
+
},
|
|
157
|
+
triggerAction(configId) {
|
|
158
|
+
validateConfigId(configId, "action-trigger");
|
|
159
|
+
execPromise("wb:plugin:action-trigger:invoke", configId);
|
|
160
|
+
},
|
|
161
|
+
registerEffect(configId, effect) {
|
|
162
|
+
validateConfigId(configId, "action-effect");
|
|
163
|
+
registeredEffects[configId] = effect;
|
|
164
|
+
return () => {
|
|
165
|
+
delete registeredEffects[configId];
|
|
166
|
+
};
|
|
167
|
+
},
|
|
168
|
+
configureEditorPanel(options) {
|
|
169
|
+
execPromise("wb:plugin:config:inspector", options);
|
|
170
|
+
},
|
|
171
|
+
setLoadingState(loadingState) {
|
|
172
|
+
execPromise("wb:plugin:config:loading-state", loadingState);
|
|
173
|
+
},
|
|
174
|
+
subscribeToWorkbookVariable(configId, callback) {
|
|
175
|
+
validateConfigId(configId, "variable");
|
|
176
|
+
const setValues = (values) => {
|
|
177
|
+
callback(values[configId]);
|
|
178
|
+
};
|
|
179
|
+
on("wb:plugin:variable:update", setValues);
|
|
180
|
+
return () => {
|
|
181
|
+
off("wb:plugin:variable:update", setValues);
|
|
182
|
+
};
|
|
183
|
+
},
|
|
184
|
+
subscribeToWorkbookInteraction(configId, callback) {
|
|
185
|
+
validateConfigId(configId, "interaction");
|
|
186
|
+
const setValues = (values) => {
|
|
187
|
+
callback(values[configId]);
|
|
188
|
+
};
|
|
189
|
+
on("wb:plugin:selection:update", setValues);
|
|
190
|
+
return () => {
|
|
191
|
+
off("wb:plugin:selection:update", setValues);
|
|
192
|
+
};
|
|
193
|
+
},
|
|
194
|
+
subscribeToUrlParameter(configId, callback) {
|
|
195
|
+
validateConfigId(configId, "url-parameter");
|
|
196
|
+
const setValues = (values) => {
|
|
197
|
+
callback(values[configId]);
|
|
198
|
+
};
|
|
199
|
+
setValues(subscribedUrlParameters);
|
|
200
|
+
on("wb:plugin:url-parameter:update", setValues);
|
|
201
|
+
return () => {
|
|
202
|
+
off("wb:plugin:url-parameter:update", setValues);
|
|
203
|
+
};
|
|
204
|
+
},
|
|
205
|
+
getUrlParameter(configId) {
|
|
206
|
+
validateConfigId(configId, "url-parameter");
|
|
207
|
+
return subscribedUrlParameters[configId];
|
|
208
|
+
},
|
|
209
|
+
setUrlParameter(configId, value) {
|
|
210
|
+
validateConfigId(configId, "url-parameter");
|
|
211
|
+
execPromise("wb:plugin:url-parameter:set", configId, value);
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
elements: {
|
|
215
|
+
getElementColumns(configId) {
|
|
216
|
+
validateConfigId(configId, "element");
|
|
217
|
+
return execPromise("wb:plugin:element:columns:get", configId);
|
|
218
|
+
},
|
|
219
|
+
subscribeToElementColumns(configId, callback) {
|
|
220
|
+
validateConfigId(configId, "element");
|
|
221
|
+
const eventName = `wb:plugin:element:${configId}:columns`;
|
|
222
|
+
on(eventName, callback);
|
|
223
|
+
execPromise("wb:plugin:element:subscribe:columns", configId);
|
|
224
|
+
return () => {
|
|
225
|
+
off(eventName, callback);
|
|
226
|
+
execPromise("wb:plugin:element:unsubscribe:columns", configId);
|
|
227
|
+
};
|
|
228
|
+
},
|
|
229
|
+
subscribeToElementData(configId, callback) {
|
|
230
|
+
validateConfigId(configId, "element");
|
|
231
|
+
const eventName = `wb:plugin:element:${configId}:data`;
|
|
232
|
+
on(eventName, callback);
|
|
233
|
+
execPromise("wb:plugin:element:subscribe:data", configId);
|
|
234
|
+
return () => {
|
|
235
|
+
off(eventName, callback);
|
|
236
|
+
execPromise("wb:plugin:element:unsubscribe:data", configId);
|
|
237
|
+
};
|
|
238
|
+
},
|
|
239
|
+
fetchMoreElementData(configId) {
|
|
240
|
+
validateConfigId(configId, "element");
|
|
241
|
+
execPromise("wb:plugin:element:fetch-more", configId);
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
style: {
|
|
245
|
+
subscribe(callback) {
|
|
246
|
+
on("wb:plugin:style:update", callback);
|
|
247
|
+
return () => off("wb:plugin:style:update", callback);
|
|
248
|
+
},
|
|
249
|
+
get() {
|
|
250
|
+
return execPromise("wb:plugin:style:get");
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
destroy() {
|
|
254
|
+
Object.keys(listeners).forEach((event) => delete listeners[event]);
|
|
255
|
+
window.removeEventListener("message", listener, false);
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
//#endregion
|
|
260
|
+
//#region src/client.ts
|
|
261
|
+
const client = initialize();
|
|
262
|
+
//#endregion
|
|
263
|
+
//#region src/react/Context.ts
|
|
264
|
+
const PluginContext = react$1.createContext(client);
|
|
265
|
+
//#endregion
|
|
266
|
+
//#region src/react/hooks.ts
|
|
267
|
+
/**
|
|
268
|
+
* Gets the entire plugin instance
|
|
269
|
+
* @returns {PluginInstance} Context for the current plugin instance
|
|
270
|
+
*/
|
|
271
|
+
function usePlugin() {
|
|
272
|
+
return react$1.useContext(PluginContext);
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Provides a setter for the Plugin's Config Options
|
|
276
|
+
* @param {CustomPluginConfigOptions[]} nextOptions Updated possible Config Options
|
|
277
|
+
*/
|
|
278
|
+
function useEditorPanelConfig(nextOptions) {
|
|
279
|
+
const client = usePlugin();
|
|
280
|
+
const optionsRef = react$1.useRef({});
|
|
281
|
+
react$1.useEffect(() => {
|
|
282
|
+
if (nextOptions == null) return;
|
|
283
|
+
if (!deepEqual(nextOptions, optionsRef.current)) {
|
|
284
|
+
client.config.configureEditorPanel(nextOptions);
|
|
285
|
+
optionsRef.current = nextOptions;
|
|
286
|
+
}
|
|
287
|
+
}, [client, nextOptions]);
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* React hook for Plugin Config loading state
|
|
291
|
+
* @param {boolean} initialState Initial value to set loading state to
|
|
292
|
+
* @returns {[boolean, Function]} Boolean value corresponding to loading state for plugin config and setter for loading state
|
|
293
|
+
*/
|
|
294
|
+
function useLoadingState(initialState) {
|
|
295
|
+
const client = usePlugin();
|
|
296
|
+
const [loading, setLoading] = react$1.useState(() => {
|
|
297
|
+
client.config.setLoadingState(initialState);
|
|
298
|
+
return initialState;
|
|
299
|
+
});
|
|
300
|
+
return [loading, (nextState) => {
|
|
301
|
+
if (nextState === loading) return;
|
|
302
|
+
setLoading(nextState);
|
|
303
|
+
client.config.setLoadingState(nextState);
|
|
304
|
+
}];
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Provides the latest column values from corresponding config element
|
|
308
|
+
* @param {string} configId ID from the config for fetching element columns, with type: 'element'
|
|
309
|
+
* @returns {WorkbookElementColumns} Values of corresponding columns contained
|
|
310
|
+
* within the config element
|
|
311
|
+
*/
|
|
312
|
+
function useElementColumns(configId) {
|
|
313
|
+
const client = usePlugin();
|
|
314
|
+
const [columns, setColumns] = react$1.useState({});
|
|
315
|
+
react$1.useEffect(() => {
|
|
316
|
+
if (configId) return client.elements.subscribeToElementColumns(configId, setColumns);
|
|
317
|
+
}, [client, configId]);
|
|
318
|
+
return columns;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Provides the latest data values from config element (max 25_000)
|
|
322
|
+
* @param {string} configId ID from the config for fetching element data, with type: 'element'
|
|
323
|
+
* @returns {WorkbookElementData} Element Data for config element, if any
|
|
324
|
+
*/
|
|
325
|
+
function useElementData(configId) {
|
|
326
|
+
const client = usePlugin();
|
|
327
|
+
const [data, setData] = react$1.useState({});
|
|
328
|
+
react$1.useEffect(() => {
|
|
329
|
+
if (configId) return client.elements.subscribeToElementData(configId, setData);
|
|
330
|
+
}, [client, configId]);
|
|
331
|
+
return data;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Provides the latest data values from corresponding config element with a callback to
|
|
335
|
+
* fetch more in chunks of 25_000 data points
|
|
336
|
+
* @param {string} configId ID from the config for fetching paginated
|
|
337
|
+
* element data, with type: 'element'
|
|
338
|
+
* @returns {WorkbookElementData} Element Data for configured config element, if any
|
|
339
|
+
*/
|
|
340
|
+
function usePaginatedElementData(configId) {
|
|
341
|
+
const client = usePlugin();
|
|
342
|
+
const [data, setData] = react$1.useState({});
|
|
343
|
+
const loadMore = react$1.useCallback(() => {
|
|
344
|
+
if (configId) client.elements.fetchMoreElementData(configId);
|
|
345
|
+
}, [configId, client.elements]);
|
|
346
|
+
react$1.useEffect(() => {
|
|
347
|
+
if (configId) return client.elements.subscribeToElementData(configId, setData);
|
|
348
|
+
}, [client, configId]);
|
|
349
|
+
return [data, loadMore];
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Provides the latest value for entire config or certain key within the config
|
|
353
|
+
* @param {string} key Key within Plugin Config, optional
|
|
354
|
+
* @returns Entire config if no key passed in or value for key within plugin config
|
|
355
|
+
*/
|
|
356
|
+
function useConfig(key) {
|
|
357
|
+
const client = usePlugin();
|
|
358
|
+
const [config, setConfig] = react$1.useState(key != null ? client.config.getKey(key) : client.config.get());
|
|
359
|
+
react$1.useEffect(() => client.config.subscribe((newConfig) => {
|
|
360
|
+
if (key != null && newConfig[key] !== config[key]) setConfig(newConfig[key]);
|
|
361
|
+
else setConfig(newConfig);
|
|
362
|
+
}), [
|
|
363
|
+
client,
|
|
364
|
+
key,
|
|
365
|
+
config
|
|
366
|
+
]);
|
|
367
|
+
return config;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* React hook for accessing a workbook control variable
|
|
371
|
+
* @param {string} id ID from the config of type: 'variable'
|
|
372
|
+
* @returns {[(WorkbookVariable | undefined), Function]} Constantly updating
|
|
373
|
+
* value of the control variable and setter for the variable
|
|
374
|
+
*/
|
|
375
|
+
function useVariable(id) {
|
|
376
|
+
const client = usePlugin();
|
|
377
|
+
const [workbookVariable, setWorkbookVariable] = react$1.useState();
|
|
378
|
+
const isFirstRender = react$1.useRef(true);
|
|
379
|
+
react$1.useEffect(() => {
|
|
380
|
+
if (isFirstRender.current) {
|
|
381
|
+
setWorkbookVariable(client.config.getVariable(id));
|
|
382
|
+
isFirstRender.current = false;
|
|
383
|
+
}
|
|
384
|
+
return client.config.subscribeToWorkbookVariable(id, setWorkbookVariable);
|
|
385
|
+
}, [client, id]);
|
|
386
|
+
return [workbookVariable, react$1.useCallback((...values) => client.config.setVariable(id, ...values), [id, client.config])];
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* React hook for accessing a url parameter
|
|
390
|
+
* @param {string} id ID from the config of type: 'url-parameter'
|
|
391
|
+
* @returns {[(UrlParameter | undefined), Function]} Constantly updating value of the url parameter and setter for the url parameter
|
|
392
|
+
*/
|
|
393
|
+
function useUrlParameter(id) {
|
|
394
|
+
const client = usePlugin();
|
|
395
|
+
const [urlParameter, setUrlParameter] = react$1.useState();
|
|
396
|
+
const isFirstRender = react$1.useRef(true);
|
|
397
|
+
react$1.useEffect(() => {
|
|
398
|
+
if (isFirstRender.current) {
|
|
399
|
+
setUrlParameter(client.config.getUrlParameter(id));
|
|
400
|
+
isFirstRender.current = false;
|
|
401
|
+
}
|
|
402
|
+
return client.config.subscribeToUrlParameter(id, setUrlParameter);
|
|
403
|
+
}, [client, id]);
|
|
404
|
+
return [urlParameter, react$1.useCallback((value) => client.config.setUrlParameter(id, value), [client, id])];
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* @deprecated Use Action API instead
|
|
408
|
+
* React hook for accessing a workbook interaction selections state
|
|
409
|
+
* @param {string} id ID from the config of type: 'interaction'
|
|
410
|
+
* @returns {[(WorkbookSelection | undefined), Function]} Constantly updating selection state and setter thereof
|
|
411
|
+
*/
|
|
412
|
+
function useInteraction(id, elementId) {
|
|
413
|
+
const client = usePlugin();
|
|
414
|
+
const [workbookInteraction, setWorkbookInteraction] = react$1.useState();
|
|
415
|
+
react$1.useEffect(() => {
|
|
416
|
+
return client.config.subscribeToWorkbookInteraction(id, setWorkbookInteraction);
|
|
417
|
+
}, [client, id]);
|
|
418
|
+
return [workbookInteraction, react$1.useCallback((value) => {
|
|
419
|
+
client.config.setInteraction(id, elementId, value);
|
|
420
|
+
}, [
|
|
421
|
+
id,
|
|
422
|
+
elementId,
|
|
423
|
+
client.config
|
|
424
|
+
])];
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* React hook for returning a triggering callback function for the registered
|
|
428
|
+
* action trigger
|
|
429
|
+
* @param {string} configId ID from the config of type: 'action-trigger'
|
|
430
|
+
* @returns {Function} A callback function to trigger the action
|
|
431
|
+
*/
|
|
432
|
+
function useActionTrigger(configId) {
|
|
433
|
+
const client = usePlugin();
|
|
434
|
+
return react$1.useCallback(() => {
|
|
435
|
+
client.config.triggerAction(configId);
|
|
436
|
+
}, [client, configId]);
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* React hook for registering and unregistering an action effect
|
|
440
|
+
* @param {string} configId ID from the config of type: 'action-effect'
|
|
441
|
+
* @param {Function} effect The function to be called when the action is triggered
|
|
442
|
+
*/
|
|
443
|
+
function useActionEffect(configId, effect) {
|
|
444
|
+
const client = usePlugin();
|
|
445
|
+
const effectRef = react$1.useRef(effect);
|
|
446
|
+
react$1.useEffect(() => {
|
|
447
|
+
effectRef.current = effect;
|
|
448
|
+
});
|
|
449
|
+
react$1.useEffect(() => {
|
|
450
|
+
return client.config.registerEffect(configId, effectRef.current);
|
|
451
|
+
}, [
|
|
452
|
+
client,
|
|
453
|
+
configId,
|
|
454
|
+
effect
|
|
455
|
+
]);
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* React hook for accessing plugin style with live updates
|
|
459
|
+
* @returns {PluginStyle | undefined} Style properties from the workbook if available
|
|
460
|
+
*/
|
|
461
|
+
function usePluginStyle() {
|
|
462
|
+
const client = usePlugin();
|
|
463
|
+
const [style, setStyle] = react$1.useState();
|
|
464
|
+
react$1.useEffect(() => {
|
|
465
|
+
client.style.get().then((response) => setStyle(response));
|
|
466
|
+
return client.style.subscribe(setStyle);
|
|
467
|
+
}, [client]);
|
|
468
|
+
return style;
|
|
469
|
+
}
|
|
470
|
+
//#endregion
|
|
471
|
+
//#region src/react/Provider.tsx
|
|
472
|
+
function SigmaClientProvider(props) {
|
|
473
|
+
return /* @__PURE__ */ react.createElement(PluginContext.Provider, { value: props.client }, props.children);
|
|
474
|
+
}
|
|
475
|
+
//#endregion
|
|
476
|
+
//#region src/utils/polyfillRequestAnimationFrame.ts
|
|
477
|
+
const FPS = 1e3 / 60;
|
|
478
|
+
/**
|
|
479
|
+
* requestAnimationFrame() calls are paused in most browsers when running in background tabs or hidden <iframe>s in order to improve performance and battery life
|
|
480
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame
|
|
481
|
+
*/
|
|
482
|
+
function polyfillRequestAnimationFrame(window) {
|
|
483
|
+
if ("requestAnimationFrame" in window) {
|
|
484
|
+
window.requestAnimationFrame = (callback) => window.setTimeout(callback, FPS);
|
|
485
|
+
window.cancelAnimationFrame = (id) => window.clearTimeout(id);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
//#endregion
|
|
489
|
+
exports.SigmaClientProvider = SigmaClientProvider;
|
|
490
|
+
exports.client = client;
|
|
491
|
+
exports.polyfillRequestAnimationFrame = polyfillRequestAnimationFrame;
|
|
492
|
+
exports.useActionEffect = useActionEffect;
|
|
493
|
+
exports.useActionTrigger = useActionTrigger;
|
|
494
|
+
exports.useConfig = useConfig;
|
|
495
|
+
exports.useEditorPanelConfig = useEditorPanelConfig;
|
|
496
|
+
exports.useElementColumns = useElementColumns;
|
|
497
|
+
exports.useElementData = useElementData;
|
|
498
|
+
exports.useInteraction = useInteraction;
|
|
499
|
+
exports.useLoadingState = useLoadingState;
|
|
500
|
+
exports.usePaginatedElementData = usePaginatedElementData;
|
|
501
|
+
exports.usePlugin = usePlugin;
|
|
502
|
+
exports.usePluginStyle = usePluginStyle;
|
|
503
|
+
exports.useUrlParameter = useUrlParameter;
|
|
504
|
+
exports.useVariable = useVariable;
|
|
505
|
+
|
|
506
|
+
//# sourceMappingURL=index.cjs.map
|