js_widget_runtime 0.4.29
js_widget_runtime: ^0.4.29 copied to clipboard
Run JavaScript widgets as Flutter widgets using QuickJS (VM) or Web Workers (web).
0.4.29 #
- Automated patch bump.
0.4.28 #
- Automated patch bump.
0.4.27 #
- Automated patch bump.
0.4.26 #
- Automated patch bump.
Unreleased #
-
feat(renderer):
audio_playernode — frame-driven declarative audio for JS scenes. Per-frameplaying/volume/loopprops andseekToMschange-seeks are reconciled against a hostJsAudioController;JsMediaControllergained concrete no-opsetVolume/setLoopdefaults, so existing hosts stay source-compatible. Zero-size widget, host-less renders are safe no-ops. -
fix(3d): flame_3d model
rotationapplied yaw as pitch and vice versa —Quaternion.euler(yaw, pitch, roll)takes yaw first, but the conversion passed pitch. Arotation: [0, 180, 0]model entry flipped the model nose-over-tail (wheels up) instead of turning it around; small yaw values (the only kind used before) looked like a slight lean.
0.4.25 #
- Automated patch bump.
0.4.24 #
- feat(3d):
unlit: trueon declarative scene3d model entries — swaps the loaded GLB's SpatialMaterial for an UnlitMaterial with the same albedo, so flat brand marks (logos, UI panels) render at their exact colors instead of being dimmed by the scene light rig.
0.4.23 #
- feat(3d):
jsrSetFlameAssetBundle— replace Flame's global asset bundle (bothFlame.bundleand the eagerly createdFlame.assetscache) so host apps rendering projects from arbitrary directories (YoClip Studio) can serve GLB/OBJ model files that are not in the app's own bundle.
0.4.22 #
- fix(3d): anti-aliased headless GLB capture — the flame_3d offscreen painter now renders the world into a 2x render target and downscales it into the widget rect with FilterQuality.high (SSAA); 1x output — and a point-sampled downscale — had visibly jagged edges on hard GLB silhouettes (extruded logos, low-poly models).
0.4.21 #
- fix(3d): the 3D host dispatcher reference-counts shared controllers — when a scene3d node unmounts and remounts within the same frame (per-frame scene rebuilds in video pipelines), the new State's initState runs before the old State's dispose; previously the late dispose killed the controller the new State had just acquired, leaving the scene permanently empty for the rest of the export.
0.4.20 #
- fix(3d): headless capture mounts the game tree manually and renders the world's children directly — an unmounted FlameGame renders and updates nothing (frozen skeletal animations, unregistered lights, invisible scenes), and a vanilla world renderTree never reached Object3D children in offscreen capture (empty GPU pass).
- fix(3d): teardown races — disposed-controller guards and a MediaQuery-free World3D (pixel ratio explicit) so final-frame capture can't crash.
- feat(3d): headless GLB rendering for the flame_3d host — offscreen capture path renders the scene into a GPU render target and composites it into any canvas (video export / board snapshots), replacing the old headless placeholder. Requires Impeller + Flutter GPU enabled by the embedder.
- feat(3d): declarative
scene3dconfigs —models: [{modelId, src, position, rotation, scale, animation}]+camera+timeapplied idempotently on every rebuild (diff-only), so video pipelines that re-render the node tree per frame can drive GLB scenes frame-accurately. - feat(3d):
Js3dCaptureSyncpending-work tracker lets headless renderers wait for GPU init / model loads before capturing a frame. - fix(3d): transparent scene background (Flame's opaque black default no longer covers layers composited behind the 3D scene).
- fix(3d): no more build→apply→notify→rebuild loop when declarative configs are applied on every widget rebuild; disposed-controller release guard; idempotent controller dispose (unmount/remount + final tree teardown).
0.4.19 #
- Automated patch bump.
0.4.18 #
- Automated patch bump.
0.4.17 #
- Automated patch bump.
0.4.16 #
- Automated patch bump.
0.4.15 #
- Automated patch bump.
0.4.14 #
- Automated patch bump.
0.4.13 #
- The
imagenode now sends a browser-ishUser-Agentfor network URLs: dart:io's defaultDart/x.y (dart:io)UA is rejected by popular CDNs (Wikimedia answers HTTP 400), which made every remote image render as a broken-image icon.
0.4.12 #
- Fix dead
button/iconButtontaps:_buttonActionIdignored the documentedonPressedprop (SKILL.md and every bundled demo use it) and fired the_tapfallback instead, so JS handlers keyed by action id never matched.onPressednow takes priority,onTapstays supported.
0.4.11 #
- Chore: split
json_widget_renderer.dart(~1900 lines) intopartfiles underlib/src/renderer/nodes/(js_layout_nodes.dart,js_text_nodes.dart,js_input_nodes.dart) via private extensions, so every source file is back under the 1500-line PR gate. Pure refactor — no behavior or public API changes.
0.4.10 #
- Add a pure-Dart software 3D pipeline to the
scene3dnode: when the node carries ameshesprop it renders onCustomPaint— perspective-projected triangles, painter's z-sort, flat Lambert shading — with zero native dependencies and noJs3dHostrequired. Props:meshes({vertices, faces, color}),camera(position,target,fov),rotation(x/y/zstatic transform; JS animates by re-rendering on raf/timer),light.direction,background, andonTap(fires with{x, y}local coordinates). Nodes withoutmesheskeep routing to the host-providedJs3dHostengine. Malformed meshes/vertices/faces are skipped, never fatal. Seedocs/3d-spike.mdfor the flutter_gl evaluation and poly-budget guidance.
0.4.9 #
- Add 3D scene support via the new
scene3drenderer node andjsr.scene3d.*JS API. The runtime provides aJs3dHostabstraction so host apps can plug in any engine (Flame 3D, three_dart,flutter_3d_controller, etc.). - Supported JS commands:
create,destroy,addModel,removeModel,setTransform,playAnimation,stopAnimation,setCamera,setLight. - The node accepts
id,width,height,camera,lightsand renders a placeholder when noJs3dHostis registered. - Add a
3d-viewerexample widget usingflutter_3d_controllerto load and display GLB models. - Add bridge and renderer tests for scene lifecycle and command forwarding.
0.4.8 #
- Add a
textAreanode to the JSON renderer: a multiline text input built on the same field machinery astextField. Props:value/initialValue,hint,minLines(default 3),maxLines(default 8, clamped to at leastminLines; the field grows tomaxLinesthen scrolls internally),onChange(fires per keystroke with{value}, exactly liketextField), and an optionalonSubmit(shows adonekeyboard action and fires with{value}; without it Enter inserts a newline).storageKey/id/nameregister the live value with the field registry. The tree normalizer aliasestextarea/TextAreaand applies the same prop aliases (placeholder,value,onChanged) astextField. - Make
listView/gridViewscrolling configurable. Both acceptshrinkWrap(bool, defaulttrue) andphysics('never'/'always'/'platform'). Defaults:listViewis always scrollable;gridViewkeeps its previousshrinkWrap: true+ non-scrollable behavior for backwards compatibility. PreviouslygridViewwas hardcoded toshrinkWrap: true+NeverScrollableScrollPhysics. Follows the renderer's input tolerance:shrinkWrapaccepts'true'/'false'strings and numbers, unknownphysicsvalues fall back to the defaults.
0.4.7 #
- Fix and extend the
chartnode. It now reads its values from the documenteddataprop (pointsremains as a backwards-compatible alias), so apps passingdatano longer render an empty box. New props:fillColor(hex with alpha allowed, e.g.#22c55e33; falls back to the line color at ~20% alpha),strokeWidth(default 2), andchartType—'line'(default, the existing sparkline) or'bar'(equal-width bars with rounded tops and a baseline). Follows the renderer's input tolerance: unknownchartTypefalls back to'line', non-numericdataentries are skipped, empty data renders nothing.
0.4.6 #
- Add transition animation nodes to the JSON renderer.
entranceplays a one-shot mount animation (animation:fade,slideUp,slideDown,slideLeft,slideRight,scale,fadeScale;delayms for staggered list entrances,duration,curve) — implemented overTweenAnimationBuilderwith anIntervalcurve, so no timers are ever scheduled.animatedSwitcherwraps Flutter'sAnimatedSwitcher: whenswitchKeychanges between renders the old child animates out and the new one in (animation:fade,slideLeft,slideRight,slideUp,scale,fadeScale), keyed viaValueKey(switchKey). Both follow the renderer's input tolerance: unknown variants fall back tofade, numeric strings parse, garbage never crashes. The curve parser is now shared asjsCurveinjs_node_helpers.dart.
0.4.5 #
- Add a
mapnode to the JSON renderer, built onflutter_map+latlong2with OpenStreetMap tiles (no API key). Props:center {lat, lng},zoom,markers [{id, lat, lng, label?, color?}],polylines [{points, color?, width?}], andfitBounds(trueto fit all markers/polylines, or an explicit[[lat, lng], [lat, lng]]corner list). Events route through the standard bridge:onTapfires with{lat, lng}andonMarkerTapwith{id}.JsonWidgetRenderer.mapTileProviderlets hosts/tests inject a customTileProviderso tile loading never has to hit the network.
0.4.4 #
- Automated patch bump.
0.4.3 #
- Renderer no longer crashes on malformed numeric props from generated
widgets:
jsDouble/jsDoubleOrNullnow parse numeric strings, take the first numeric element of a list, and fall back instead of throwing a cast error (e.g.borderRadius: [14, 14, 0, 0]previously killed the whole render tree).borderRadiusin decorations, cards, inkWell and clipRRect also accepts CSS-style corner lists ([all],[tl-br, tr-bl],[tl, tr-bl, br],[tl, tr, br, bl]) via the newjsBorderRadius.
0.4.2 #
- Fix web compilation of
JsWidgetEngine:_defaultBackendreferencedFlutterJsWidgetEngineBackendunconditionally, but the conditional import resolves to the Web Worker backend on the web, so any web build importing the wrapper failed with "Method not found: 'FlutterJsWidgetEngineBackend'". The platform pick now lives in a factory behind its own conditional import (js_widget_engine_default.dart/js_widget_engine_default_web.dart).
0.4.1 #
- Fix
JsWidgetBridge.callEventfor rapid-fire gestures: concurrent events (tap-down / tap-up / tap) raced on a single completer, so a stale__jsr_event_donecompleted the next event early and the following callEvent crashed with "Future already completed", permanently wedging event delivery (dead buttons in gesture-heavy widgets). Events are now serialized through an internal queue, and__jsr_event_donehandling is take-and-null so stray/duplicate dones are ignored.
0.4.0 #
- Add pluggable JS engine backend:
- New
JsWidgetEngineBackendinterface. JsRuntimeConfig.backendlets hosts use a custom engine (e.g. QuickJS FFI).- Default backends remain
flutter_json VM and Web Worker on web.
- New
- Add host-provided media support for
video/audionodes:JsMediaHost,JsVideoController,JsAudioControllerinterfaces.JsonWidgetRenderer.mediaHostwires real players while the core package stays free of heavy native media dependencies.
- Add
ExternalAssetResolverandJsonWidgetRenderer.externalAssetResolverforexternal:<id>image sources. - Add dynamic font loading via
JsFontResolver,JsFontLoader, and thefontFamilytext style prop.
0.3.2 #
- Export
UiViewTreeNormalizerfrom the public API so hosts can reuse the same React/HTML-style node-name aliases.
0.3.1 #
- Automated patch bump.
0.3.0 #
- Add
pathnode for SVG path stroking with optional progress animation. - Add
absoluteFillnode (aliasfill) for expanded background fills. - Add
stack.fitsupport (expand/loose). - Add universal effect props (
offsetX/offsetY,scale,rotation,opacity,blur) on any node. - Text improvements:
style.gradientrenders text with a gradient viaShaderMask.style.fontStyle: 'italic'supported in addition toitalic: true.style.lineHeightaliasesstyle.height.
- Image improvements:
asset:andfile:source prefixes.- Optional
imageResolvercallback for custom image providers.
- Add
customBuildersmap for host-defined node types. - Add
videoandaudioplaceholder nodes.
0.2.0 #
- Add
jsr.ease.*easing helpers (linear,easeIn,easeOut,easeInOut,bounce,elastic,backIn,backOut). - Add renderer effects from YoClip:
- Radial gradients (
gradient.type: 'radial'). - Box shadows (
decoration.shadows). - Blur node and
blurproperty on containers. clip: trueon rounded containers.- Static 3D transforms (
rotateX,rotateY,perspective) on containers. - Text shadows and
textTransform(uppercase/lowercase).
- Radial gradients (
0.1.1 #
- Automated patch bump.
0.1.0 #
- BREAKING CHANGE: Rename global JS object and channels from
yoloittojsr.- All widgets must use
jsr.render(),jsr.onEvent(),jsr.fetchJson(), etc. - All internal bridge channels are now prefixed with
__jsr_instead of__yoloit_.
- All widgets must use
- Add
JsRuntimeConfig.hostBootstrapJsso hosts can inject host-specific APIs (e.g.,jsr.yoloit = {...}) without polluting the core runtime. - Update example widgets and documentation to use the new
jsrAPI. - Add
AGENTS.md,CLAUDE.md, and agent skills for widget authoring and engine maintenance.
0.0.7 #
- Automated patch bump.
0.0.6 #
- Automated patch bump.
0.0.5 #
- Automated patch bump.
0.0.4 #
- Automated patch bump.
0.0.3 #
- Automated patch bump.
0.0.1 #
- Initial release.
- JavaScript widget runtime for Flutter (VM via
flutter_js, web via Web Workers). - JSON-to-Flutter renderer (
JsonWidgetRenderer) with layout, input, list, image, chart and animation nodes. - Widget manifest loader (
WidgetManifest,WidgetFileReader,AssetWidgetFileReader). - Bridge APIs:
render,fetchJson,exec,storage,secrets, timers andrequestAnimationFrame.