@lunora/cli 1.0.0-alpha.15 → 1.0.0-alpha.151

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.
Files changed (108) hide show
  1. package/LICENSE.md +6 -0
  2. package/README.md +1 -1
  3. package/__assets__/package-og.svg +1 -1
  4. package/dist/bin.mjs +2 -10
  5. package/dist/index.d.mts +658 -335
  6. package/dist/index.d.ts +658 -335
  7. package/dist/index.mjs +1 -19
  8. package/dist/packem_chunks/handler.mjs +1 -150
  9. package/dist/packem_chunks/handler10.mjs +1 -22
  10. package/dist/packem_chunks/handler11.mjs +2 -192
  11. package/dist/packem_chunks/handler12.mjs +2 -131
  12. package/dist/packem_chunks/handler13.mjs +1 -65
  13. package/dist/packem_chunks/handler14.mjs +1 -58
  14. package/dist/packem_chunks/handler15.mjs +1 -79
  15. package/dist/packem_chunks/handler16.mjs +1 -43
  16. package/dist/packem_chunks/handler17.mjs +3 -105
  17. package/dist/packem_chunks/handler18.mjs +1 -170
  18. package/dist/packem_chunks/handler19.mjs +1 -89
  19. package/dist/packem_chunks/handler2.mjs +2 -114
  20. package/dist/packem_chunks/handler20.mjs +7 -94
  21. package/dist/packem_chunks/handler21.mjs +2 -311
  22. package/dist/packem_chunks/handler22.mjs +2 -0
  23. package/dist/packem_chunks/handler23.mjs +1 -0
  24. package/dist/packem_chunks/handler24.mjs +99 -0
  25. package/dist/packem_chunks/handler25.mjs +10 -0
  26. package/dist/packem_chunks/handler3.mjs +2 -204
  27. package/dist/packem_chunks/handler4.mjs +1 -33
  28. package/dist/packem_chunks/handler5.mjs +1 -49
  29. package/dist/packem_chunks/handler6.mjs +1 -91
  30. package/dist/packem_chunks/handler7.mjs +1 -42
  31. package/dist/packem_chunks/handler8.mjs +3 -174
  32. package/dist/packem_chunks/handler9.mjs +1 -16
  33. package/dist/packem_chunks/planDevCommand.mjs +7 -500
  34. package/dist/packem_chunks/runCodegenCommand.mjs +4 -52
  35. package/dist/packem_chunks/runDeployCommand.mjs +1 -504
  36. package/dist/packem_chunks/runInitCommand.mjs +1018 -1315
  37. package/dist/packem_chunks/runMigrateGenerateCommand.mjs +9 -395
  38. package/dist/packem_chunks/runResetCommand.mjs +1 -41
  39. package/dist/packem_chunks/runRpcCommand.mjs +1 -68
  40. package/dist/packem_shared/COMMANDS-DMyRipjO.mjs +1 -0
  41. package/dist/packem_shared/DEFAULT_IMPORT_BATCH_SIZE-Dqu4Zmi0.mjs +1 -0
  42. package/dist/packem_shared/admin-token-BKmc3AUm.mjs +1 -0
  43. package/dist/packem_shared/admin-url-Ca-KI3d_.mjs +1 -0
  44. package/dist/packem_shared/advisory-gate-yaOOyUQl.mjs +1 -0
  45. package/dist/packem_shared/api-spec-BENwiyUa.mjs +1 -0
  46. package/dist/packem_shared/buildRegistryIndex-DwySASBu.mjs +1 -0
  47. package/dist/packem_shared/cli-RVVu3rxm.mjs +3 -0
  48. package/dist/packem_shared/codegen-error-DJN6pTH5.mjs +3 -0
  49. package/dist/packem_shared/command-0l-ZPhIX.mjs +1 -0
  50. package/dist/packem_shared/commands-CG9qEtqR.mjs +19 -0
  51. package/dist/packem_shared/createLogger-BoSxdb2T.mjs +2 -0
  52. package/dist/packem_shared/createRecordingSpawner-SKs4R1fc.mjs +1 -0
  53. package/dist/packem_shared/deploy-target-Dvr9vxpR.mjs +1 -0
  54. package/dist/packem_shared/detect-package-manager-DXDstphE.mjs +1 -0
  55. package/dist/packem_shared/diffSnapshots-BbwCuhoN.mjs +5 -0
  56. package/dist/packem_shared/docker-CKvYE9YF.mjs +1 -0
  57. package/dist/packem_shared/health-probe-CiFgh1hn.mjs +1 -0
  58. package/dist/packem_shared/import-DLyCq-2j.mjs +12 -0
  59. package/dist/packem_shared/insertSchemaExtension-DZReBZ4_.mjs +8 -0
  60. package/dist/packem_shared/lint-ignore-report-CKDXv9MQ.mjs +2 -0
  61. package/dist/packem_shared/open-url-zbbAo_D7.mjs +1 -0
  62. package/dist/packem_shared/output-format-Cv3aLqhP.mjs +2 -0
  63. package/dist/packem_shared/parseManifest-x3WsxKHz.mjs +1 -0
  64. package/dist/packem_shared/platform-diagnostics-C4TFj5Pu.mjs +4 -0
  65. package/dist/packem_shared/post-codegen-hook-DhL1RH5u.mjs +1 -0
  66. package/dist/packem_shared/prompt-cancelled-C8Sj7OqI.mjs +1 -0
  67. package/dist/packem_shared/resolve-target-CeiNrCAx.mjs +1 -0
  68. package/dist/packem_shared/runAddCommand-a_rW768_.mjs +1 -0
  69. package/dist/packem_shared/runExportCommand-BpE4AbuX.mjs +5 -0
  70. package/dist/packem_shared/schema-drift-gate-d12lMICD.mjs +1 -0
  71. package/dist/packem_shared/schemaIrToSnapshot-Dahp39qH.mjs +1 -0
  72. package/dist/packem_shared/shared-Ce9bKz5c.mjs +1 -0
  73. package/dist/packem_shared/tui-prompts-BU3irGxV.mjs +4 -0
  74. package/dist/packem_shared/vectorize-metadata-BvZbbqUD.mjs +1 -0
  75. package/dist/packem_shared/wrangler-name-CHDf3rMP.mjs +1 -0
  76. package/dist/packem_shared/wrangler-secrets-D0Tv5GWn.mjs +1 -0
  77. package/package.json +39 -17
  78. package/skills/README.md +28 -14
  79. package/skills/lunora/SKILL.md +48 -9
  80. package/skills/lunora-functions/SKILL.md +38 -3
  81. package/skills/lunora-migration-helper/SKILL.md +70 -17
  82. package/skills/lunora-performance-audit/SKILL.md +36 -6
  83. package/skills/lunora-quickstart/SKILL.md +86 -24
  84. package/skills/lunora-realtime/SKILL.md +58 -30
  85. package/dist/packem_shared/COMMANDS-D3h9Iwvl.mjs +0 -944
  86. package/dist/packem_shared/DEFAULT_IMPORT_BATCH_SIZE-Ck-2bU08.mjs +0 -244
  87. package/dist/packem_shared/admin-url-4UzT-CI4.mjs +0 -19
  88. package/dist/packem_shared/api-spec-CtA6ilu4.mjs +0 -13
  89. package/dist/packem_shared/buildRegistryIndex-BcYe607_.mjs +0 -38
  90. package/dist/packem_shared/command-BC30oSBW.mjs +0 -14
  91. package/dist/packem_shared/commands-hl0mRqqg.mjs +0 -845
  92. package/dist/packem_shared/createLogger-B40gPzQo.mjs +0 -78
  93. package/dist/packem_shared/createRecordingSpawner-DxI3mebw.mjs +0 -43
  94. package/dist/packem_shared/detect-package-manager-DYp7n3mJ.mjs +0 -61
  95. package/dist/packem_shared/diffSnapshots-BeDvvNiF.mjs +0 -161
  96. package/dist/packem_shared/docker-hMQ97KSQ.mjs +0 -21
  97. package/dist/packem_shared/insertSchemaExtension-DAqbfr9Z.mjs +0 -64
  98. package/dist/packem_shared/open-url-Dfq6fAyT.mjs +0 -41
  99. package/dist/packem_shared/output-format-wUvAN6AL.mjs +0 -17
  100. package/dist/packem_shared/parseArgs-YXFuKdEk.mjs +0 -56
  101. package/dist/packem_shared/parseManifest--vZf2FY1.mjs +0 -94
  102. package/dist/packem_shared/resolve-target-qbsJ_5sF.mjs +0 -16
  103. package/dist/packem_shared/runAddCommand-vJdgiR5t.mjs +0 -4
  104. package/dist/packem_shared/schema-drift-gate-BtBt0as0.mjs +0 -79
  105. package/dist/packem_shared/schemaIrToSnapshot-DdsljJT-.mjs +0 -43
  106. package/dist/packem_shared/storage-B7hHSTZP.mjs +0 -84
  107. package/dist/packem_shared/tui-prompts-M6OWsuyw.mjs +0 -663
  108. package/dist/packem_shared/wrangler-name-cy4yhm9j.mjs +0 -12
