From 6b531f80ce2360e595991080c877c91b7780f3b1 Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Fri, 7 Aug 2026 12:48:48 +0200 Subject: [PATCH] fix: detect context providers without private fields --- src/adapter/11/bindings.test.ts | 24 ++++++++++++++++++++++++ src/adapter/11/bindings.ts | 8 ++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 src/adapter/11/bindings.test.ts diff --git a/src/adapter/11/bindings.test.ts b/src/adapter/11/bindings.test.ts new file mode 100644 index 00000000..161de71d --- /dev/null +++ b/src/adapter/11/bindings.test.ts @@ -0,0 +1,24 @@ +import { expect } from "vitest"; +import { + getDisplayName, + getPropsVNodeDisplayName, + TYPE_FUNCTION, +} from "./bindings"; + +describe("Preact 11 bindings", () => { + it("should detect context providers without a private back-reference", () => { + const context: any = Object.assign(() => null, { + displayName: "Foobar", + __: "default value", + }); + context.Provider = context; + + const config = { Fragment: () => null }; + expect( + getPropsVNodeDisplayName({ type: context, props: {} } as any, config), + ).to.equal("Foobar.Provider"); + expect( + getDisplayName({ type: context, flags: TYPE_FUNCTION } as any, config), + ).to.equal("Foobar.Provider"); + }); +}); diff --git a/src/adapter/11/bindings.ts b/src/adapter/11/bindings.ts index 58fdbdca..d6cf7d74 100644 --- a/src/adapter/11/bindings.ts +++ b/src/adapter/11/bindings.ts @@ -94,6 +94,10 @@ export function getSuspenseStateKey(c: Component) { return null; } +function getContextProvider(type: any) { + return type.Provider === type ? type : type._contextRef || type.__; +} + // Mangle accessors // When serializing props we're dealing with vnodes instead of @@ -112,7 +116,7 @@ export function getPropsVNodeDisplayName(vnode: VNode, config: RendererConfig) { } // Provider - const ctx = (type as any)._contextRef || (type as any).__; + const ctx = getContextProvider(type); if (ctx && ctx.displayName) { return `${ctx.displayName}.Provider`; } @@ -148,7 +152,7 @@ export function getDisplayName(internal: Internal, config: RendererConfig) { } // Provider - const ctx = (type as any)._contextRef || (type as any).__; + const ctx = getContextProvider(type); if (ctx && ctx.displayName) { return `${ctx.displayName}.Provider`; }