Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0a4e81b

Browse files
committed
Fold @offbit-ai/reflow-wasm into @offbit-ai/reflow
One npm package, one import path. Bundlers pick the wasm bundle in the browser via the new "browser" conditional export; Node keeps loading the napi addon as before. - sdk/node/reflow.browser.mjs: new entry. Imports the wasm-bindgen build from sdk/node/wasm/ and re-exports Graph, Network (alias for GraphNetwork), bindInputEvents, version, plus a ready() helper that wraps wasm init. - sdk/node/package.json: add "browser" condition, plus a "./browser" subpath for bundlers that don't honor the condition. wasm/ added to files[]. - .github/workflows/publish-node.yml: build the wasm bundle into sdk/node/wasm/ during publish (wasm-pack --target web). Strip the auto-generated package.json + .gitignore so the subdir doesn't shadow the parent. - .github/workflows/publish-wasm.yml: deleted. The standalone @offbit-ai/reflow-wasm package was never released; folding it in instead. - sdk/wasm/: deleted. README content merged into sdk/node/README.md under a new "Browser target" section. - README.md: replace the separate wasm-package badge + table row with a single bundled-browser-wasm badge. The browser surface is still narrower than Node — Graph + Network + DOM input event binding, no full Actor base class with stream helpers — and method names follow wasm-bindgen conventions (snake_case). Documented in sdk/node/README.md. A future minor release will add a JS shim that aligns naming. All 23 Node SDK tests pass after the fold.
1 parent 861c325 commit 0a4e81b

9 files changed

Lines changed: 140 additions & 171 deletions

File tree

.github/workflows/publish-node.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,31 @@ jobs:
158158
- uses: actions/download-artifact@v4
159159
with:
160160
path: sdk/node/artifacts
161+
162+
# Build the wasm32 browser bundle and stage it into sdk/node/wasm/
163+
# so it ships inside the same `@offbit-ai/reflow` npm package.
164+
# The `"browser"` conditional export in package.json picks this
165+
# up when bundlers target the browser; Node imports the napi
166+
# addon as before.
167+
- uses: dtolnay/rust-toolchain@stable
168+
with:
169+
targets: wasm32-unknown-unknown
170+
- uses: jetli/[email protected]
171+
with:
172+
version: latest
173+
- name: Build browser-WASM bundle
174+
# `--target web` emits an ES module + .wasm pair that loads
175+
# via `await init()`. wasm-pack also writes a per-package
176+
# `package.json` and `.gitignore` into the out-dir; we strip
177+
# them so the wasm/ subtree doesn't shadow the parent
178+
# package.json or look like a standalone npm package.
179+
run: |
180+
wasm-pack build crates/reflow_rt_wasm \
181+
--target web \
182+
--release \
183+
--out-dir ../../sdk/node/wasm
184+
rm -f sdk/node/wasm/package.json sdk/node/wasm/.gitignore
185+
161186
- name: Distribute addons to per-platform npm packages
162187
working-directory: sdk/node
163188
# `napi create-npm-dir` scaffolds `npm/<platform>/` (one

.github/workflows/publish-wasm.yml

Lines changed: 0 additions & 109 deletions
This file was deleted.

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ examples/skeleton_animation/animation.mp4
1717
# mdBook build output
1818
/book/
1919

20-
# wasm-pack output (built by CI on tag)
21-
/sdk/wasm/pkg/
20+
# wasm-pack output bundled into @offbit-ai/reflow at publish time
21+
/sdk/node/wasm/
2222

2323
# claude-code planning + scratch
2424
/.claude/

