Skip to content

feat(worker): add Flagship binding#979

Open
connyay wants to merge 11 commits into
cloudflare:mainfrom
connyay:cjh-fun-with-flags
Open

feat(worker): add Flagship binding#979
connyay wants to merge 11 commits into
cloudflare:mainfrom
connyay:cjh-fun-with-flags

Conversation

@connyay
Copy link
Copy Markdown
Contributor

@connyay connyay commented Apr 20, 2026

Adds first-class support for the Flagship feature-flag binding announced on 2026-04-17. Users can now evaluate flags via env.flagship("FLAGS") with a fluent EvaluationContext builder and typed EvaluationDetails<T> responses.

  • worker-sys: raw wasm_bindgen externs for all 9 Flagship JS methods
  • worker: Flagship wrapper, EvaluationContext builder, EvaluationDetails
  • test: mini-flagship miniflare mock + 10 handlers + 16 vitest specs
  • examples/flagship: runnable worker demoing value/details/context usage

@connyay connyay marked this pull request as draft April 29, 2026 13:16
@connyay
Copy link
Copy Markdown
Contributor Author

connyay commented Apr 29, 2026

@guybedford I took an initial swing at ts-gen for flagship.

Mostly worked, but a few maybe controversial things:

(resolved) - promise values that returned primitives had pretty bad ergonomics: 1. promise values that returned primitives had pretty bad ergonomics: ```rust let value = env .flagship(BINDING)? .get_string_value(&flag, "fallback") .await? .as_string() .unwrap_or("fallback") ``` ~Tried this https://github.com/wasm-bindgen/ts-gen/pull/11 which improved consumer ergonomics at the cost of generation complexity and ugliness. let me know what you think.~

EDIT: less bad version wasm-bindgen/ts-gen#14

not too bad:

let value: bool = env
        .flagship(BINDING)?
        .get_boolean_value(&flag, false)
        .await?
        .value_of();
let value = String::from(
        env.flagship(BINDING)?
            .get_string_value(&flag, "fallback")
            .await?,
);
  1. I continue to fight with object generic / jsgeneric ergonomics in wasm
    with ootb ts-gen the .get_object_value call looked like:
pub async fn handle_object(req: Request, env: Env, _data: SomeSharedData) -> Result<Response> {
    let flag = last_segment(&req)?;
    let default = serde_wasm_bindgen::to_value(&default_theme())?;
    let raw = env
        .flagship(BINDING)?
        .get_object_value(&flag, &default)
        .await?;
    let value: Theme = serde_wasm_bindgen::from_value(raw)?;
    Response::from_json(&serde_json::json!({ "flag": flag, "value": value }))
}

yuck. fix for this was to comment out the type for generation and handroll. open to ideas to improve this. hit similar stuff in workflows as we've discussed before #918 (comment)

  1. the ts-gen _with_record_N generation is pretty nasty.
    what do you think about Collapse Record<K, Union> per-arm explosion to a single binding wasm-bindgen/ts-gen#13

@guybedford
Copy link
Copy Markdown
Collaborator

Thanks for working through the concerns here! This gives a lot of interesting feedback to think about - I will look into this next week and see if I can come up with some further suggestions as well.

Comment thread examples/flagship/src/lib.rs Outdated
@connyay connyay marked this pull request as ready for review April 30, 2026 01:09
@guybedford
Copy link
Copy Markdown
Collaborator

I ran out of time again this week to include this one - but there are a number of major updates to ts-gen that might update this output considerably.

It would be good to continue working through the outstanding bindgen edges here, perhaps we can sync on this via Discord or otherwise further.

@guybedford guybedford force-pushed the cjh-fun-with-flags branch from e9d6b11 to 933d664 Compare May 15, 2026 00:12
@guybedford
Copy link
Copy Markdown
Collaborator

I updated this to the latest ts-gen which now outputs correct generics. @connyay please take a look.

I agree with the use of wrappers to support custom structs for details and object types - at least until we can support first-class structs in wasm-bindgen itself. This is great feedback to motivate that work.

Overall, the current approach looks good to land to me, and we now no longer name methods like record2 etc in ts-gen rather using descriptive names based on param positions.

Please let me know if you spot any more rough edges!

@connyay
Copy link
Copy Markdown
Contributor Author

connyay commented May 22, 2026

This looks great to me! Ship it

connyay and others added 9 commits May 25, 2026 11:53
Adds first-class support for the Flagship feature-flag binding announced
on 2026-04-17. Users can now evaluate flags via `env.flagship("FLAGS")`
with a fluent `EvaluationContext` builder and typed `EvaluationDetails<T>`
responses.

- worker-sys: raw wasm_bindgen externs for all 9 Flagship JS methods
- worker: Flagship wrapper, EvaluationContext builder, EvaluationDetails<T>
- test: mini-flagship miniflare mock + 10 handlers + 16 vitest specs
- examples/flagship: runnable worker demoing value/details/context usage
@guybedford guybedford force-pushed the cjh-fun-with-flags branch from 933d664 to 2e0c8f3 Compare May 25, 2026 18:55
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 25, 2026

Merging this PR will not alter performance

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

✅ 2 untouched benchmarks


Comparing connyay:cjh-fun-with-flags (79452f8) with main (df7593a)

Open in CodSpeed

@guybedford
Copy link
Copy Markdown
Collaborator

Putting some more thought to this the JsString etc generics just don't work nicely. Instead I posted wasm-bindgen/wasm-bindgen#5167 and have based the bindings to that which support proper primitive generic types in the functions and FlagshipEvaluationDetails.

After the next release of wasm-bindgen will re-evaluate then. There are likely further improvements that can be made as well.

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.

2 participants