diff --git a/CHANGELOG.md b/CHANGELOG.md index 1342cc12..7ae3dac0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,13 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve manual dispatch still run it. macOS jobs prefer Xcode libclang over Homebrew LLVM when present. +### Core + +- `rong` re-exports `TaskScope`. The scope methods reached embedders already, + being inherent on `JSContext`, but the type did not, so a scope could only + be opened and cancelled inside one function — never stored, which is what + one scope per request needs. + ## [0.6.2] - 2026-09-11 Independent crate and npm releases: first publish of `rong_crypto` 0.6.0, diff --git a/Cargo.toml b/Cargo.toml index 410bb81f..67c260df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -123,7 +123,7 @@ base64 = { version = "0.22.1" } [package] name = "rong" -version = "0.6.0" +version = "0.6.1" edition = "2024" description = "RongJS runtime and embedding API" diff --git a/src/lib.rs b/src/lib.rs index 41d89c5c..1864b217 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,7 +9,7 @@ pub use rong_core::{ JSRuntime as CoreJSRuntime, JSRuntimeService, JSSymbol as CoreJSSymbol, JSTypedArray as CoreJSTypedArray, JSTypedArrayKind, JSValue as CoreJSValue, JSValueType, JsonToJSValue, Promise as CorePromise, PropertyDescriptor as CorePropertyDescriptor, - RongJSError, Source, SourceKind, Uint8Clamped, error, illegal_constructor, + RongJSError, Source, SourceKind, TaskScope, Uint8Clamped, error, illegal_constructor, install_async_iterator_symbol, install_iterator_symbol, }; // Re-export selected runtime API from rong_core::rong so downstream crates use `rong::...` diff --git a/tests/task_scope.rs b/tests/task_scope.rs index c0ffdfab..6ab35885 100644 --- a/tests/task_scope.rs +++ b/tests/task_scope.rs @@ -185,3 +185,26 @@ fn scope_ids_are_not_reused_across_runtimes() { assert_eq!(ctx.current_task_scope(), Some(second)); assert!(ctx.cancel_task_scope(second)); } + +/// An embedder that opens a scope per request cannot open and cancel it in one +/// function: it opens the scope where the request starts and cancels it where +/// the request ends, so the value has to live in a field in between. Writing a +/// field means writing the type, which means `TaskScope` has to be reachable +/// under the name an embedder depends on — `rong`, not `rong_core`. +/// +/// Every other test here gets the type from inference, so none of them would +/// notice it missing from the facade. +#[test] +fn a_scope_can_be_stored_under_its_public_name() { + struct PendingRequest { + scope: TaskScope, + } + + let runtime = RongJS::runtime(); + let ctx = runtime.context(); + let request = PendingRequest { + scope: ctx.begin_task_scope(), + }; + // Opened elsewhere, cancelled here, exactly as a request's lifetime runs. + assert!(ctx.cancel_task_scope(request.scope)); +}