Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upjs-sys: Expose bindings to ALL the global JS things #275
Comments
fitzgen
added
help wanted
good first issue
more-types
labels
Jun 18, 2018
fitzgen
changed the title
Expose bindings to all the global JS things
Expose bindings to ALL the global JS things
Jun 18, 2018
fitzgen
referenced this issue
Jun 18, 2018
Merged
Expose objects and functions from the JavaScript global scope #274
This comment has been minimized.
This comment has been minimized.
coreh
commented
Jun 19, 2018
|
Would it make sense to reference (or perhaps even automatically convert?) the TypeScript definitions for these? Additional definitions are separated per ES version and available on this directory. |
This comment has been minimized.
This comment has been minimized.
|
@coreh we are building a TypeScript frontend to For Web APIs, we intend to use our work-in-progress WebIDL frontend to generate a sys crate for the whole Web platform. WebIDL does give us more info, and crucially whether a method throws or not. |
This comment has been minimized.
This comment has been minimized.
|
I would like to help! I know some Javascript and i' m currently learning rust. But i want to understand, maybe my question is silly. What is the purpose of all this bindings ? |
This comment has been minimized.
This comment has been minimized.
|
How would multiple, optional arguments be handled for something like |
This comment has been minimized.
This comment has been minimized.
|
@sepiropht the purpose is so that we don't duplicate bindings across the ecosystem (or even within a single crate dependency graph) and people can be productive more quickly. |
This comment has been minimized.
This comment has been minimized.
|
@wismer we don't have great support for optional arguments at the moment, so for now it is best to do one of:
different choices may make sense for different methods. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
This comment has been minimized.
This comment has been minimized.
|
@fitzgen ok thanks - I'm eager to get started but I've run into a hiccup with the tests and it looks like it's a propagating JS error regarding |
This comment has been minimized.
This comment has been minimized.
|
@wismer yeah, I'm trying to fix the gh-pages deploy on travis ci right now >.< Make sure you've got node 10 installed (there are tests that depend on BigInt, which is >= 10; WebAssembly is >= 8). |
This comment has been minimized.
This comment has been minimized.
|
Also, the gh-pages should be fixed now! |
This comment has been minimized.
This comment has been minimized.
|
@fitzgen is this close to what you are looking for? ( extern {
pub type Array;
#[wasm_bindgen(method, js_name = indexOf)]
pub fn index_of(this: &Array, value: JsValue) -> i32;
}
// Array.rs
#[test]
fn index_of() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn get_index_of(this: &js::Array, value: JsValue) -> i32 {
this.index_of(value)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
let characters = ["a", "c", "x", "n"];
let index = wasm.get_index_of(characters, "x");
let notFoundIndex = wasm.get_index_of(characters, "z");
assert.equal(index, 2);
assert.equal(notFoundIndex, -1);
}
"#)
.test()
}update: I've done for
Assuming of course that I'm on the right track, though! I'm curious what you think would work for callback functions that are used in methods like fn find(this: &Array, pred_fn: &Closure<&Fn(JsValue) -> bool>) -> JsValue;but the compiler complains about unimplemented traits like Thanks! |
This comment has been minimized.
This comment has been minimized.
UtherII
commented
Jun 20, 2018
•
|
Shouldn't the doc comments (copied from the MDN summary) be updated to use the function names on the Rust side ? For instance the |
This comment has been minimized.
This comment has been minimized.
|
Solved by #277 |
This comment has been minimized.
This comment has been minimized.
Sure! Want to send a PR updating existing docs and adding that to the comment in |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
@fitzgen oh great! Would you prefer a PR for each individual one done, or have them batched together. I updated that comment with some other questions just a moment ago so let me know what you think! |
This comment has been minimized.
This comment has been minimized.
|
@wismer, I would say do ~one PR per day, so batch however many that happens to be together :) Individual commits for each bindings is still preferred :) |
This comment has been minimized.
This comment has been minimized.
|
Hello! For a good start, I'll take care of the |
This comment has been minimized.
This comment has been minimized.
|
Trying my hands on |
This comment has been minimized.
This comment has been minimized.
coreh
commented
Jun 20, 2018
Gotcha, that's indeed a current shortcoming of the TypeScript type system, hopefully they'll add support for typing exceptions in the future. |
This comment has been minimized.
This comment has been minimized.
|
@belfz I think you want If this doesn't work, we might want to start with non-closure taking methods. |
This comment has been minimized.
This comment has been minimized.
|
@fitzgen thanks, I removed my last comment because I noticed I was wrong about the shape of Promise's |
This comment has been minimized.
This comment has been minimized.
|
Ok, as far as I can tell, the definition of #[wasm_bindgen(constructor)]
pub fn new(executor: &Closure<FnMut(Fn(JsValue), Fn(JsValue))>) -> Promise;It is consistent with JavaScript's new Promise( /* executor */ function(resolve, reject) { ... } );where However, this implementation throws: 92 | #[wasm_bindgen]
| ^ `core::ops::Fn(JsValue) + 'static` does not have a constant size known at compile-timeThe cause of this error in that particular place is vague to me. |
This comment has been minimized.
This comment has been minimized.
|
@belfz are you on IRC? can you share your branch? As I mentioned earlier, it might be easier to start with non-closure methods first. |
This comment has been minimized.
This comment has been minimized.
|
Hey @quelledanielle - how goes |
This comment has been minimized.
This comment has been minimized.
|
@twilco I'm planning on working through them tomorrow so I'll do that one first :) |
This comment has been minimized.
This comment has been minimized.
|
Edit: had to update node version |
This comment has been minimized.
This comment has been minimized.
|
Are you using a Node version > 10? I can recommend using `nvm` which is
short for node version manager. Allows you to easily install and switch
between node versions!
Sorry, I replied via E-Mail and didn't see your edit.
…On Sun, 19 Aug 2018, 02:23 Danielle Pham, ***@***.***> wrote:
I've been getting this error (yesterday and today) on master
|
This comment has been minimized.
This comment has been minimized.
|
@thomaseizinger I am using nvm, but assumed I qualified as "most users" |
fitzgen
added a commit
to fitzgen/wasm-bindgen
that referenced
this issue
Sep 6, 2018
fitzgen
added a commit
to fitzgen/wasm-bindgen
that referenced
this issue
Sep 6, 2018
fitzgen
added a commit
to fitzgen/wasm-bindgen
that referenced
this issue
Sep 6, 2018
fitzgen
added a commit
to fitzgen/wasm-bindgen
that referenced
this issue
Sep 6, 2018
fitzgen
added a commit
to fitzgen/wasm-bindgen
that referenced
this issue
Sep 6, 2018
fitzgen
added a commit
to fitzgen/wasm-bindgen
that referenced
this issue
Sep 6, 2018
fitzgen
added a commit
to fitzgen/wasm-bindgen
that referenced
this issue
Sep 6, 2018
This comment has been minimized.
This comment has been minimized.
|
I finished the WebAssembly bindings in #795, so we are down to only eight static methods of |
This comment has been minimized.
This comment has been minimized.
|
@fitzgen I can start off with the first two: |
This comment has been minimized.
This comment has been minimized.
|
Great! |
fitzgen
added
Blocking Rust 2018
labels
Sep 13, 2018
This comment has been minimized.
This comment has been minimized.
|
I can take the remaining six too :-) |
This was referenced Sep 16, 2018
This comment has been minimized.
This comment has been minimized.
|
Last four up for review! :-) |
This comment has been minimized.
This comment has been minimized.
|
Thanks to the awesome work of @brisad, all that is left is |
This comment has been minimized.
This comment has been minimized.
|
@afdw did the bindings for Three months and one day from when this issue was opened to completion. That's almost 5 bindings per day -- not bad! HUGE thank you to everyone who helped out! We couldn't have done it without you |
fitzgen commentedJun 18, 2018
•
edited
This is about exposing ALL of the globally available JS APIs through the
js-syscrate. Things that are guaranteed by the ECMAScript standard, not Web/Node/etc APIs.A good overview/list/documentation of these APIs is available here and I've also made a checklist below. As we implement bindings for these APIs, I will check them off.
How to Implement New Bindings
Comment here saying which thing you are going to make bindings for (so that we don't accidentally duplicate effort). I'll add your username next to the checkbox item.
Open the MDN page for the relevant JS API.
Open
crates/js-sys/src/lib.rsin your editor; this is the file where we are implementing the bindings.Follow the instructions in
crates/js-sys/src/lib.rsabout how to add new bindings:wasm-bindgen/crates/js-sys/src/lib.rs
Lines 28 to 44 in aa348f9
Add a test for the new binding to
crates/js-sys/tests/wasm/MyType.rsRun the JS global API bindings tests with
cargo test -p js-sys --target wasm32-unknown-unknownSend a pull request!😸
Depends on this PR for the initial skeleton and infrastructure:
All
Stringbindings depend on:ArrayArray.length(@robertDurst)Array.from()Array.isArray()Array.of()Array.prototype.concat()Array.prototype.copyWithin()Array.prototype.entries()Array.prototype.every()Array.prototype.fill()Array.prototype.filter()Array.prototype.find()Array.prototype.findIndex()Array.prototype.forEach()Array.prototype.includes()Array.prototype.indexOf()Array.prototype.join()Array.prototype.keys()Array.prototype.lastIndexOf()Array.prototype.map()Array.prototype.pop()(@sepiropht)Array.prototype.push()Array.prototype.reduce()Array.prototype.reduceRight()Array.prototype.reverse()Array.prototype.shift()Array.prototype.slice()Array.prototype.some()Array.prototype.sort()Array.prototype.splice()Array.prototype.toLocaleString()Array.prototype.toString()Array.prototype.unshift()Array.prototype.values()ArrayBufferArrayBuffer.prototype.byteLengthArrayBuffer.isView()ArrayBuffer.prototype.slice()BooleanDataViewDataView.prototype.bufferDataView.prototype.byteLengthDataView.prototype.byteOffsetDataView.prototype.getFloat32()DataView.prototype.getFloat64()DataView.prototype.getInt16()DataView.prototype.getInt32()DataView.prototype.getInt8()DataView.prototype.getUint16()DataView.prototype.getUint32()DataView.prototype.getUint8()DataView.prototype.setFloat32()DataView.prototype.setFloat64()DataView.prototype.setInt16()DataView.prototype.setInt32()DataView.prototype.setInt8()DataView.prototype.setUint16()DataView.prototype.setUint32()DataView.prototype.setUint8()DateDate.UTC()Date.now()Date.parse()Date.prototype.getDate()Date.prototype.getDay()Date.prototype.getFullYear()Date.prototype.getHours()Date.prototype.getMilliseconds()Date.prototype.getMinutes()Date.prototype.getMonth()Date.prototype.getSeconds()Date.prototype.getTime()Date.prototype.getTimezoneOffset()Date.prototype.getUTCDate()Date.prototype.getUTCDay()Date.prototype.getUTCFullYear()Date.prototype.getUTCHours()Date.prototype.getUTCMilliseconds()Date.prototype.getUTCMinutes()Date.prototype.getUTCMonth()Date.prototype.getUTCSeconds()Date.prototype.setDate()Date.prototype.setFullYear()Date.prototype.setHours()Date.prototype.setMilliseconds()Date.prototype.setMinutes()Date.prototype.setMonth()Date.prototype.setSeconds()Date.prototype.setTime()Date.prototype.setUTCDate()Date.prototype.setUTCFullYear()Date.prototype.setUTCHours()Date.prototype.setUTCMilliseconds()Date.prototype.setUTCMinutes()Date.prototype.setUTCMonth()Date.prototype.setUTCSeconds()Date.prototype.toDateString()Date.prototype.toISOString()Date.prototype.toJSON()Date.prototype.toLocaleDateString()Date.prototype.toLocaleString()Date.prototype.toLocaleTimeString()Date.prototype.toString()Date.prototype.toTimeString()Date.prototype.toUTCString()Date.prototype.valueOf()ErrorError.prototype.messageError.prototype.nameError.prototype.toString()EvalErrorFloat32ArrayFloat64ArrayFunctionFunction.lengthFunction.nameFunction.prototype.apply()Function.prototype.bind()Function.prototype.call()Function.prototype.toString()GeneratorGenerator.prototype.next()Generator.prototype.return()Generator.prototype.throw()Int16ArrayInt32ArrayInt8ArrayIntlIntl.getCanonicalLocales()Intl.CollatorIntl.Collator.prototype.compareIntl.Collator.prototype.resolvedOptions()Intl.Collator.supportedLocalesOf()Intl.DateTimeFormatIntl.DateTimeFormat.prototype.formatIntl.DateTimeFormat.prototype.formatToParts()Intl.DateTimeFormat.prototype.resolvedOptions()Intl.DateTimeFormat.supportedLocalesOf()Intl.NumberFormatIntl.NumberFormat.prototype.formatIntl.NumberFormat.prototype.formatToParts()Intl.NumberFormat.prototype.resolvedOptions()Intl.NumberFormat.supportedLocalesOf()Intl.PluralRulesIntl.PluralRules.prototype.resolvedOptions()Intl.PluralRules.select()Intl.PluralRules.supportedLocalesOf()JSONJSON.parse()JSON.stringify()MapMap.prototype.sizeMap.prototype.clear()Map.prototype.delete()Map.prototype.entries()Map.prototype.forEach()Map.prototype.get()Map.prototype.has()Map.prototype.keys()Map.prototype.set()Map.prototype.values()MathMath.abs()Math.acos()Math.acosh()Math.asin()Math.asinh()Math.atan()Math.atan2()Math.atanh()Math.cbrt()Math.ceil()Math.clz32()Math.cos()Math.cosh()Math.exp()Math.expm1()Math.floor()Math.fround()Math.hypot()Math.imul()Math.log()Math.log10()Math.log1p()Math.log2()Math.max()Math.min()Math.pow()Math.random()Math.round()Math.sign()Math.sin()Math.sinh()Math.sqrt()Math.tan()Math.tanh()Math.trunc()NumberNumber.isFinite()Number.isInteger()Number.isNaN()Number.isSafeInteger()Number.parseFloat()Number.parseInt()Number.prototype.toExponential()Number.prototype.toFixed()Number.prototype.toLocaleString()Number.prototype.toPrecision()Number.prototype.toString()Number.prototype.valueOf()ObjectObject.prototype.constructorObject.assign()Object.create()Object.defineProperties()Object.defineProperty()Object.entries()Object.freeze()Object.getOwnPropertyDescriptor()Object.getOwnPropertyDescriptors()Object.getOwnPropertyNames()Object.getOwnPropertySymbols()Object.getPrototypeOf()Object.is()Object.isExtensible()Object.isFrozen()Object.isSealed()Object.keys()Object.preventExtensions()Object.prototype.hasOwnProperty()Object.prototype.isPrototypeOf()(@belfz)Object.prototype.propertyIsEnumerable()(@belfz )Object.prototype.toLocaleString()Object.prototype.toString()(@jonathan-s)Object.prototype.valueOf()Object.seal()Object.setPrototypeOf()Object.values()PromisePromise.all()Promise.prototype.catch()Promise.prototype.finally()Promise.prototype.then()Promise.race()Promise.reject()Promise.resolve()ProxyRangeErrorReferenceErrorReflectReflect.apply()Reflect.construct()Reflect.defineProperty()Reflect.deleteProperty()Reflect.get()Reflect.getOwnPropertyDescriptor()Reflect.getPrototypeOf()Reflect.has()Reflect.isExtensible()Reflect.ownKeys()Reflect.preventExtensions()Reflect.set()Reflect.setPrototypeOf()RegExpRegExp.$1-$9RegExp.input ($_)RegExp.lastMatch ($&)RegExp.lastParen ($+)RegExp.leftContext ($)`RegExp.prototype.flagsRegExp.prototype.globalRegExp.prototype.ignoreCaseRegExp.prototype.multilineRegExp.prototype.sourceRegExp.prototype.stickyRegExp.prototype.unicodeRegExp.rightContext ($')regexp.lastIndexRegExp.prototype.exec()RegExp.prototype.test()RegExp.prototype.toString()SetSet.prototype.sizeSet.prototype.add()Set.prototype.clear()Set.prototype.delete()Set.prototype.entries()Set.prototype.forEach()Set.prototype.has()Set.prototype.values()Stringstring.lengthString.fromCharCode()String.fromCodePoint()String.prototype.charAt()String.prototype.charCodeAt()String.prototype.codePointAt()String.prototype.concat()String.prototype.endsWith()String.prototype.includes()String.prototype.indexOf()String.prototype.lastIndexOf()String.prototype.localeCompare()String.prototype.match()String.prototype.normalize()String.prototype.padEnd()String.prototype.padStart()String.prototype.repeat()String.prototype.replace()String.prototype.search()String.prototype.slice()String.prototype.split()String.prototype.startsWith()String.prototype.substr()String.prototype.substring()String.prototype.toLocaleLowerCase()String.prototype.toLocaleUpperCase()String.prototype.toLowerCase()String.prototype.toString()String.prototype.toUpperCase()String.prototype.trim()String.prototype.trimEnd()String.prototype.trimStart()String.prototype.valueOf()String.raw()SymbolSymbol.hasInstanceSymbol.isConcatSpreadableSymbol.iteratorSymbol.matchSymbol.replaceSymbol.searchSymbol.speciesSymbol.splitSymbol.toPrimitiveSymbol.toStringTagSymbol.unscopablesSymbol.for()Symbol.keyFor()Symbol.prototype.toString()Symbol.prototype.valueOf()SyntaxErrorTypeErrorURIErrorUint16ArrayUint32ArrayUint8ArrayUint8ClampedArrayWeakMapWeakMap.prototype.delete()WeakMap.prototype.get()WeakMap.prototype.has()WeakMap.prototype.set()WeakSetWeakSet.prototype.add()WeakSet.prototype.delete()WeakSet.prototype.has()WebAssemblyWebAssembly.compile()WebAssembly.instantiate()WebAssembly.instantiateStreaming()WebAssembly.validate()WebAssembly.ModuleWebAssembly.Module.customSections()WebAssembly.Module.exports()WebAssembly.Module.imports()WebAssembly.InstanceWebAssembly.Instance.prototype.exportsWebAssembly.MemoryWebAssembly.Memory.prototype.bufferWebAssembly.Memory.prototype.growWebAssembly.TableWebAssembly.Table.prototype.lengthWebAssembly.Table.prototype.getWebAssembly.Table.prototype.growWebAssembly.Table.prototype.setWebAssembly.CompileErrorWebAssembly.LinkErrorWebAssembly.RuntimeErrordecodeURI()decodeURIComponent()encodeURI()encodeURIComponent()escape()eval()isFinite()isNaN()nullparseFloat()parseInt()undefinedunescape()