Skip to content

Commit

Permalink
add simple example, update readme for bundler instructions
Browse files Browse the repository at this point in the history
Signed-off-by: ks2211 <[email protected]>
  • Loading branch information
ks2211 committed Aug 31, 2021
1 parent 0810351 commit 51a6884
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 26 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
node_modules/*
dist/*
index.html
!examples/**/*index.html*
*.sh*
wasmcloud-rs-js/pkg/
51 changes: 33 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@ In this demonstration video we will demonstration the following:
* Load an HTTP Server capability into a wasmCloud Host running on a machine
* Load an the wasmcloud-js host into a web browser
* Load an 'echo' actor into the web browser
* **seemlessly** bind the actor to the capability provider through Lattice
* **seamlessly** bind the actor to the capability provider through Lattice
* Access the webserver, which in turn delivers the request to the actor, processes it, and returns it to the requestion client via the capability
* Unload the actor

https://user-images.githubusercontent.com/1530656/130013412-b9a9daa6-fc71-424b-814c-2ca400926794.mp4




## Prerequisities

* NATS with WebSockets enabled
Expand Down Expand Up @@ -45,6 +44,8 @@ $ npm install @wasmcloud/wasmcloud-js

## Usage

More examples can be found in the [examples](examples/) directory, including sample `webpack` and `esbuild` configurations

**Browser**

```html
Expand All @@ -53,18 +54,19 @@ $ npm install @wasmcloud/wasmcloud-js
(async () => {
// start the host passing the name, registry tls enabled, a list of nats ws/wss hosts or the natsConnection object, a map of invocation callbacks, and a host heartbeat interval (default is 30 seconds)
const host = await wasmcloudjs.startHost("default", false, ["ws://localhost:4222"], {}, 30000);
// the host will automatically listen for actors start & stop messages, to manually listen for these messages
// the host will automatically listen for actors start & stop messages, to manually listen for these messages the following methods are exposed
// only call these methods if your host is not listening for actor start/stop
// actor invocations are automatically returned to the host. if a user wants to handle the data, they can pass a map of callbacks using the actor ref/wasm file name as the key with a callback(data, result) function. The data contains the invocation data and the result contains the invocation result
(async() => {
await host.listenLaunchActor(
{
"localhost:5000/echo:0.2.2": (data, result) => console.log(data.operation, result);
}
);
await host.listenStopActor();
})();
// to launch an actor manually from the library from a registry
await host.launchActor("registry.com/actor:0.1.1")
// (async() => {
// await host.listenLaunchActor(
// {
// "localhost:5000/echo:0.2.2": (data, result) => console.log(data.operation, result);
// }
// );
// await host.listenStopActor();
// })();
// to launch an actor manually from the library from a registry, optionally a callback can be passed to handle the invocation results
await host.launchActor("registry.com/actor:0.1.1", (data) => { /* handle data */})
// to launch an actrom manually from local disk (note the .wasm is required)
await host.launchActor("./actor.wasm");
// to listen for events, you can call the subscribeToEvents and pass an optional callback to handle the event data
Expand All @@ -90,18 +92,31 @@ $ npm install @wasmcloud/wasmcloud-js

There are some caveats to using with a bundler:

* The module contains `.wasm` files that need to be present alongside the final build output. Using `webpack-copy-plugin` can solve this issue.
* The module contains `.wasm` files that need to be present alongside the final build output. Using `webpack-copy-plugin` (or `fs.copyFile` with other bundlers) can solve this issue.

* Using the es6 imports is currently broken due to `webpack` bundling and the `.wasm` file -- this is being tracked/fixed.
* If using with `create-react-app`, the webpack config will need to be ejected via `npm run eject` OR an npm library like `react-app-rewired` can handle the config injection.

```javascript
// as commonjs -- import or require both work
import { wasmcloudjs } from '@wasmcloud/wasmcloud-js/dist/cjs/wasmcloud'

