@mindees/renderer 0.13.0 β†’ 0.14.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.
package/README.md CHANGED
@@ -6,12 +6,16 @@ reactive bindings**: a changing signal patches exactly the affected
6
6
  attribute/text/region β€” no virtual-DOM diffing.
7
7
 
8
8
  > **Status: πŸ§ͺ Experimental.** Implemented and tested: the reconciler, the
9
- > **web/DOM backend**, **SSR + hydration**, a **headless** test backend, a
10
- > **native command backend** (`createNativeCommandBackend()`), a strict reference
11
- > host (`createReferenceHost()`), and iOS/Android host projects that compile and
12
- > render the command stream into native view trees in CI. A full end-to-end native
13
- > app bridge/embedded JS engine and GPU canvas remain **research tracks**; the
14
- > direct `createNativeBackend()` and `createCanvasBackend()` seams throw
9
+ > **web/DOM backend**, **SSR + hydration**, a **headless** test backend, the
10
+ > **Helix Canvas strand** (`createCanvas2DBackend()` β€” a reconciler-driven 2D
11
+ > scene graph), a **native command backend** (`createNativeCommandBackend()`), a
12
+ > one-call native entry (`createNativeApp()`), and a strict reference host
13
+ > (`createReferenceHost()`). The same TypeScript app now runs **end to end on a
14
+ > real Android emulator (embedded QuickJS bridge) and a real iOS simulator
15
+ > (JavaScriptCore)** β€” both CI-verified β€” with native events that carry values
16
+ > (e.g. `onChangeText` delivers the typed text). The **GPU** canvas
17
+ > (wgpu/WebGPU) and a direct in-process runtime native backend remain **research
18
+ > tracks**; the `createNativeBackend()` and `createCanvasBackend()` seams throw
15
19
  > `NotImplementedError`. APIs may change before `1.0`.
16
20
 
17
21
  ## Install
@@ -29,8 +33,9 @@ pnpm add @mindees/renderer
29
33
  `text`β†’`span`, …), unlike canvas-based web renderers. `hydrate` attaches
30
34
  reactivity on the client.
31
35
  - **Backend-agnostic** β€” the reconciler speaks only the `HostBackend` contract,
32
- so a new platform is "implement `HostBackend<N>`." DOM, headless, native command
33
- stream, and reference-host validation ship today.
36
+ so a new platform is "implement `HostBackend<N>`." DOM, headless, the 2D Canvas
37
+ strand, the native command stream (running on a real Android emulator + iOS
38
+ simulator via embedded JS), and reference-host validation all ship today.
34
39
 
35
40
  ## Quick start
36
41
 
@@ -77,12 +82,15 @@ const commands = backend.flushCommands() // ship this batch to a native host
77
82
  // backend.dispatchEvent(handlerId, event)
78
83
  ```
79
84
 
80
- > This is the **foundation** for native rendering β€” it produces the command
81
- > stream, and the host projects in
85
+ > This is the engine behind native rendering β€” it produces the command stream,
86
+ > and the host projects in
82
87
  > [`examples/native-hosts/`](https://github.com/mindees/mindees/tree/main/examples/native-hosts)
83
- > replay/render that stream in CI. You cannot build a native mobile app
84
- > end-to-end yet because Phase 8F still needs an embedded JS engine plus a
85
- > JS↔native bridge running the reactive app on-device.
88
+ > replay/render that stream. Phase 8F is **done**: those hosts now embed a JS
89
+ > engine (QuickJS on Android, JavaScriptCore on iOS) plus a JS↔native bridge that
90
+ > runs the reactive app **on-device**, so the same app renders + is interactive on
91
+ > a real Android emulator and iOS simulator in CI. For an app you'd use the
92
+ > higher-level [`createNativeApp()`](#one-call-native-entry-createnativeapp) below
93
+ > rather than wiring the command backend by hand.
86
94
 
87
95
  ### Reference host + conformance contract (Phase 8B)
88
96
 
@@ -103,6 +111,46 @@ host.serialize() // the reconstructed tree, e.g. '<button>count: 0</button>
103
111
  host.liveNodeCount() // 0 after app.dispose() β€” no orphaned/leaked nodes
104
112
  ```
105
113
 
