mjswan 0.7.1 → 0.8.1-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +85 -132
  2. package/dist/{__vite-browser-external-8AMVH69C.js → __vite-browser-external-Dwe4W7e4.js} +1 -1
  3. package/dist/assets/__vite-browser-external-2n1CrYhI.js +1 -0
  4. package/dist/assets/chunk-aKtaBQYM.js +1 -0
  5. package/dist/assets/index-gYT_EbJW.js +15597 -0
  6. package/dist/assets/mujoco-8POSCP5_.wasm +0 -0
  7. package/dist/assets/mujoco-Bacjb_-g.js +17 -0
  8. package/dist/assets/{mujoco-C7EP5tg_.js → mujoco-CKOf6FiF.js} +3 -3
  9. package/dist/assets/mujoco-Dwp_ZZKt.js +16 -0
  10. package/dist/{chunk-CCV5GAnU.js → chunk-CWhphoD1.js} +11 -4
  11. package/dist/fixtures/container.mjz +0 -0
  12. package/dist/index.html +2 -2
  13. package/dist/manifest.js +106 -0
  14. package/dist/mjswan-engine-8POSCP5_.wasm +0 -0
  15. package/dist/mjswan.js +16901 -31691
  16. package/dist/mujoco-Bcpro754.js +16 -0
  17. package/dist/{mujoco-SDyjJ6Ar.js → mujoco-DADnw4E2.js} +3 -3
  18. package/dist/mujoco-DBWSDs2q.js +4116 -0
  19. package/lib.d.ts +6 -35
  20. package/manifest.d.ts +9 -0
  21. package/package.json +16 -3
  22. package/src/core/command/CommandManager.ts +10 -59
  23. package/src/core/command/TrackingCommand.ts +4 -6
  24. package/src/core/command/custom_commands.ts +1 -4
  25. package/src/core/command/index.ts +1 -5
  26. package/src/core/dsl/primitives.ts +14 -14
  27. package/src/core/engine/runtime.ts +207 -290
  28. package/src/core/engine/viewer_config.ts +10 -1
  29. package/src/core/event/custom_events.ts +1 -4
  30. package/src/core/observation/DslObservation.ts +21 -5
  31. package/src/core/observation/custom_observations.ts +1 -3
  32. package/src/core/plugins.ts +17 -0
  33. package/src/core/policy/OnnxModule.ts +9 -20
  34. package/src/core/policy/PolicyRunner.ts +32 -4
  35. package/src/core/policy/types.ts +9 -2
  36. package/src/core/scene/collider.ts +2 -2
  37. package/src/core/scene/npz.ts +2 -7
  38. package/src/core/scene/scene.ts +0 -204
  39. package/src/core/scene/splat.ts +31 -17
  40. package/src/core/termination/DslTermination.ts +1 -3
  41. package/src/core/termination/TerminationBase.ts +4 -1
  42. package/src/core/termination/TerminationManager.ts +1 -1
  43. package/src/core/termination/custom_terminations.ts +2 -5
  44. package/src/core/termination/terminations.ts +4 -1
  45. package/src/core/utils/bytes.ts +7 -0
  46. package/src/core/utils/mjzLoader.ts +9 -10
  47. package/src/engine/createEngine.ts +204 -0
  48. package/src/engine/harness.ts +43 -0
  49. package/src/engine/index.ts +19 -0
  50. package/src/engine/plugin-three-shim.cjs +13 -0
  51. package/src/engine/types.ts +123 -0
  52. package/src/manifest/index.test.ts +97 -0
  53. package/src/manifest/index.ts +232 -0
  54. package/dist/assets/__vite-browser-external-DhMFdDJY.js +0 -1
  55. package/dist/assets/chunk-BHe-jwch.js +0 -1
  56. package/dist/assets/index-Dhi7GSsD.js +0 -15597
  57. package/src/core/appConfig.ts +0 -132
  58. package/src/core/cache/memoryMonitor.ts +0 -170
  59. package/src/core/cache/onnxCacheAdapter.ts +0 -108
  60. package/src/core/cache/resourceTracker.ts +0 -289
  61. package/src/core/cache/sceneCacheManager.ts +0 -366
  62. package/src/core/utils/localAssets.ts +0 -88
  63. package/src/core/utils/mujocoAssetCollector.ts +0 -331
  64. package/src/core/utils/pathUtils.ts +0 -37
