Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,9 @@ These features exist in the Roku SDK but were removed from JS SDK v2. Keep them
| `refresh()` manual refresh | Caller-driven refresh on app resume |
| `onReady` / `onRefresh` / `onUpdate` callbacks (SGNode events `ready` / `refreshed` / `updated`) | Roku event model uses field observers, not Promises |
| `activate()` method | Experiment activation tracking is useful for analytics |
| `interceptContext` / `configureBucketKey` / `configureBucketValue` callbacks | Needed until hooks system is implemented |
| `interceptContext` / `configureBucketKey` / `configureBucketValue` callbacks | Legacy callbacks kept alongside the new hooks system for backward compat |
| `initialFeatures` option | Before datafile loads, return known defaults |
| `spawn()` / child instances | No concrete Roku use case; deferred — requires OverrideOptions per-call sticky to be useful |

---

Expand All @@ -77,6 +78,7 @@ These features exist in the Roku SDK but were removed from JS SDK v2. Keep them
|------|---------------|
| `FeaturevisorSDK.brs` | Public API factory — thin wrapper over the SGNode instance |
| `Featurevisor.instance.brs` | Core evaluation engine (`evaluateFlag`, `evaluateVariation`, `evaluateVariable`, context, sticky, bucketing) |
| `FeaturevisorHooks.brs` | Hooks manager — `add`, `remove`, `getAll` for `before`/`after`/`bucketKey`/`bucketValue` hooks |
| `Featurevisor.instance.xml` | SGNode definition (fields: `ready`, `activated`, `refreshed`, `updated`) |
| `Featurevisor.request.brs` | HTTP task for datafile fetch (uses createRequest) |
| `FeaturevisorDatafileReader.brs` | Datafile accessor — handles both v1 (array) and v2 (dict) for features/segments |
Expand Down
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ Visit [https://featurevisor.com/docs/sdks/roku](https://featurevisor.com/docs/sd
- [`f.startRefreshing`](#fstartrefreshing)
- [`f.stopRefreshing`](#fstoprefreshing)
- [Evaluation object](#evaluation-object)
- [Differences from the JS SDK](#differences-from-the-js-sdk)

## Installation

Expand Down Expand Up @@ -737,18 +738,34 @@ The `evaluateFlag`, `evaluateVariation`, and `evaluateVariable` methods return a
| `"initial"` | Instance not yet ready; using `initialFeatures` value |
| `"no_match"` | No traffic rule matched |
| `"no_variations"` | Feature has no variations defined |
| `"not_found"` | Feature not found in the datafile |
| `"feature_not_found"` | Feature not found in the datafile |
| `"variable_not_found"` | Variable key not found in the feature's schema |
| `"out_of_range"` | Feature is in a mutually-exclusive group but bucket is out of range|
| `"override"` | Variable overridden by a condition inside a variation (v1 format) |
| `"required"` | A required feature is not enabled |
| `"rule"` | Matched a traffic rule |
| `"sticky"` | Using a sticky feature override |
| `"variable_default"` | Variable falls back to its `defaultValue` |
| `"variable_disabled"` | Feature is disabled; variable `disabledValue` is returned |
| `"variable_override_rule"` | Variable overridden directly by a traffic rule |
| `"variable_override_variation"` | Variable overridden by a condition inside a variation |
| `"variation_disabled"` | Feature is disabled; `disabledVariationValue` is returned |

## Differences from the JS SDK

The Roku SDK intentionally diverges from the JavaScript SDK in the following ways:

| Feature | Why |
|---------|-----|
| `datafileUrl` + HTTP fetch | Roku apps fetch the datafile themselves; there is no built-in fetch API outside the SDK |
| `refreshInterval` + `startRefreshing()` / `stopRefreshing()` | TV apps need periodic polling; no background threads available |
| `refresh()` manual method | Caller-driven refresh on app resume |
| `onReady` / `onRefresh` / `onUpdate` / `onDatafileChanged` / `onContextChanged` / `onStickyChanged` callbacks | Roku uses SGNode field observers, not Promises or EventEmitter |
| `activate()` method | Experiment activation tracking for analytics |
| `interceptContext` / `configureBucketKey` / `configureBucketValue` callbacks | Legacy callback API; kept alongside the hooks system |
| `initialFeatures` option | Return known defaults before the datafile loads |
| `spawn()` / child instances | No concrete Roku use case identified; deferred — no equivalent implementation planned |

## License <!-- omit in toc -->

MIT © Błażej Chełkowski
Loading