@@ -2,8 +2,8 @@
2
2
  name: lunora-realtime
3
3
  description: Wires Lunora's live data into a client. Use for `LunoraClient`/`LunoraProvider`,
4
4
  reactive `useQuery`/`useSubscription`, `useMutation` with optimistic updates,
5
- pagination, connection status, the React/Vue/Solid/Svelte adapters, and the
6
- `@lunora/db` TanStack binding.
5
+ pagination, connection status, the React/Vue/Solid/Svelte/Angular/React Native
6
+ adapters, and the `@lunora/db` TanStack binding.
7
7
  ---
8
8
 
9
9
  # Lunora Realtime
@@ -15,7 +15,8 @@ automatic rollback.
15
15
 
16
16
  ## When to Use
17
17
 
18
- - Wiring a frontend to a Lunora backend (React, Vue, Solid, Svelte).
18
+ - Wiring a frontend to a Lunora backend (React, Vue, Solid, Svelte, Angular,
19
+ React Native/Expo, or an Astro/Nuxt meta-framework).
19
20
  - Adding optimistic updates, pagination, or presence to the UI.
20
21
  - Choosing between live hooks and the `@lunora/db` collection layer.
21
22
 
@@ -42,6 +43,19 @@ const client = new LunoraClient({ url });
42
43
  Vue / Solid / Svelte have matching providers in `@lunora/vue`, `@lunora/solid`,
