Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TypeScript bindings #369

Merged
merged 20 commits into from Aug 23, 2019

Conversation

@albrow
Copy link
Member

albrow commented Aug 21, 2019

Fixes #298.

This PR adds TypeScript bindings and an npm package for using Mesh in the browser. The Wasm bytecode is embedded in the package itself which makes it really easy to import and use. It also adds an example of how to import and use the TypeScript bindings.

Here's a breakdown of the directory structure and key files:

  • browser/ contains TypeScript bindings for running Mesh in the browser. This directory is a publishable npm package called @0x/mesh-browser.
    • go/ The source code for the Wasm bytecode that will be embedded in the package. It imports 0x-mesh/core and adds everything we need to the global scope.
    • scripts/ contains one-off scripts related to the TypeScript bindings.
      • generate_wasm_buffer.go a script that generates a TypeScript file containing the Wasm bytecode as a base64-encoded ArrayBuffer.
    • ts/ the entry point for the npm package. This is a lightweight wrapper around the variables that we injected into global scope that adds some extra niceties.
      • generated/ contains the TypeScript file generated by scripts/generate_wasm_buffer.go.
    • wasm/ contains the Wasm bytecode itself (the result of compiling go/main.go).
    • lib/ contains the JavaScript code, source maps, and type definitions (the result of compiling ts/).
  • examples/browser is an example of how to import and use the @0x/mesh-browser package in a browser-based application. It uses TypeScript and webpack.
    • src/ is the TypeScript code for the example application.
    • dist/ is where webpack outputs the results. Everything is compiled into a single bundle.js file.

I'm planning to clean this up and document it in a README, but for now here are the steps for running the example:

  1. In the browser/ directory run yarn install && yarn build.
  2. In the examples/browser directory run yarn install && yarn build.
  3. In the root of the repository, run goexec 'http.ListenAndServe(":8000", http.FileServer(http.Dir("./examples/browser/dist")))'
  4. Visit http://localhost:8000 in your browser and look at the console output.
@albrow albrow added the browser label Aug 21, 2019
@albrow albrow added this to the MVP Browser Support milestone Aug 21, 2019
@albrow albrow requested a review from fabioberger Aug 21, 2019
albrow added 3 commits Aug 21, 2019
…e_modules
@albrow

This comment has been minimized.

Copy link
Member Author

albrow commented Aug 22, 2019

Latest commit adds a setOrderEventsHandler method, which is analogous to the mesh_subscribe("orders") JSON RPC endpoint.

@albrow albrow force-pushed the feature/typescript-bindings branch from 733dee3 to 8aafd19 Aug 22, 2019
albrow added 4 commits Aug 22, 2019
@albrow albrow changed the title WIP: Add TypeScript bindings Add TypeScript bindings Aug 22, 2019
@albrow

This comment has been minimized.

Copy link
Member Author

albrow commented Aug 22, 2019

@fabioberger I removed the WIP tag and this PR is ready for review. I still expect that there will be some discussion about naming, interface design, and project structure.

browser/package.json Outdated Show resolved Hide resolved
browser/package.json Outdated Show resolved Hide resolved
const zeroExMesh: ZeroExMesh;
}

