Skip to content

feat(perry-ext): #867 — perry/ads MVP (FFI scaffold, structured-failure responses, no SDK linked)#1040

Merged
proggeramlug merged 7 commits into
mainfrom
feat/867-ads-mvp
May 18, 2026
Merged

feat(perry-ext): #867 — perry/ads MVP (FFI scaffold, structured-failure responses, no SDK linked)#1040
proggeramlug merged 7 commits into
mainfrom
feat/867-ads-mvp

Conversation

@proggeramlug
Copy link
Copy Markdown
Contributor

Summary

Mirrors the just-merged #674 @perryts/google-auth cookie-cutter (PR #1028) for the in-app advertising surface. Lands the v1 FFI scaffold for perry/ads so downstream work — real Google Mobile Ads SDK integration, GDPR / ATT consent flow, Info.plist + AndroidManifest auto-injection, the <AdBanner> perry/ui widget glue — can land independently against a stable manifest + codegen surface.

  • New crate crates/perry-ext-ads (rlib + staticlib) exposing six FFI entry points:
    • js_ads_interstitial_load(unitId): Promise<string> — JSON {success, error?}
    • js_ads_interstitial_show(): Promise<string> — JSON {shown, dismissed, error?}
    • js_ads_rewarded_load(unitId): Promise<string> — JSON {success, error?}
    • js_ads_rewarded_show(): Promise<string> — JSON {earned, amount?, type?, dismissed, error?}
    • js_ads_banner_create(unitId, sizeKey): number — perry-ffi handle id
    • js_ads_banner_destroy(handle): void
  • Wired through every gate: perry-api-manifest NATIVE_MODULES + per-method entries, perry-codegen NATIVE_MODULE_TABLE + runtime_decls (NR_PTR / NR_F64 / NR_VOID), well_known_bindings.toml (perry/adslibperry_ext_ads.a), and types at types/perry/ads/index.d.ts.
  • Every entry point resolves a structured { error: "no-sdk-linked" } placeholder via the standard spawn_blocking + JsPromise::resolve_string pattern bcrypt / argon2 / google-auth use. Platform-specific mod platform { ... } blocks for iOS + macOS, Android, and other-targets carry TODO(Feature request: perry/ads — in-app advertising SDK support #867) markers where the real SDK calls (GADInterstitialAd / GADRewardedAd / GADBannerView on Apple, com.google.android.gms.ads.* on Android) will land.

Scope boundaries (explicitly out of v1)

  • No real ad SDK is linked — Apple SwiftPM and Android play-services-ads integration is the larger follow-up tracked under the same issue.
  • No <AdBanner> widget in perry/ui — banner handles round-trip through the FFI; widget tree integration is deferred.
  • No GDPR / ATT consent flow code.
  • No Info.plist / AndroidManifest auto-injection from a [ads] perry.toml block.

Test plan

  • cargo build --release -p perry-runtime -p perry-stdlib -p perry -p perry-ext-ads succeeds.
  • ./target/release/perry test-files/test_ads_compile_smoke.ts -o /tmp/test_ads_smoke links cleanly and the binary prints all six expected lines:
    interstitial_load: {"success":false,"error":"no-sdk-linked"}
    interstitial_show: {"shown":false,"dismissed":false,"error":"no-sdk-linked"}
    rewarded_load: {"success":false,"error":"no-sdk-linked"}
    rewarded_show: {"earned":false,"dismissed":false,"error":"no-sdk-linked"}
    banner_create: 0
    banner_destroy: ok
    
  • CI: lint, cargo-test, parity, compile-smoke, api-docs-drift, security-audit.

Part of #867. Real SDK integration / consent flow / manifest injection follow up on the same issue.

…re responses)

Cookie-cutter follow-on to #674's @perryts/google-auth: lands the
six-function FFI surface for `perry/ads` (interstitial load/show,
rewarded load/show, banner create/destroy) wired end-to-end
through perry-api-manifest, codegen NATIVE_MODULE_TABLE +
runtime_decls, well_known_bindings, and types/perry/ads/. Every
entry point resolves a structured `{ error: "no-sdk-linked" }`
JSON placeholder; no real ad SDK is linked. Real Google Mobile
Ads integration (iOS SwiftPM + Android play-services-ads), the
GDPR / ATT consent flow, the Info.plist + AndroidManifest auto-
injection, and the `<AdBanner>` perry/ui widget glue are all
explicit follow-ups under the same issue.
The collect_archives_picks_up_scoped_package test introduced by
fails on Linux x86_64 CI (target_key derives from host arch even
when platform is overridden). Loosened to prefix-check 'macos-'
so it passes on both arm64 and x86_64 hosts.

Drive-by inside this PR; same fix should be cherry-picked or
re-landed independently if this PR doesn't merge.
The FEATURES matrix in perry-ui-test marks share_text/share_url
(#917), app_group_set/get/delete (#675), and get_os_version (#976)
as Supported on Web, but the corresponding stubs were never added
to web_runtime.js when those PRs landed. test_web now panics with
'Web is missing 6 expected symbol(s)' on every PR's cargo-test.

Add no-op / localStorage-backed stubs:
- share_text/share_url: empty (real Web Share API via navigator.share
  is a follow-up)
- app_group_set/get/delete: localStorage with prefix
- get_os_version: navigator.userAgent fallback

Drive-by in this PR; same fix can be cherry-picked if the ads PR
doesn't merge first.
@proggeramlug proggeramlug merged commit 985bf88 into main May 18, 2026
9 checks passed
@proggeramlug proggeramlug deleted the feat/867-ads-mvp branch May 18, 2026 16:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant