diff --git a/packages/plugin-sdk-react/README.md b/packages/plugin-sdk-react/README.md
new file mode 100644
index 0000000..d80dff2
--- /dev/null
+++ b/packages/plugin-sdk-react/README.md
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+React bindings for the [`@sigmacomputing/plugin`](https://www.npmjs.com/package/@sigmacomputing/plugin) Client SDK.
+
+This package provides the `SigmaClientProvider` context provider and a set of
+React hooks (`usePlugin`, `useConfig`, `useElementColumns`, `useElementData`,
+etc.) that wrap the framework-agnostic client exported from
+`@sigmacomputing/plugin`.
+
+## Installation
+
+```sh
+yarn add @sigmacomputing/plugin @sigmacomputing/plugin-sdk-react
+# or
+npm install @sigmacomputing/plugin @sigmacomputing/plugin-sdk-react
+```
+
+`react` (`>= 16.8`) is required as a peer dependency.
+
+## Usage
+
+```tsx
+import { client } from '@sigmacomputing/plugin';
+import { SigmaClientProvider, useConfig } from '@sigmacomputing/plugin-sdk-react';
+
+function MyPlugin() {
+ const config = useConfig();
+ return {JSON.stringify(config, null, 2)};
+}
+
+export function App() {
+ return (
+
+
+
+ );
+}
+```
+
+See the [`@sigmacomputing/plugin` README](https://github.com/sigmacomputing/plugin/blob/main/packages/plugin-sdk/README.md)
+for the full hook reference.
diff --git a/packages/plugin-sdk-react/package.json b/packages/plugin-sdk-react/package.json
new file mode 100644
index 0000000..6bd9815
--- /dev/null
+++ b/packages/plugin-sdk-react/package.json
@@ -0,0 +1,54 @@
+{
+ "name": "@sigmacomputing/plugin-sdk-react",
+ "version": "1.2.0",
+ "description": "React bindings for the Sigma Computing Plugin Client SDK",
+ "license": "MIT",
+ "type": "module",
+ "scripts": {
+ "build": "tsdown",
+ "build:watch": "tsdown --watch",
+ "format": "yarn g:format",
+ "lint": "yarn g:lint",
+ "publish": "yarn g:publlish",
+ "test": "vitest run",
+ "test:watch": "vitest",
+ "types": "yarn g:types"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ },
+ "dependencies": {
+ "@sigmacomputing/plugin": "^1.2.0",
+ "dequal": "^2.0.3"
+ },
+ "devDependencies": {
+ "tsdown": "^0.21.10",
+ "vitest": "^4.1.5"
+ },
+ "main": "./dist/cjs/index.cjs",
+ "module": "./dist/esm/index.js",
+ "types": "./dist/cjs/index.d.cts",
+ "unpkg": "./dist/umd/sigmacomputing-plugin-sdk-react.umd.js",
+ "jsdelivr": "./dist/umd/sigmacomputing-plugin-sdk-react.umd.js",
+ "exports": {
+ ".": {
+ "import": {
+ "types": "./dist/esm/index.d.ts",
+ "default": "./dist/esm/index.js"
+ },
+ "require": {
+ "types": "./dist/cjs/index.d.cts",
+ "default": "./dist/cjs/index.cjs"
+ }
+ },
+ "./package.json": "./package.json"
+ },
+ "files": [
+ "dist/**/*",
+ "src/**/*",
+ "!src/**/__tests__/**/*"
+ ],
+ "publishConfig": {
+ "access": "public"
+ }
+}
diff --git a/packages/plugin-sdk/src/react/Context.ts b/packages/plugin-sdk-react/src/Context.ts
similarity index 57%
rename from packages/plugin-sdk/src/react/Context.ts
rename to packages/plugin-sdk-react/src/Context.ts
index 2f1f941..7675119 100644
--- a/packages/plugin-sdk/src/react/Context.ts
+++ b/packages/plugin-sdk-react/src/Context.ts
@@ -1,6 +1,5 @@
import * as React from 'react';
-import { client } from '../client';
-import { PluginInstance } from '../types';
+import { client, PluginInstance } from '@sigmacomputing/plugin';
export const PluginContext = React.createContext(client);
diff --git a/packages/plugin-sdk/src/react/Provider.tsx b/packages/plugin-sdk-react/src/Provider.tsx
similarity index 87%
rename from packages/plugin-sdk/src/react/Provider.tsx
rename to packages/plugin-sdk-react/src/Provider.tsx
index d5a4070..dbf9139 100644
--- a/packages/plugin-sdk/src/react/Provider.tsx
+++ b/packages/plugin-sdk-react/src/Provider.tsx
@@ -1,6 +1,6 @@
import * as React from 'react';
-import { PluginInstance } from '../types';
+import { PluginInstance } from '@sigmacomputing/plugin';
import { PluginContext } from './Context';
diff --git a/packages/plugin-sdk/src/react/__tests__/hooks.test.tsx b/packages/plugin-sdk-react/src/__tests__/hooks.test.tsx
similarity index 99%
rename from packages/plugin-sdk/src/react/__tests__/hooks.test.tsx
rename to packages/plugin-sdk-react/src/__tests__/hooks.test.tsx
index 99f4cf7..ad65992 100644
--- a/packages/plugin-sdk/src/react/__tests__/hooks.test.tsx
+++ b/packages/plugin-sdk-react/src/__tests__/hooks.test.tsx
@@ -1,9 +1,8 @@
import { act, renderHook } from '@testing-library/react';
import * as React from 'react';
-import { initialize } from '../../client/initialize';
-import { PluginInstance } from '../../types';
-import { SigmaClientProvider } from '../Provider';
+import { initialize, PluginInstance } from '@sigmacomputing/plugin';
+
import {
useActionEffect,
useActionTrigger,
@@ -19,6 +18,7 @@ import {
useUrlParameter,
useVariable,
} from '../hooks';
+import { SigmaClientProvider } from '../Provider';
type Subscriber = (value: T) => void;
diff --git a/packages/plugin-sdk/src/react/hooks.ts b/packages/plugin-sdk-react/src/hooks.ts
similarity index 98%
rename from packages/plugin-sdk/src/react/hooks.ts
rename to packages/plugin-sdk-react/src/hooks.ts
index adfd0b1..2ff08db 100644
--- a/packages/plugin-sdk/src/react/hooks.ts
+++ b/packages/plugin-sdk-react/src/hooks.ts
@@ -1,3 +1,4 @@
+import { dequal } from 'dequal/lite';
import * as React from 'react';
import {
@@ -9,8 +10,7 @@ import {
WorkbookVariable,
PluginStyle,
UrlParameter,
-} from '../types';
-import { deepEqual } from '../utils/deepEqual';
+} from '@sigmacomputing/plugin';
import { PluginContext } from './Context';
@@ -34,7 +34,7 @@ export function useEditorPanelConfig(
React.useEffect(() => {
if (nextOptions == null) return;
- if (!deepEqual(nextOptions, optionsRef.current)) {
+ if (!dequal(nextOptions, optionsRef.current)) {
client.config.configureEditorPanel(nextOptions);
optionsRef.current = nextOptions;
}
diff --git a/packages/plugin-sdk-react/src/index.ts b/packages/plugin-sdk-react/src/index.ts
new file mode 100644
index 0000000..6960485
--- /dev/null
+++ b/packages/plugin-sdk-react/src/index.ts
@@ -0,0 +1,3 @@
+export * from './hooks';
+export type { SigmaClientProviderProps } from './Provider';
+export { SigmaClientProvider } from './Provider';
diff --git a/packages/plugin-sdk-react/tsconfig.app.json b/packages/plugin-sdk-react/tsconfig.app.json
new file mode 100644
index 0000000..2ed40b8
--- /dev/null
+++ b/packages/plugin-sdk-react/tsconfig.app.json
@@ -0,0 +1,7 @@
+{
+ "extends": "../../tsconfig.app.json",
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo"
+ },
+ "include": ["src"]
+}
diff --git a/packages/plugin-sdk-react/tsconfig.json b/packages/plugin-sdk-react/tsconfig.json
new file mode 100644
index 0000000..473104a
--- /dev/null
+++ b/packages/plugin-sdk-react/tsconfig.json
@@ -0,0 +1,12 @@
+{
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.tsbuildinfo",
+
+ "noEmit": true
+ },
+ "files": [],
+ "references": [
+ { "path": "./tsconfig.app.json" },
+ { "path": "./tsconfig.node.json" }
+ ]
+}
diff --git a/packages/plugin-sdk-react/tsconfig.node.json b/packages/plugin-sdk-react/tsconfig.node.json
new file mode 100644
index 0000000..42f7286
--- /dev/null
+++ b/packages/plugin-sdk-react/tsconfig.node.json
@@ -0,0 +1,7 @@
+{
+ "extends": "../../tsconfig.node.json",
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo"
+ },
+ "include": ["tsdown.config.ts", "vitest.config.ts"]
+}
diff --git a/packages/plugin-sdk-react/tsdown.config.ts b/packages/plugin-sdk-react/tsdown.config.ts
new file mode 100644
index 0000000..8d85220
--- /dev/null
+++ b/packages/plugin-sdk-react/tsdown.config.ts
@@ -0,0 +1,37 @@
+import { defineConfig } from 'tsdown';
+
+// @ts-ignore - base config is defined outside of this package
+import baseConfig from '../../tsdown.base.ts';
+
+// Split into two configs so dequal stays external for ESM/CJS (consumers
+// install it via npm) but is bundled into the UMD build, where shipping
+// a self-contained file matters more than dedup.
+
+const baseFormat = baseConfig.format as Record;
+
+export default [
+ defineConfig({
+ ...baseConfig,
+ format: {
+ esm: baseFormat.esm,
+ cjs: baseFormat.cjs,
+ },
+ }),
+ defineConfig({
+ ...baseConfig,
+ deps: { alwaysBundle: [/^dequal(\/|$)/] },
+ format: {
+ umd: {
+ outputOptions: {
+ ...baseFormat.umd.outputOptions,
+ entryFileNames: 'sigmacomputing-plugin-sdk-react.umd.js',
+ globals: {
+ ...baseFormat.umd.outputOptions.globals,
+ '@sigmacomputing/plugin': 'SigmaPlugin',
+ },
+ name: 'SigmaPluginReact',
+ },
+ },
+ },
+ }),
+];
diff --git a/packages/plugin-sdk-react/vitest.config.ts b/packages/plugin-sdk-react/vitest.config.ts
new file mode 100644
index 0000000..150a68b
--- /dev/null
+++ b/packages/plugin-sdk-react/vitest.config.ts
@@ -0,0 +1,2 @@
+// @ts-ignore - base config is defined outside of this package
+export { default } from '../../vitest.base.ts';
diff --git a/packages/plugin-sdk/package.json b/packages/plugin-sdk/package.json
index 5098326..53d8ab7 100644
--- a/packages/plugin-sdk/package.json
+++ b/packages/plugin-sdk/package.json
@@ -14,14 +14,6 @@
"test:watch": "vitest",
"types": "yarn g:types"
},
- "peerDependencies": {
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
- },
- "peerDependenciesMeta": {
- "react": {
- "optional": true
- }
- },
"devDependencies": {
"tsdown": "^0.21.10",
"vitest": "^4.1.5"
diff --git a/packages/plugin-sdk/src/index.ts b/packages/plugin-sdk/src/index.ts
index ff3725e..8f011eb 100644
--- a/packages/plugin-sdk/src/index.ts
+++ b/packages/plugin-sdk/src/index.ts
@@ -1,5 +1,5 @@
export * from './types';
-export * from './react';
export * from './client';
+export { initialize } from './client/initialize';
export { polyfillRequestAnimationFrame } from './utils/polyfillRequestAnimationFrame';
diff --git a/packages/plugin-sdk/src/react.ts b/packages/plugin-sdk/src/react.ts
deleted file mode 100644
index ae662c6..0000000
--- a/packages/plugin-sdk/src/react.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from './react/hooks';
-export type { SigmaClientProviderProps } from './react/Provider';
-export { SigmaClientProvider } from './react/Provider';
diff --git a/packages/plugin-sdk/tsdown.config.ts b/packages/plugin-sdk/tsdown.config.ts
index fdb5930..b14ad3f 100644
--- a/packages/plugin-sdk/tsdown.config.ts
+++ b/packages/plugin-sdk/tsdown.config.ts
@@ -1,15 +1,2 @@
-import { defineConfig, mergeConfig } from 'tsdown';
-
// @ts-ignore - base config is defined outside of this package
-import baseConfig from '../../tsdown.base.ts';
-
-import packageJson from './package.json' with { type: 'json' };
-
-export default mergeConfig(
- baseConfig,
- defineConfig({
- define: {
- __VERSION__: JSON.stringify(packageJson.version),
- },
- }),
-);
+export { default } from '../../tsdown.base.ts';
diff --git a/packages/plugin-sdk/vitest.config.ts b/packages/plugin-sdk/vitest.config.ts
index c3e1107..150a68b 100644
--- a/packages/plugin-sdk/vitest.config.ts
+++ b/packages/plugin-sdk/vitest.config.ts
@@ -1,15 +1,2 @@
-import { defineConfig, mergeConfig } from 'vitest/config';
-
// @ts-ignore - base config is defined outside of this package
-import baseConfig from '../../vitest.base.ts';
-
-import packageJson from './package.json' with { type: 'json' };
-
-export default mergeConfig(
- baseConfig,
- defineConfig({
- define: {
- __VERSION__: JSON.stringify(packageJson.version),
- },
- }),
-);
+export { default } from '../../vitest.base.ts';
diff --git a/scripts/bump-version.ts b/scripts/bump-version.ts
index 9a115df..ab94027 100644
--- a/scripts/bump-version.ts
+++ b/scripts/bump-version.ts
@@ -109,13 +109,34 @@ const writeNewVersion = (pkgPath: string, version: string): void => {
writeFileSync(pkgPath, raw.replace(pattern, `$1${version}$2`));
};
+const escapeRegex = (value: string): string =>
+ value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+
+const bumpInternalDeps = (
+ pkgPath: string,
+ internalPackageNames: readonly string[],
+ version: string,
+): void => {
+ let raw = readFileSync(pkgPath, 'utf8');
+ for (const depName of internalPackageNames) {
+ const pattern = new RegExp(
+ `("${escapeRegex(depName)}"\\s*:\\s*")(?!workspace:)[^"]+(")`,
+ 'g',
+ );
+ raw = raw.replace(pattern, `$1^${version}$2`);
+ }
+ writeFileSync(pkgPath, raw);
+};
+
type TurboQueryLsResponse = {
packages: {
items: { name: string; path: string }[];
};
};
-const findWorkspacePackageJsons = (): string[] => {
+type WorkspacePackage = { name: string; pkgPath: string };
+
+const findWorkspacePackages = (): WorkspacePackage[] => {
const result = spawnSync(
'yarn',
['turbo', 'query', 'ls', '--output', 'json'],
@@ -137,9 +158,10 @@ const findWorkspacePackageJsons = (): string[] => {
result.stdout.slice(jsonStart),
) as TurboQueryLsResponse;
- return parsed.packages.items.map(item =>
- path.join(item.path, 'package.json'),
- );
+ return parsed.packages.items.map(item => ({
+ name: item.name,
+ pkgPath: path.join(item.path, 'package.json'),
+ }));
};
const main = async (): Promise => {
@@ -147,9 +169,13 @@ const main = async (): Promise => {
const choices = buildChoices(current);
const choice = await promptChoice(current.version, choices);
- const targets = [PACKAGE_JSON_PATH, ...findWorkspacePackageJsons()];
+ const workspaces = findWorkspacePackages();
+ const internalPackageNames = workspaces.map(w => w.name);
+ const targets = [PACKAGE_JSON_PATH, ...workspaces.map(w => w.pkgPath)];
+
for (const pkgPath of targets) {
writeNewVersion(pkgPath, choice.next);
+ bumpInternalDeps(pkgPath, internalPackageNames, choice.next);
console.log(`Bumped ${pkgPath}: ${current.version} -> ${choice.next}`);
}
};
diff --git a/vitest.base.ts b/vitest.base.ts
index d84730c..a3de5fd 100644
--- a/vitest.base.ts
+++ b/vitest.base.ts
@@ -1,8 +1,11 @@
import { playwright } from '@vitest/browser-playwright';
import { defineConfig } from 'vitest/config';
+import packageJson from './package.json' with { type: 'json' };
+
export default defineConfig({
define: {
+ __VERSION__: JSON.stringify(packageJson.version),
__VITEST_BROWSER__: true.toString(),
},
oxc: {
diff --git a/yarn.lock b/yarn.lock
index 6620614..602ae3b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1193,6 +1193,19 @@ __metadata:
languageName: node
linkType: hard
+"@sigmacomputing/plugin-sdk-react@workspace:packages/plugin-sdk-react":
+ version: 0.0.0-use.local
+ resolution: "@sigmacomputing/plugin-sdk-react@workspace:packages/plugin-sdk-react"
+ dependencies:
+ "@sigmacomputing/plugin": "npm:^1.2.0"
+ dequal: "npm:^2.0.3"
+ tsdown: "npm:^0.21.10"
+ vitest: "npm:^4.1.5"
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ languageName: unknown
+ linkType: soft
+
"@sigmacomputing/plugin-sdk-root@workspace:.":
version: 0.0.0-use.local
resolution: "@sigmacomputing/plugin-sdk-root@workspace:."
@@ -1226,17 +1239,12 @@ __metadata:
languageName: unknown
linkType: soft
-"@sigmacomputing/plugin@workspace:packages/plugin-sdk":
+"@sigmacomputing/plugin@npm:^1.2.0, @sigmacomputing/plugin@workspace:packages/plugin-sdk":
version: 0.0.0-use.local
resolution: "@sigmacomputing/plugin@workspace:packages/plugin-sdk"
dependencies:
tsdown: "npm:^0.21.10"
vitest: "npm:^4.1.5"
- peerDependencies:
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
- peerDependenciesMeta:
- react:
- optional: true
languageName: unknown
linkType: soft