plushie 0.0.1 → 0.6.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.
- checksums.yaml +4 -4
- data/.yardopts +22 -0
- data/AGENTS.md +595 -0
- data/CHANGELOG.md +209 -0
- data/CLAUDE.md +1 -0
- data/CONTRIBUTING.md +115 -0
- data/Gemfile +15 -0
- data/{LICENSE → LICENSE.txt} +6 -6
- data/README.md +163 -5
- data/Rakefile +21 -0
- data/Steepfile +52 -0
- data/docs/README.md +56 -0
- data/docs/guides/01-introduction.md +266 -0
- data/docs/guides/02-getting-started.md +472 -0
- data/docs/guides/03-your-first-app.md +516 -0
- data/docs/guides/04-the-development-loop.md +499 -0
- data/docs/guides/05-events.md +548 -0
- data/docs/guides/06-lists-and-inputs.md +605 -0
- data/docs/guides/07-layout.md +530 -0
- data/docs/guides/08-styling.md +599 -0
- data/docs/guides/09-animation.md +516 -0
- data/docs/guides/10-subscriptions.md +470 -0
- data/docs/guides/11-async-and-effects.md +531 -0
- data/docs/guides/12-canvas.md +583 -0
- data/docs/guides/13-custom-widgets.md +705 -0
- data/docs/guides/14-state-management.md +600 -0
- data/docs/guides/15-testing.md +649 -0
- data/docs/guides/16-shared-state.md +567 -0
- data/docs/guides/17-packaging.md +549 -0
- data/docs/reference/accessibility.md +420 -0
- data/docs/reference/animation.md +482 -0
- data/docs/reference/app-lifecycle.md +504 -0
- data/docs/reference/built-in-widgets.md +702 -0
- data/docs/reference/canvas.md +589 -0
- data/docs/reference/commands.md +376 -0
- data/docs/reference/composition-patterns.md +816 -0
- data/docs/reference/configuration.md +302 -0
- data/docs/reference/custom-types.md +203 -0
- data/docs/reference/custom-widgets.md +681 -0
- data/docs/reference/dsl.md +500 -0
- data/docs/reference/events.md +596 -0
- data/docs/reference/native-extension.md +636 -0
- data/docs/reference/rake-tasks.md +440 -0
- data/docs/reference/scoped-ids.md +336 -0
- data/docs/reference/subscriptions.md +248 -0
- data/docs/reference/testing.md +448 -0
- data/docs/reference/themes-and-styling.md +511 -0
- data/docs/reference/versioning.md +174 -0
- data/docs/reference/windows-and-layout.md +692 -0
- data/docs/reference/wire-protocol.md +328 -0
- data/docs/stewardship/README.md +109 -0
- data/docs/stewardship/concurrency-shape.md +208 -0
- data/docs/stewardship/dsl-discipline.md +204 -0
- data/docs/stewardship/elm-invariants.md +196 -0
- data/docs/stewardship/goals-and-non-goals.md +95 -0
- data/docs/stewardship/performance-bar.md +157 -0
- data/docs/stewardship/posture.md +118 -0
- data/docs/stewardship/resilience.md +159 -0
- data/docs/stewardship/roadmap/README.md +20 -0
- data/docs/stewardship/simplicity.md +182 -0
- data/docs/stewardship/test-discipline.md +154 -0
- data/docs/stewardship/triage.md +153 -0
- data/docs/stewardship/trust-model.md +112 -0
- data/examples/README.md +163 -0
- data/examples/async_fetch.rb +71 -0
- data/examples/clock.rb +43 -0
- data/examples/color_picker.rb +96 -0
- data/examples/counter.rb +34 -0
- data/examples/notes.rb +219 -0
- data/examples/rate_plushie.rb +288 -0
- data/examples/shortcuts.rb +79 -0
- data/examples/todo.rb +102 -0
- data/examples/widgets/color_picker_widget.rb +360 -0
- data/examples/widgets/star_rating.rb +153 -0
- data/examples/widgets/theme_toggle.rb +141 -0
- data/lib/plushie/animation/sequence.rb +58 -0
- data/lib/plushie/animation/spring.rb +88 -0
- data/lib/plushie/animation/transition.rb +86 -0
- data/lib/plushie/animation/tween.rb +264 -0
- data/lib/plushie/animation.rb +30 -0
- data/lib/plushie/app.rb +82 -0
- data/lib/plushie/binary.rb +317 -0
- data/lib/plushie/bounded_queue.rb +32 -0
- data/lib/plushie/bridge.rb +277 -0
- data/lib/plushie/canvas/shape/canvas_image.rb +29 -0
- data/lib/plushie/canvas/shape/canvas_svg.rb +25 -0
- data/lib/plushie/canvas/shape/canvas_text.rb +31 -0
- data/lib/plushie/canvas/shape/circle.rb +31 -0
- data/lib/plushie/canvas/shape/clip.rb +22 -0
- data/lib/plushie/canvas/shape/dash.rb +26 -0
- data/lib/plushie/canvas/shape/drag_bounds.rb +31 -0
- data/lib/plushie/canvas/shape/group.rb +80 -0
- data/lib/plushie/canvas/shape/hit_rect.rb +25 -0
- data/lib/plushie/canvas/shape/line.rb +30 -0
- data/lib/plushie/canvas/shape/linear_gradient.rb +26 -0
- data/lib/plushie/canvas/shape/path.rb +31 -0
- data/lib/plushie/canvas/shape/rect.rb +36 -0
- data/lib/plushie/canvas/shape/shape_style.rb +30 -0
- data/lib/plushie/canvas/shape/stroke.rb +31 -0
- data/lib/plushie/canvas/shape/transform.rb +62 -0
- data/lib/plushie/canvas/shape.rb +183 -0
- data/lib/plushie/canvas_widget.rb +508 -0
- data/lib/plushie/cargo_plushie.rb +121 -0
- data/lib/plushie/command/image.rb +78 -0
- data/lib/plushie/command/scroll.rb +51 -0
- data/lib/plushie/command/text.rb +55 -0
- data/lib/plushie/command/window.rb +146 -0
- data/lib/plushie/command/window_query.rb +54 -0
- data/lib/plushie/command.rb +345 -0
- data/lib/plushie/connection.rb +383 -0
- data/lib/plushie/data.rb +106 -0
- data/lib/plushie/dev_server.rb +113 -0
- data/lib/plushie/dsl/buildable.rb +48 -0
- data/lib/plushie/effect.rb +170 -0
- data/lib/plushie/encode.rb +71 -0
- data/lib/plushie/event/diagnostic.rb +221 -0
- data/lib/plushie/event/specs.rb +211 -0
- data/lib/plushie/event.rb +413 -0
- data/lib/plushie/key_modifiers.rb +99 -0
- data/lib/plushie/model.rb +34 -0
- data/lib/plushie/node.rb +48 -0
- data/lib/plushie/protocol/decode.rb +1053 -0
- data/lib/plushie/protocol/encode.rb +460 -0
- data/lib/plushie/protocol/keys.rb +295 -0
- data/lib/plushie/protocol/parsers.rb +66 -0
- data/lib/plushie/protocol.rb +23 -0
- data/lib/plushie/rake.rb +261 -0
- data/lib/plushie/renderer_env.rb +122 -0
- data/lib/plushie/renderer_exit.rb +41 -0
- data/lib/plushie/route.rb +86 -0
- data/lib/plushie/runtime/commands.rb +327 -0
- data/lib/plushie/runtime/subscriptions.rb +151 -0
- data/lib/plushie/runtime/windows.rb +178 -0
- data/lib/plushie/runtime.rb +1306 -0
- data/lib/plushie/selection.rb +135 -0
- data/lib/plushie/state.rb +136 -0
- data/lib/plushie/subscription.rb +279 -0
- data/lib/plushie/test/case.rb +62 -0
- data/lib/plushie/test/helpers.rb +374 -0
- data/lib/plushie/test/rspec.rb +78 -0
- data/lib/plushie/test/script/runner.rb +109 -0
- data/lib/plushie/test/script.rb +129 -0
- data/lib/plushie/test/session.rb +694 -0
- data/lib/plushie/test/session_pool.rb +195 -0
- data/lib/plushie/test/snapshot.rb +117 -0
- data/lib/plushie/test.rb +72 -0
- data/lib/plushie/thread_pool.rb +83 -0
- data/lib/plushie/timer_scheduler.rb +103 -0
- data/lib/plushie/transport/framing.rb +112 -0
- data/lib/plushie/transport/tcp_adapter.rb +75 -0
- data/lib/plushie/tree/diff.rb +208 -0
- data/lib/plushie/tree/search.rb +98 -0
- data/lib/plushie/tree.rb +806 -0
- data/lib/plushie/type/a11y.rb +102 -0
- data/lib/plushie/type/alignment.rb +29 -0
- data/lib/plushie/type/anchor.rb +22 -0
- data/lib/plushie/type/border.rb +104 -0
- data/lib/plushie/type/color.rb +175 -0
- data/lib/plushie/type/content_fit.rb +22 -0
- data/lib/plushie/type/direction.rb +23 -0
- data/lib/plushie/type/filter_method.rb +22 -0
- data/lib/plushie/type/font.rb +83 -0
- data/lib/plushie/type/gradient.rb +78 -0
- data/lib/plushie/type/length.rb +41 -0
- data/lib/plushie/type/line_height.rb +42 -0
- data/lib/plushie/type/padding.rb +98 -0
- data/lib/plushie/type/position.rb +22 -0
- data/lib/plushie/type/shadow.rb +79 -0
- data/lib/plushie/type/shaping.rb +22 -0
- data/lib/plushie/type/style_map.rb +116 -0
- data/lib/plushie/type/theme.rb +120 -0
- data/lib/plushie/type/wrapping.rb +22 -0
- data/lib/plushie/ui.rb +970 -0
- data/lib/plushie/undo.rb +208 -0
- data/lib/plushie/version.rb +12 -0
- data/lib/plushie/widget/build.rb +95 -0
- data/lib/plushie/widget/button.rb +18 -0
- data/lib/plushie/widget/canvas.rb +43 -0
- data/lib/plushie/widget/checkbox.rb +37 -0
- data/lib/plushie/widget/column.rb +16 -0
- data/lib/plushie/widget/combo_box.rb +41 -0
- data/lib/plushie/widget/container.rb +35 -0
- data/lib/plushie/widget/floating.rb +24 -0
- data/lib/plushie/widget/grid.rb +28 -0
- data/lib/plushie/widget/image.rb +37 -0
- data/lib/plushie/widget/keyed_column.rb +24 -0
- data/lib/plushie/widget/markdown.rb +32 -0
- data/lib/plushie/widget/native_build.rb +333 -0
- data/lib/plushie/widget/overlay.rb +28 -0
- data/lib/plushie/widget/pane_grid.rb +30 -0
- data/lib/plushie/widget/pick_list.rb +40 -0
- data/lib/plushie/widget/pin.rb +23 -0
- data/lib/plushie/widget/pointer_area.rb +38 -0
- data/lib/plushie/widget/progress_bar.rb +29 -0
- data/lib/plushie/widget/qr_code.rb +29 -0
- data/lib/plushie/widget/radio.rb +36 -0
- data/lib/plushie/widget/responsive.rb +21 -0
- data/lib/plushie/widget/rich_text.rb +90 -0
- data/lib/plushie/widget/row.rb +16 -0
- data/lib/plushie/widget/rule.rb +24 -0
- data/lib/plushie/widget/scrollable.rb +34 -0
- data/lib/plushie/widget/sensor.rb +22 -0
- data/lib/plushie/widget/slider.rb +35 -0
- data/lib/plushie/widget/space.rb +20 -0
- data/lib/plushie/widget/stack.rb +23 -0
- data/lib/plushie/widget/svg.rb +32 -0
- data/lib/plushie/widget/table.rb +84 -0
- data/lib/plushie/widget/text.rb +18 -0
- data/lib/plushie/widget/text_editor.rb +42 -0
- data/lib/plushie/widget/text_input.rb +25 -0
- data/lib/plushie/widget/themer.rb +21 -0
- data/lib/plushie/widget/toggler.rb +35 -0
- data/lib/plushie/widget/tooltip.rb +29 -0
- data/lib/plushie/widget/vertical_slider.rb +33 -0
- data/lib/plushie/widget/window.rb +24 -0
- data/lib/plushie/widget.rb +760 -0
- data/lib/plushie/widget_set.rb +82 -0
- data/lib/plushie.rb +263 -5
- data/sig/base64.rbs +6 -0
- data/sig/msgpack.rbs +13 -0
- data/sig/plushie/animation.rbs +79 -0
- data/sig/plushie/app.rbs +29 -0
- data/sig/plushie/binary.rbs +21 -0
- data/sig/plushie/bounded_queue.rbs +13 -0
- data/sig/plushie/bridge.rbs +53 -0
- data/sig/plushie/canvas/shape.rbs +304 -0
- data/sig/plushie/canvas_widget.rbs +55 -0
- data/sig/plushie/cargo_plushie.rbs +11 -0
- data/sig/plushie/command/image.rbs +11 -0
- data/sig/plushie/command/scroll.rbs +10 -0
- data/sig/plushie/command/text.rbs +11 -0
- data/sig/plushie/command/window.rbs +29 -0
- data/sig/plushie/command/window_query.rbs +14 -0
- data/sig/plushie/command.rbs +101 -0
- data/sig/plushie/connection.rbs +63 -0
- data/sig/plushie/data.rbs +13 -0
- data/sig/plushie/dev_server.rbs +15 -0
- data/sig/plushie/dsl/buildable.rbs +13 -0
- data/sig/plushie/effect.rbs +31 -0
- data/sig/plushie/encode.rbs +10 -0
- data/sig/plushie/event.rbs +254 -0
- data/sig/plushie/key_modifiers.rbs +31 -0
- data/sig/plushie/model.rbs +11 -0
- data/sig/plushie/node.rbs +19 -0
- data/sig/plushie/protocol.rbs +134 -0
- data/sig/plushie/renderer_env.rbs +11 -0
- data/sig/plushie/route.rbs +19 -0
- data/sig/plushie/runtime/windows.rbs +32 -0
- data/sig/plushie/runtime.rbs +208 -0
- data/sig/plushie/selection.rbs +23 -0
- data/sig/plushie/state.rbs +23 -0
- data/sig/plushie/subscription.rbs +39 -0
- data/sig/plushie/thread_pool.rbs +19 -0
- data/sig/plushie/timer_scheduler.rbs +19 -0
- data/sig/plushie/transport/framing.rbs +13 -0
- data/sig/plushie/tree/diff.rbs +13 -0
- data/sig/plushie/tree/search.rbs +12 -0
- data/sig/plushie/tree.rbs +52 -0
- data/sig/plushie/type/a11y.rbs +44 -0
- data/sig/plushie/type/font.rbs +23 -0
- data/sig/plushie/type/gradient.rbs +9 -0
- data/sig/plushie/type/line_height.rbs +10 -0
- data/sig/plushie/ui.rbs +81 -0
- data/sig/plushie/undo.rbs +43 -0
- data/sig/plushie/widget/build.rbs +18 -0
- data/sig/plushie/widget_dsl.rbs +47 -0
- data/sig/plushie/widget_set.rbs +5 -0
- data/sig/plushie.rbs +29 -0
- metadata +322 -10
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/).
|
|
6
|
+
|
|
7
|
+
## [0.6.0] - 2026-05-09
|
|
8
|
+
|
|
9
|
+
Targets plushie-renderer 0.7.1.
|
|
10
|
+
|
|
11
|
+
### Breaking changes
|
|
12
|
+
|
|
13
|
+
- Environment variable `PLUSHIE_SOURCE_PATH` renamed to
|
|
14
|
+
`PLUSHIE_RUST_SOURCE_PATH`. Update shell profiles and CI configs.
|
|
15
|
+
- Constant `Plushie::BINARY_VERSION` renamed to
|
|
16
|
+
`Plushie::PLUSHIE_RUST_VERSION` to match the plushie-rust release
|
|
17
|
+
identifier. Anything referencing the old name needs updating.
|
|
18
|
+
- `Command.async` renamed to `Command.task` for cross-SDK consistency
|
|
19
|
+
(`async` is reserved in Python and Rust). `Command.done` renamed to
|
|
20
|
+
`Command.dispatch` to reflect the "send through update" semantic.
|
|
21
|
+
`Command.widget_commands` renamed to `Command.widget_batch` to match
|
|
22
|
+
the Elixir SDK and disambiguate from the `Plushie::Command` type.
|
|
23
|
+
- Grid widget `columns` prop renamed to `num_columns`.
|
|
24
|
+
- `Command.Image.create_image` and `update_image` no longer accept
|
|
25
|
+
`pixels:`, `width:`, `height:` keyword arguments for raw RGBA data.
|
|
26
|
+
Use the new dedicated `create_image_rgba(handle, width, height, pixels)`
|
|
27
|
+
and `update_image_rgba(handle, width, height, pixels)` constructors
|
|
28
|
+
instead. The blob-data form of `create_image` and `update_image`
|
|
29
|
+
(passing raw binary data directly) is unchanged.
|
|
30
|
+
- Table widget `:selected` and `:striped` props removed; they were
|
|
31
|
+
dead code with no renderer-side effect.
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- `Plushie::CargoPlushie.resolve` helper that locates a usable
|
|
36
|
+
cargo-plushie via `PLUSHIE_RUST_SOURCE_PATH`, falling back to a
|
|
37
|
+
version-matched binary on `PATH`, otherwise raising with
|
|
38
|
+
`cargo install cargo-plushie --version <version> --locked`
|
|
39
|
+
guidance.
|
|
40
|
+
- `docs/versioning.md` documenting the `PLUSHIE_RUST_VERSION` pin and
|
|
41
|
+
SDK-vs-plushie-rust versioning rules.
|
|
42
|
+
- `Event::SessionError` and `Event::SessionClosed` typed variants.
|
|
43
|
+
`SessionError` includes a `code` field carrying the numeric error code
|
|
44
|
+
from the renderer.
|
|
45
|
+
- `Event::Diagnostic` typed variants: `crash`, `update_panicked`,
|
|
46
|
+
`renderer_error`, `protocol_error`, and `unknown`. Previously all
|
|
47
|
+
diagnostics arrived as the generic `Diagnostic` struct; each kind
|
|
48
|
+
now has its own Data class with kind-specific fields.
|
|
49
|
+
- `Plushie::BufferOverflowError` and `Plushie::ProtocolVersionMismatchError`
|
|
50
|
+
typed error classes raised on the matching renderer-side conditions.
|
|
51
|
+
- `Event::Effect` typed per-kind result variants. Effect callbacks now
|
|
52
|
+
receive a typed struct rather than a raw Hash.
|
|
53
|
+
- `RichText::Span` typed Data class for inline text spans.
|
|
54
|
+
- `link_click` events decoded as a typed `:link_click` variant on
|
|
55
|
+
`Event::Widget`.
|
|
56
|
+
- Touch release events carry a `lost` flag when the pointer left the
|
|
57
|
+
window before the release.
|
|
58
|
+
- `Rule` widget `thickness` prop as a direction-agnostic alternative to
|
|
59
|
+
the existing `width`/`height` split.
|
|
60
|
+
- SDK-side event coalescing: high-frequency events declared coalesable
|
|
61
|
+
are deduplicated in the bounded queue before reaching `update`.
|
|
62
|
+
- `Command.dispatch` chain depth is now capped; dispatching beyond the
|
|
63
|
+
limit raises rather than looping indefinitely.
|
|
64
|
+
- `Binary.resolve` falls back to a locally built renderer binary under
|
|
65
|
+
`../plushie-rust/target/{release,debug}/plushie-renderer` when
|
|
66
|
+
`PLUSHIE_RUST_SOURCE_PATH` is set and no explicit path is configured.
|
|
67
|
+
- `rake plushie:preflight` rebuilds the renderer binary from the local
|
|
68
|
+
plushie-rust checkout when `PLUSHIE_RUST_SOURCE_PATH` is set.
|
|
69
|
+
- Negative padding, border width, and border radius values are now
|
|
70
|
+
rejected at build time with an `ArgumentError`.
|
|
71
|
+
|
|
72
|
+
### Fixed
|
|
73
|
+
|
|
74
|
+
- Subscription `key_press` and `key_release` events now read the
|
|
75
|
+
structured key payload (`key`, `modified_key`, `physical_key`,
|
|
76
|
+
`location`, `text`, `repeat`) from the `value` field. The previous
|
|
77
|
+
fallback to top-level message fields read modifiers from the wrong
|
|
78
|
+
location when value was non-Hash and would silently misread future
|
|
79
|
+
shape changes.
|
|
80
|
+
- `animation_frame` and `theme_changed` no longer carry dead fallback
|
|
81
|
+
reads alongside the canonical `value` access; the fallbacks could
|
|
82
|
+
never fire against the real renderer and masked the intended source
|
|
83
|
+
field.
|
|
84
|
+
- `ime_preedit` and `ime_commit` now raise `ArgumentError` when the
|
|
85
|
+
`value` payload is missing or non-Hash, surfacing wire-shape drift
|
|
86
|
+
instead of producing an `Event::Ime` with nil text and cursor.
|
|
87
|
+
- Concurrency bugs in the runtime, bridge, and session pool: a race in
|
|
88
|
+
the timer scheduler, a missing mutex on effect-kind state, and a
|
|
89
|
+
session-pool drain condition that could deadlock under session churn.
|
|
90
|
+
- Cancelled async threads are now properly released; previously a
|
|
91
|
+
cancelled task could hold its thread until the pool was torn down.
|
|
92
|
+
- Effect cancellation events are dispatched to `update` during SDK
|
|
93
|
+
shutdown so apps can clean up transient state.
|
|
94
|
+
- `image_list` and `image_clear` now route through the typed `image_op`
|
|
95
|
+
wire channel rather than a generic command envelope.
|
|
96
|
+
- `default_font` is always encoded as a `{ family: ... }` object; the
|
|
97
|
+
previous path emitted a bare string that the renderer rejected.
|
|
98
|
+
- `window_opened` position fields are now read from top-level `x`/`y`
|
|
99
|
+
keys as the protocol specifies; the previous path read from a nested
|
|
100
|
+
`position` map that does not exist.
|
|
101
|
+
- Effect tag supersession correctly clears the effect-kinds index when
|
|
102
|
+
a new registration replaces an existing one under the same tag.
|
|
103
|
+
- Unknown event families tolerate a missing `window_id` field instead
|
|
104
|
+
of raising a `KeyError`.
|
|
105
|
+
- Wayland-specific environment variables are now forwarded to the
|
|
106
|
+
renderer subprocess.
|
|
107
|
+
- `Plushie.configure { |c| c.log_level = ... }` is now honoured; the
|
|
108
|
+
previous path set the logger level only on the initial connection,
|
|
109
|
+
which was overwritten on restart.
|
|
110
|
+
- Renderer build lookup no longer raises on a missing `_build` directory;
|
|
111
|
+
it falls through to the next resolution step.
|
|
112
|
+
- Runtime event queue is bounded; a stalled app no longer causes
|
|
113
|
+
unbounded memory growth under high-frequency event sources.
|
|
114
|
+
- Widget state callbacks are no longer inherited across unrelated widget
|
|
115
|
+
subclasses defined with `Widget.define`.
|
|
116
|
+
- Effects are cancelled and their callbacks suppressed when the SDK
|
|
117
|
+
shuts down.
|
|
118
|
+
- Timeout error messages include the action and selector for easier
|
|
119
|
+
diagnosis in test output.
|
|
120
|
+
- Widget set override names are validated to prevent accidental
|
|
121
|
+
shadowing of built-in DSL methods.
|
|
122
|
+
- Renderer exit details are sanitised before appearing in error messages
|
|
123
|
+
and logs.
|
|
124
|
+
|
|
125
|
+
### Changed
|
|
126
|
+
|
|
127
|
+
- Native widget builds now delegate workspace generation and
|
|
128
|
+
`cargo build` to [cargo-plushie](https://crates.io/crates/cargo-plushie).
|
|
129
|
+
The Ruby SDK writes a minimal virtual app manifest under
|
|
130
|
+
`_build/plushie-renderer-spec/` and shells out to
|
|
131
|
+
`cargo plushie build`. Widget discovery, [patch.crates-io] forwarding,
|
|
132
|
+
collision checks, and constructor validation now live in
|
|
133
|
+
cargo-plushie and are shared across host SDKs.
|
|
134
|
+
- Native widget crates must now declare
|
|
135
|
+
`[package.metadata.plushie.widget] { type_name, constructor }` in
|
|
136
|
+
their Cargo.toml. cargo-plushie uses that table for discovery.
|
|
137
|
+
- Renderer subprocess environment is now filtered to variables with a
|
|
138
|
+
`PLUSHIE_` prefix plus a small display-server allowlist. Previously
|
|
139
|
+
the full shell environment was forwarded.
|
|
140
|
+
- Per-timer threads replaced with a single `TimerScheduler` thread
|
|
141
|
+
using deadline-based `IO.select`. Timer count no longer scales the
|
|
142
|
+
thread count.
|
|
143
|
+
- Renderer restart backoff parameters, nil-view handling, and frozen
|
|
144
|
+
overlay semantics aligned with the Elixir and other SDKs.
|
|
145
|
+
|
|
146
|
+
### Removed
|
|
147
|
+
|
|
148
|
+
- The checked-in `native/plushie/Cargo.lock` stash. cargo-plushie
|
|
149
|
+
manages the scratch workspace's lock file.
|
|
150
|
+
|
|
151
|
+
## [0.5.0] - 2026-03-23
|
|
152
|
+
|
|
153
|
+
Initial release. Targets plushie-renderer 0.5.0.
|
|
154
|
+
|
|
155
|
+
### Added
|
|
156
|
+
|
|
157
|
+
- Elm architecture (init/update/view/subscribe) via `include Plushie::App`
|
|
158
|
+
- Immutable models via `Plushie::Model.define` (Data.define + #with)
|
|
159
|
+
- Block-based UI DSL with 39 widget types
|
|
160
|
+
- Canvas shape DSL with typed structs (Rect, Circle, Line, Text, Path, Group)
|
|
161
|
+
- Canvas Group with transforms array, clip field, and top-level
|
|
162
|
+
interactive properties (on_click, on_hover, focus_style, focusable, a11y)
|
|
163
|
+
- Canvas widget `role` and `arrow_mode` props for accessible containers
|
|
164
|
+
- Complete wire protocol encode/decode (MessagePack + JSONL)
|
|
165
|
+
- Tree diffing with incremental patch generation
|
|
166
|
+
- 72+ command constructors (async, focus, scroll, window ops, effects,
|
|
167
|
+
focus_element for canvas, etc.)
|
|
168
|
+
- Platform effects (file dialogs, clipboard, notifications)
|
|
169
|
+
- Subscription system (timers, keyboard, mouse, window events)
|
|
170
|
+
- Three transport modes: spawn, stdio, iostream
|
|
171
|
+
- Renderer lifecycle management with exponential backoff restart
|
|
172
|
+
- Error recovery: StandardError rescue in update/view with model
|
|
173
|
+
preservation and log throttling
|
|
174
|
+
- 18 property type modules with wire encoding
|
|
175
|
+
- State helpers: Animation, Route, Selection, Undo, DataQuery, State,
|
|
176
|
+
KeyModifiers
|
|
177
|
+
- Widget extension system (pure Ruby composites + native Rust-backed)
|
|
178
|
+
- Native Rust extension build pipeline via `rake plushie:build` --
|
|
179
|
+
generates Cargo workspace, validates crate paths and constructors,
|
|
180
|
+
detects type name and crate collisions, builds custom renderer binary
|
|
181
|
+
- `Plushie.configure` block for SDK-wide configuration: `binary_path`,
|
|
182
|
+
`source_path`, `build_name`, `widgets`, `widget_config`,
|
|
183
|
+
`test_backend`
|
|
184
|
+
- `widget_config` runtime configuration passed to native widgets
|
|
185
|
+
via the Settings wire message and `InitCtx`
|
|
186
|
+
- WASM renderer download via `rake plushie:download[wasm]`
|
|
187
|
+
- `PLUSHIE_BIN_FILE` and `PLUSHIE_WASM_DIR` env vars for overriding
|
|
188
|
+
download and build output paths
|
|
189
|
+
- `rake plushie:connect` task for stdio transport (plushie --exec)
|
|
190
|
+
- Token authentication for --exec and remote rendering
|
|
191
|
+
- `RendererEnv` to filter sensitive environment variables from renderer
|
|
192
|
+
subprocess
|
|
193
|
+
- Dev server with hot code reloading
|
|
194
|
+
- Test framework with three backends (mock, headless, windowed)
|
|
195
|
+
- Session pooling for parallel test execution
|
|
196
|
+
- Snapshot and screenshot assertion helpers
|
|
197
|
+
- .plushie script format parser and runner
|
|
198
|
+
- Minitest and RSpec integration
|
|
199
|
+
- 100% YARD documentation coverage with zero warnings
|
|
200
|
+
- RBS type signatures for all modules
|
|
201
|
+
- GitHub Actions CI workflow (Ruby 3.2 + 3.3 + 4.0 matrix)
|
|
202
|
+
- CONTRIBUTING.md with commit conventions and development guide
|
|
203
|
+
- Rake tasks: download, build, run, connect, inspect, script, replay,
|
|
204
|
+
preflight
|
|
205
|
+
- Binary download with SHA-256 checksum verification
|
|
206
|
+
- 9 examples: counter, clock, todo, async_fetch, notes, shortcuts,
|
|
207
|
+
color_picker, catalog, rate_plushie
|
|
208
|
+
- Extracted reusable canvas widgets: StarRating, ThemeToggle,
|
|
209
|
+
ColorPickerWidget (in examples/widgets/)
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
AGENTS.md
|
data/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Contributing to plushie-ruby
|
|
2
|
+
|
|
3
|
+
## Setup
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
git clone https://github.com/plushie-ui/plushie-ruby.git
|
|
7
|
+
cd plushie-ruby
|
|
8
|
+
bundle install
|
|
9
|
+
rake plushie:download # precompiled renderer binary
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Requires Ruby 3.2+. No Rust toolchain needed unless building from
|
|
13
|
+
source or writing native extensions.
|
|
14
|
+
|
|
15
|
+
## Running checks
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
bundle exec rake # tests + linter + type check
|
|
19
|
+
bundle exec rake test # tests only
|
|
20
|
+
bundle exec rake standard # linter only
|
|
21
|
+
bundle exec rake steep # type check only
|
|
22
|
+
bundle exec rake yard # generate API docs to doc/
|
|
23
|
+
rake plushie:preflight # pre-push gate (standard, test, steep, yard)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Test backends
|
|
27
|
+
|
|
28
|
+
Tests run against the renderer binary. Three interchangeable backends:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
bundle exec rake test # mock (default, fastest)
|
|
32
|
+
PLUSHIE_TEST_BACKEND=headless bundle exec rake test # real rendering, no display
|
|
33
|
+
PLUSHIE_TEST_BACKEND=windowed bundle exec rake test # real windows (needs display)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Mock is fast enough for TDD loops. CI runs both mock and headless.
|
|
37
|
+
|
|
38
|
+
## Commits
|
|
39
|
+
|
|
40
|
+
Run `bundle exec rake` before committing. CI runs the same checks.
|
|
41
|
+
|
|
42
|
+
### Message format
|
|
43
|
+
|
|
44
|
+
Use imperative mood. Describe what changed and why, not how.
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
feat: add on_resize subscription for window resize events
|
|
48
|
+
|
|
49
|
+
The renderer already emits resize events but the SDK had no
|
|
50
|
+
subscription type for them. Apps had to poll window dimensions
|
|
51
|
+
on a timer, which was wasteful and laggy.
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Prefix with a category when it clarifies intent:
|
|
55
|
+
|
|
56
|
+
| Prefix | Use for |
|
|
57
|
+
|------------|--------------------------------------------|
|
|
58
|
+
| `feat:` | new user-facing functionality |
|
|
59
|
+
| `fix:` | bug fix |
|
|
60
|
+
| `docs:` | documentation only |
|
|
61
|
+
| `test:` | test additions or corrections |
|
|
62
|
+
| `refactor:`| restructuring without behaviour change |
|
|
63
|
+
| `chore:` | deps, CI, tooling, release prep |
|
|
64
|
+
|
|
65
|
+
# Pull requests
|
|
66
|
+
|
|
67
|
+
- One logical change per PR. If a refactor enables a feature, consider
|
|
68
|
+
splitting them unless the refactor is small and tightly coupled.
|
|
69
|
+
- PR title follows the same format as commit messages.
|
|
70
|
+
- Include a brief description of what and why. If there's a visual
|
|
71
|
+
change, a screenshot or before/after helps.
|
|
72
|
+
- All CI checks must pass.
|
|
73
|
+
|
|
74
|
+
## Code style
|
|
75
|
+
|
|
76
|
+
[Standard](https://github.com/standardrb/standard) handles formatting
|
|
77
|
+
and linting. No configuration to argue about.
|
|
78
|
+
|
|
79
|
+
Beyond what Standard enforces:
|
|
80
|
+
|
|
81
|
+
- **Let the code speak.** Only comment when intent isn't obvious from
|
|
82
|
+
the code itself.
|
|
83
|
+
- **Prefer real implementations over mocks in tests.** The mock backend
|
|
84
|
+
is already fast; mocking Ruby internals hides real bugs.
|
|
85
|
+
- **Tests are documentation.** Write them so the next person
|
|
86
|
+
understands the behaviour, not just that it "passes".
|
|
87
|
+
- **ID is always the first argument** for widget builders.
|
|
88
|
+
|
|
89
|
+
## Type signatures
|
|
90
|
+
|
|
91
|
+
RBS signatures live in `sig/`. When adding or changing public API
|
|
92
|
+
methods, update the corresponding `.rbs` file. Run `bundle exec rake
|
|
93
|
+
steep` to verify.
|
|
94
|
+
|
|
95
|
+
## Documentation
|
|
96
|
+
|
|
97
|
+
Public API methods use YARD-style doc comments (`@param`, `@return`,
|
|
98
|
+
`@example`). Guides live in `docs/` as Markdown. Generate and browse
|
|
99
|
+
locally:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
bundle exec rake yard
|
|
103
|
+
open doc/index.html
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Architecture overview
|
|
107
|
+
|
|
108
|
+
See the [project layout and architecture](README.md#how-it-works) in
|
|
109
|
+
the README, or the detailed guide docs:
|
|
110
|
+
|
|
111
|
+
- [Getting started](docs/getting-started.md)
|
|
112
|
+
- [App behaviour](docs/app-behaviour.md)
|
|
113
|
+
- [Events](docs/events.md)
|
|
114
|
+
- [Commands](docs/commands.md)
|
|
115
|
+
- [Testing](docs/testing.md)
|
data/Gemfile
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gemspec
|
|
6
|
+
|
|
7
|
+
gem "irb"
|
|
8
|
+
gem "rake", "~> 13.0"
|
|
9
|
+
gem "minitest", "~> 5.16"
|
|
10
|
+
gem "standard", "~> 1.3"
|
|
11
|
+
gem "steep", require: false
|
|
12
|
+
gem "yard", require: false
|
|
13
|
+
|
|
14
|
+
# Optional: hot reload in dev mode (Plushie.run(MyApp, dev: true))
|
|
15
|
+
gem "listen", "~> 3.0", require: false
|
data/{LICENSE → LICENSE.txt}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
MIT License
|
|
1
|
+
The MIT License (MIT)
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2026 Daniel Hedlund
|
|
3
|
+
Copyright (c) 2026 Daniel Hedlund
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -9,13 +9,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
9
9
|
copies of the Software, and to permit persons to whom the Software is
|
|
10
10
|
furnished to do so, subject to the following conditions:
|
|
11
11
|
|
|
12
|
-
The above copyright notice and this permission notice shall be included in
|
|
13
|
-
copies or substantial portions of the Software.
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
14
|
|
|
15
15
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
16
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
17
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
18
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
-
SOFTWARE.
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
CHANGED
|
@@ -1,8 +1,166 @@
|
|
|
1
|
-
#
|
|
1
|
+
# plushie
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Build native desktop apps in Ruby. **[Pre-1.0](#status)**
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
Write your entire application in Ruby (state, events, UI) and get
|
|
6
|
+
native windows on Linux, macOS, and Windows. Available on
|
|
7
|
+
[RubyGems](https://rubygems.org/gems/plushie) as `plushie`. The
|
|
8
|
+
[renderer](https://github.com/plushie-ui/plushie-rust) is built on
|
|
9
|
+
[Iced](https://github.com/iced-rs/iced) and ships as a precompiled
|
|
10
|
+
binary, no Rust toolchain required.
|
|
7
11
|
|
|
8
|
-
|
|
12
|
+
SDKs are also available for
|
|
13
|
+
[Elixir](https://github.com/plushie-ui/plushie-elixir),
|
|
14
|
+
[Gleam](https://github.com/plushie-ui/plushie-gleam),
|
|
15
|
+
[Python](https://github.com/plushie-ui/plushie-python), and
|
|
16
|
+
[TypeScript](https://github.com/plushie-ui/plushie-typescript).
|
|
17
|
+
|
|
18
|
+
## Quick start
|
|
19
|
+
|
|
20
|
+
```ruby
|
|
21
|
+
class Counter
|
|
22
|
+
include Plushie::App
|
|
23
|
+
|
|
24
|
+
Model = Plushie::Model.define(:count)
|
|
25
|
+
|
|
26
|
+
def init(_opts) = Model.new(count: 0)
|
|
27
|
+
|
|
28
|
+
def update(model, event)
|
|
29
|
+
case event
|
|
30
|
+
in Event::Widget[type: :click, id: "inc"]
|
|
31
|
+
model.with(count: model.count + 1)
|
|
32
|
+
in Event::Widget[type: :click, id: "dec"]
|
|
33
|
+
model.with(count: model.count - 1)
|
|
34
|
+
else
|
|
35
|
+
model
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def view(model)
|
|
40
|
+
window("main", title: "Counter") do
|
|
41
|
+
column(padding: 16, spacing: 8) do
|
|
42
|
+
text("count", "Count: #{model.count}")
|
|
43
|
+
row(spacing: 8) do
|
|
44
|
+
button("inc", "+")
|
|
45
|
+
button("dec", "-")
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
Plushie.run(Counter)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Add plushie to your Gemfile and download the renderer:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Gemfile
|
|
59
|
+
gem "plushie", "== 0.1.0"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
bundle install
|
|
64
|
+
rake plushie:download # download precompiled renderer binary
|
|
65
|
+
ruby lib/counter.rb
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Requires Ruby 3.2+. The repo includes
|
|
69
|
+
[several other examples](examples/) you can try. For multi-file
|
|
70
|
+
projects (custom widgets, native Rust extensions, real project
|
|
71
|
+
scaffolding), see the
|
|
72
|
+
[plushie-demos](https://github.com/plushie-ui/plushie-demos/tree/main/ruby)
|
|
73
|
+
repo.
|
|
74
|
+
|
|
75
|
+
To add Plushie to your own project, see the
|
|
76
|
+
[getting started guide](docs/getting-started.md), or browse the
|
|
77
|
+
[docs](docs/) for all guides and references.
|
|
78
|
+
|
|
79
|
+
## How it works
|
|
80
|
+
|
|
81
|
+
Your Ruby application and the renderer run as two OS processes
|
|
82
|
+
that exchange messages. Think of it like talking to a database,
|
|
83
|
+
except the database is a GPU-accelerated GUI toolkit. The SDK builds
|
|
84
|
+
UI trees and handles events; the renderer draws native windows and
|
|
85
|
+
captures input.
|
|
86
|
+
|
|
87
|
+
The SDK diffs each new tree against the previous one and sends only
|
|
88
|
+
the changes. If the renderer crashes, Plushie restarts it and
|
|
89
|
+
re-syncs your state. If your code raises, the SDK reverts to the
|
|
90
|
+
last good state. Neither process can take the other down.
|
|
91
|
+
|
|
92
|
+
The same protocol works over a local pipe, an SSH connection, or
|
|
93
|
+
any bidirectional byte stream. Your code doesn't need to change.
|
|
94
|
+
|
|
95
|
+
## Features
|
|
96
|
+
|
|
97
|
+
- **Elm architecture** - init, update, view. State lives in Ruby,
|
|
98
|
+
pure functions, predictable updates
|
|
99
|
+
- **Block DSL** - nested Ruby blocks build the widget tree with
|
|
100
|
+
natural indentation, no templates or markup
|
|
101
|
+
- **Built-in widgets** - layout, input, display, and interactive
|
|
102
|
+
widgets out of the box
|
|
103
|
+
- **Canvas** - shapes, paths, gradients, transforms, and
|
|
104
|
+
interactive elements for custom 2D drawing
|
|
105
|
+
- **Themes** - dark, light, nord, catppuccin, tokyo night, and
|
|
106
|
+
more, with custom palettes and per-widget style overrides
|
|
107
|
+
- **Animation** - renderer-side transitions, springs, and
|
|
108
|
+
sequences with no wire traffic per frame
|
|
109
|
+
- **Multi-window** - declare windows in your view; the framework
|
|
110
|
+
manages the rest
|
|
111
|
+
- **Platform effects** - native file dialogs, clipboard, OS
|
|
112
|
+
notifications
|
|
113
|
+
- **Accessibility** - keyboard navigation, screen readers, and
|
|
114
|
+
focus management via [AccessKit](https://accesskit.dev)
|
|
115
|
+
- **Custom widgets** - compose existing widgets in pure Ruby,
|
|
116
|
+
draw on the canvas, or extend with native Rust
|
|
117
|
+
- **Hot reload** - `Plushie.run(MyApp, dev: true)` watches lib/
|
|
118
|
+
and reloads on file changes with full state preservation
|
|
119
|
+
- **Remote rendering** - app on a server or embedded device,
|
|
120
|
+
renderer on a display machine over SSH or any byte stream
|
|
121
|
+
- **Fault-tolerant** - renderer crashes auto-recover; app
|
|
122
|
+
exceptions are caught and state reverted
|
|
123
|
+
- **Configuration system** - `Plushie.configure` for binary paths,
|
|
124
|
+
extensions, test backends, and widget runtime config
|
|
125
|
+
- **WASM renderer** - `rake plushie:download[wasm]` for browser
|
|
126
|
+
targets
|
|
127
|
+
|
|
128
|
+
## Testing and automation
|
|
129
|
+
|
|
130
|
+
Tests run through the real renderer binary, not mocks. Interact like
|
|
131
|
+
a user: click, type, find elements, assert on text. All backends
|
|
132
|
+
support concurrent test execution to keep your suite fast as it
|
|
133
|
+
grows. Three interchangeable backends:
|
|
134
|
+
|
|
135
|
+
- **Mock** - millisecond tests, no display server
|
|
136
|
+
- **Headless** - real rendering via
|
|
137
|
+
[tiny-skia](https://github.com/linebender/tiny-skia), supports
|
|
138
|
+
screenshots for pixel regression in CI
|
|
139
|
+
- **Windowed** - real windows with GPU rendering, platform effects,
|
|
140
|
+
real input
|
|
141
|
+
|
|
142
|
+
```ruby
|
|
143
|
+
class CounterTest < Plushie::Test::Case
|
|
144
|
+
app Counter
|
|
145
|
+
|
|
146
|
+
def test_clicking_increment_updates_counter
|
|
147
|
+
click("#inc")
|
|
148
|
+
assert_text "#count", "Count: 1"
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
The same interaction API is available outside Minitest via
|
|
154
|
+
`Plushie::Automation::Session`. Attach to any running app and drive
|
|
155
|
+
it programmatically. Agent-friendly by design.
|
|
156
|
+
|
|
157
|
+
## Status
|
|
158
|
+
|
|
159
|
+
Pre-1.0. The core works (built-in widgets, event system, themes,
|
|
160
|
+
multi-window, testing framework, accessibility) but the API is
|
|
161
|
+
still evolving. Pin to an exact version and read the
|
|
162
|
+
[CHANGELOG](CHANGELOG.md) when upgrading.
|
|
163
|
+
|
|
164
|
+
## License
|
|
165
|
+
|
|
166
|
+
MIT
|
data/Rakefile
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bundler/gem_tasks"
|
|
4
|
+
require "minitest/test_task"
|
|
5
|
+
|
|
6
|
+
Minitest::TestTask.create
|
|
7
|
+
|
|
8
|
+
require "standard/rake"
|
|
9
|
+
require "plushie/rake"
|
|
10
|
+
|
|
11
|
+
desc "Run Steep type checker"
|
|
12
|
+
task :steep do
|
|
13
|
+
sh "bundle exec steep check"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
desc "Generate YARD documentation"
|
|
17
|
+
task :yard do
|
|
18
|
+
sh "bundle exec yard doc"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
task default: %i[test standard steep]
|
data/Steepfile
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Steepfile
|
|
2
|
+
#
|
|
3
|
+
# Files listed here are type-checked against their RBS declarations.
|
|
4
|
+
# Files with heavy metaprogramming (widget.rb define_method closures,
|
|
5
|
+
# Widget.define class_eval blocks) are excluded because Steep cannot
|
|
6
|
+
# analyze their dynamic method generation.
|
|
7
|
+
target :lib do
|
|
8
|
+
signature "sig"
|
|
9
|
+
|
|
10
|
+
# Core modules
|
|
11
|
+
check "lib/plushie/app.rb"
|
|
12
|
+
check "lib/plushie/encode.rb"
|
|
13
|
+
check "lib/plushie/event/specs.rb"
|
|
14
|
+
check "lib/plushie/key_modifiers.rb"
|
|
15
|
+
check "lib/plushie/route.rb"
|
|
16
|
+
check "lib/plushie/selection.rb"
|
|
17
|
+
check "lib/plushie/undo.rb"
|
|
18
|
+
check "lib/plushie/version.rb"
|
|
19
|
+
|
|
20
|
+
# Excluded from checking (RBS declarations retained for consumers):
|
|
21
|
+
#
|
|
22
|
+
# - model.rb: Extensions#with is defined inside a Data.define block;
|
|
23
|
+
# Steep resolves `self` to the enclosing module, not the Data class.
|
|
24
|
+
# - node.rb: Node = Data.define block; same self-resolution issue.
|
|
25
|
+
# - subscription.rb: Sub = Data.define block; same self-resolution issue.
|
|
26
|
+
# - event.rb: Widget/Key/Ime/Window/Modifiers/CommandError/System are
|
|
27
|
+
# all Data.define with block overrides; same self-resolution issue.
|
|
28
|
+
|
|
29
|
+
# Tree (normalization, search, diff)
|
|
30
|
+
check "lib/plushie/tree.rb"
|
|
31
|
+
check "lib/plushie/tree/search.rb"
|
|
32
|
+
check "lib/plushie/tree/diff.rb"
|
|
33
|
+
|
|
34
|
+
# Protocol (decode is the most type-critical)
|
|
35
|
+
check "lib/plushie/protocol.rb"
|
|
36
|
+
check "lib/plushie/protocol/decode.rb"
|
|
37
|
+
|
|
38
|
+
# Runtime
|
|
39
|
+
check "lib/plushie/runtime.rb"
|
|
40
|
+
check "lib/plushie/runtime/commands.rb"
|
|
41
|
+
check "lib/plushie/animation.rb"
|
|
42
|
+
|
|
43
|
+
# Widget build helpers
|
|
44
|
+
check "lib/plushie/widget/build.rb"
|
|
45
|
+
|
|
46
|
+
# Type modules
|
|
47
|
+
check "lib/plushie/type/line_height.rb"
|
|
48
|
+
|
|
49
|
+
library "json"
|
|
50
|
+
library "logger"
|
|
51
|
+
library "securerandom"
|
|
52
|
+
end
|
data/docs/README.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Documentation
|
|
2
|
+
|
|
3
|
+
## Guides
|
|
4
|
+
|
|
5
|
+
Sequential chapters that build on each other. Start here if you're
|
|
6
|
+
new to Plushie.
|
|
7
|
+
|
|
8
|
+
1. [Introduction](guides/01-introduction.md) - what Plushie is and how it works
|
|
9
|
+
2. [Getting Started](guides/02-getting-started.md) - installation, binary setup, first run
|
|
10
|
+
3. [Your First App](guides/03-your-first-app.md) - building a counter with the Elm architecture
|
|
11
|
+
4. [The Development Loop](guides/04-the-development-loop.md) - hot reload, IRB, debugging
|
|
12
|
+
5. [Events](guides/05-events.md) - widget events, keyboard, pointer, pattern matching
|
|
13
|
+
6. [Lists and Inputs](guides/06-lists-and-inputs.md) - dynamic lists, text inputs, forms
|
|
14
|
+
7. [Layout](guides/07-layout.md) - rows, columns, containers, responsive sizing
|
|
15
|
+
8. [Styling](guides/08-styling.md) - themes, colors, fonts, per-widget style overrides
|
|
16
|
+
9. [Animation and Transitions](guides/09-animation.md) - transitions, springs, tweens, easing
|
|
17
|
+
10. [Subscriptions](guides/10-subscriptions.md) - timers, global key/pointer events, window events
|
|
18
|
+
11. [Async and Effects](guides/11-async-and-effects.md) - tasks, streams, platform effects
|
|
19
|
+
12. [Canvas](guides/12-canvas.md) - shapes, layers, transforms, interactive elements
|
|
20
|
+
13. [Custom Widgets](guides/13-custom-widgets.md) - composing widgets, canvas widgets, native Rust widgets
|
|
21
|
+
14. [State Management](guides/14-state-management.md) - routing, undo/redo, selection, data pipelines
|
|
22
|
+
15. [Testing](guides/15-testing.md) - test framework, backends, selectors, screenshots
|
|
23
|
+
16. [Shared State](guides/16-shared-state.md) - multi-session apps over SSH
|
|
24
|
+
17. [Packaging](guides/17-packaging.md) - publishing a gem and shipping a native renderer
|
|
25
|
+
|
|
26
|
+
## Reference
|
|
27
|
+
|
|
28
|
+
Lookup material organized by topic. Each page is self-contained.
|
|
29
|
+
|
|
30
|
+
- [Accessibility](reference/accessibility.md) - AccessKit integration, roles, labels, keyboard navigation
|
|
31
|
+
- [Animation](reference/animation.md) - transitions, springs, sequences, easing curves, animatable props
|
|
32
|
+
- [App Lifecycle](reference/app-lifecycle.md) - init/update/view callbacks, startup, renderer restart
|
|
33
|
+
- [Built-in Widgets](reference/built-in-widgets.md) - every widget with props, events, and examples
|
|
34
|
+
- [Canvas](reference/canvas.md) - shapes, layers, groups, transforms, clips, gradients
|
|
35
|
+
- [Commands and Effects](reference/commands.md) - async, focus, scroll, window ops, platform effects
|
|
36
|
+
- [Composition Patterns](reference/composition-patterns.md) - reusable components, overlays, navigation, state-helper integration
|
|
37
|
+
- [Configuration](reference/configuration.md) - Plushie.configure, environment variables, runtime options
|
|
38
|
+
- [Custom Types](reference/custom-types.md) - shared prop-type catalog
|
|
39
|
+
- [Custom Widgets](reference/custom-widgets.md) - Widget.define, behavioral widgets, canvas widgets, native crates
|
|
40
|
+
- [DSL](reference/dsl.md) - block DSL mechanics, context stack, auto-IDs, memo caching
|
|
41
|
+
- [Events](reference/events.md) - every event class, widget event taxonomy, pattern-matching cookbook
|
|
42
|
+
- [Native Extensions](reference/native-extension.md) - authoring a Rust widget crate and shipping it alongside a Ruby gem
|
|
43
|
+
- [Rake Tasks](reference/rake-tasks.md) - plushie:download, plushie:build, plushie:run, preflight
|
|
44
|
+
- [Scoped IDs](reference/scoped-ids.md) - ID scoping rules, scope matching, command paths
|
|
45
|
+
- [Subscriptions](reference/subscriptions.md) - timer, keyboard, pointer, window, catch-all subscriptions
|
|
46
|
+
- [Testing](reference/testing.md) - Plushie::Test::Case, RSpec helpers, backends, snapshots, scripts
|
|
47
|
+
- [Themes and Styling](reference/themes-and-styling.md) - built-in themes, custom palettes, style maps, gradients
|
|
48
|
+
- [Versioning](reference/versioning.md) - SDK version, PLUSHIE_RUST_VERSION pinning, Ruby version floor
|
|
49
|
+
- [Windows and Layout](reference/windows-and-layout.md) - window props, layout containers, Length/Padding/Alignment/Border/Shadow
|
|
50
|
+
- [Wire Protocol](reference/wire-protocol.md) - MessagePack/JSONL framing, handshake, session multiplexing
|
|
51
|
+
|
|
52
|
+
## Other resources
|
|
53
|
+
|
|
54
|
+
- [Examples](https://github.com/plushie-ui/plushie-ruby/tree/main/examples) - example apps included in the repo
|
|
55
|
+
- [Changelog](../CHANGELOG.md) - version history and migration notes
|
|
56
|
+
- [Demo apps](https://github.com/plushie-ui/plushie-demos/tree/main/ruby) - multi-file projects with custom widgets and real scaffolding
|