@lunora/cli 1.0.0-alpha.400 → 1.0.0-alpha.401
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/cli",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.401",
|
|
4
4
|
"description": "The Lunora CLI: init, dev, deploy, codegen, migrate, seed, doctor, insights, logs, registry, and the rest of the project commands",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent-skills",
|
|
@@ -52,16 +52,16 @@
|
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@bomb.sh/tab": "0.0.22",
|
|
55
|
-
"@lunora/advisor": "1.0.0-alpha.
|
|
55
|
+
"@lunora/advisor": "1.0.0-alpha.236",
|
|
56
56
|
"@lunora/bindings": "1.0.0-alpha.123",
|
|
57
|
-
"@lunora/codegen": "1.0.0-alpha.
|
|
58
|
-
"@lunora/config": "1.0.0-alpha.
|
|
57
|
+
"@lunora/codegen": "1.0.0-alpha.327",
|
|
58
|
+
"@lunora/config": "1.0.0-alpha.377",
|
|
59
59
|
"@lunora/container": "1.0.0-alpha.82",
|
|
60
60
|
"@lunora/d1": "1.0.0-alpha.190",
|
|
61
61
|
"@lunora/errors": ">=1.0.0-alpha.51 <2.0.0-0",
|
|
62
|
-
"@lunora/mcp": "1.0.0-alpha.
|
|
62
|
+
"@lunora/mcp": "1.0.0-alpha.243",
|
|
63
63
|
"@lunora/runtime": "1.0.0-alpha.219",
|
|
64
|
-
"@lunora/seed": "1.0.0-alpha.
|
|
64
|
+
"@lunora/seed": "1.0.0-alpha.238",
|
|
65
65
|
"@visulima/cerebro": "3.1.2",
|
|
66
66
|
"@visulima/error": "6.1.0",
|
|
67
67
|
"@visulima/fs": "6.0.29",
|
package/skills/lunora/SKILL.md
CHANGED
|
@@ -42,7 +42,9 @@ Scaffolded projects gitignore `lunora/_generated/`; never hand-edit it.
|
|
|
42
42
|
- New project, or adding Lunora to an existing app: `lunora-quickstart`
|
|
43
43
|
- Writing or reviewing schema + functions (the core authoring rules):
|
|
44
44
|
`lunora-functions`
|
|
45
|
-
- Wiring live data into a client (hooks, optimistic updates)
|
|
45
|
+
- Wiring live data into a client (hooks, optimistic updates), or choosing
|
|
46
|
+
between a live query, stream, live topic, whisper, room and socket (including
|
|
47
|
+
pushing a server event to the browser): `lunora-realtime`
|
|
46
48
|
- Authentication (email/password, OAuth, magic link, OTP): `lunora-setup-auth`
|
|
47
49
|
- Transactional email: `lunora-setup-mail`
|
|
48
50
|
- R2 file storage (signed upload/download): `lunora-setup-storage`
|
|
@@ -285,6 +285,7 @@ first, then run `lunora codegen` to wire the binding and typed context:
|
|
|
285
285
|
| `ctx.workflows` / `ctx.runStep` | `@lunora/workflow` |
|
|
286
286
|
| `ctx.containers` | `@lunora/container` |
|
|
287
287
|
| `ctx.browser` (action-only) | `@lunora/browser` |
|
|
288
|
+
| `ctx.live` (action-side only; see `lunora-realtime`) | `@lunora/server` |
|
|
288
289
|
| `ctx.sql` (action-only) | `@lunora/hyperdrive` |
|
|
289
290
|
| `ctx.kv` / `ctx.images` / `ctx.analytics` | `@lunora/bindings` subpaths |
|
|
290
291
|
| `ctx.pipelines` / `ctx.vectors` / `ctx.r2sql` | `@lunora/bindings` subpaths |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: lunora-realtime
|
|
3
|
-
description: Wires Lunora's live data into a client app. Covers `LunoraClient` and the per-framework provider, reactive `useQuery`/`useSubscription`, `useMutation` with optimistic updates, `usePaginatedQuery`, `shardKey` routing, connection status, presence, the React/Vue/Solid/Svelte/Angular/React Native adapters, and the `@lunora/db` TanStack DB binding. Use when building UI that reads or writes Lunora functions, when asked to "show live data", "make this update in real time", "add optimistic updates", "add infinite scroll/pagination", or "show offline/reconnecting state", when editing components that import `@lunora/react`/`vue`/`solid`/`svelte`/`angular`/`react-native` or `lunorash/client`,
|
|
3
|
+
description: Wires Lunora's live data into a client app. Covers `LunoraClient` and the per-framework provider, reactive `useQuery`/`useSubscription`, `useMutation` with optimistic updates, `usePaginatedQuery`, `shardKey` routing, connection status, presence, the React/Vue/Solid/Svelte/Angular/React Native adapters, and the `@lunora/db` TanStack DB binding. Use when building UI that reads or writes Lunora functions, when asked to "show live data", "make this update in real time", "add optimistic updates", "add infinite scroll/pagination", or "show offline/reconnecting state", when editing components that import `@lunora/react`/`vue`/`solid`/`svelte`/`angular`/`react-native` or `lunorash/client`, when a live query stays `undefined`, freezes, or doesn't update, or when choosing between a live query, a stream, a live topic (`defineLiveStream`, `useLiveTopic`, `ctx.live.publish`, SSE), a whisper, a room and a socket, such as "push an event to the browser" or "notify the page when X happens".
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Lunora Realtime
|
|
@@ -10,6 +10,27 @@ subscriptions over WebSocket — a `useQuery` re-renders as soon as a mutation
|
|
|
10
10
|
changes the rows it reads — and mutations can paint optimistically with
|
|
11
11
|
automatic rollback.
|
|
12
12
|
|
|
13
|
+
## Choosing a Channel
|
|
14
|
+
|
|
15
|
+
Decide by what you are sending. If the client could get it by running a query,
|
|
16
|
+
use a live query: it is typed, runs under the caller's identity, and works across
|
|
17
|
+
shards. Reach past it only for the rest.
|
|
18
|
+
|
|
19
|
+
| You want | Use |
|
|
20
|
+
| -------------------------------------------------- | ------------------------------------------------------ |
|
|
21
|
+
| Rows that stay fresh | `useQuery` (WebSocket, typed through `api.*`) |
|
|
22
|
+
| A write / a side effect | `useMutation` / `useAction` |
|
|
23
|
+
| Chunks of one long call (model tokens) | `query.stream()` + `useStream` (`durable` to resume) |
|
|
24
|
+
| Chunks of one HTTP request | `httpRoute.get(path).stream()` + `useHttpStream` |
|
|
25
|
+
| A server-published event that is not a row | live topic: `defineLiveStream` + `useLiveTopic` |
|
|
26
|
+
| A client-to-clients ephemeral message (cursors) | whisper (`client.whisper`; authorize with `onWhisper`) |
|
|
27
|
+
| A room with server join / message / leave handlers | `defineRoom` + `client.connectRoom` |
|
|
28
|
+
| A dedicated socket at your own path | `defineWebSocket` + `client.connectWebSocket(path)` |
|
|
29
|
+
| Who is online | `usePresence` |
|
|
30
|
+
|
|
31
|
+
Live topics are the untyped one: the topic is a string and the payload is
|
|
32
|
+
`unknown`. Full guide: the "Choosing a data channel" docs page.
|
|
33
|
+
|
|
13
34
|
## When Not to Use
|
|
14
35
|
|
|
15
36
|
- Writing the server functions themselves — that's `lunora-functions`.
|
|
@@ -170,6 +191,46 @@ TanStack-style alternative.
|
|
|
170
191
|
- `useAuth` + `Authenticated` / `Unauthenticated` / `AuthLoading` — see
|
|
171
192
|
`lunora-setup-auth`.
|
|
172
193
|
|
|
194
|
+
## Live Topics
|
|
195
|
+
|
|
196
|
+
For an event with no query behind it ("a comment was posted"), the server
|
|
197
|
+
publishes to a named topic and the browser follows topics over one shared SSE
|
|
198
|
+
connection (shared when the connection options match). Declare the stream once, mount its two handlers on the HTTP router,
|
|
199
|
+
and follow topics with the adapter's hook (all return `{ lastEvent, error }`):
|
|
200
|
+
|
|
201
|
+
| Package | Primitive |
|
|
202
|
+
| ---------------------- | ------------------------- |
|
|
203
|
+
| `@lunora/react`, `vue` | `useLiveTopic` |
|
|
204
|
+
| `@lunora/solid` | `createLiveTopic` |
|
|
205
|
+
| `@lunora/svelte` | `liveTopic` (a store) |
|
|
206
|
+
| `@lunora/angular` | `liveTopic` (signals) |
|
|
207
|
+
| `@lunora/react-native` | re-exports `useLiveTopic` |
|
|
208
|
+
|
|
209
|
+
```tsx
|
|
210
|
+
const { lastEvent, error } = useLiveTopic({ url: "/live/posts/connect", topic: `post:${postId}`, onEvent: (payload) => refresh(payload) });
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
- Several hooks with the same URL, credentials, headers, `retryDelay`, `maxDelayMs` and
|
|
214
|
+
`sessionKey` share a single connection; the last to unmount closes it. On a
|
|
215
|
+
cookie-authenticated stream pass `sessionKey` (the user id), or the connection
|
|
216
|
+
outlives a sign-out and keeps the previous user's topics.
|
|
217
|
+
- Publish from server code with `ctx.live.publish(topic, payload, { stream })`.
|
|
218
|
+
`ctx.live` exists only on actions, HTTP actions, queue consumers and scheduled
|
|
219
|
+
actions, NOT on a query or mutation. It is always present on an HTTP action
|
|
220
|
+
but typed optional on an `action` and a queue consumer, so write
|
|
221
|
+
`ctx.live?.publish(...)` there. To tell a page about a write, have the
|
|
222
|
+
mutation `ctx.scheduler.runAfter(0, internal.x.publish, args)`: it is held until
|
|
223
|
+
the commit, so a rolled-back write sends nothing. If the page already has a
|
|
224
|
+
`useQuery` over those rows, skip the event.
|
|
225
|
+
- Without `onSubscribe` every subscribe is DENIED (unless `allowAnonymousControl`
|
|
226
|
+
admits anonymous callers). Only a literal `true` allows.
|
|
227
|
+
- Delivery is at least once (a retried action publishes again) and shard-local
|
|
228
|
+
(no fan-out across Durable Objects). Put an id in the payload to dedupe.
|
|
229
|
+
- React Native's stock `fetch` does not stream, so events never arrive; use a
|
|
230
|
+
streaming `fetch` such as `expo/fetch`.
|
|
231
|
+
- Live streams are native on Cloudflare and celld, emulated on Node. Codegen
|
|
232
|
+
refuses an app that reads `ctx.live` on a target that withholds them.
|
|
233
|
+
|
|
173
234
|
## `@lunora/db` — TanStack DB Collections
|
|
174
235
|
|
|
175
236
|
For indexed local collections, cross-query joins, or a durable offline outbox,
|
|
@@ -216,3 +277,5 @@ hold stale ones, while `useLiveQuery` still looks correct.
|
|
|
216
277
|
`optimisticUpdate` rows match the query's element shape.
|
|
217
278
|
- [ ] Lists that grow use `usePaginatedQuery` over a `.paginate` query.
|
|
218
279
|
- [ ] `@lunora/db`: one `defineCollections` instance; no parallel copy of rows.
|
|
280
|
+
- [ ] Events that are not rows use a live topic, published from an action (via
|
|
281
|
+
`ctx.scheduler` after a write); data a query could return stays a `useQuery`.
|