43
44
  `@lunora/svelte`; the hook names and semantics below mirror across them.
44
45
 
46
+ Two adapters differ in shape:
47
+
48
+ - **`@lunora/angular`** is signal-based rather than hook-based: register with
49
+ `provideLunora(...)`, read the client via `injectLunoraClient()`, and use
50
+ `liveQuery(...)` / `mutate(...)` / `connectionStatus(...)` in place of the
51
+ hooks below.
52
+ - **`@lunora/react-native`** re-exports all of `@lunora/react` and adds
53
+ `createLunoraClient` (plus `@lunora/react-native/auth` for the better-auth
54
+ Expo bridge) — build the client with that instead of `new LunoraClient`.
55
+
56
+ For SSR meta-frameworks, `@lunora/astro` and `@lunora/nuxt` compose Lunora into
57
+ the server (Nitro for Nuxt) and ship reactive-loader server helpers.
58
+
45
59
  ## Live Queries
46
60
 
47
61
  `useQuery(reference, args)` opens a subscription and returns the value, or
@@ -67,33 +81,32 @@ const todos = useQuery(api.todos.list, {}) as Doc<"todos">[] | undefined;
67
81
 
68
82
  ## Authorization & Live Queries
69
83
 
70
- Subscriptions re-run the query handler **server-side under anonymous
71
- identity**. The one-shot `fetch` RPC behind the initial load carries the
72
- caller's identity, but the live WebSocket channel (the subscription seed and
73
- every write-driven refresh) does not it evaluates as anonymous.
74
-
75
- This matters for any query that authorizes or filters on the authenticated
76
- user:
77
-
78
- - A query guarded by `.use(rls(...))` or one that reads `ctx.auth.userId`
79
- directly returns the user's rows on the **initial** HTTP fetch, but its
80
- **live** updates evaluate anonymously and may resolve to an empty/denied
81
- set.
82
- - This **fails closed** — the live channel shows _less_ data, never another
83
- user's data, so there is no leak. But it is a correctness caveat: the
84
- initial render and the live updates can disagree.
85
-
86
- The supported pattern today is to scope per-user data **outside** of
87
- `ctx.auth` inside a subscribed query:
88
-
89
- - Partition the data by shard with `.shardBy(userId)` (or tenant/room), so the
90
- subscription is already scoped to the right state, or
91
- - Pass the identifier as an **explicit query arg**
92
- (`useQuery(api.todos.list, { userId })`) and filter on the arg rather than on
93
- `ctx.auth`.
94
-
95
- Reserve `rls()` / `ctx.auth`-based filtering for non-subscribed reads (one-shot
96
- actions/queries) where identity is always present.
84
+ **Live queries are identity-aware.** At the WebSocket upgrade the runtime
85
+ stamps the caller's verified identity onto the socket (from the server-minted
86
+ `x-lunora-userid` / `x-lunora-identity` headers, which a client cannot forge).
87
+ Every subscription re-run, shape resolution, and poke-driven refresh executes
88
+ under that socket's own identity, passed by value so a concurrent RPC can't
89
+ clobber it.
90
+
91
+ Practically, this means:
92
+
93
+ - `.use(rls(...))` and `ctx.auth.userId` work the same in a subscribed query as
94
+ in a one-shot read. Shape subscriptions AND-merge the shape predicate with
95
+ the table's RLS read base-where, so the membership query the poke protocol
96
+ runs is RLS-correct by constructionnever the client's word for it.
97
+ - An **anonymous** socket carries no identity, so an RLS/`ctx.auth` query fails
98
+ closed (empty/denied) rather than leaking another user's rows.
99
+ - **Token expiry is enforced on the socket.** When the resolved credential
100
+ carries an expiry, the DO sends a `TOKEN_EXPIRED` error frame and closes with
101
+ code `4001` at the next send at or after that instant. `LunoraClient`
102
+ reconnects automatically and re-resolves a fresh identity — but surface it in
103
+ the UI if a re-login is required.
104
+
105
+ You can still scope data structurally when it fits the domain — `.shardBy(userId)`
106
+ (or tenant/room) partitions state so a subscription is narrow by construction,
107
+ and explicit query args keep subscriptions cheap (see the args-scoping note
108
+ above). Prefer those for _performance_; use `rls()` / `ctx.auth` for
109
+ _authorization_. They compose.
97
110
 
