Rovenue SDK
FunnelsNative

Purchases & Effects

What a native funnel session yields — effects, the store purchase path, attributes, dismissal, and resume.

A running session answers every interaction with a step: the screen to draw plus the effects the host must act on. The effect vocabulary lives in one place — FunnelEffect in librovenue.udl (packages/core-rs/src/librovenue.udl:351-360): Dismiss, OpenUrl, ShowAlert, Custom, Purchase, and RestorePurchases. Navigation, variables and visibility are the machine's own business and produce no effect (packages/funnel-core-rs/src/actions.rs:146-147).

Buying: purchase_selected and restore_purchases

An authored purchase_selected action means the funnel waits on the store (packages/funnel-core-rs/src/actions.rs:126-129). It surfaces to the host as a Purchase effect carrying the selected package id; restore_purchases surfaces as RestorePurchases (packages/funnel-core-rs/src/actions.rs:170-179). The host completes both through the SDK's normal store purchase path — purchase alongside restorePurchases on every SDK (packages/sdk-swift/Sources/Rovenue/Rovenue.swift:835, packages/sdk-swift/Sources/Rovenue/Rovenue.swift:888, packages/sdk-kotlin/src/main/kotlin/dev/rovenue/sdk/Rovenue.kt:737, packages/sdk-kotlin/src/main/kotlin/dev/rovenue/sdk/Rovenue.kt:801, packages/sdk-rn/src/index.ts:54, packages/sdk-flutter/rovenue_flutter/lib/src/rovenue.dart:176, packages/sdk-flutter/rovenue_flutter/lib/src/rovenue.dart:196).

A purchase with nothing selected produces no effect at all — there is nothing to buy, and the screen's purchase button is disabled in that state (packages/funnel-core-rs/src/actions.rs:170-173). The purchase the host then makes carries the funnel's attribution snapshot, so revenue lands on the placement, funnel and variant that converted the subscriber: without it a purchase made inside a funnel lands unattributed and nothing errors (packages/core-rs/src/librovenue.udl:164-167).

set_attribute never reaches the host

SetAttribute is deliberately absent from the effect enum: librovenue intercepts it and routes it into the existing attributes module, so it is never implemented three times (packages/core-rs/src/librovenue.udl:348-350, packages/core-rs/src/funnel/session.rs:18). Inside the session the step converter absorbs it — recorded for the owning core to flush through its attributes path — while every other effect is forwarded to the host (packages/core-rs/src/funnel/session.rs:316-322).

Ending: close_funnel and dismiss()

An authored close_funnel action means the funnel is over (packages/funnel-core-rs/src/actions.rs:124-126); it surfaces as the Dismiss effect (packages/funnel-core-rs/src/actions.rs:151). The host side is dismiss(): the façade calls it when the host closes the view or on a Dismiss effect, and it emits funnel_dismiss — once only, so a close handler firing twice never double-counts the dismissal (packages/core-rs/src/funnel/session.rs:421-427).

Resume: state_json restores and re-emits nothing

state_json() persists the session — machine state plus the presentation id (packages/core-rs/src/funnel/session.rs:404-416). The host stores the string and hands it back to open_funnel as restored_state_json (packages/core-rs/src/librovenue.udl:373-376). A fresh open emits funnel_view plus funnel_screen_view for the first screen; a restored open emits nothing and keeps the stored presentation id, so the resumed session counts once (packages/core-rs/src/librovenue.udl:258-263, packages/core-rs/src/funnel/session.rs:186-192).

Restore seeds the emission tracking where the restored machine stands: the first post-restore step does not re-emit the arrival it resumes on, and an already-finished machine does not emit a completion for a funnel that ended before this wave (packages/core-rs/src/funnel/session.rs:237-248). A stored session recorded against a different funnel or revision is discarded rather than replayed, so handing back a stale one is safe (packages/sdk-swift/Sources/Rovenue/FunnelUI/ResolvedFunnel.swift:15-17). Garbage degrades to fresh; a pre-wave bare machine state still restores, with a fresh id (packages/core-rs/src/funnel/session.rs:452-466).

The device wire names are funnel_view, funnel_screen_view, funnel_complete and funnel_dismiss — a closed list; any other funnel_<x> stays outside the session vocabulary (apps/api/src/lib/funnel-event-shape.ts:86-91).

On this page