Commit Graph
4 Commits
Author SHA1 Message Date
Antonio PallaresandCursor e6a0d9531c Compare strings by UTF-16 code unit in the rules engine (#7518)
* Compare strings by UTF-16 code unit in the rules engine

A JS string is a sequence of UTF-16 code units and every string operation
works on those units. Swift's String compares canonical equivalence over
Unicode scalars, so <, <=, >, >=, ==, ===, in and rc.entries key ordering
all had cases where a predicate evaluated one way on iOS and the other in
JS and Kotlin.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Keep the new fixture descriptions platform-neutral

The fixture files are byte-identical across the iOS and Android engines, so
a description that explains the contract in terms of one host language's
string comparison does not read correctly in the other repository.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Name the characters under test in the UTF-16 fixture descriptions

The predicates spell these strings as \uXXXX escapes so the exact code
units are unambiguous, which leaves a reader unable to tell which
character a fixture is about. Each description now shows the glyph and
its code point, and spells out the surrogate pair where one is the
point of the case.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Route rc.sortBy string keys through jsStringPrecedes

The operator open-coded the UTF-16 comparison because the shared helper
did not exist yet when it landed. It does now, and the rationale lives
in the helper's doc, so the operator no longer repeats it.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-01 10:51:39 +02:00
Antonio PallaresandCursor 2deacfd190 Add Scope plumbing and custom operator extension point (#7433)
* Add Scope plumbing and custom operator extension point

Thread evaluation scope through the rules engine and delegate unknown
operators to an empty CustomOperators dispatcher, without changing behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fix project.pbxproj: restore RewardedAdTrackingMetadata entries

The RulesEngine registration edit accidentally dropped four
RewardedAdTrackingMetadata.swift entries from the Xcode project.
Restore them and normalize CustomOperators identifiers to 24 hex chars.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Promote firstArgEvaluated to shared Operators helpers

Move the unary-arg helper from LogicOperators to Operators so custom
operators can use the same json-logic-js spread convention.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Address review comments on custom operator extension point

Drop the cross-engine registration note from CustomOperators, and restore
the single-line var extra-args warning that was reflowed without changing
its text.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-19 08:04:21 +00:00
Antonio PallaresandCursor f732e06eb6 refactor: namespace rules engine types under RulesEngine (#7295)
* refactor: move rules engine into core SDK as internal

Move the RulesEngineInternal sources and tests into the RevenueCat target
under Sources/RulesEngine and Tests/UnitTests/RulesEngine. The moved
symbols are marked internal so no new public API is exposed, and the
standalone RulesEngineInternal target is removed from Package manifests,
Tuist, the Xcode project, and CI. No usages yet.

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor: namespace rules engine types under RulesEngine

Nest the generically-named rules engine types (Value, Evaluator,
Operators and the per-category operator enums), the JS coercion helpers,
and PrintLogger inside the RulesEngine enum so the subsystem exposes a
single top-level symbol instead of polluting the RevenueCat module's
internal namespace. RulesEngineLogger stays top-level (already prefixed).
Production cross-references resolve via enclosing scope; tests use local
typealiases or explicit RulesEngine. qualification.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Document why the rules engine owns its own logging abstraction

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-27 18:26:46 +02:00
Antonio PallaresandCursor b8200785c7 refactor: move rules engine into core SDK as internal (#7292)
* refactor: move rules engine into core SDK as internal

Move the RulesEngineInternal sources and tests into the RevenueCat target
under Sources/RulesEngine and Tests/UnitTests/RulesEngine. The moved
symbols are marked internal so no new public API is exposed, and the
standalone RulesEngineInternal target is removed from Package manifests,
Tuist, the Xcode project, and CI. No usages yet.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Document why the rules engine owns its own logging abstraction

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-27 16:28:21 +02:00