98
111
  ## Mutations + Optimistic Updates
99
112
 
@@ -154,6 +167,13 @@ schema + functions into live TanStack DB collections). Reach for it when the app
154
167
  needs client-side indexes/joins or a persistent optimistic outbox; raw `useQuery`
155
168
  /`useMutation` are enough for straightforward live lists.
156
169
 
170
+ Call `defineCollections` **once** at module scope and treat the returned
171
+ collections as the single source of truth for each table. Don't mirror rows into
172
+ a parallel store, and never build derived indexes (trees, search, undo captures)
173
+ from a copy — optimistic writes and sync deltas land only on the Lunora
174
+ collection, so code reading a copy silently reads stale rows while `useLiveQuery`
175
+ renders fresh data.
176
+
157
177
  ## Common Pitfalls
158
178
 
159
179
  1. **Creating `LunoraClient` inside a component.** It re-opens the socket every
@@ -165,6 +185,12 @@ needs client-side indexes/joins or a persistent optimistic outbox; raw `useQuery
165
185
  4. **Optimistic shape drift.** The provisional value must match the query's
166
186
  element shape (including `_id`/`_creationTime`) or the UI flickers when the
167
187
  real delta lands.
188
+ 5. **Two sources of truth for the same rows.** `defineCollections` more than once
189
+ per table (or a parallel store of your own) mints copies that drift. Reads
190
+ through `useLiveQuery` look fine, but derived indexes built from the copy can
191
+ **miss rows** — rows written to the collection after the copy was taken never
192
+ appear in the index — or **hold stale rows** — rows updated or deleted in the
193
+ collection still show their old value. One instance, one collection per table.
168
194
 
169
195
  ## Checklist
170
196
 
@@ -175,3 +201,5 @@ needs client-side indexes/joins or a persistent optimistic outbox; raw `useQuery
175
201
  - [ ] Query `args` scoped narrowly to avoid over-broad re-renders.
176
202
  - [ ] Pagination via `usePaginatedQuery`/`useInfiniteQuery` over `.paginate`.
177
203
  - [ ] Considered `@lunora/db` if the app needs local indexes/joins or an outbox.
204
+ - [ ] `@lunora/db`: one `defineCollections` instance; no parallel copy of rows;
205
+ derived indexes built from the same collection the UI renders.