/**

This comment has been minimized.

Copy link
@albrow

albrow Aug 22, 2019

Author Member

@fabioberger We should probably generate docs for the TypeScript bindings similar to what we did for the TypeScript RPC client. Can you point me in the right direction? Alternatively we could do that in a separate PR since this is already pretty big.

This comment has been minimized.

Copy link
@fabioberger

fabioberger Aug 23, 2019

Contributor

You'll need "@0x/ts-doc-gen": "^0.0.16", dep and a command:

"scripts": {
    "docs:md": "ts-doc-gen --sourceDir=./src --output=${npm_package_config_docsPath}"
},
"config": {
    "docsPath": "../../../docs/json_rpc_clients/typescript"
},

Just change the docsPath to where you want the MD generated to and it should work 👍

This comment has been minimized.

Copy link
@albrow

albrow Aug 23, 2019

Author Member

👍@fabioberger just added this. Mind eyeballing the docs to make sure everything looks right?

@albrow

This comment has been minimized.

Copy link
Member Author

albrow commented Aug 22, 2019

I know there's not a lot of tests here. I'm planning to write integration tests in a separate PR. The way it will work is that we'll spin up a few nodes on a local network and confirm that they can connect and share orders with one another. It will involve coordinating between some native Go nodes and some that are running in a headless browser. In the meantime, examples/browser can serve as a sort of ad hoc integration test.

"webpack-cli": "^3.3.7"
},
"dependencies": {
"@0x/mesh-browser": "./../../browser/"

This comment has been minimized.

Copy link
@albrow

albrow Aug 22, 2019

Author Member

Right now the example uses a local copy of the TypeScript bindings. I'll update this to use the actual version once we have published the package on NPM.

loadEventName = "0xmeshload"
// orderEventsBufferSize is the buffer size for the orderEvents channel. If
// the buffer is full, any additional events won't be processed.
orderEventsBufferSize = 100

This comment has been minimized.

Copy link
@fabioberger

fabioberger Aug 23, 2019

Contributor

Any reason not to bump this up a bit higher?

This comment has been minimized.

Copy link
@albrow

albrow Aug 23, 2019

Author Member

Increasing orderEventsBufferSize reduces the chance of order events being missed but increases memory usage. I think 100 is a decent starting point but we can adjust it if needed. The channel should never get that full if an orderEventsHandler is set.

browser/go/main.go Outdated Show resolved Hide resolved
browser/package.json Outdated Show resolved Hide resolved
browser/package.json Outdated Show resolved Hide resolved
browser/package.json Outdated Show resolved Hide resolved
signedOrder: MeshSignedOrder;
kind: RejectedOrderKind;
status: RejectedOrderStatus;
}

This comment has been minimized.

Copy link
@fabioberger

fabioberger Aug 23, 2019

Contributor

These are all duplicated from @0x/mesh-rpc-client. Any ideas on how to avoid that? I can't think of any without creating a TS monorepo within this repo...

This comment has been minimized.

Copy link
@albrow

albrow Aug 23, 2019

Author Member

I can't think of anything else either. I'm not sure if it's worth the overhead of using a TS monorepo here. Let's copy it manually for now and discuss later?

browser/package.json Outdated Show resolved Hide resolved
return new Promise(resolve => setTimeout(resolve, ms));
}

function meshSignedOrderToSignedOrder(meshSignedOrder: MeshSignedOrder): SignedOrder {

This comment has been minimized.

Copy link
@fabioberger

fabioberger Aug 23, 2019

Contributor

Why you're calling MeshSignedOrder we call StringifiedSignedOrder in mesh-rpc-client. Thoughts on standardizing?

This comment has been minimized.

Copy link
@albrow

albrow Aug 23, 2019

Author Member

Hmm... StringifiedSignedOrder is an okay name in this case because all the types are strings. However, I want to pick a name that highlights the pattern of converting between Go types and TypeScript types. I'm thinking that there will be other type conversions in the future and not just string to BigNumber. I can't think of a good name to cover the use cases in both mesh-rpc-client and mesh-browser. Maybe something like BasicSignedOrder?

This comment has been minimized.

Copy link
@fabioberger

fabioberger Aug 23, 2019

Contributor

My vote would perhaps be StringifiedSignedOrder for now, and if there are other types involved in the future, changing it then. Don't feel too strongly about this though, so we can also leave it for now.

This comment has been minimized.

Copy link
@albrow

albrow Aug 23, 2019

Author Member

I'm going to go with WrapperSignedOrder, WrapperOrderEvent, WrapperValidationResults, etc. to more closely match the fact that these are types exposed by MeshWrapper that might need further conversion. This is what I was originally trying to show with the Mesh* prefix but I feel that name was too confusing. Happy to re-evaluate later.

examples/browser/src/index.ts Outdated Show resolved Hide resolved
examples/browser/src/index.ts Show resolved Hide resolved
albrow and others added 4 commits Aug 23, 2019
Co-Authored-By: Fabio B <me@fabioberger.com>
Co-Authored-By: Fabio B <me@fabioberger.com>
…-mesh into feature/typescript-bindings
albrow added 4 commits Aug 23, 2019
@albrow albrow requested a review from fabioberger Aug 23, 2019
@albrow albrow merged commit 3e68040 into development Aug 23, 2019
1 check passed
1 check passed
ci/circleci: build Your tests passed on CircleCI!
Details
@albrow albrow deleted the feature/typescript-bindings branch Aug 23, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.