package/README.md CHANGED
@@ -1,29 +1,21 @@
1
- # mjswan Web Viewer
1
+ # mjswan web engine
2
2
 
3
- Browser-based interactive viewer for MuJoCo robotics simulations with real-time policy control.
3
+ [![npm version](https://img.shields.io/npm/v/mjswan.svg?logo=nodedotjs)](https://www.npmjs.com/package/mjswan)
4
+ [![docs](https://img.shields.io/readthedocs/mjswan?logo=readthedocs)](https://mjswan.readthedocs.io)
4
5
 
5
- ## Overview
6
+ Browser-side runtime for [mjswan](https://github.com/ttktjmt/mjswan). Interactive MuJoCo
7
+ simulations with real-time policy control, running entirely in the browser via WebAssembly.
6
8
 
7
- A React + TypeScript application that runs MuJoCo physics simulations entirely in the browser using WebAssembly, featuring 3D visualization with Three.js and real-time ONNX policy execution.
9
+ The package runs MuJoCo physics ([mujoco-wasm](https://github.com/google-deepmind/mujoco/tree/main/javascript)),
10
+ renders with [three.js](https://github.com/mrdoob/three.js), and executes policies with
11
+ [ONNX Runtime Web](https://github.com/microsoft/onnxruntime).
8
12
 
9
- ## Key Features
10
-
11
- - MuJoCo physics simulation via WebAssembly
12
- - Interactive 3D rendering with Three.js
13
- - Real-time ONNX policy execution
14
- - Drag-to-apply forces on objects
15
- - Multi-project and multi-scene support
16
- - WebXR/VR ready
17
- - Static site output for easy deployment
18
-
19
- ## Technology Stack
20
-
21
- - React 18 + TypeScript
22
- - Three.js (WebGL 2.0)
23
- - MuJoCo WebAssembly ([mujoco-js](https://github.com/google-deepmind/mujoco/tree/main/javascript))
24
- - ONNX Runtime Web
25
- - Mantine UI
26
- - Vite
13
+ > **Most users want the Python package.** mjswan is primarily authored in Python
14
+ > (`pip install mjswan`), which bundles your models, policies, and UI into a static
15
+ > site. This npm package is the browser side, and is useful directly in two cases:
16
+ > **embedding** a published simulation in your own page, and **authoring custom MDP
17
+ > terms** in TypeScript with full type support. See the
18
+ > [documentation](https://mjswan.readthedocs.io) for the full Python workflow.
27
19
 
28
20
  ## Installation
29
21
 
@@ -31,141 +23,102 @@ A React + TypeScript application that runs MuJoCo physics simulations entirely i
31
23
  npm install mjswan
32
24
  ```
33
25
 
34
- ## Embedding a published simulation (`mount`)
26
+ Requires Node.js 20+ and a bundler that handles TypeScript sources (Vite recommended.
27
+ See [Custom MDP terms](#custom-mdp-terms) below for why).
28
+
29
+ ## Embedding a simulation (`mount`)
35
30
 
36
- The package ships a self-contained library build (`dist/mjswan.js`) that renders
37
- a published mjswan simulation into any element. It bundles every dependency and
38
- co-locates its WASM, so it can be loaded directly from a CDN:
31
+ The package ships a self-contained library build (`dist/mjswan.js`) that renders a
32
+ published mjswan simulation into any element. It bundles every dependency and co-locates
33
+ its WASM, runs single-threaded by default (no COOP/COEP headers needed), and works
34
+ cross-origin — so it can be loaded straight from a CDN:
39
35
 
40
36
  ```js
41
37
  const { mount } = await import(
42
- 'https://cdn.jsdelivr.net/npm/mjswan@<version>/dist/mjswan.js'
38
+ 'https://cdn.jsdelivr.net/npm/mjswan@0.7.1/dist/mjswan.js'
43
39
  );
44
- // configUrl points at a published simulation's config.json; every other asset
40
+
41
+ // `source` points at a published simulation's config.json; every other asset
45
42
  // (scene.mjz, policy.onnx/json, motion.npz, splats) resolves relative to it.
46
- await mount(container, 'https://cdn.mjswan.com/mjswan/scenes/<id>/config.json');
43
+ const sim = await mount(container, 'https://cdn.mjswan.com/scenes/<id>/config.json');
47
44
  ```
48
45
 
49
- It runs single-threaded by default (no COOP/COEP needed) and works cross-origin.
50
- See mjswan-cloud ADR 0001.
51
-
52
- ## Development
53
-
54
- ```bash
55
- # Install dependencies
56
- npm install
46
+ Or as a normal bundled import:
57
47
 
58
- # Start dev server
59
- npm run dev
48
+ ```ts
49
+ import { mount } from 'mjswan';
60
50
 
61
- # Build for production
62
- npm run build
63
-
64
- # Type check
65
- npm run typecheck
66
-
67
- # Lint
68
- npm run lint
51
+ const sim = await mount(document.getElementById('viewer')!, configUrl);
69
52
  ```
70
53
 
71
- ## Configuration
72
-
73
- The viewer requires a configuration file at `assets/config.json`:
74
-
75
- ```json
76
- {
77
- "version": "0.0.4",
78
- "projects": [
79
- {
80
- "name": "Project Name",
81
- "id": "project_id",
82
- "scenes": [
83
- {
84
- "name": "Scene Name",
85
- "path": "scene/scene_name/scene.xml",
86
- "policies": [
87
- {
88
- "name": "Policy Name",
89
- "source": "policy/scene_name/policy.onnx"
90
- }
91
- ]
92
- }
93
- ]
94
- }
95
- ]
96
- }
97
- ```
54
+ `mount(element, source)` resolves, once the first scene is running, to an instance:
98
55
 
99
- ### Asset Structure
100
-
101
- ```
102
- assets/
103
- ├── config.json
104
- ├── scene/
105
- │ └── {scene_name}/
106
- │ └── scene.xml
107
- └── policy/
108
- └── {scene_name}/
109
- └── {policy}.onnx
56
+ ```ts
57
+ interface MjswanInstance {
58
+ // Capture the current frame as a JPEG Blob.
59
+ captureThumbnail(options?: { maxDim?: number; quality?: number }): Promise<Blob>;
60
+ // Tear down the simulation and free resources.
61
+ dispose(): void;
62
+ }
110
63
  ```
111
64
 
112
- ## URL Routing
65
+ `source` is either a **config.json URL** (assets resolve against its directory) or an
66
+ **in-memory file resolver** `{ resolve(path): Promise<ArrayBuffer | null> }` for rendering
67
+ locally-selected files without an upload round-trip. Call `unmount(element)` to dispose a
68
+ mounted instance by its host element.
113
69
 
114
- - `/` - Default project
115
- - `/{project-id}/` - Specific project
116
- - `?scene={name}&policy={name}` - Pre-select scene and policy
117
- - `?panel=0` - Start with the control panel hidden
70
+ ## Custom MDP terms
118
71
 
119
- ## Core Architecture
72
+ When authoring custom observations, commands, events, or terminations for a mjswan
73
+ simulation, import the base classes and helpers from subpath exports instead of fragile
74
+ relative paths. Install mjswan as a dev dependency and import directly:
120
75
 
121
- ### mjswanRuntime
76
+ ```ts
77
+ import { ObservationBase } from 'mjswan/observation';
78
+ import { mjcToThreeCoordinate } from 'mjswan/coordinate';
79
+ import type { PolicyState } from 'mjswan/types';
122
80
 
123
- Manages simulation, rendering, policy inference, and user interactions.
124
- Located in [src/core/runtime.ts](src/core/runtime.ts)
81
+ export class MyObservation extends ObservationBase {
82
+ get size(): number {
83
+ return 3;
84
+ }
125
85
 
126
- ### Scene Loading
127
-
128
- Handles MJCF XML parsing, asset loading, and Three.js mesh generation.
129
- Located in [src/core/scene.ts](src/core/scene.ts)
130
-
131
- ### Policy Execution
132
-
133
- 1. Extract observations from MuJoCo state
134
- 2. Run ONNX inference
135
- 3. Apply actions to simulation
136
-
137
- ## Project Structure
138
-
139
- ```
140
- src/
141
- ├── App.tsx # Main application with routing
142
- ├── index.tsx # Application entry point
143
- ├── index.css # Global styles
144
- ├── components/ # React components
145
- │ └── mjswanViewer.tsx # Main viewer component
146
- ├── core/ # Core engine
147
- │ ├── engine/ # Physics simulation
148
- │ ├── scene/ # Three.js scene setup
149
- │ └── utils/ # Helper utilities
150
- ├── types/ # TypeScript type definitions
151
- └── utils/ # Utility functions
86
+ compute(state: PolicyState): Float32Array {
87
+ // ... read MuJoCo state, return the observation vector
88
+ }
89
+ }
152
90
  ```
153
91
 
154
- ### Base Path Configuration
92
+ The build step bundles your source into the engine. See the
93
+ [examples](https://github.com/ttktjmt/mjswan/tree/main/examples) for complete custom terms.
94
+
95
+ > Subpath exports point at TypeScript source (not compiled `.d.ts`), so consumers need a
96
+ > bundler that handles TypeScript. Vite does; plain `tsc` does not. This keeps full IDE
97
+ > IntelliSense without a separate types package — see
98
+ > [ADR 0001](https://github.com/ttktjmt/mjswan/blob/main/docs/adr/0001-npm-self-reference-for-custom-mdp-imports.md).
99
+
100
+ ### Available subpaths
101
+
102
+ | Import | Provides |
103
+ |---|---|
104
+ | `mjswan` | `mount`, `unmount` (the runtime library build) |
105
+ | `mjswan/observation` | `ObservationBase`, `ObservationConfig` |
106
+ | `mjswan/command` | `CommandManager`, command types and helpers |
107
+ | `mjswan/event` | `EventBase`, event config and context types |
108
+ | `mjswan/termination` | `TerminationBase`, termination config types |
109
+ | `mjswan/scene` | Scene helpers (`getPosition`, `getQuaternion`, …) |
110
+ | `mjswan/npz` | `.npz` loading (`loadNpz`, `NpzEntry`) |
111
+ | `mjswan/coordinate` | MuJoCo ↔ three.js coordinate conversions |
112
+ | `mjswan/math` | Quaternion / vector math utilities |
113
+ | `mjswan/types` | Shared types (`PolicyState`, `PolicyRunner`, …) |
155
114
 
156
- For subdirectory deployment, update `vite.config.ts`:
115
+ ## Links
157
116
 
158
- ```typescript
159
- export default defineConfig({
160
- base: '/your-repo-name/',
161
- })
162
- ```
117
+ - **Documentation**: [mjswan.readthedocs.io](https://mjswan.readthedocs.io)
118
+ - **Repository**: [github.com/ttktjmt/mjswan](https://github.com/ttktjmt/mjswan)
119
+ - **Python package**: [pypi.org/project/mjswan](https://pypi.org/project/mjswan)
120
+ - **Live demo**: [ttktjmt.github.io/mjswan](https://ttktjmt.github.io/mjswan)
163
121
 
164
122
  ## License
165
123
 
166
124
  Apache-2.0
167
-
168
- ## Links
169
-
170
- - **Repository**: [github.com/ttktjmt/mjswan](https://github.com/ttktjmt/mjswan)
171
- - **Author**: Tatsuki Tsujimoto
@@ -1,4 +1,4 @@
1
- import { t as e } from "./chunk-CCV5GAnU.js";
1
+ import { t as e } from "./chunk-CWhphoD1.js";
2
2
  //#region __vite-browser-external
3
3
  var t = /* @__PURE__ */ e(((e, t) => {
4
4
  t.exports = {};
@@ -0,0 +1 @@
1
+ import{t as e}from"./chunk-aKtaBQYM.js";var t=e(((e,t)=>{t.exports={}}));export default t();
@@ -0,0 +1 @@
1
+ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),s=(e,n)=>{let r={};for(var i in e)t(r,i,{get:e[i],enumerable:!0});return n||t(r,Symbol.toStringTag,{value:`Module`}),r},c=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},l=(n,r,a)=>(a=n==null?{}:e(i(n)),c(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n)),u=(e=>typeof require<`u`?require:typeof Proxy<`u`?new Proxy(e,{get:(e,t)=>(typeof require<`u`?require:e)[t]}):e)(function(e){if(typeof require<`u`)return require.apply(this,arguments);throw Error('Calling `require` for "'+e+"\" in an environment that doesn't expose the `require` function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details.")});export{l as i,s as n,u as r,o as t};