Repository navigation
Commit 79b52cd
feat: add YAML flag configuration loading with schema validation (#7)
* feat: add YAML flag configuration loading with schema validation
- Add serde_yaml dependency (non-WASM only) to Rust core and Python crate
- Add src/yaml.rs with yaml_to_json() conversion helper
- Add FlagEvaluator::update_state_from_yaml() in Rust (non-WASM only)
- Add FlagEvaluator.updateStateFromYaml() in Java with SnakeYAML
- Add update_state_from_yaml() in Python PyO3 bindings
- Expose yaml module in lib.rs (non-WASM only)
- Add Rust integration tests (yaml_tests module)
- Add Java YamlLoadingTest
- Add Python tests/test_yaml.py
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>
* fix(yaml): address review comments and fix formatting
- Extract static YAML_PARSER field in Java FlagEvaluator
- Simplify exception handling in updateStateFromYaml
- Use complete JSON equivalent in Java parity test
- Extract update_caches_from_response helper in Python
- Use complete JSON equivalent in Python parity test
- Fix Rust formatting (cargo fmt)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>
* feat(java): auto-detect JSON vs YAML in updateState
Addresses review comment: consumers should not need to specify the
string format. updateState now detects JSON (starts with '{') and
treats everything else as YAML, converting via SnakeYAML before
passing to the WASM boundary.
updateStateFromYaml is kept for explicitness but delegates to
updateState.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>
* feat: move YAML conversion into WASM module
serde_yaml 0.9 compiles to wasm32-unknown-unknown, so YAML conversion
can be owned by the WASM module rather than each language binding.
- Move serde_yaml from cfg-gated to regular [dependencies]
- Remove #[cfg(not(target_family = "wasm"))] gate from yaml module
- Remove cfg gate from FlagEvaluator::update_state_from_yaml
- Expose update_state_from_yaml as a WASM export
- update_state auto-detects JSON vs YAML ('{' prefix = JSON, else YAML)
- Remove cfg gate from yaml_tests in integration_tests.rs
- Remove SnakeYAML dependency from Java (no host-side conversion)
- Simplify Java updateState to pass raw string directly to WASM
- updateInstance now throws EvaluatorException on success=false
- Remove serde_yaml from Python binding Cargo.toml
- Python update_state_from_yaml delegates to inner.update_state_from_yaml
Bindings are now format-agnostic: pass JSON or YAML, WASM handles both.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>
* refactor: unified update_state API accepts JSON or YAML string
The WASM module now owns YAML conversion — serde_yaml 0.9 compiles to
wasm32-unknown-unknown so no host-side conversion is needed.
- update_state WASM export auto-detects JSON (starts with '{') vs YAML
- Remove update_state_from_yaml WASM export (redundant)
- Java: remove SnakeYAML dependency, updateState passes raw string to WASM
- Python: update_state accepts str (JSON or YAML), remove update_state_from_yaml
- Update all Python tests to pass JSON strings instead of dicts
- serde_yaml promoted to regular dependency (no cfg gates)
- Add use pyo3::types::PyDict (not re-exported by pyo3::prelude in 0.22)
- Serialize WASM unit tests with static mutex to prevent global-state races
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>
* refactor: remove updateStateFromYaml convenience method
The WASM module owns YAML/JSON detection via update_state. There is no
need for a separate convenience method — updateState(String) accepts
both formats transparently. Remove updateStateFromYaml from Java and
update tests to call updateState directly. Clean up stale comment in
Python bindings.
Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: handle new CompiledNode variants from datalogic-rs 4.0.18
datalogic-rs 4.0.18 added CompiledVar, CompiledExists, CompiledSplitRegex
and CompiledStringConcat variants to CompiledNode. The walk_node_for_vars
match was non-exhaustive. Add a wildcard arm that conservatively returns
false (send full context) for any unknown variants.
Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(evaluator): handle CompiledVar/CompiledExists nodes and fix getrandom for WASM
datalogic-rs 4.0.18 introduced dedicated CompiledVar and CompiledExists nodes
replacing BuiltinOperator { opcode: Var/Exists }. Update walk_node_for_vars to
extract variable paths from PathSegment slices so required_context_keys works
correctly and optimization tests pass.
Also replace the wasm_js getrandom feature (browser-only) with the unsupported
cfg backend via .cargo/config.toml. This eliminates __wbg_getRandomValues imports
that broke wasmtime, Chicory, and wazero runtimes. The evaluator never calls
getrandom at runtime since murmurhash3 is fully deterministic.
Regenerate flagd_evaluator.wasm with the clean WASM binary.
Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(evaluator): update CompiledNode variant matching for datalogic-rs fork
Switch to tuple-variant syntax for CustomOperator, StructuredObject,
CompiledExists, CompiledSplitRegex, CompiledThrow to match the refactored
struct layout in the patched datalogic-rs fork.
Use [patch.crates-io] with git URL pointing to fix/wasm-wasmbind-unconditional
branch in aepfli/datalogic-rs, which removes the unconditional chrono/wasmbind
dependency on wasm32 targets. This eliminates __wbg_* browser imports that break
wasmtime, Chicory, and wazero. PR upstream: GoPlasmatic/datalogic-rs#48.
Regenerate flagd_evaluator.wasm — binary is now clean of wasm-bindgen imports.
Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(wasm): use datalogic-rs 4.0.19, no wasm-bindgen imports
Switch from git-patched fork to registry datalogic-rs 4.0.19 which fixed
the WASM browser dependency issue properly: the 'wasm' feature (chrono/wasmbind)
is now opt-in and disabled by default.
Use getrandom_backend="unsupported" cfg flag since nothing in the evaluation
path calls getrandom at runtime (ahash uses compile-time-rng, murmurhash3 is
deterministic). This produces a fully clean WASM binary with zero __wbg_*
imports.
Update walk_node_for_vars to use 4.0.19's tuple-variant CompiledNode API
(CustomOperator, StructuredObject, CompiledExists, CompiledSplitRegex,
CompiledThrow).
Result: flagd_evaluator.wasm has no wasm-bindgen imports at all — compatible
with Chicory, wazero, Wasmtime, and any other non-browser WASM runtime.
Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(wasm): provide custom getrandom backend to prevent runtime panic
ahash's default features include runtime-rng, which calls getrandom at
startup to XOR a runtime-random value into the compile-time seed. With
getrandom_backend="unsupported", this panicked (unreachable trap) on
every update_state call across all language runtimes.
Switch to getrandom_backend="custom" and define __getrandom_v03_custom
to fill with zeros. This is safe: ahash already has a strong compile-time
seed via const-random, and the evaluator has no cryptographic randomness
requirements. Result: zero __wbg_* imports, no runtime panics.
Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* chore: update Cargo.lock for getrandom 0.3 custom backend dep
Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(dotnet): make wasm-bindgen imports optional in WasmRuntime
The WASM binary no longer has __wbindgen_placeholder__ imports since
switching to getrandom_backend="custom". WasmRuntime now only requires
host::get_current_time_unix_seconds and gracefully skips registration
of any wasm-bindgen functions that are absent from the module.
Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* docs: update HOST_FUNCTIONS.md to reflect single import
The WASM module now has only one import: host::get_current_time_unix_seconds.
All wasm-bindgen imports (__wbindgen_placeholder__, __wbindgen_externref_xform__)
were eliminated by switching to getrandom_backend="custom" and datalogic-rs
without the wasm feature. Update docs and java/README.md accordingly.
Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent 63b7879 commit 79b52cd
18 files changed
Lines changed: 915 additions & 445 deletions
File tree
- .cargo
- dotnet/src/FlagdEvaluator
- java
- src
- main/java/dev/openfeature/flagd/evaluator
- test/java/dev/openfeature/flagd/evaluator
- python
- src
- tests
- src
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
4 | 7 | | |
5 | 8 | | |
6 | | - | |
| 9 | + | |
| 10 | + | |
7 | 11 | | |
0 commit comments