114
+ ### One-call native entry (`createNativeApp`)
115
+
116
+ `createNativeApp(<App />)` is the whole entry file for a MindeesNative app on an
117
+ embedded native host. It wires the command backend, renders the root, flushes the
118
+ initial batch, and exposes the `start()` / `dispatchEvent()` / `frameTick()`
119
+ contract the host calls β€” so on-device it also makes **animations + concurrency
120
+ work by default** (it installs the reactive scheduler and a vsync-driven frame
121
+ source that runs **only while something is animating**, battery-friendly). Native
122
+ events can **carry values**: `dispatchEvent(handlerId, text)` wraps `text` as
123
+ `{ target: { value } }` so handlers read it via the standard event shape.
124
+
125
+ ```tsx
126
+ import { createNativeApp } from '@mindees/renderer'
127
+ import { App } from './App'
128
+
129
+ createNativeApp(<App />) // host injects MindeesHost.emit + calls MindeesApp.start()
130
+ ```
131
+
132
+ The Android (QuickJS) and iOS (JavaScriptCore) hosts in `examples/native-hosts/`
133
+ run exactly this on a real emulator/simulator in CI.
134
+
135
+ ### Canvas strand (`createCanvas2DBackend`)
136
+
137
+ The **same reconciler** can drive a retained-mode 2D scene graph β€” Flutter-grade
138
+ pixel control exactly where you want it. A `canvas-rect` / `canvas-circle` /
139
+ `canvas-line` / `canvas-text` subtree is built + fine-grain-diffed by Helix, and
140
+ `paint(ctx, w, h)` rasterizes it. The 2D context is an interface, so a real
141
+ `CanvasRenderingContext2D` satisfies it on web today and a WebGPU rasterizer can
142
+ drive the same scene later without touching app code (the **GPU** backend itself
143
+ is still a research track β€” see `createCanvasBackend` below).
144
+
145
+ ```ts
146
+ import { createElement as h } from '@mindees/core'
147
+ import { createCanvas2DBackend, render } from '@mindees/renderer'
148
+
149
+ const backend = createCanvas2DBackend({ onDirty: () => requestRepaint() })
150
+ render(() => h('canvas-rect', { x: 8, y: 8, width: 64, height: 64, fill: '#09f' }), backend, backend.root)
151
+ backend.paint(ctx, 320, 240) // once for static art, or on a frame loop for animation
152
+ ```
153
+
106
154
  ## API
107
155
 
108
156
  | Export | Kind | Description |
@@ -112,12 +160,14 @@ host.liveNodeCount() // 0 after app.dispose() β€” no orphaned/leaked nodes
112
160
  | `hydrate(container, node\|component, [props,] opts?)` | fn | Attach reactivity to server HTML (developer preview). |
113
161
  | `createDomBackend(doc?)` | fn | Web/DOM `HostBackend`. |
114
162
  | `createHeadlessBackend()` / `createHeadlessRoot()` | fn | In-memory backend (tests, snapshots, SSR). |
163
+ | `createCanvas2DBackend(opts?)` | fn | Helix Canvas strand: reconciler-driven 2D scene graph; `paint(ctx, w, h)` rasterizes. |
115
164
  | `domTagFor(tag)` | fn | Map a semantic tag to its HTML tag. |
116
165
  | `HostBackend` / `SerializableBackend` | type | The platform seam. |
117
166
  | `createNativeCommandBackend(opts?)` | fn | Native `HostBackend` that emits a serializable `NativeCommand` stream (Phase 8A). |
167
+ | `createNativeApp(node, opts?)` | fn | One-call native entry: wires the command backend + reactive engines + host contract (`start`/`dispatchEvent`/`frameTick`). |
118
168
  | `createReferenceHost(rootId?)` | fn | Strict reference host: replays + validates a `NativeCommand` stream (Phase 8B). |
119
169
  | `NativeCommand` + `isNativeCommand` / `isNativePropValue` / `normalizeNativeProp` / `createNativeNodeIdFactory` | type/fn | The native command protocol + helpers. |
120
- | `createNativeBackend` / `createCanvasBackend` | fn | πŸ”¬ research tracks (direct runtime native backend + GPU canvas) β€” throw `NotImplementedError`. |
170
+ | `createNativeBackend` / `createCanvasBackend` | fn | πŸ”¬ research tracks (direct in-process runtime native backend + GPU/WebGPU canvas) β€” throw `NotImplementedError`. |
121
171
 
122
172
  ### Reactive bindings
123
173
 
package/dist/index.d.ts CHANGED
@@ -17,7 +17,7 @@ import { Maturity, NotImplementedError, PackageInfo, notImplemented } from "@min
17
17
  /** The npm package name. */
18
18
  declare const name = "@mindees/renderer";
19
19
  /** The package version. All `@mindees/*` packages share one locked version line. */
20
- declare const VERSION = "0.13.0";
20
+ declare const VERSION = "0.14.0";
21
21
  /**
22
22
  * Current maturity. The Helix **web/DOM** renderer (reconciler, DOM backend,
23
23
  * headless backend, SSR + hydration) is implemented and tested. Native
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@ import { NotImplementedError, notImplemented } from "@mindees/core";
16
16
  /** The npm package name. */
17
17
  const name = "@mindees/renderer";