README.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
[![Go SDK release](https://img.shields.io/github/v/release/offbit-ai/reflow?filter=sdk%2Fgo%2Fv*&label=Go%20SDK&logo=go&logoColor=white&color=00ADD8)](https://github.com/offbit-ai/reflow/releases?q=sdk%2Fgo)
2222
[![ai.offbit:reflow on Maven Central](https://img.shields.io/maven-central/v/ai.offbit/reflow?label=ai.offbit%3Areflow&logo=gradle&logoColor=white&color=02303A)](https://central.sonatype.com/artifact/ai.offbit/reflow)
2323
[![C++ SDK header-only](https://img.shields.io/badge/C%2B%2B-header--only-00599C?logo=cplusplus&logoColor=white)](./sdk/cpp)
24-
[![@offbit-ai/reflow-wasm on npm](https://img.shields.io/npm/v/%40offbit-ai%2Freflow-wasm?label=%40offbit-ai%2Freflow-wasm&logo=webassembly&logoColor=white&color=654FF0)](https://www.npmjs.com/package/@offbit-ai/reflow-wasm)
24+
[![Browser-WASM (in @offbit-ai/reflow)](https://img.shields.io/badge/browser--wasm-bundled-654FF0?logo=webassembly&logoColor=white)](./sdk/node#browser-target)
2525

2626
[Documentation](https://offbit-ai.github.io/reflow/) | [Runtime Crate](./crates/reflow_rt/README.md) | [Quick Start](https://offbit-ai.github.io/reflow/getting-started/README.html) | [SDKs](https://offbit-ai.github.io/reflow/sdks/README.html) | [Examples](./examples/) | [API Reference](https://offbit-ai.github.io/reflow/reference/api-reference.html)
2727

@@ -109,20 +109,19 @@ dependencies { implementation("ai.offbit:reflow:0.2.2") }
109109
add_subdirectory(third_party/reflow/sdk/cpp)
110110
target_link_libraries(myapp PRIVATE reflow::cpp)
111111
```
112-
```sh
113-
# Browser — pure-WASM build of the runtime (Graph + GraphNetwork).
114-
# No per-platform native; ships a .wasm + JS glue.
115-
npm install @offbit-ai/reflow-wasm
116-
```
112+
The same `@offbit-ai/reflow` package falls back to a wasm bundle in
113+
the browser via the `"browser"` conditional export — Vite, webpack,
114+
and esbuild pick it up automatically. Node continues to load the
115+
napi `.node` addon. See [sdk/node#browser-target](./sdk/node#browser-target)
116+
for the runtime surface available there.
117117

118118
| SDK | Package | Docs |
119119
|---|---|---|
120-
| Node.js | [`@offbit-ai/reflow`](https://www.npmjs.com/package/@offbit-ai/reflow) | [sdk/node/README.md](./sdk/node/README.md) |
120+
| Node.js + Browser | [`@offbit-ai/reflow`](https://www.npmjs.com/package/@offbit-ai/reflow) | [sdk/node/README.md](./sdk/node/README.md) |
121121
| Python | [`offbit-reflow`](https://pypi.org/project/offbit-reflow/) | [sdk/python/README.md](./sdk/python/README.md) |
122122
| Go | [`github.com/offbit-ai/reflow/sdk/go`](https://github.com/offbit-ai/reflow/releases?q=sdk%2Fgo) | [sdk/go/README.md](./sdk/go/README.md) |
123123
| JVM | [`ai.offbit:reflow`](https://central.sonatype.com/artifact/ai.offbit/reflow) | [sdk/jvm/README.md](./sdk/jvm/README.md) |
124124
| C++ | header-only at [`sdk/cpp/`](./sdk/cpp/) (links `libreflow_rt_capi`) | [sdk/cpp/README.md](./sdk/cpp/README.md) |
125-
| Browser-WASM | [`@offbit-ai/reflow-wasm`](https://www.npmjs.com/package/@offbit-ai/reflow-wasm) | [sdk/wasm/README.md](./sdk/wasm/README.md) |
126125

127126
Optional [`.rflpack`](./sdk/packs/README.md) bundles plug additional actor palettes (GPU renderers, ML, browser automation, ~6,700 SaaS API actors) into any SDK at runtime — load via `loadPack()` / `load_pack()` / `LoadPack()` / `Packs.loadPack()`.
128127

sdk/node/Cargo.lock

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sdk/node/README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,50 @@ npm test # runs test/*.mjs against the built addon
267267

268268
- `import { ... } from "@offbit-ai/reflow"` → high-level API with the `Actor` class.
269269
- `import { ... } from "@offbit-ai/reflow/native"` → raw napi-rs bindings (`ReflowActor`, `ReflowNetwork`, ...) if you want to skip the class layer.
270+
- `import { ... } from "@offbit-ai/reflow/browser"` → explicit browser-WASM build (rarely needed; bundlers route the default import here automatically).
271+
272+
## Browser target
273+
274+
The same package ships a wasm-bindgen build of the runtime under
275+
[`wasm/`](./wasm) for browser use. The `"browser"` conditional
276+
export in `package.json` makes Vite/webpack/esbuild resolve
277+
`import { Graph, Network } from "@offbit-ai/reflow"` to the wasm
278+
bundle when bundling for the browser; Node continues to load the
279+
napi `.node` addon.
280+
281+
```js
282+
import { Graph, Network, ready } from "@offbit-ai/reflow";
283+
284+
await ready(); // initialize the wasm module once
285+
286+
const g = new Graph("demo");
287+
g.add_node("a", "tpl_doubler");
288+
g.add_node("b", "tpl_collector");
289+
g.add_connection("a", "out", "b", "in");
290+
291+
const net = Network.from_graph(g);
292+
net.register_actor_js("tpl_doubler", { /* JS class with run(ctx) */ });
293+
net.start();
294+
```
295+
296+
Browser-side scope (current):
297+
298+
- `Graph` — full Tier-1 + Tier-2 mutators and queries
299+
- `Network` (alias for `GraphNetwork`) — runtime execution of JS
300+
actors registered via `register_actor_js(name, klass)`
301+
- `bindInputEvents(network, target)` — routes DOM events
302+
(keyboard, mouse, touch, wheel, resize) to input actors
303+
- `version()` — runtime version string
304+
305+
Native-only stacks (file I/O, GPU, video encode, headless browser
306+
automation, ML/CV taskpacks) are not in the wasm bundle — those
307+
remain in the Node-side reflow_components catalog.
308+
309+
The wasm module method names follow wasm-bindgen conventions
310+
(snake_case, `Network.from_graph(g)` rather than `new Network(g)`).
311+
A future minor release will add a JS shim that aligns naming with
312+
the Node SDK; for now isomorphic code uses the browser-side names
313+
where they differ.
270314

271315
## License
272316

sdk/node/package.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@
77
"types": "reflow.d.ts",
88
"exports": {
99
".": {
10+
"browser": "./reflow.browser.mjs",
1011
"import": "./reflow.mjs",
1112
"require": "./reflow.js",
1213
"types": "./reflow.d.ts"
1314
},
15+
"./browser": {
16+
"import": "./reflow.browser.mjs",
17+
"types": "./wasm/reflow_rt_wasm.d.ts"
18+
},
1419
"./native": {
1520
"require": "./index.js",
1621
"types": "./index.d.ts"
@@ -63,9 +68,11 @@
6368
"files": [
6469
"reflow.js",
6570
"reflow.mjs",
71+
"reflow.browser.mjs",
6672
"reflow.d.ts",
6773
"index.js",
6874
"index.d.ts",
69-
"*.node"
75+
"*.node",
76+
"wasm/"
7077
]
7178
}

sdk/node/reflow.browser.mjs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Browser entrypoint for @offbit-ai/reflow.
2+
//
3+
// In browsers, the napi `.node` addon can't load — there's no Node
4+
// process and no native module loader. This file is selected via the
5+
// `"browser"` conditional export in package.json so bundlers
6+
// (Vite, webpack, esbuild, …) resolve `import { Graph } from
7+
// "@offbit-ai/reflow"` to the wasm-bindgen build instead.
8+
//
9+
// The runtime surface is intentionally narrower than the Node SDK —
10+
// it covers Graph + GraphNetwork (the subset that compiles to wasm),
11+
// not the full Actor base class with stream helpers. Browser-side
12+
// actors are authored as JS classes and registered via
13+
// `network.registerActorJs(name, klass)`.
14+
15+
import init, * as wasm from "./wasm/reflow_rt_wasm.js";
16+
17+
let _ready;
18+
19+
/**
20+
* Initialize the wasm module. Call once before constructing Graph
21+
* or GraphNetwork. Subsequent calls return the cached promise.
22+
*
23+
* @param {RequestInfo|URL|BufferSource|WebAssembly.Module} [moduleOrUrl]
24+
* Optional override for where to fetch the .wasm. By default
25+
* wasm-bindgen resolves relative to this module's URL.
26+
*/
27+
export function ready(moduleOrUrl) {
28+
if (!_ready) _ready = init(moduleOrUrl);
29+
return _ready;
30+
}
31+
32+
// Re-export the wasm-bindgen surface under the names used by the
33+
// Node SDK so isomorphic code keeps the same imports. Method-name
34+
// mismatches (snake_case vs camelCase) are documented in
35+
// sdk/wasm/README.md; we don't paper over them here because that
36+
// would mean shadowing every class with a JS proxy and inflating
37+
// the bundle.
38+
export const Graph = wasm.Graph;
39+
export const Network = wasm.GraphNetwork;
40+
export const GraphNetwork = wasm.GraphNetwork;
41+
export const version = wasm.version;
42+
export const bindInputEvents = wasm.bindInputEvents;
43+
44+
export default {
45+
Graph,
46+
Network,
47+
GraphNetwork,
48+
version,
49+
bindInputEvents,
50+
ready,
51+
};

sdk/wasm/README.md

Lines changed: 0 additions & 50 deletions
This file was deleted.

0 commit comments

Comments
 (0)