11# RemoteState
22
33[ ![ CI] ( https://github.com/bcdev/remotestate/actions/workflows/ci.yml/badge.svg )] ( https://github.com/bcdev/remotestate/actions/workflows/ci.yml )
4+
5+ [ ![ PyPI version] ( https://img.shields.io/pypi/v/remotestate?logo=pypi )] ( https://pypi.org/project/remotestate/ )
6+ [ ![ Python] ( https://img.shields.io/badge/Python-3776AB?logo=python&logoColor=white )] ( https://www.python.org/ )
7+ [ ![ FastAPI] ( https://img.shields.io/badge/FastAPI-009688?logo=fastapi&logoColor=white )] ( https://fastapi.tiangolo.com/ )
8+ [ ![ pydantic] ( https://img.shields.io/badge/pydantic-E92063?logo=pydantic&logoColor=white )] ( https://docs.pydantic.dev/ )
9+ [ ![ Ruff] ( https://img.shields.io/badge/Ruff-2C2F3A?logo=ruff&logoColor=white )] ( https://docs.astral.sh/ruff/ )
10+
11+ [ ![ npm version] ( https://img.shields.io/npm/v/remotestate?logo=npm )] ( https://www.npmjs.com/package/remotestate )
412[ ![ TypeScript] ( https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white )] ( https://www.typescriptlang.org/ )
13+ [ ![ React] ( https://img.shields.io/badge/React-61DAFB?logo=react&logoColor=black )] ( https://react.dev/ )
514[ ![ Vite] ( https://img.shields.io/badge/Vite-646CFF?logo=vite&logoColor=white )] ( https://vite.dev/ )
6- [ ![ Ruff] ( https://img.shields.io/badge/Ruff-2C2F3A?logo=ruff&logoColor=white )] ( https://docs.astral.sh/ruff/ )
7- [ ![ Python] ( https://img.shields.io/badge/Python-3776AB?logo=python&logoColor=white )] ( https://www.python.org/ )
15+
816[ ![ License: MIT] ( https://img.shields.io/badge/License-MIT-yellow.svg )] ( https://opensource.org/licenses/MIT )
917
1018> ** Python state, React UI.** One runtime for notebook apps and addon backends.
@@ -184,16 +192,16 @@ npm install remotestate
184192
185193## Python API
186194
187- ### ` Store(initial: dict) `
195+ ### ` Store(initial: dict[str, Any] ) `
188196
189197Holds application state. Supports nested dicts, lists, Pydantic models, and dataclasses.
190198
191199``` python
192- store = rs.Store({" items" : [], " user" : UserModel(name = " Norman " )})
193- store.get(" user.name" ) # "Norman "
200+ store = rs.Store({" items" : [], " user" : UserModel(name = " forman " )})
201+ store.get(" user.name" ) # "forman "
194202store.set(" items[0].label" , " foo" )
195203```
196-
204+ ^^
197205Paths use a JSONPath-inspired syntax such as ` user.name ` or ` items[3].label ` .
198206
199207### ` @action `
@@ -219,35 +227,38 @@ async def process(self, path: str) -> dict:
219227 return result
220228```
221229
222- ### ` rs.serve(service, *, dist_dir, host, port, open_browser, open_iframe, iframe_height) `
230+ ### ` rs.serve(service, *, ui_dist, app, open_browser, open_iframe, iframe_height, host, port, **uvicorn_settings ) `
223231
224232Starts the Remote State server and connects it to a frontend bundle.
225233
226- | Parameter | Default | Description |
227- | ---| ---| ---|
228- | ` service ` | required | A ` Service ` instance |
229- | ` dist_dir ` | ` None ` | Path to the React build output (` dist/ ` ) |
230- | ` host ` | ` "localhost" ` | Server host |
231- | ` port ` | ` 9753 ` | Server port |
232- | ` open_browser ` | auto | Open in browser, default outside Jupyter |
233- | ` open_iframe ` | auto | Render as IFrame, default in Jupyter |
234- | ` iframe_height ` | ` 600 ` | IFrame height in pixels |
234+ | Parameter | Default | Description |
235+ | --------------------| ---------------| -----------------------------------------------------------------|
236+ | ` service ` | required | A ` Service ` instance |
237+ | ` ui_dist ` | ` None ` | Path to the React build output (` dist/ ` ) or URL |
238+ | ` mounts ` | ` None ` | Mapping of an endpoint paths to local directories |
239+ | ` app ` | ` None ` | [ FastAPI] ( https://fastapi.tiangolo.com/ ) instance |
240+ | ` open_browser ` | auto | Open in browser, default outside Jupyter |
241+ | ` open_iframe ` | auto | Render as IFrame, default in Jupyter |
242+ | ` iframe_height ` | ` 400 ` | IFrame height in pixels |
243+ | ` host ` | ` "localhost" ` | Server host |
244+ | ` port ` | ` 9753 ` | Server port |
245+ | ` uvicorn_settings ` | - | Additional [ uvicorn settings] ((https://uvicorn.dev/settings/) |
235246
236247Re-running the same Jupyter cell restarts the server automatically.
237248
238249---
239250
240251## TypeScript API
241252
242- ### ` createRemoteState<TService >(url) `
253+ ### ` createRemoteState<S >(url) `
243254
244255Creates a typed RemoteState bridge.
245256
246257``` typescript
247258const remoteState = createRemoteState <MyService >(" ws://localhost:9753/ws" );
248259```
249260
250- ### ` RemoteStateProvider ` and ` useRemoteStateClient<TService >() `
261+ ### ` RemoteStateProvider ` and ` useRemoteStateClient<S >() `
251262
252263React context wrapper for a RemoteState bridge bound to a WebSocket URL, plus
253264a hook to access it.
@@ -260,7 +271,7 @@ a hook to access it.
260271const remoteState = useRemoteStateClient <MyService >();
261272```
262273
263- ### ` useState <T>(path, initialValue?)`
274+ ### ` useRemoteState <T>(path, initialValue?)`
264275
265276React-like state hook backed by the Python store. It returns ` [value, setValue] ` .
266277
@@ -275,7 +286,7 @@ Calls a Python `@action`. Fire-and-forget by default.
275286
276287``` typescript
277288await remoteState .action (" increment" );
278- await remoteState .action (" set_name" , [" Norman " ]);
289+ await remoteState .action (" set_name" , [" forman " ]);
279290await remoteState .action (" save" , [], {}, { awaitInvalidate: true });
280291```
281292
@@ -284,7 +295,7 @@ await remoteState.action("save", [], {}, { awaitInvalidate: true });
284295Calls a Python ` @query ` and returns the result.
285296
286297``` typescript
287- const result = await remoteState .query (" compute" , [5.0 ]);
298+ const result = await remoteState .query (" compute" , [2.5 ]);
288299```
289300
290301### ` useRemoteStateValue<T>(path) `
@@ -297,9 +308,7 @@ re-renders on invalidation.
297308- ` RemoteState ` is the bridge object that used to be called ` Client ` .
298309- ` useRemoteStateClient() ` returns that bridge object.
299310- ` useRemoteStore() ` returns the cached store view used by the hooks.
300- - ` useState() ` remains the ergonomic path-bound state hook for components.
301- - We use ` useRemoteStateClient() ` instead of ` useRemoteState() ` to keep it
302- clearly distinct from ` useState() ` and ` useRemoteStore() ` .
311+ - ` useRemoteState() ` remains the ergonomic path-bound state hook for components.
303312
304313---
305314
0 commit comments