Skip to content

feat(paywalls): add web_view message value types (PWENG-98)#3662

Draft
alexrepty wants to merge 1 commit into
alexrepty/paywalls-web-view-cspfrom
alexrepty/paywalls-web-view-value-types
Draft

feat(paywalls): add web_view message value types (PWENG-98)#3662
alexrepty wants to merge 1 commit into
alexrepty/paywalls-web-view-cspfrom
alexrepty/paywalls-web-view-value-types

Conversation

@alexrepty

@alexrepty alexrepty commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Checklist

  • If applicable, unit tests
  • If applicable, create follow-up issues for purchases-ios and hybrids

Motivation

The web_view bidirectional-messaging bridge needs a JSON-compatible value type to represent message payloads in a type-safe, public-API-friendly way.

Part of PWENG-98.

Description

  • Adds the public PaywallWebViewValue sealed type (String / Number / Boolean / Object / Array / Null) plus JSON conversion helpers.
  • Pure data type — no message envelope, parser, or bridge yet.
  • Tested by PaywallWebViewValueTest.

iOS parity: mirrors purchases-ios (web-view-bridge-wiring).
Stack (merge bottom-up): schema → rendering → CSP → value types → message model → variables provider → JS bridge → wiring.


Note

Low Risk
Additive public API and internal helpers only; no changes to purchase, auth, or existing paywall runtime behavior.

Overview
Introduces PaywallWebViewValue, a new public JSON-shaped type for Paywalls V2 web_view message payloads, ahead of the JS bridge stack (PWENG-98).

The type is an abstract class with nested variants (String, Number, Boolean, Object, Array, Null)—same pattern as CustomVariableValue for stable public API. api.txt documents the new surface.

Internal helpers add fromJson (with a nesting depth cap and rejection of non-JSON types) and outbound serialization via toJsonRepresentation / toJsonObject (whole numbers emitted as integers). No message envelope, parser, or WebView wiring in this PR—data layer only.

PaywallWebViewValueTest covers primitives, nested structures, depth limits, and round-trip JSON.

Reviewed by Cursor Bugbot for commit cf8d3d0. Bugbot is set up for automated code reviews on this repo. Configure here.

@emerge-tools

emerge-tools Bot commented Jun 26, 2026

Copy link
Copy Markdown

📸 Snapshot Test

593 unchanged

Name Added Removed Modified Renamed Unchanged Errored Approval
TestPurchasesUIAndroidCompatibility Paparazzi
com.revenuecat.testpurchasesuiandroidcompatibility.paparazzi
0 0 0 0 258 0 N/A
TestPurchasesUIAndroidCompatibility
com.revenuecat.testpurchasesuiandroidcompatibility
0 0 0 0 335 0 N/A

🛸 Powered by Emerge Tools

@alexrepty alexrepty force-pushed the alexrepty/paywalls-web-view-csp branch from a3e9e1a to 0dffacc Compare June 26, 2026 14:20
@alexrepty alexrepty force-pushed the alexrepty/paywalls-web-view-value-types branch from 3e62e49 to 2716386 Compare June 26, 2026 14:20
@alexrepty alexrepty force-pushed the alexrepty/paywalls-web-view-csp branch from 0dffacc to 353f584 Compare June 26, 2026 14:26
@alexrepty alexrepty force-pushed the alexrepty/paywalls-web-view-value-types branch from 2716386 to 27793a8 Compare June 26, 2026 14:26
@alexrepty alexrepty changed the title feat(paywalls): add web_view message value types feat(paywalls): add web_view message value types (PWENG-98) Jun 29, 2026
@alexrepty alexrepty force-pushed the alexrepty/paywalls-web-view-csp branch from 353f584 to df0ae01 Compare June 29, 2026 13:58
@alexrepty alexrepty force-pushed the alexrepty/paywalls-web-view-value-types branch 2 times, most recently from 81453b8 to 5505947 Compare June 29, 2026 14:14
@alexrepty alexrepty force-pushed the alexrepty/paywalls-web-view-csp branch from df0ae01 to 22be911 Compare June 29, 2026 14:14
@alexrepty alexrepty marked this pull request as ready for review June 29, 2026 14:42
@alexrepty alexrepty requested a review from a team as a code owner June 29, 2026 14:42
@alexrepty alexrepty force-pushed the alexrepty/paywalls-web-view-csp branch from 22be911 to 9cff885 Compare June 30, 2026 07:44
@alexrepty alexrepty force-pushed the alexrepty/paywalls-web-view-value-types branch 2 times, most recently from 74610d7 to a42c874 Compare June 30, 2026 08:43
@alexrepty alexrepty force-pushed the alexrepty/paywalls-web-view-csp branch from 9cff885 to 9349754 Compare June 30, 2026 08:43
@AlvaroBrey AlvaroBrey force-pushed the alexrepty/paywalls-web-view-value-types branch from a42c874 to 7aceb78 Compare July 6, 2026 08:12
@AlvaroBrey AlvaroBrey force-pushed the alexrepty/paywalls-web-view-csp branch from 9349754 to 428d1c2 Compare July 6, 2026 08:12
@AlvaroBrey AlvaroBrey self-assigned this Jul 6, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 7aceb78. Configure here.

public constructor(value: kotlin.Float) : this(value.toDouble())

override fun equals(other: Any?): kotlin.Boolean = other is Number && value == other.value
override fun hashCode(): Int = value.hashCode()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Number.equals/hashCode contract violation with IEEE 754 doubles

Low Severity

Number.equals uses IEEE 754 == (value == other.value) while hashCode delegates to Double.hashCode() which uses doubleToLongBits. This breaks the equals/hashCode contract: Number(0.0) and Number(-0.0) are equal but produce different hash codes, and Number(NaN) violates reflexivity (not equal to itself). Using value.toBits() == other.value.toBits() in equals would make both methods consistent.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 7aceb78. Configure here.

@AlvaroBrey AlvaroBrey force-pushed the alexrepty/paywalls-web-view-csp branch from 428d1c2 to ef64abf Compare July 6, 2026 13:57
@AlvaroBrey AlvaroBrey force-pushed the alexrepty/paywalls-web-view-value-types branch from 7aceb78 to cf8d3d0 Compare July 6, 2026 13:57
@AlvaroBrey AlvaroBrey marked this pull request as draft July 6, 2026 14:42
Adds a bidirectional JS<->native bridge for the Paywalls V2 `web_view` component: a document-start `window.RevenueCatWebView` shim, message parsing/validation (`WebViewMessageParser`, `WebViewMessageType`), the public `PaywallWebViewMessage` / `PaywallWebViewValue` / `PaywallWebViewMessageHandler` / `PaywallWebViewController` surface, and an SDK-managed variables provider (locale, color scheme, custom variables). Apps opt in via `PaywallOptions.setWebViewMessageHandler(...)`, threaded through `PaywallState` / `OfferingToStateMapper`.

Regenerates ui/revenuecatui/api.txt for the new public API.

Recommended labels: pr:feat, pr:RevenueCatUI, feat:Paywalls_V2
@AlvaroBrey AlvaroBrey force-pushed the alexrepty/paywalls-web-view-csp branch from ef64abf to c25018a Compare July 7, 2026 13:22
@AlvaroBrey AlvaroBrey force-pushed the alexrepty/paywalls-web-view-value-types branch from cf8d3d0 to 9cad6e3 Compare July 7, 2026 13:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants