@ic-reactor/vite-plugin 0.13.1 → 0.15.1
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/README.md +97 -13
- package/dist/index.cjs +385 -118
- package/dist/index.d.cts +14 -2
- package/dist/index.d.ts +14 -2
- package/dist/index.js +389 -120
- package/llms.txt +134 -33
- package/package.json +4 -4
- package/src/dev-environment.ts +268 -0
- package/src/env.ts +60 -16
- package/src/index.ts +476 -178
package/README.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# @ic-reactor/vite-plugin
|
|
2
2
|
|
|
3
|
+
> **AI coding agents:** read [`llms.txt`](./llms.txt) in this package
|
|
4
|
+
> (`node_modules/@ic-reactor/vite-plugin/llms.txt`) before writing code with it. It
|
|
5
|
+
> is written for the installed version and lists the patterns to use and the
|
|
6
|
+
> mistakes to avoid.
|
|
7
|
+
|
|
3
8
|
Vite plugin for IC Reactor code generation. It runs the shared
|
|
4
9
|
`@ic-reactor/codegen` pipeline, watches `.did` files, and can inject the
|
|
5
10
|
`ic_env` cookie used by `ClientManager` during local development.
|
|
@@ -43,8 +48,9 @@ export const clientManager = new ClientManager({
|
|
|
43
48
|
No opt-in flag is needed to pick up the plugin's environment in development:
|
|
44
49
|
the plugin sets the `ic_env` cookie and `ClientManager` reads it automatically
|
|
45
50
|
in the browser. That trust stops at the local replica — cookies are not
|
|
46
|
-
origin-isolated, so on a custom domain
|
|
47
|
-
|
|
51
|
+
origin-isolated, so on a custom domain, on mainnet, and on Codespaces or Gitpod
|
|
52
|
+
(whose workspaces share a parent domain with every other user's) the cookie is
|
|
53
|
+
ignored and a reactor with no `canisterId` throws. Set the per-canister `canisterId` in the
|
|
48
54
|
plugin config to bake it into the generated output for those builds, or pass
|
|
49
55
|
`allowEnvConfig: true` to `ClientManager` if you trust every subdomain of the
|
|
50
56
|
domain you serve from.
|
|
@@ -57,12 +63,52 @@ exports the reactor and six hooks named after the canister
|
|
|
57
63
|
`use<Canister>InfiniteQuery`, `use<Canister>SuspenseInfiniteQuery`,
|
|
58
64
|
`use<Canister>Mutation`, `use<Canister>Method`).
|
|
59
65
|
|
|
66
|
+
Set `factories: true` on a canister to also generate
|
|
67
|
+
`index.factories.generated.ts`, a query or mutation object per method bound to
|
|
68
|
+
the generated reactor: `createQuery` for a query method without arguments,
|
|
69
|
+
`createQueryFactory` for one with arguments, and `createMutation` for an
|
|
70
|
+
update or oneway method, named `<method>Query` or `<method>Mutation` with the
|
|
71
|
+
method name in camelCase. The default `index.ts` wrapper re-exports it; an
|
|
72
|
+
`index.ts` you have edited is left alone, and the plugin warns in the terminal
|
|
73
|
+
until it re-exports the factories. It needs `target: "react"`. See
|
|
74
|
+
https://ic-reactor.b3pay.net/v3/packages/codegen#query-and-mutation-factories
|
|
75
|
+
for the naming rule for any method name.
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
import { icReactor } from "@ic-reactor/vite-plugin"
|
|
79
|
+
|
|
80
|
+
icReactor({
|
|
81
|
+
canisters: [
|
|
82
|
+
{ name: "backend", didFile: "./backend/backend.did", factories: true },
|
|
83
|
+
],
|
|
84
|
+
})
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
import { getMessageQuery, setMessageMutation } from "./declarations/backend"
|
|
89
|
+
|
|
90
|
+
// In a component
|
|
91
|
+
const { data } = getMessageQuery.useQuery()
|
|
92
|
+
|
|
93
|
+
// Anywhere, outside React included
|
|
94
|
+
await setMessageMutation.execute(["hello"])
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
If Prettier resolves from Vite's `config.root`, the plugin formats the
|
|
98
|
+
generated `.js`, `.d.ts`, `index.generated.ts`, `index.factories.generated.ts`
|
|
99
|
+
and the `index.ts` wrapper it writes with it and your Prettier config, so a rebuild leaves formatted,
|
|
100
|
+
committed output unchanged. Without Prettier the declarations hold the Candid
|
|
101
|
+
parser's output followed by a newline, and a formatting error never fails the
|
|
102
|
+
build.
|
|
103
|
+
|
|
60
104
|
If you want non-React output, set `target: "core"` and install the matching
|
|
61
105
|
runtime package instead of `@ic-reactor/react`.
|
|
62
106
|
|
|
63
107
|
## Options
|
|
64
108
|
|
|
65
109
|
```ts
|
|
110
|
+
import { icReactor } from "@ic-reactor/vite-plugin"
|
|
111
|
+
|
|
66
112
|
icReactor({
|
|
67
113
|
canisters: [
|
|
68
114
|
{
|
|
@@ -104,6 +150,14 @@ of a `.did` file being edited.
|
|
|
104
150
|
- `target`
|
|
105
151
|
- `mode`
|
|
106
152
|
- `canisterId`
|
|
153
|
+
- `factories`: also generate `index.factories.generated.ts` (default `false`)
|
|
154
|
+
|
|
155
|
+
Each entry needs an output directory of its own. Two entries with the same
|
|
156
|
+
`name` and no `outDir`, or with `outDir` values that reach one directory, would
|
|
157
|
+
overwrite each other's output, so the plugin generates the first of them and
|
|
158
|
+
fails the later one with the error the CLI reports. To generate one canister
|
|
159
|
+
twice, say as a `DisplayReactor` and as a `Reactor`, give each entry its own
|
|
160
|
+
`outDir`.
|
|
107
161
|
|
|
108
162
|
Supported `mode` values:
|
|
109
163
|
|
|
@@ -120,12 +174,13 @@ Supported `target` values:
|
|
|
120
174
|
|
|
121
175
|
## Local Development Behavior
|
|
122
176
|
|
|
123
|
-
When `injectEnvironment` is enabled during `vite dev`, the
|
|
177
|
+
When `injectEnvironment` is enabled during `vite dev` or `vite preview`, the
|
|
178
|
+
plugin:
|
|
124
179
|
|
|
125
180
|
1. asks `icp` for the local network status
|
|
126
181
|
2. resolves canister IDs — `internet_identity` is added automatically if not
|
|
127
182
|
already in your canister list
|
|
128
|
-
3. sets the `ic_env` cookie
|
|
183
|
+
3. sets the `ic_env` cookie on each response
|
|
129
184
|
4. proxies `/api` to the local replica
|
|
130
185
|
|
|
131
186
|
If a canister has a `canisterId` set in the plugin config, that value overrides
|
|
@@ -134,25 +189,54 @@ the auto-detected ID for that canister.
|
|
|
134
189
|
Set the `ICP_ENVIRONMENT` environment variable to target a non-default network
|
|
135
190
|
(defaults to `"local"`).
|
|
136
191
|
|
|
137
|
-
If environment detection fails, the plugin
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
192
|
+
If environment detection fails, the plugin falls back to proxying `/api` to
|
|
193
|
+
`http://127.0.0.1:4943`, and sets no cookie, or with no canisters configured one
|
|
194
|
+
that names only icp-cli's built-in Internet Identity. It warns when that happens
|
|
195
|
+
with canisters configured, and when a configured canister has no ID, because
|
|
196
|
+
the failure is otherwise indistinguishable from success until the app breaks on
|
|
197
|
+
an undefined canister id. Run with `DEBUG=ic-reactor` to see the `icp` output
|
|
198
|
+
behind the warning.
|
|
199
|
+
|
|
200
|
+
Detection is complete once `icp` reports the network and every configured
|
|
201
|
+
canister has an ID. Until then the plugin asks `icp` again on each page load,
|
|
202
|
+
and that page gets the answer: start `vite dev` first, then run
|
|
203
|
+
`icp network start` and `icp deploy`, and reload the page. The `/api` proxy
|
|
204
|
+
moves to the network `icp` reports, the fallback included. Once detection is
|
|
205
|
+
complete, page loads run no further `icp` commands, so redeploying into a
|
|
206
|
+
fresh network, with new canister IDs and a new root key, needs a dev server
|
|
207
|
+
restart. A configured canister you never deploy locally keeps detection
|
|
208
|
+
incomplete, so every page load runs `icp` for it; set its `canisterId` and it
|
|
209
|
+
counts as resolved. If you never run a local network, set
|
|
210
|
+
`injectEnvironment: false` and page loads run no `icp`.
|
|
211
|
+
|
|
212
|
+
If your Vite config or another plugin sets `server.proxy["/api"]`, the plugin
|
|
213
|
+
leaves that entry alone, whether detection succeeds or not, and that proxy does
|
|
214
|
+
not follow detection.
|
|
142
215
|
|
|
143
216
|
## File Regeneration
|
|
144
217
|
|
|
145
218
|
On startup and on `.did` file changes, the plugin regenerates declarations and
|
|
146
|
-
the managed `index.generated.ts` implementation
|
|
219
|
+
the managed `index.generated.ts` implementation, and `index.factories.generated.ts`
|
|
220
|
+
for a canister that sets `factories: true`. The user-facing `index.ts`
|
|
147
221
|
entry is created once, then preserved unless it still matches the default
|
|
148
222
|
wrapper or a legacy generated scaffold that can be migrated automatically.
|
|
149
223
|
When a watched `.did` file changes, the plugin sends a full browser reload so
|
|
150
|
-
the new declarations are picked up.
|
|
151
|
-
|
|
152
|
-
|
|
224
|
+
the new declarations are picked up.
|
|
225
|
+
|
|
226
|
+
The plugin follows the dev server's file watcher itself, so a `.did` file that
|
|
227
|
+
appears after the server started, or that a build tool deletes and writes
|
|
228
|
+
again, is generated too, and saves regenerate even with `server.hmr: false`.
|
|
229
|
+
|
|
230
|
+
Regeneration is serialized per canister — saves that land while a run is in
|
|
231
|
+
flight collapse into a single rerun — so two rapid saves cannot interleave
|
|
232
|
+
inside the pipeline's delete-then-write sequence.
|
|
153
233
|
A regeneration that fails is reported to the terminal and to the browser error
|
|
154
234
|
overlay rather than leaving the page on stale bindings.
|
|
155
235
|
|
|
236
|
+
`vite build --watch` watches the configured `.did` files as well. Saving one
|
|
237
|
+
starts a rebuild that regenerates that canister's bindings. A rebuild that any
|
|
238
|
+
other file starts leaves the generated files alone.
|
|
239
|
+
|
|
156
240
|
## When To Use It
|
|
157
241
|
|
|
158
242
|
- Vite apps with active `.did` iteration
|