mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-24 10:12:44 +00:00
fix(plugins): restore deprecated useRevealedText compatibility (#7780)
The 0.13 UI entry rename dropped the reveal hook from the 0.12 runtime. Keep it on the legacy entry until that entry is removed, with deprecated SDK typing and migration guidance. Closes #7577 Closes #7722 Co-authored-by: luke <luopeihuan@gmail.com> Co-authored-by: RoundRedDot <roundreddot@gmail.com> Co-authored-by: Matt Cowger <1929548+mcowger@users.noreply.github.com>
This commit is contained in:
co-authored by
luke
RoundRedDot
Matt Cowger
parent
686588c44b
commit
f3d74b8575
@@ -1,4 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { useRevealedText } from "@/hooks/use-revealed-text";
|
||||
import { runPluginClientBundle, type PluginClientRuntime } from "./evaluate";
|
||||
|
||||
const runtime = {
|
||||
@@ -705,6 +706,21 @@ describe("evaluatePluginClientBundle", () => {
|
||||
expect(plugin.surfaces.map((surface) => surface.id)).toEqual(["main"]);
|
||||
});
|
||||
|
||||
it("keeps the host reveal hook on the deprecated client/react-native entry", () => {
|
||||
const plugin = evaluatePluginClientBundle(
|
||||
"legacy-reveal",
|
||||
bundle(`
|
||||
const legacy = require("@getpaseo/plugin/client/react-native");
|
||||
const ui = require("@getpaseo/plugin/client/ui");
|
||||
if (typeof legacy.useRevealedText !== "function") throw new Error("Missing legacy reveal hook");
|
||||
if (legacy.StreamedText !== ui.StreamedText) throw new Error("Missing current UI exports");
|
||||
if ("useRevealedText" in ui) throw new Error("Legacy hook leaked into current UI");
|
||||
plugin.addScreen({ id: "reveal", title: "Reveal", Component: legacy.useRevealedText });
|
||||
`),
|
||||
);
|
||||
expect(plugin.surfaces[0]?.Component).toBe(useRevealedText);
|
||||
});
|
||||
|
||||
it("keeps shared and client runtime exports separate", () => {
|
||||
expect(() =>
|
||||
evaluatePluginClientBundle(
|
||||
|
||||
@@ -2,6 +2,7 @@ import { requirePluginText } from "@getpaseo/plugin/client/host";
|
||||
import type { createPluginHosts } from "./hosts";
|
||||
import { openExternalUrl } from "@/utils/open-external-url";
|
||||
import * as pluginUiRuntime from "./react-native/ui";
|
||||
import { useRevealedText } from "@/hooks/use-revealed-text";
|
||||
import { useSettings } from "./settings/use-settings";
|
||||
import * as pluginSharedRuntime from "@getpaseo/plugin";
|
||||
import * as pluginClientRuntime from "@getpaseo/plugin/client";
|
||||
@@ -114,6 +115,10 @@ export type PluginClientRuntime = Pick<
|
||||
| "addHeaderButton"
|
||||
> & { hosts: ReturnType<typeof createPluginHosts> };
|
||||
|
||||
// COMPAT(pluginReactNativeEntrypoint): added in v0.13.0, remove after 2027-04-20
|
||||
// The 0.12 entry exposed the reveal hook as well as UI components.
|
||||
const pluginReactNativeCompatRuntime = { ...pluginUiRuntime, useRevealedText };
|
||||
|
||||
export function runPluginClientBundle(
|
||||
id: string,
|
||||
bundle: string,
|
||||
@@ -503,7 +508,7 @@ export function runPluginClientBundle(
|
||||
};
|
||||
const runtimeRequire = (name: string): unknown => {
|
||||
// COMPAT(pluginReactNativeEntrypoint): added in v0.13.0, remove after 2027-04-20
|
||||
if (name === "@getpaseo/plugin/client/react-native") return pluginUiRuntime;
|
||||
if (name === "@getpaseo/plugin/client/react-native") return pluginReactNativeCompatRuntime;
|
||||
if (name === "@getpaseo/plugin/client/ui") return pluginUiRuntime;
|
||||
if (name === "react") return React;
|
||||
if (name === "react/jsx-runtime") return ReactJsxRuntime;
|
||||
|
||||
@@ -101,12 +101,29 @@ describe("plugin SDK import boundaries", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it.each(compatibilityEntries)("%s only re-exports the UI entry", (entry) => {
|
||||
const source = readFileSync(
|
||||
path.resolve(sourceDirectory, "..", manifest.exports[entry].source),
|
||||
"utf8",
|
||||
);
|
||||
expect(source.replace(/\/\/[^\n]*|\/\*[^]*?\*\//g, "").trim()).toBe('export * from "./ui.js";');
|
||||
it.each(compatibilityEntries)("%s respects the client boundary", (entry) => {
|
||||
expect(
|
||||
boundaryViolations(
|
||||
path.resolve(sourceDirectory, "..", manifest.exports[entry].source),
|
||||
"client",
|
||||
),
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
it("typechecks a 0.12 reveal-hook consumer without exposing the hook on current UI", () => {
|
||||
expect(
|
||||
typeErrors(`
|
||||
import { useRevealedText, Icon } from "@getpaseo/plugin/client/react-native";
|
||||
import { StreamedText } from "@getpaseo/plugin/client/ui";
|
||||
// @ts-expect-error the legacy hook is not part of the current UI API
|
||||
import { useRevealedText as currentHook } from "@getpaseo/plugin/client/ui";
|
||||
import { Text } from "react-native";
|
||||
function LegacyRow({ text, phase }: { text: string; phase: "streaming" | "complete" }) {
|
||||
const revealed: string = useRevealedText(text, phase);
|
||||
return <Text>{revealed}</Text>;
|
||||
}
|
||||
`),
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
it.each(Object.entries(entries))(
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// COMPAT(pluginReactNativeEntrypoint): added in v0.13.0, remove after 2027-04-20
|
||||
/** @deprecated Import Paseo UI from @getpaseo/plugin/client/ui. */
|
||||
export * from "./ui.js";
|
||||
|
||||
/** @deprecated Render StreamedText from @getpaseo/plugin/client/ui. Removed after 2027-04-20 with this entry. */
|
||||
export declare function useRevealedText(text: string, phase: "streaming" | "complete"): string;
|
||||
|
||||
@@ -176,8 +176,9 @@ its registration; that registration belongs in the client entry.
|
||||
|
||||
### UI imports in v0.13
|
||||
|
||||
Use `/client/ui` for all Paseo UI components and UI hooks. The previous entry remains an
|
||||
undocumented compatibility alias until 2027-04-20.
|
||||
Use `/client/ui` for all Paseo UI components and UI hooks. The deprecated
|
||||
`/client/react-native` entry retains `useRevealedText(text, phase): string` for 0.12 plugins
|
||||
until removal after 2027-04-20. The hook is deprecated and is not exported from `/client/ui`.
|
||||
|
||||
For paced timeline text, replace `useRevealedText(text, phase)` and the surrounding `Text` with
|
||||
`<StreamedText text={text} phase={phase} style={style} />` from `/client/ui`.
|
||||
|
||||
Reference in New Issue
Block a user