(async() => {
// as esm -- this will grant you access to the types/params
// either import or require will work
const { startHost } = require('@wasmcloud/wasmcloud-js);
import { startHost } from '@wasmcloud/wasmcloud-js';
async function cjsHost() {
const host = await wasmcloudjs.startHost('default', false, ['ws://localhost:4222'])
console.log(host);
})()
}

async function esmHost() {
const host = await startHost('default', false, ['ws://localhost:4222'])
console.log(host);
}

cjsHost();
esmHost();
```
```javascript
Expand All @@ -110,7 +125,7 @@ plugins: [
new CopyPlugin({
patterns: [
{
from: 'node_modules/@wasmcloud/wasmcloud-js/dist/cjs/*.wasm',
from: 'node_modules/@wasmcloud/wasmcloud-js/dist/wasmcloud-rs-js/pkg/*.wasm',
to: '[name].wasm'
}
]
Expand Down
33 changes: 33 additions & 0 deletions examples/simple/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# wasmcloud-js Examples

This directory contains examples of using the `wasmcloud-js` library with sample `webpack` and `esbuild` configurations.

## Prerequisities

* NATS with WebSockets enabled

* wasmCloud lattice (OTP Version)

* (OPTIONAL) Docker Registry with CORS configured

* If launching actors from remote registries in the browser host, CORS must be configured on the registry server

* NodeJS, NPM, npx

## Build

```sh
$ npm install webpack esbuild copy-webpack-plugin fs
$ node esbuild.js # this produces the esbuild version
$ npx webpack --config=example-webpack.config.js # this produces the webpack output
```

## Usage

1. Build the code

2. Start a web server inside this directory (e.g `python3 -m http.server`)

3. Navigate to a browser `localhost:<PORT>`

4. Open the developer console to view the host output
18 changes: 18 additions & 0 deletions examples/simple/esbuild.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Use this path in projects using the node import
let defaultWasmFileLocation = './node_modules/@wasmcloud/wasmcloud-js/dist/wasmcloud-rs-js/pkgwasmcloud.wasm'
let wasmFileLocationForLocal = '../../dist/wasmcloud-rs-js/pkg/wasmcloud.wasm'

let copyPlugin = {
name: 'copy',
setup(build) {
require('fs').copyFile(wasmFileLocationForLocal, `${process.cwd()}/wasmcloud.wasm`, (err) => {
if (err) throw err;
});
}
}
require('esbuild').build({
entryPoints: ['main.js'],
bundle: true,
outfile: 'out-esbuild.js',
plugins: [copyPlugin]
}).catch(() => process.exit(1))
41 changes: 41 additions & 0 deletions examples/simple/example-webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const path = require('path');
const CopyPlugin = require('copy-webpack-plugin')

module.exports = {
stats: { assets: false, modules: false },
entry: './main.js',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
// this is needed to copy the wasm file used by the js code to initiate a host key/extract the token from a signed actor
// this SHOULD go away once the upstream webpack build issues are resolved (webpack will automatically pick up the webpack file without needing a copy)
plugins: [
new CopyPlugin({
patterns: [
{
// the node_module path should be referenced in projects using the node import
// from: 'node_modules/@wasmcloud/wasmcloud-js/dist/*.wasm',
from: '../../dist/wasmcloud-rs-js/pkg/*.wasm',
to: '[name].wasm'
}
]
})
],
mode: 'production',
resolve: {
extensions: ['.tsx', '.ts', '.js', '.wasm']
},
experiments: {
asyncWebAssembly: true
},
output: {
filename: 'out-webpack.js',
path: path.resolve(__dirname, '')
}
}
22 changes: 22 additions & 0 deletions examples/simple/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World - wasmcloudjs</title>
<!-- <script src="https://unpkg.com/@wasmcloud/[email protected]/dist/wasmcloud.js"></script> -->
<script src="./out.js"></script>

<!-- this uses the npm library-->
<!-- <script src="./out-webpack.js"></script> -->
<!-- <script src="./out-esbuild.js"></script> -->
<script>
// (async() => {
// console.log("USING THE BROWSER BUNDLE")
// const host = await wasmcloudjs.startHost("default", false, ["ws://localhost:4222"])
// console.log(host);
// })()
</script>
</head>
<body>
</body>
</html>
11 changes: 11 additions & 0 deletions examples/simple/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { startHost } from '../../dist/src'

// Importing inside of a project
// import { startHost } from '@wasmcloud/wasmcloud-js';
// const { startHost } = require('@wasmcloud/wasmcloud-js');

(async () => {
console.log('USING A JS BUNDLER')
const host = await startHost('default', false, ['ws://localhost:4222'])
console.log(host);
})()
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@wasmcloud/wasmcloud-js",
"version": "1.0.4",
"version": "1.0.5",
"description": "wasmcloud host in JavaScript/Browser",
"main": "dist/src/index.js",
"types": "dist/src/index.d.ts",
Expand Down
14 changes: 7 additions & 7 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,23 @@ const baseConfig = {
...sharedConfig
}

// this is used for require(wasmcloudjs) or import { wasmcloudjs } from 'dist/cjs/'
const commonJSConfig = {
// this is specifically to use in a script tag
const browserConfig = {
output: {
webassemblyModuleFilename: 'wasmcloud.wasm',
filename: 'wasmcloud.js',
path: path.resolve(__dirname, 'dist', 'cjs'),
libraryTarget: 'commonjs',
path: path.resolve(__dirname, 'dist'),
library: 'wasmcloudjs'
}
}

// this is specifically to use in a script tag
const browserConfig = {
// this is used for require(wasmcloudjs) or import { wasmcloudjs } from 'dist/cjs/'
const commonJSConfig = {
output: {
webassemblyModuleFilename: 'wasmcloud.wasm',
filename: 'wasmcloud.js',
path: path.resolve(__dirname, 'dist'),
path: path.resolve(__dirname, 'dist', 'cjs'),
libraryTarget: 'commonjs2',
library: 'wasmcloudjs'
}
}
Expand Down

0 comments on commit 51a6884

Please sign in to comment.