Your app runs on the server.
Moss builds each person’s app on the server, from the screens and rows the charter grants them. The browser only draws it. So an assistant can work inside a person’s app through that person’s session, and it is given what they are given.
pnpm add @niscorp/moss @niscorp/charter @niscorp/nova @niscorp/prism @niscorp/strata @niscorp/tide @niscorp/vex zod · 0.8.2 · Apache-2.0
A running app is called a shell. Nova is at both ends of the socket: it runs your shell on the server, and draws it in the browser.
First steps →You are sent only your app.
In Nisc the charter says which screens and which rows each person has. A browser cannot be trusted to keep to that, because whatever is sent to it can be read. So Moss builds each person’s app on the server, out of what they were granted, and sends the browser only what to draw.
Where the pieces of Nisc meet.
Moss adds no language of its own. It puts the other packages to work, for one user at a time.
Charter decides once, at sign-in, and Moss enforces it twice: in the screens a shell is built from, and in every query Vex makes for it.
Where an assistant runs.
An assistant has to run on a server, because its model key cannot go to a browser. On a usual server the user’s screen is not there. On Moss it is: the assistant is a function beside the user’s shell, and Moss hands it that user’s session.
Nobody asked, and the screen changed.
A web server answers when it is asked. An app on a server changes when nobody asked: somebody else wrote a row, or an assistant opened a screen. So Moss holds a socket to every shell.
Your app keeps running when you close the tab.
A shell runs in the server’s memory for as long as you are around. What has to last is saved to the database.
Restarting the server stops every app at once. Saved data is not affected.
Every press is a round trip.
That is the price of running the app on the server, and Moss’s design document measures it. One connected person costs the server about this much memory:
A changed screen is sent whole. With shellFrameDelta on, a change in place is sent as 1 to 4% of it. Typing does not wait for the server: a new screen never overwrites the input you are typing in.
What an engineer asks.
nisc export draws every page at build, and any host serves the files. This site is served that way.renderDocument reads the person’s screen off their shell, and your own components draw it into your page. The socket takes over from there.session can be your own function that says who a token is. Moss asks it at connect, and again every minute the socket lives.session.revoke() closes every connection that person has, and drops their shell.invalidateIdentity builds their shell again, from what they are granted now.runs. Moss stamps who asked and when, and you hand it the model and every turn.