mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-04 19:28:46 +01:00
Export full React surface from plugin shim
This commit is contained in:
1 parent
b9434fc08f
commit
d15fb5de01
2 files changed
+39
-12
No files matched your search
@@ -23,6 +23,7 @@ import {
|
||||
type PluginBridgeContextValue,
|
||||
} from "./bridge";
|
||||
import { initPluginBridge } from "./bridge-init";
|
||||
import { _createReactShimSourceForTests } from "./slots";
|
||||
|
||||
function clickEvent(
|
||||
overrides: Partial<ReactMouseEvent<HTMLAnchorElement>> = {},
|
||||
@@ -304,3 +305,20 @@ describe("plugin SDK markdown component bridge", () => {
|
||||
}))).toContain("Run lint");
|
||||
});
|
||||
});
|
||||
|
||||
describe("plugin React shim", () => {
|
||||
it("re-exports every named export from the host React module", () => {
|
||||
const source = _createReactShimSourceForTests(React);
|
||||
|
||||
for (const name of Object.keys(React).sort()) {
|
||||
if (name === "default") continue;
|
||||
expect(source).toContain(`export const ${name} = R.${name};`);
|
||||
}
|
||||
|
||||
expect(source).toContain("export default R;");
|
||||
expect(source).toContain("export const useInsertionEffect = R.useInsertionEffect;");
|
||||
expect(source).toContain("export const useId = R.useId;");
|
||||
expect(source).toContain("export const useSyncExternalStore = R.useSyncExternalStore;");
|
||||
expect(source).toContain("export const startTransition = R.startTransition;");
|
||||
});
|
||||
});
|
||||
+21
-12
@@ -29,6 +29,7 @@ import {
|
||||
type ReactNode,
|
||||
type ComponentType,
|
||||
} from "react";
|
||||
import * as ReactModule from "react";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import type {
|
||||
PluginLauncherDeclaration,
|
||||
@@ -244,24 +245,31 @@ function applyJsxRuntimeKey(
|
||||
return { ...(props ?? {}), key };
|
||||
}
|
||||
|
||||
function createReactShimSource(reactModule: object): string {
|
||||
const exportNames = Object.keys(reactModule)
|
||||
.filter((name) => name !== "default" && /^[A-Za-z_$][\w$]*$/.test(name))
|
||||
.sort();
|
||||
const namedExports = exportNames
|
||||
.map((name) => ` export const ${name} = R.${name};`)
|
||||
.join("\n");
|
||||
|
||||
return `
|
||||
const R = globalThis.__paperclipPluginBridge__?.react;
|
||||
if (!R) {
|
||||
throw new Error("Paperclip plugin React runtime is not initialized.");
|
||||
}
|
||||
export default R;
|
||||
${namedExports}
|
||||
`;
|
||||
}
|
||||
|
||||
function getShimBlobUrl(specifier: "react" | "react-dom" | "react-dom/client" | "react/jsx-runtime" | "sdk-ui"): string {
|
||||
if (shimBlobUrls[specifier]) return shimBlobUrls[specifier];
|
||||
|
||||
let source: string;
|
||||
switch (specifier) {
|
||||
case "react":
|
||||
source = `
|
||||
const R = globalThis.__paperclipPluginBridge__?.react;
|
||||
export default R;
|
||||
const { useState, useEffect, useCallback, useMemo, useRef, useContext,
|
||||
createContext, createElement, Fragment, Component, forwardRef,
|
||||
memo, lazy, Suspense, StrictMode, cloneElement, Children,
|
||||
isValidElement, createRef } = R;
|
||||
export { useState, useEffect, useCallback, useMemo, useRef, useContext,
|
||||
createContext, createElement, Fragment, Component, forwardRef,
|
||||
memo, lazy, Suspense, StrictMode, cloneElement, Children,
|
||||
isValidElement, createRef };
|
||||
`;
|
||||
source = createReactShimSource(ReactModule);
|
||||
break;
|
||||
case "react/jsx-runtime":
|
||||
source = `
|
||||
@@ -900,4 +908,5 @@ export function _resetPluginModuleLoader(): void {
|
||||
}
|
||||
|
||||
export const _applyJsxRuntimeKeyForTests = applyJsxRuntimeKey;
|
||||
export const _createReactShimSourceForTests = createReactShimSource;
|
||||
export const _rewriteBareSpecifiersForTests = rewriteBareSpecifiers;
|
||||
Reference in new issue
Block a user