Declares a screen: its id in the core screen catalog (NATIVE_SCREENS), its
kind, its schemas, the burst the app sends when it shows the screen, and
what can be done from it. An item of a list is declared with
defineScreenItem.
input and data are what an edge passes and what enter returns (the
user's data, flat on the handle, checked against data).
state: ({ input, data }) => State is what continuing from the screen
needs — a token that came with the edge's input included;
noScreenState for a screen that keeps none.
enter({ input, navigate }) is the burst, once per frame: the requests the
app sends, and navigate — the screen's own navigation event, exactly
once — at the point a recording shows.
leave and resume (optional) are a visit's end and a new visit's start:
run each time the screen stops being on top and each time it is on top
again after that.
actions are action((state, ...args) => Effect) (something done on the
screen) and opens(id, (state, ...args) => ({ source, skipOrdinals?, input })) (a transition into another screen; with arguments, their
schema comes third). Both see the state, not the data.
items are the lists of items it shows, each a plain object over a field
of its data: { at: 'threads', key: 'thread', item: ThreadItem }, or,
for entries of several kinds, { at: 'media', key: 'pk', by: 'media_type', variants: { 1: PhotoItem, 2: VideoItem, 8: CarouselItem } }
(see ScreenItemListCheck). key is the entries' identity field.
The handle is a snapshot: { id, kind, origin, ...data, ...actions, ...items },
frozen all the way down; an action does not change its data — fresh data comes with opening
the screen again. A key used twice, or a reserved key, is a type error.
Declares a screen: its id in the core screen catalog (
NATIVE_SCREENS), its kind, its schemas, the burst the app sends when it shows the screen, and what can be done from it. An item of a list is declared with defineScreenItem.inputanddataare what an edge passes and whatenterreturns (the user's data, flat on the handle, checked againstdata).state: ({ input, data }) => Stateis what continuing from the screen needs — a token that came with the edge's input included;noScreenStatefor a screen that keeps none.enter({ input, navigate })is the burst, once per frame: the requests the app sends, andnavigate— the screen's own navigation event, exactly once — at the point a recording shows.leaveandresume(optional) are a visit's end and a new visit's start: run each time the screen stops being on top and each time it is on top again after that.actionsareaction((state, ...args) => Effect)(something done on the screen) andopens(id, (state, ...args) => ({ source, skipOrdinals?, input }))(a transition into another screen; with arguments, their schema comes third). Both see the state, not the data.itemsare the lists of items it shows, each a plain object over a field of its data:{ at: 'threads', key: 'thread', item: ThreadItem }, or, for entries of several kinds,{ at: 'media', key: 'pk', by: 'media_type', variants: { 1: PhotoItem, 2: VideoItem, 8: CarouselItem } }(see ScreenItemListCheck).keyis the entries' identity field.The handle is a snapshot:
{ id, kind, origin, ...data, ...actions, ...items }, frozen all the way down; an action does not change its data — fresh data comes with opening the screen again. A key used twice, or a reserved key, is a type error.