18
18
  /** The package version. All `@mindees/*` packages share one locked version line. */
19
- const VERSION = "0.13.0";
19
+ const VERSION = "0.14.0";
20
20
  /**
21
21
  * Current maturity. The Helix **web/DOM** renderer (reconciler, DOM backend,
22
22
  * headless backend, SSR + hydration) is implemented and tested. Native
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { Maturity, PackageInfo } from '@mindees/core'\nimport { NotImplementedError, notImplemented } from '@mindees/core'\n\n/** Host-backend contract + capability detection. */\nexport {\n type HostBackend,\n isSerializable,\n type SerializableBackend,\n} from './backend'\n/** Helix Canvas strand β€” a 2D scene graph driven by the reconciler, painted to a 2D context (Β§6.2). */\nexport {\n type Canvas2DBackend,\n createCanvas2DBackend,\n type Scene2DContext,\n type SceneNode,\n} from './canvas'\n/** DOM (web) backend. */\nexport {\n createDomBackend,\n type DomDocument,\n type DomElement,\n type DomNode,\n type DomText,\n domTagFor,\n} from './dom'\n/** Keyed list reconciliation (the renderer side of core's KeyedRegion). */\nexport { bindKeyedChild } from './for'\n/** Headless (in-memory) backend β€” the reference/test target. */\nexport {\n createHeadlessBackend,\n createHeadlessRoot,\n type HeadlessNode,\n isEventProp,\n} from './headless'\n/**\n * Native backends. `createNativeCommandBackend` is implemented (emits a native\n * command stream); `createNativeBackend`/`createCanvasBackend` are research\n * tracks that throw `NotImplementedError`.\n */\nexport {\n type CanvasBackend,\n createCanvasBackend,\n createNativeBackend,\n createNativeCommandBackend,\n type NativeBackend,\n type NativeCommandBackend,\n type NativeCommandBackendOptions,\n type NativeCommandNode,\n} from './native'\n/** One-call native app entry β€” wires the command backend + host contract. */\nexport {\n type CreateNativeAppOptions,\n createNativeApp,\n type NativeApp,\n} from './native-app'\n/**\n * The strict reference native host β€” applies a command stream to a model tree and\n * validates it (the executable conformance contract real native hosts implement).\n */\nexport {\n createReferenceHost,\n NativeHostError,\n type ReferenceHost,\n type ReferenceHostNode,\n} from './native-host'\n/** The native command protocol: command types + serialization-safe helpers. */\nexport {\n type CreateNodeCommand,\n type CreateTextCommand,\n createNativeNodeIdFactory,\n type DisposeNodeCommand,\n type InsertChildCommand,\n isNativeCommand,\n isNativePropValue,\n type NativeCommand,\n type NativeNodeId,\n type NativePropValue,\n normalizeNativeProp,\n type RegisterEventCommand,\n type RemoveChildCommand,\n type RemovePropCommand,\n type SetPropCommand,\n type UnregisterEventCommand,\n type UpdateTextCommand,\n} from './native-protocol'\n/** Portal reconciliation (the renderer side of core's PortalRegion). */\nexport { bindPortalChild } from './portal'\n/** The fine-grained reactive reconciler. */\nexport { type Mounted, mountNode, render } from './render'\n/** Server-side rendering + hydration (web). */\nexport { hydrate, renderToString } from './ssr'\n\n/** The npm package name. */\nexport const name = '@mindees/renderer'\n\n/** The package version. All `@mindees/*` packages share one locked version line. */\nexport const VERSION = '0.13.0'\n\n/**\n * Current maturity. The Helix **web/DOM** renderer (reconciler, DOM backend,\n * headless backend, SSR + hydration) is implemented and tested. Native\n * (iOS/Android) and the GPU canvas are research tracks (throw\n * `NotImplementedError`). See the repository `STATUS.md`.\n */\nexport const maturity: Maturity = 'experimental'\n\n/**\n * Static identity + maturity metadata for this package. Frozen so the\n * self-reported identity tooling introspects cannot be mutated at runtime,\n * matching the `readonly` fields of {@link PackageInfo}.\n */\nexport const info: PackageInfo = Object.freeze({ name, version: VERSION, maturity })\n\nexport type { Maturity, PackageInfo }\nexport { NotImplementedError, notImplemented }\n"],"mappings":";;;;;;;;;;;;;;;;AA6FA,MAAa,OAAO;;AAGpB,MAAa,UAAU;;;;;;;AAQvB,MAAa,WAAqB;;;;;;AAOlC,MAAa,OAAoB,OAAO,OAAO;CAAE;CAAM,SAAS;CAAS;AAAS,CAAC"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { Maturity, PackageInfo } from '@mindees/core'\nimport { NotImplementedError, notImplemented } from '@mindees/core'\n\n/** Host-backend contract + capability detection. */\nexport {\n type HostBackend,\n isSerializable,\n type SerializableBackend,\n} from './backend'\n/** Helix Canvas strand β€” a 2D scene graph driven by the reconciler, painted to a 2D context (Β§6.2). */\nexport {\n type Canvas2DBackend,\n createCanvas2DBackend,\n type Scene2DContext,\n type SceneNode,\n} from './canvas'\n/** DOM (web) backend. */\nexport {\n createDomBackend,\n type DomDocument,\n type DomElement,\n type DomNode,\n type DomText,\n domTagFor,\n} from './dom'\n/** Keyed list reconciliation (the renderer side of core's KeyedRegion). */\nexport { bindKeyedChild } from './for'\n/** Headless (in-memory) backend β€” the reference/test target. */\nexport {\n createHeadlessBackend,\n createHeadlessRoot,\n type HeadlessNode,\n isEventProp,\n} from './headless'\n/**\n * Native backends. `createNativeCommandBackend` is implemented (emits a native\n * command stream); `createNativeBackend`/`createCanvasBackend` are research\n * tracks that throw `NotImplementedError`.\n */\nexport {\n type CanvasBackend,\n createCanvasBackend,\n createNativeBackend,\n createNativeCommandBackend,\n type NativeBackend,\n type NativeCommandBackend,\n type NativeCommandBackendOptions,\n type NativeCommandNode,\n} from './native'\n/** One-call native app entry β€” wires the command backend + host contract. */\nexport {\n type CreateNativeAppOptions,\n createNativeApp,\n type NativeApp,\n} from './native-app'\n/**\n * The strict reference native host β€” applies a command stream to a model tree and\n * validates it (the executable conformance contract real native hosts implement).\n */\nexport {\n createReferenceHost,\n NativeHostError,\n type ReferenceHost,\n type ReferenceHostNode,\n} from './native-host'\n/** The native command protocol: command types + serialization-safe helpers. */\nexport {\n type CreateNodeCommand,\n type CreateTextCommand,\n createNativeNodeIdFactory,\n type DisposeNodeCommand,\n type InsertChildCommand,\n isNativeCommand,\n isNativePropValue,\n type NativeCommand,\n type NativeNodeId,\n type NativePropValue,\n normalizeNativeProp,\n type RegisterEventCommand,\n type RemoveChildCommand,\n type RemovePropCommand,\n type SetPropCommand,\n type UnregisterEventCommand,\n type UpdateTextCommand,\n} from './native-protocol'\n/** Portal reconciliation (the renderer side of core's PortalRegion). */\nexport { bindPortalChild } from './portal'\n/** The fine-grained reactive reconciler. */\nexport { type Mounted, mountNode, render } from './render'\n/** Server-side rendering + hydration (web). */\nexport { hydrate, renderToString } from './ssr'\n\n/** The npm package name. */\nexport const name = '@mindees/renderer'\n\n/** The package version. All `@mindees/*` packages share one locked version line. */\nexport const VERSION = '0.14.0'\n\n/**\n * Current maturity. The Helix **web/DOM** renderer (reconciler, DOM backend,\n * headless backend, SSR + hydration) is implemented and tested. Native\n * (iOS/Android) and the GPU canvas are research tracks (throw\n * `NotImplementedError`). See the repository `STATUS.md`.\n */\nexport const maturity: Maturity = 'experimental'\n\n/**\n * Static identity + maturity metadata for this package. Frozen so the\n * self-reported identity tooling introspects cannot be mutated at runtime,\n * matching the `readonly` fields of {@link PackageInfo}.\n */\nexport const info: PackageInfo = Object.freeze({ name, version: VERSION, maturity })\n\nexport type { Maturity, PackageInfo }\nexport { NotImplementedError, notImplemented }\n"],"mappings":";;;;;;;;;;;;;;;;AA6FA,MAAa,OAAO;;AAGpB,MAAa,UAAU;;;;;;;AAQvB,MAAa,WAAqB;;;;;;AAOlC,MAAa,OAAoB,OAAO,OAAO;CAAE;CAAM,SAAS;CAAS;AAAS,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindees/renderer",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "MindeesNative Helix β€” fine-grained reactive renderer with a web/DOM backend, SSR + hydration, and a headless test backend. Native and GPU-canvas backends are research tracks.",
5
5
  "license": "MIT OR Apache-2.0",
6
6
  "type": "module",
@@ -23,7 +23,7 @@
23
23
  "directory": "packages/renderer"
24
24
  },
25
25
  "dependencies": {
26
- "@mindees/core": "0.13.0"
26
+ "@mindees/core": "0.14.0"
27
27
  },
28
28
  "devDependencies": {
29
29
  "happy-dom": "20.9.0"