Added
-
A borrowed number,
bool,charor borrowed string crosses by copy, so
&f64,&Option<T>,&Nullable<T>,Option<&f64>and
Option<&Nullable<T>>are argument types, and an
experimental_generic_monoimport taking&TacceptsT = f64,
Option<f64>orNullable<String>, as std'scontains(&T)does.
#5436 -
Added a rejection type parameter to
js_sys::Promise<T, E = JsValue>,
mirrored onJsFuture<T, E>,PromiseState<T, E>and
PromiseWithResolvers<T, E>. Awaiting aPromise<T, E>yields
Result<T, E>, converting the rejection reason as anEthe same unchecked
way the fulfilled value is converted as aT. Both parameters are covariant
underUpcast;catch,then_with_rejectand thewithResolversreject
function receive anE;all_tuple/all_settled_tuplecarry a sharedE
through; and underjs_sys_unstable_apis,Promise::new,Promise::reject
andPromise::anyare typed on the rejection too,anyas
AggregateError. The default keeps existingPromise<T>code unchanged.
PromiseWithResolvers<T, E>is invariant in both, since itsresolveand
rejectfunctions take them, andJsFuture<T, E>isUnwindSafewhenever
TandEare.
#5426 -
Added the
--js-string-builtinsCLI flag, importingstatic_string
constants as JS String Builtins
string constants fromwasm:js/string-constantsinstead of defining them in
the JS glue. With reference types,static_stringconstants now occupy
fixedexternreftable slots filled in when the module is instantiated, so
cloning and dropping them is free and never calls into JS.
#5401 -
Added
Nullable<T>, re-exported asjs_sys::Nullable, for aT | null
value at the JS boundary, asOption<T>is forT | undefined, with
Option<Nullable<T>>forT | null | undefined. Both are accepted wherever
Option<T>is, for everyTand in every position: JSnullis
Nullable::Nulland is sent back asnull, whileundefinedinto a plain
Nullable<T>goes toT's own conversion. A plainOption<T>still reads
bothundefinedandnullasNoneand writesNoneasundefined; the
Optionlayer ofOption<Nullable<T>>treats onlyundefinedasNone,
sincenullhas to reach theNullablelayer.Option<T>converts from
and intoNullable<T>, and
JsNullable<T>converts from both and intoOption<Nullable<T>>for
T: JsGeneric.
The API followsOption's, includingok_or,and_then,filter,
as_deref,take,replaceandIntoIterator, and
--cfg wasm_bindgen_unstable_try_traitenables?on nightly.
NullableIntoWasmAbi/NullableFromWasmAbicarryNullable<T>'snull
for everyT, and are supertraits ofJsStringLikeand the js-sys
primitive-union markers, soNullable<impl JsStringLike>and
Nullable<impl JsNumberOrStringLike>work underexperimental_generic_mono,
andNullable<T>erases likeOption<T>on a generic import.
#5410
#5423 -
Nullable<T>converts intoJsValuewithFrom,Nullbecomingnull
asNonebecomesundefinedforOption<T>, andOption<T>,
Nullable<T>andResult<T, E>arePromisingfor anyT: Promising,
so aPromise<Nullable<JsString>>awaits to aNullable<JsString>.
Stringand&strupcast toJsValue, andStringto itself, so a
Promise<String>from anexperimental_generic_monoimport isJsGeneric
and upcasts toPromise<JsValue>asPromise<bool>does. Together these
make aPromise<Nullable<JsString>>orPromise<String>from a mono
import usable wherever a promise is expected.&strandStringupcast to
each other, so anArray<&str>inferred from borrowed arguments settles to
Array<String>.Option<T>andNullable<T>upcast toJsValuewhenever
Tdoes, so aPromise<Option<String>>relabels toPromise<JsValue>, and
UndefinedandNullupcast toOption<T>andNulltoNullable<T>, so a
Function<fn(A) -> R>stands in for aFunction<fn(A, Option<B>) -> R>.
Every Rust and JS carrier wraps intoOption<Target>andNullable<Target>
whenever it upcasts toTarget, andNullable<T>upcasts toOption<T>,
so anArray<JsString>relabels toArray<Option<JsString>>or
Array<Option<Nullable<JsString>>>, and aFunction<fn(Option<T>) -> R>
stands in for aFunction<fn(T) -> R>.
#5427
#5437 -
Added
MaybeIntoWasmAbi/MaybeFromWasmAbi, the ABI ofOption<T>for
everyT, with an associatedMaybeAbithat lets a type without a spare
value in its own ABI, such asi32orf64, pick a wider one.Option<T>
converts through it, and a blanket impl provides it for every
OptionIntoWasmAbi/OptionFromWasmAbitype, so existing impls and bounds
are unaffected.NullableIntoWasmAbi/NullableFromWasmAbiextend it with
null. As a result,Option<impl JsNumberOrStringLike>and the other
primitive-union bounds now work inexperimental_generic_monoimports
without awhere Option<T>: IntoWasmAbiclause.
#5423 -
Under
js_sys_unstable_apis,RegExp::execandJsString::match_return
Nullable<T>rather thanOption<T>, as the JS APIs returnnullon no
match.
#5410 -
Added the
slice = view | copy | arrayandvec = copy | array
attributes for imported JS functions, choosing what JS receives for a
sequence argument with numeric elements: a live typed array over wasm
memory, a fresh typed array, or a fresh plainArray.sliceapplies to
borrowed slices (&[T],Option<&[T]>,Clamped<&[u8]>) andvecto
owned ones (Vec<T>,Box<[T]>,Option<Vec<T>>,Clamped<Vec<u8>>).
Each key is accepted per argument, per function and perextern "C"block,
with a more specific level overriding a broader one. Inherited from a
function or block, a key only affects arguments of its own shape; written
on an argument it doesn't fit, it is an error. A generic element type
resolves the mode per instantiation underexperimental_generic_mono,
whereOption<&[T]>is now supported too. Neither key is accepted on
exported functions.
#5384 -
Borrowed slices of
String,&str,bool,charand exported enums
(&[T]andOption<&[T]>) can be passed to imported JS functions,
arriving as a freshArray.
#5384 -
Slices of every
JsStringLikeshape, including&String,&Box<str>,
&Cow<str>and&JsString, can be passed to imported JS functions, and
JsStringLikealone bounds a&[T]argument of an
experimental_generic_monoimport.
#5384 -
Owned vectors (
Vec<T>,Box<[T]>,Option<Vec<T>>) ofbool,char
and string enums can be passed to and from JS, andVec<&str>can be
passed to JS.
#5384 -
String enums implement
TryFromJsValue, accepting only their listed values,
so they can be used as dynamic-union variant payloads.
#5376 -
Added
JsValue::from_utf8_lossyto create a JS string directly from a
&[u8], decoding on the JS side with replacement characters for invalid
UTF-8 instead of requiring aString::from_utf8_lossyallocation first.
#5370 -
Documented in the guide that passing an exported Rust type by value moves it
out of the JavaScript object, which throws on any later use.
#5354 -
Added Rolldown compatibility to the deployment docs in the guide.
#5355 -
Added
sourceproperty to ToggleEvent.
#5353 -
Added 11 experimental
js-sysmarker traits for every union of two or more
of the TypeScriptbigint,boolean,number, andstringprimitive
categories. Traits such asJsNumberOrStringLikecan bound
experimental_generic_monoimport parameters while preserving each concrete
Rust type's native ABI representation. String-containing unions accept every
wasm_bindgen::JsStringLiketype.
#5341 -
Added the experimental
js_sys::PropertyKeymarker trait for the
string | number | symbolkeys accepted by TypeScript'sRecordtype.
JsNumberOrStringLikewidens toPropertyKey.
#5341 -
JsStringLikeand thejs-sysstring primitive-union traits now accept
&String,&Box<str>and&Cow<str>. These shapes, andOptionof each,
also work as plain import argument types.
#5374 -
Added support for threads on memory64 (
wasm64-unknown-unknownwith
+atomics). On memory64,__wbindgen_thread_destroytakes JS numbers.
#5378 -
Added
js-sysbindings for the modern ECMAScript builtins that were still
missing: theIteratorhelpers (Iterator.fromasfrom_iterable,
Iterator.concat,map,
filter,take,drop,flatMap,reduce,toArray,forEach,some,
every,find),Map/WeakMapgetOrInsertandgetOrInsertComputed,
Object.groupByandMap.groupBy,Promise.tryand
Promise.withResolvers(with aPromiseWithResolvers<T>type), explicit
resource management (DisposableStack,AsyncDisposableStack,
SuppressedError,Symbol.dispose,Symbol.asyncDispose),Uint8Array
base64 and hex conversion (fromBase64,fromHex,toBase64,toHex,
setFromBase64,setFromHex, withBase64Options, itsBase64Alphabet
andBase64LastChunkHandlingenums and aSetFromResulttype),Error.isError,Math.sumPrecise,Math.f16round,
RegExp.escapeand thedotAll,hasIndicesandunicodeSetsflag
getters,String.prototype.isWellFormedandtoWellFormed,
Symbol.prototype.description,JSON.rawJSONandJSON.isRawJSON, and
the typed arraytoReversed,toSorted,with,findLast,
findLastIndex,includesandindexOfmethods. From ECMA-402, the
Intl.LocalefirstDayOfWeekandvariantsgetters. From the WebAssembly
JS API,WebAssembly.JSTag, the compile-options variants ofvalidate,
compile,compileStreaming,instantiate,instantiateStreamingand
theModuleconstructor (taking aCompileOptionsdictionary, with an
InstantiatedSourceresult type),
MemorytoResizableBufferandtoFixedLengthBuffer,Global.valueOf
andException.stack.
#5403
#5421
Changed
-
Reworked the
js_sys::Temporalbindings andDate::to_temporal_instant,
which stay behindjs_sys_unstable_apisand now also need the newtemporal
feature, against the final Stage 4
specification and reshaped them to the web-sys conventions. Inputs are
typed:*Likedictionaries such asPlainDateLikeforfrom, calendar-free
*Fieldsdictionaries forwith, and the bare form of a method takes the
type its argument converts to (&strtime zones and calendars,&PlainTime,
&Duration,&Selfforuntil/since/equals), while every other member
of a specification union gets a_with_<type>variant, so
with_calendar_with_plain_date,add_with_duration_like,add_with_str,
equals_with_zoned_date_time,with_plain_time_with_str,
PlainYearMonth::from_with_plain_dateand the typedrelativeTo,calendar,
timeZoneandplainTimedictionary setters all exist;comparekeeps
taking&Selfonly. Optional arguments expand to the plain method plus
_with_options/_and_options,to_locale_stringtakes no locale, a
_with_str/_with_str_sequenceone or anOption<&str>with options, andround,
totalandget_time_zone_transitiontake their options dictionary, with
round_with_unit,total_with_unitand
get_time_zone_transition_with_directionshortcuts. The option dictionaries
areOverflowOptions,DifferenceOptions,RoundToOptions::new(unit),
DurationTotalOptions::new(unit),TimeZoneTransitionOptions::new(direction)
and friends, the enums drop theirTemporalprefix (Overflow,Unit,
LargestUnit,TransitionDirection, …). Bindings for the removed
toPlainYearMonth/toPlainMonthDayonPlainDateTimeandZonedDateTime,
ZonedDateTime::with_plain_dateandPlainTime::to_plain_date_timeare gone,
offset_nanosecondsreturnsf64,era,era_year,week_of_yearand
year_of_weekreturnOptions,fractionalSecondDigitsis au8,
get_time_zone_transitionreturnsNullable<ZonedDateTime>,
to_js_string_with_optionsandto_locale_stringare fallible, constructors
expand their optional trailing fields (PlainTime::new(),new_with_hour, …,
PlainDate::new_with_calendar), andcatchfollows the specification:
equals,compare, the typedfromforms (exceptPlainYearMonth's date
conversions, which can leave the range) and the option-less
Instant/PlainTimearithmetic are infallible, while
ZonedDateTime::start_of_day,hours_in_dayand
PlainDate::to_plain_year_monthare fallible. Fallible bindings return
Result<T, RangeError>, orResult<T, Error>where a property bag, a
relativeTo/plainTimeunion orIntloptions can also throw aTypeError.PartialEq/Eqon the
date-time types compare by the specequals(), andInstantandPlainTime
areOrdthroughcompare().
#5402 -
The js-sys
JsFunction*traits' associated types (Ret,ArgN,BindN)
no longer carry aJsGenericbound, so aFunction<fn(..)>signature may
name a converted carrier such asNullable<JsString>, and
Function::from_closureaccepts a closure with converted arguments. Generic
code over these traits that callscall*orbind*now needs the bound
itself, aswhere F::Ret: JsGeneric, F::Arg1: JsGeneric. The hidden
PromiseTupletrait'sJoinedandSettledlikewise drop it, its
Rust-tuple impl packing the promise handles directly rather than upcasting
each, and the
JsGenericbounds that only existed to satisfy aFunction<fn(..)>slot
or to tag a type argument are gone:Promising for Promise<T, E>,
Promise::new_typed, thePromiseWithResolversresolve/reject
getters, thePropertyDescriptorget/setaccessors,WeakMap::newand
theentries/from_entriesfamily ofArray,Set,MapandObject.
#5427 -
Option<T>: TryFromJsValuenow readsnullasNone, as theOption<T>
ABI does, soOption::<JsValue>::try_from_js_value(JsValue::NULL)is
Nonewhere it wasSome(null). ATthat acceptsnullas a distinct
value space sets the newTryFromJsValue::NULLABLEconst, as
Nullable<T>does, and anOptionof it passesnullthrough, so
Option<Nullable<T>>reads it asSome(Nullable::Null).Nullable<T>
itself converts from aJsValuewithTryFromJsValue.
#5427 -
With reference types,
static_stringconstants and the reserved
undefined,null,trueandfalsevalues are stored at fixed slots of
theexternreftable, which is now sized to include them, and cloning or
dropping them no longer allocates or calls into JS. The per-string JS import
function is no longer emitted.
#5401 -
Breaking (experimental):
experimental_generic_monoimports no longer add
hidden ABI bounds to the generated wrapper. The conversion bounds each
position needs are now declared on the import like any other bound:
T: IntoWasmAbifor an argument,T: RefIntoWasmAbi(a new trait in
wasm_bindgen::convert) for a&Targument,T: VectorRefIntoWasmAbifor a
&[T]orOption<&[T]>argument,T: FromWasmAbifor a return
(+ 'staticwhenasync),A: FromWasmAbifor a callback argument and
R: IntoWasmAbifor a callback return. A missing bound is reported at the
position that needs it.
#5385 -
The generated
TextDecoderno longer setsfatal: true. Rust&stris
always valid UTF-8, so this only removes a redundant check and lets
JsValue::from_strandJsValue::from_utf8_lossyshare a single decoder.
#5370 -
Replaced the
once_celldependency withcore::cell::LazyCell, which is
available now that the library MSRV is 1.81.
#5359 -
Under
js_sys_unstable_apis, the unsuffixedObject::define_property,
Object::from_entries,Object::get_own_property_descriptor,
Object::has_own,Object::property_is_enumerable,
Reflect::define_property,Reflect::delete_property,Reflect::get,
Reflect::get_own_property_descriptor,Reflect::has, andReflect::set
now take a genericK: PropertyKeykey, accepting string, number, or symbol
keys.Object::get_own_property_descriptorand
Reflect::get_own_property_descriptornow return
Option<PropertyDescriptor<T>>, andReflect::hasnow takes an
&Object<T>target. Callers passing&"key".into()should pass"key"(or
another concrete key type) instead.
#5341 -
wasm-bindgen-testno longer depends onasync-trait. Its benchmark code
now uses nativeasync fnin traits.
#5365 -
Escape string inputs in
debugString.
#5366 -
#[wasm_bindgen]now warns when a function sets more than one ofthis,
getter,setter,indexing_getter,indexing_setterand
indexing_deleter. Only one of them takes effect, and the others used to be
ignored silently. Conflicting options will be an error in the next major
version.
#4272
#5369 -
&[T],Vec<T>,Box<[T]>,Option<Vec<T>>andOption<Box<[T]>>
arguments with a number element type are now declared in TypeScript and
JSDoc as the typed array or a plain array (e.g.Uint8Array | number[], or
BigInt64Array | bigint[]for 64-bit elements), matching what the generated
JS already accepts. Read-write struct fields of these types are declared as
a getter and setter pair.&mut [T]arguments still take only a typed
array, since the results are copied back into its buffer, and so do
Clampedarguments, since numbers in a plain array would wrap around
instead of being clamped.
#4504 -
Numeric enums are passed between JS and Rust as an
f64, so a value from
JS that isn't one of the enum's values, such as'abc',NaN,1.5or
2 ** 32, throws "invalid enum value passed" in release builds too,
rather than becoming variant 0 or being truncated. Conversions from
JsValuelikewise rejectNaNand fractions. Values above
i32::MAXin a#[repr(u32)]enum are now returned to JS unchanged
rather than as negative numbers.
#5384 -
A
Vec<T>of a numeric enum passed from JS checks each element as a
single enum value, so a wrong element throws the same error a single
argument would, rather than "array contains a value of the wrong type".
#5384
Fixed
-
Upcast::upcastandupcast_intono longer let a safeUpcastFromimpl
extend a borrow's lifetime:ErasableGeneric::Reprnow keeps the real
lifetime of a reference, slice,&str, closure reference or
ScopedClosureinstead of'static, so theRepr-equality bound rejects
such an upcast. A generic import likewise no longer accepts an owned
ScopedClosurethat borrows a non-'staticvalue, which handed JS a
closure over freed data; borrowed arguments, and owned ones that only
contain a borrow, still accept any lifetime.
#5178 -
Concurrent calls to the
webandno-modulesinit function no longer
instantiate the module more than once; later calls share the in-flight
initialization and resolve to the same instance.
#5429 -
js_sys::Promise::catch_map's handler now receives the rejection reason,
typed as the promise'sE, instead of the reason mislabelled as the
fulfilled typeT. A handler on aPromise<Foo>written as|v: Foo|must
takeJsValue; it was never aFoo.
#5426 -
Large JS snippets (
module = "...",inline_js) and
typescript_custom_sectionexpressions such asinclude_str!no longer make
compilation slow or print "constant evaluation is taking a long time"
warnings. The macro now lays out the__wasm_bindgen_unstablecustom section
as a#[repr(C)]struct of byte arrays, so const evaluation copies each
chunk at once instead of byte by byte. A crate with a 5 MB snippet went from
64 s to under a second forcargo check; the section's bytes are unchanged.
#5413 -
Emscripten output now keeps a
privateclass that is only created from
Rust, such as one converted into aJsValueand passed to JS. Every
generated function that references a class by name now lists it in its
__deps. Previously emcc dropped the class, and calling into it failed with
ReferenceError: <Class> is not defined.
#5415 -
Imported methods, static methods and constructors without a
js_classnow
bind to thejs_nameandjs_namespaceof the type they belong to when that
type is declared in the sameextern "C"block. Previously they used the
type's Rust name, so for example a constructor of
#[wasm_bindgen(js_name = CustomName)] type Type;callednew Type().
#5391 -
Lists passed from JS to Rust no longer leak memory when an element is
rejected, such as a value of the wrong type in aVec<String>or
Vec<T>of exported structs, or an invalid value in aVec<T>of a
numeric enum.
#5384 -
An exported function or closure that rejects an argument from JS, such as
an invalid numeric enum value or an exported struct that is still borrowed,
no longer leaks its other arguments or leaves an exported object it borrowed,
includingself, permanently borrowed. Field setters,free()on a
borrowed object, closures called after being dropped andFnOnceclosures
called twice also release what JS passed them. The same holds when the
generated JS rejects an argument before calling Rust, such as an object of
the wrong class or a number passed for au64, after copying an earlier
string or array into Wasm memory.
#5388 -
An exported function taking an
Option<JsValue>, or without reference
types an ownedJsValue, no longer leaks an externref table or JS heap
slot when Wasm rejects a later numeric argument, such as a number passed
for au64.
#5404 -
The test runner works again with
WASM_BINDGEN_NO_DEBUG=1, so a test suite
can run against the glue a release build gets. The tests are reached through
the__wasmexport, which only debug glue has had since #4879; the new
Bindgen::export_wasmoption exports it on its own.
#5404 -
An
asyncexport now converts its arguments when it is called, rather than
when its future is first polled. A rejected argument rejects the returned
promise, instead of throwing from the task queue, and anasyncmethod's
selfstays borrowed from the call on, so freeing the object before the
future runs throws instead of leaving the method with a freedself.
#5388 -
Reference types are now detected from the runtime's externref intrinsics when
thetarget_featuressection is missing, as withstrip = true. Previously
such builds skipped the externref transform, and#[wasm_bindgen(catch)]
imports failed withexternref table required for catch wrappers. A warning
now recommends runningwasm-opton the wasm-bindgen output instead of
strip = true.
#5382 -
String enums, numeric enums and dynamic unions with the same name in
different modules of one crate are now handled like same-named items in
different crates: two public definitions report that the name is exported
multiple times, andprivatecopies are numbered (Mode,Mode2, ...).
Previouslywasm-bindgenfailed withdynamic union variant descriptor not foundorduplicate enums.
#5381 -
privatestring enums and dynamic unions with the same name in different
crates can now coexist, numbered like structs and numeric enums.
#5381 -
The TypeScript alias for a string enum that is only referenced through a
dynamic union is now emitted.
#5376 -
Attributes on imported statics, such as doc comments,
#[allow(...)],
#[deprecated]and#[cfg(...)], are now applied to the generated static
instead of being dropped.
#5377 -
Imported functions and statics from two different
inline_jssnippets no
longer share one binding when they have the same name and signature. The
snippet contents are now part of the generated shim name, so each import
reads its own snippet's export.
#3878 -
Imported types with the same Rust name no longer share one
instanceof
check when their module,inline_jssnippet,js_nameorjs_namespace
differ. Importedstatic_stringstatics with the same name no longer share
one string.
#5352 -
Imported functions with the same name and signature no longer share one
binding when they differ in how JS is called:catch,variadic,final,
slice_to_array,suspending,experimental_generic_mono, the method kind
(constructor,static_method_of,getter,setter,indexing_*), or a
js_namewith characters that a shim name drops. Two
experimental_generic_monoimports that differ only in one of these now
both bind instead of failing the build.
#5352 -
debugStringhandlesbigintvalues (e.g.123n).
#5356 -
Fixed JSPI task pointers being truncated to 32 bits on
wasm64.
#5358 -
Return pointers above 2 GiB on
wasm32(e.g. thread stacks allocated under
+atomics) are no longer treated as negative offsets in the generated JS,
which previously threw aRangeErroron number and string conversions.
#5360 -
With
--debug, passing a value that is not an object with a numeric
length, such as anArrayBufferor a string, where Rust takes&[T],
Vec<T>,Box<[T]>orOption<Vec<T>>now throws an error naming the
expected and received types, instead of silently passing an empty or zeroed
slice.&mut [T]arguments must be a typed array with the same element size
and the same integer or float kind, since the results are copied back into
its buffer.
#1961 -
Exported function arguments named like an identifier their generated JS
glue binds or references, such aswasm,retor a class name, no longer
shadow it, which made calling the function throw. Such arguments get a
numeric suffix in the JS, while the TypeScript definitions keep their name.
#3729 -
Getters generated by
getter_with_cloneno longer trigger the
clippy::clone_on_copylint.
#5363