Files
Charlie CheeverandClaude Opus 5.5 7da7f53c14 app.json's rust.data names an app's data crate, and generated host crates link it through one shared bake
LLP 1153.003 D2. `rust.data { crate, type, source? }` names the data crate
and its DataSource; the source defaults to `<type>::default()` and is the
type itself, `::default()` or `::new(…)` with literal arguments. The
generated workspace gives such an app host crates that link the data crate
and whose build script is one line, `exact_bake::host::app(platform, app,
source)` (bake/src/host.rs, the game's bake lifted and generalized; the
game now calls it too). Without app.ts they link no exact-js, so no Hermes;
with app.ts beside the crate the two compose (`exact_data::Mixed`), Rust
answering what the crate's `RUST_SOURCES` names and TypeScript the rest.
The web's Rust module is a member of the same workspace
(`.exact/shells/module`), built `--locked --offline` over the source the
manifest names, so `bakedRustSource` and the source-copying it did are
gone. The JS dev loop also watches the module's path dependencies outside
the app, read from its dep-info (D1.6).

Decided here, by the RFC's principles:
- A data crate composed with app.ts exports `RUST_SOURCES`, the sources it
  answers; the mixed bake reads it rather than guessing from the plan.
- The generated hosts wrap the source in `exact_data_host::Storage`, as the
  authored Rust apps already did, so storage-backed answers work unchanged.
- A data crate that names no app (`DataSource::app_id`'s default, as
  `exact new --rust` writes it) takes app.json's identity: alone, through
  `Swappable::named` as before; beside app.ts, through the new
  `exact_data::Placed::named`, which gives it the module's, since `Mixed`
  requires both sides to share one. The bake's identity check likewise
  lets an unnamed Rust source pass, as the runner's gate does (LLP 1023
  D5). A crate that names its own id keeps it.
- `rustData` joins the compatibility inputs only when declared, so every
  in-repository Rust-data app's compatibility id changes once, with this
  commit, and apps without it keep theirs.
- `contract::rust_entry_naming` refuses a web entry whose source differs
  from the manifest's, which the JS target's module runs. A native host
  crate the app wrote may pass another type of the same data crate:
  markdown-stress's Apple host runs `NativeMarkdownStress`, its native
  document lane, by design, which the RFC's refusal of every differing
  authored entry would forbid. messages-stress names
  `ReusableMessagesStress`, the source all three of its entries already
  passed; a web build of its stateless control now sets rust.data too
  (its README says so).

Every in-repository Rust-data app's app.json names its rust.data.

Part of #423
Part of #578

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-14 17:27:31 -08:00

45 lines
985 B
JSON

{
"$schema": "../../scripts/app.schema.json",
"name": "Shared Elements",
"short_name": "Shared Elements",
"id": "com.exact.sharedelements",
"start_url": "/",
"display": "standalone",
"theme_color": "#111418",
"background_color": "#f2f2f7",
"color_scheme_dark": { "background_color": "#000000" },
"app": {
"id": "com.exact.sharedelements",
"name": "Shared Elements"
},
"host": {
"ios": {
"minimumOS": "17.0",
"deviceFamily": [
"iphone",
"ipad"
]
},
"macos": {
"minimumOS": "14.0",
"window": {
"width": 420,
"height": 780,
"minWidth": 360,
"minHeight": 560
}
},
"web": {},
"linux": {}
},
"deploy": {
"store": {
"web": "0",
"macos": "0",
"ios": "0",
"linux": "0"
}
},
"rust": { "data": { "crate": "shared-elements-data", "type": "shared_elements_data::Shared", "source": "shared_elements_data::Shared" } }
}