@gaganref/confect-react 0.0.0-stage → 10.3.1-fork.10
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/CHANGELOG.md +1404 -0
- package/LICENSE +7 -0
- package/README.md +16 -2
- package/dist/OptimisticLocalStore.d.ts +25 -0
- package/dist/OptimisticLocalStore.d.ts.map +1 -0
- package/dist/OptimisticLocalStore.js +38 -0
- package/dist/OptimisticLocalStore.js.map +1 -0
- package/dist/PaginatedQueryResult.d.ts +123 -0
- package/dist/PaginatedQueryResult.d.ts.map +1 -0
- package/dist/PaginatedQueryResult.js +91 -0
- package/dist/PaginatedQueryResult.js.map +1 -0
- package/dist/QueryResult.d.ts +68 -0
- package/dist/QueryResult.d.ts.map +1 -0
- package/dist/QueryResult.js +69 -0
- package/dist/QueryResult.js.map +1 -0
- package/dist/StreamPagination.d.ts +159 -0
- package/dist/StreamPagination.d.ts.map +1 -0
- package/dist/StreamPagination.js +182 -0
- package/dist/StreamPagination.js.map +1 -0
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/index.d.ts +133 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +302 -0
- package/dist/index.js.map +1 -0
- package/package.json +55 -3
- package/src/OptimisticLocalStore.ts +70 -0
- package/src/PaginatedQueryResult.ts +321 -0
- package/src/QueryResult.ts +177 -0
- package/src/StreamPagination.ts +403 -0
- package/src/index.ts +737 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,1404 @@
|
|
|
1
|
+
# @confect/react
|
|
2
|
+
|
|
3
|
+
## 10.3.1
|
|
4
|
+
|
|
5
|
+
No changes in this release.
|
|
6
|
+
|
|
7
|
+
## 10.3.0
|
|
8
|
+
|
|
9
|
+
No changes in this release.
|
|
10
|
+
|
|
11
|
+
## 10.2.0
|
|
12
|
+
|
|
13
|
+
No changes in this release.
|
|
14
|
+
|
|
15
|
+
## 10.1.0
|
|
16
|
+
|
|
17
|
+
No changes in this release.
|
|
18
|
+
|
|
19
|
+
## 10.0.0
|
|
20
|
+
|
|
21
|
+
### Major Changes
|
|
22
|
+
|
|
23
|
+
- c05ae0b: Migrate Confect to Effect 4, add middleware, experimental composable query streams, Foldkit bindings, and Convex AI gateway integrations. This release requires changes to function argument declarations, HTTP routers, runner calls, and test setup when upgrading from v9.
|
|
24
|
+
|
|
25
|
+
### Requirements
|
|
26
|
+
- All Confect packages require Node.js 24 or later and `effect ^4.0.0`.
|
|
27
|
+
- `@confect/server` requires `convex ^1.45.0`.
|
|
28
|
+
- `@confect/server`'s optional `@effect/platform-node` peer requires `^4.0.0` for Node actions.
|
|
29
|
+
- The new `@confect/foldkit` package requires `foldkit ^0.165.0`.
|
|
30
|
+
|
|
31
|
+
Confect no longer depends on `@effect/platform` or `@effect/cli`. Run `confect codegen` to regenerate the v10 bindings after updating your Confect declarations.
|
|
32
|
+
|
|
33
|
+
### Breaking changes
|
|
34
|
+
|
|
35
|
+
#### Declare function arguments as lazy field maps
|
|
36
|
+
|
|
37
|
+
Pass a callback returning the fields of an argument object, rather than a callback returning `Schema.Struct`. This applies to queries, mutations, actions, and paginated queries. You can omit `args` when a function takes no arguments; Confect supplies an empty object. Keep `returns`, `item`, and `error` as callbacks returning schemas.
|
|
38
|
+
|
|
39
|
+
**Before:**
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { FunctionSpec } from "@confect/core";
|
|
43
|
+
import * as Schema from "effect/Schema";
|
|
44
|
+
|
|
45
|
+
FunctionSpec.publicQuery({
|
|
46
|
+
name: "greet",
|
|
47
|
+
args: () => Schema.Struct({ name: Schema.String }),
|
|
48
|
+
returns: () => Schema.String,
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**After:**
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { FunctionSpec } from "@confect/core";
|
|
56
|
+
import * as Schema from "effect/Schema";
|
|
57
|
+
|
|
58
|
+
FunctionSpec.publicQuery({
|
|
59
|
+
name: "greet",
|
|
60
|
+
args: () => ({ name: Schema.String }),
|
|
61
|
+
returns: () => Schema.String,
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
#### Keep table declarations client-safe
|
|
66
|
+
|
|
67
|
+
Import `Table` from `@confect/core` in your table declarations. Specs can then return a generated table's `Doc` without pulling server code into the client. `confect codegen` rejects value imports of `@confect/server` anywhere reachable from a spec, including table and generated modules. Type-only imports remain allowed.
|
|
68
|
+
|
|
69
|
+
**Before:**
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import { Table } from "@confect/server";
|
|
73
|
+
import * as Schema from "effect/Schema";
|
|
74
|
+
|
|
75
|
+
export default Table.make(() => Schema.Struct({ text: Schema.String }));
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**After:**
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import { Table } from "@confect/core";
|
|
82
|
+
import * as Schema from "effect/Schema";
|
|
83
|
+
|
|
84
|
+
export default Table.make(() => Schema.Struct({ text: Schema.String }));
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Table declarations still return a schema, not the field maps now used by function arguments. The server's `Table` re-exports remain available for server-only use. Run `confect codegen` to regenerate the deploy schema and client-safe table bindings.
|
|
88
|
+
|
|
89
|
+
#### Use serializable schemas and handle updated errors
|
|
90
|
+
|
|
91
|
+
Confect function schemas must encode to Convex values. Use a serializable codec such as `Schema.OptionFromNullOr(...)` for an `Option` crossing that boundary: `Schema.Option` no longer provides the serialized representation expected there.
|
|
92
|
+
|
|
93
|
+
Table schemas support object-shaped transformations, encoded-key mappings, brands, suspended schemas, and unions of those schemas while retaining Convex system fields. Every step must remain object-shaped; class schemas such as `Schema.Class` are not valid table schemas.
|
|
94
|
+
|
|
95
|
+
Decode failures now use `Schema.SchemaError` instead of `ParseError`, including JavaScript clients, React hooks, and test helpers. React `useMutation` and `useAction` calls with declared errors return Effect `Result` values instead of `Either` values. Update matching and error annotations accordingly.
|
|
96
|
+
|
|
97
|
+
#### Replace HTTP API mounts with route layers
|
|
98
|
+
|
|
99
|
+
Replace Confect's `HttpApi.make` with `HttpRouter.make`. The old record of path prefixes and `apiLive`, `middleware`, and `scalar` options is replaced by one layer registering all routes. Build API routes with Effect's `HttpApiBuilder.layer`, provide each group's handlers, and add Scalar documentation explicitly.
|
|
100
|
+
|
|
101
|
+
For an API named `Api` and its group handler layer `ApiLive`:
|
|
102
|
+
|
|
103
|
+
**Before:**
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import { HttpApi as ConfectHttpApi } from "@confect/server";
|
|
107
|
+
import * as HttpApiBuilder from "@effect/platform/HttpApiBuilder";
|
|
108
|
+
import * as Layer from "effect/Layer";
|
|
109
|
+
|
|
110
|
+
export default ConfectHttpApi.make({
|
|
111
|
+
"/api/": {
|
|
112
|
+
apiLive: HttpApiBuilder.api(Api).pipe(Layer.provide(ApiLive)),
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**After:**
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
import { HttpRouter as ConfectHttpRouter } from "@confect/server";
|
|
121
|
+
import * as Layer from "effect/Layer";
|
|
122
|
+
import * as HttpApiBuilder from "effect/http-api/HttpApiBuilder";
|
|
123
|
+
import * as HttpApiScalar from "effect/http-api/HttpApiScalar";
|
|
124
|
+
|
|
125
|
+
export default ConfectHttpRouter.make(
|
|
126
|
+
Layer.mergeAll(
|
|
127
|
+
HttpApiBuilder.layer(Api).pipe(Layer.provide(ApiLive)),
|
|
128
|
+
HttpApiScalar.layer(Api, { path: "/api/docs" }),
|
|
129
|
+
),
|
|
130
|
+
);
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Put the endpoint prefix on the Effect API itself, for example with `.prefix("/api")`. For interactive documentation, configure Scalar's `baseServerURL` with your deployment's site URL. Missing API handler groups are compile-time errors. You can merge plain routes from `effect/http/HttpRouter.add` and global middleware from `HttpRouter.middleware` into the same layer.
|
|
134
|
+
|
|
135
|
+
The returned Convex router serves Effect routes through a catch-all at `/`; plain Convex routes added to it still take precedence. Route-layer construction, handlers, and middleware can read Convex environment variables through Confect's configuration provider.
|
|
136
|
+
|
|
137
|
+
#### Call named runner methods
|
|
138
|
+
|
|
139
|
+
`QueryRunner`, `MutationRunner`, and `ActionRunner` are no longer callable services. Destructure `runQuery`, `runMutation`, or `runAction` instead.
|
|
140
|
+
|
|
141
|
+
**Before:**
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
import * as Effect from "effect/Effect";
|
|
145
|
+
|
|
146
|
+
const firstNote = Effect.gen(function* () {
|
|
147
|
+
const runQuery = yield* QueryRunner;
|
|
148
|
+
return yield* runQuery(refs.public.notes.getFirst, {});
|
|
149
|
+
});
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**After:**
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
import * as Effect from "effect/Effect";
|
|
156
|
+
|
|
157
|
+
const firstNote = Effect.gen(function* () {
|
|
158
|
+
const { runQuery } = yield* QueryRunner;
|
|
159
|
+
return yield* runQuery(refs.public.notes.getFirst, {});
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Runner availability is unchanged. Inside queries or mutations, `runQuery` also accepts a third argument such as `{ transactionLimits: { documentsRead: 100 } }`. Inside mutations, `runMutation` accepts limits such as `{ transactionLimits: { documentsWritten: 10 } }`, and `runQuery` can request `useStaleSnapshot`. Supplying `useStaleSnapshot` requires a mutation context even when it is `false`. Actions and HTTP handlers use runners without transaction options; `runAction` has no options argument.
|
|
164
|
+
|
|
165
|
+
#### Yield upload URL generation directly
|
|
166
|
+
|
|
167
|
+
`StorageWriter.generateUploadUrl` is an Effect value instead of a zero-argument function.
|
|
168
|
+
|
|
169
|
+
**Before:**
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
import * as Effect from "effect/Effect";
|
|
173
|
+
|
|
174
|
+
const uploadUrl = Effect.gen(function* () {
|
|
175
|
+
const storage = yield* StorageWriter;
|
|
176
|
+
return yield* storage.generateUploadUrl();
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**After:**
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
import * as Effect from "effect/Effect";
|
|
184
|
+
|
|
185
|
+
const uploadUrl = Effect.gen(function* () {
|
|
186
|
+
const storage = yield* StorageWriter;
|
|
187
|
+
return yield* storage.generateUploadUrl;
|
|
188
|
+
});
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Methods that take arguments, such as `delete(storageId)`, remain functions.
|
|
192
|
+
|
|
193
|
+
#### Provide test layers without an extra call
|
|
194
|
+
|
|
195
|
+
`TestConfect.layer(schema, convexSchema, modules)` now returns a layer directly instead of a function returning that layer. For a project that exports the result as `TestConfect.layer`:
|
|
196
|
+
|
|
197
|
+
**Before:**
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
const test = testEffect.pipe(Effect.provide(TestConfect.layer()));
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**After:**
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
const test = testEffect.pipe(Effect.provide(TestConfect.layer));
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Each separate provision still creates a fresh test database.
|
|
210
|
+
|
|
211
|
+
#### Update handwritten container annotations
|
|
212
|
+
|
|
213
|
+
Read assembled groups with `Spec.groups(spec)` instead of `spec.groups`, and tables with `DatabaseSchema.tables(schema)` instead of `schema.tables`. Explicit `Spec.Spec`, `DatabaseSchema.DatabaseSchema`, and `DataModel.DataModel` annotations now take a record keyed by name rather than a union of members.
|
|
214
|
+
|
|
215
|
+
**Before:**
|
|
216
|
+
|
|
217
|
+
```ts
|
|
218
|
+
type AppSpec = Spec.Spec<typeof notesGroup>;
|
|
219
|
+
type AppSchema = DatabaseSchema.DatabaseSchema<typeof notesTable>;
|
|
220
|
+
type AppDataModel = DataModel.DataModel<typeof notesTable>;
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**After:**
|
|
224
|
+
|
|
225
|
+
```ts
|
|
226
|
+
type AppSpec = Spec.Spec<{ readonly notes: typeof notesGroup }>;
|
|
227
|
+
type AppSchema = DatabaseSchema.DatabaseSchema<{
|
|
228
|
+
readonly notes: typeof notesTable;
|
|
229
|
+
}>;
|
|
230
|
+
type AppDataModel = DataModel.DataModel<{
|
|
231
|
+
readonly notes: typeof notesTable;
|
|
232
|
+
}>;
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Ordinary builder calls are unchanged, and `DataModel.FromTables` still accepts a table union. Adding a group under an existing name replaces both its value and its inferred type. Run `confect codegen` rather than editing generated annotations.
|
|
236
|
+
|
|
237
|
+
#### Review configuration and time-dependent queries
|
|
238
|
+
|
|
239
|
+
Confect's configuration provider now treats empty-string environment variables as missing values, so `Config.withDefault` and `Config.option` recover from them.
|
|
240
|
+
|
|
241
|
+
Raw `Date.now()` calls in queries now observe time and invalidate Convex's query cache instead of returning v9's globally stubbed value. Explicit Effect clock reads such as `Clock.currentTimeMillis` and `Clock.currentTimeNanos` continue to opt into time tracking. Effect's internal timestamps for logging and tracing do not invalidate the cache.
|
|
242
|
+
|
|
243
|
+
### Middleware with typed services and errors
|
|
244
|
+
|
|
245
|
+
Add reusable policies in `confect/middleware/`, with a client-safe `<Name>.spec.ts` and a server-side `<Name>.impl.ts`. This directory is reserved and can no longer contain ordinary function groups.
|
|
246
|
+
|
|
247
|
+
Declare a policy with `MiddlewareSpec.MiddlewareSpec`, including its provided services, error schema, and explicit query/mutation/action coverage. Attach it with `.middleware(Policy)` on a group or individual function, or declare an `options` schema and use `.middleware(Policy, options)`. Options are validated without coercion and must be client-safe because generated refs carry them.
|
|
248
|
+
|
|
249
|
+
Implement policies with `MiddlewareImpl.make`, `MiddlewareImpl.makeByFunctionType`, or `MiddlewareImpl.provides`, then supply the implementation to the group layer. Callbacks receive `{ invocation }`, plus `options` when declared. Policies run after argument decoding, with group policies before function policies, and can supply services to later policies and handlers. Typed policy failures reach clients alongside function errors and short-circuit the remaining chain.
|
|
250
|
+
|
|
251
|
+
The same policy can run more than once with different options; equivalent attachments are rejected. Coverage and service dependencies are checked, missing implementations fail codegen, middleware does not propagate to subgroups, and plain Convex functions cannot have Confect middleware attached.
|
|
252
|
+
|
|
253
|
+
### Experimental composable query streams
|
|
254
|
+
|
|
255
|
+
Use `reader.table(...).stream(index, range?, order?)` and `QueryStream` from `@confect/server` to merge, filter, map, join, deduplicate, narrow, and reverse indexed queries while retaining cursor pagination. Ordering compatibility is checked, joins can provide left-join placeholders, effectful filters and maps support ordered concurrency, and reversing a distinct stream preserves its selected representatives.
|
|
256
|
+
|
|
257
|
+
```ts
|
|
258
|
+
import { QueryStream } from "@confect/server";
|
|
259
|
+
import * as Effect from "effect/Effect";
|
|
260
|
+
|
|
261
|
+
const firstPage = Effect.gen(function* () {
|
|
262
|
+
const reader = yield* DatabaseReader;
|
|
263
|
+
const stream = reader.table("notes").stream("by_creation_time");
|
|
264
|
+
return yield* QueryStream.paginate(stream, {
|
|
265
|
+
cursor: null,
|
|
266
|
+
numItems: 20,
|
|
267
|
+
maximumRowsRead: 1000,
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Read budgets count underlying reads, including documents filtered out of the result; byte budgets are estimates. Invalid page sizes and read limits are rejected before reads. If a budget prevents safe progress or splitting, pagination fails rather than skipping results. Increase the budget or reduce the query's read requirements.
|
|
273
|
+
|
|
274
|
+
Use React's new `useStreamPaginatedQuery` for stream-backed paginated queries. It pins loaded page ranges, handles page splits, and restarts on invalid cursors. Foldkit pagination also preserves page ranges during navigation. Ordinary paginated queries and `usePaginatedQuery` remain available.
|
|
275
|
+
|
|
276
|
+
All `QueryStream` APIs are experimental. Treat cursors as opaque continuation values, but do not treat them as confidential: they expose order-key values. Avoid public pagination over sensitive indexed fields unless those fields are fixed with `eq`.
|
|
277
|
+
|
|
278
|
+
### Foldkit client bindings
|
|
279
|
+
|
|
280
|
+
Add `@confect/foldkit` for Foldkit applications. `Client.layer` provides the scoped client; `Command.query`, `Command.mutation`, and `Command.action` turn Confect calls into commands with declared messages and required success/error handlers. The factories support Foldkit interruption, and the corresponding `queryEffect`, `mutationEffect`, and `actionEffect` helpers support handwritten command definitions.
|
|
281
|
+
|
|
282
|
+
`Subscription.reactiveQuery` follows optional arguments derived from your model and manages the live query subscription. `PaginatedQuery` and `Subscription.paginatedQuery` provide reactive next/previous-page navigation, preserve the last complete page while refreshing, ignore superseded settlements, and recover from invalid cursors. Failed refreshes retain stale data, and typed function errors remain available to your message handlers.
|
|
283
|
+
|
|
284
|
+
### Convex AI gateway models
|
|
285
|
+
|
|
286
|
+
Use `AiGatewayLanguageClient` and `AiGatewayLanguageModel` to call language models through the Convex AI gateway from actions without supplying provider API keys. Use `AiGatewayDecisionClient` and `AiGatewayDecisionModel` with Effect's `DecisionModel` to classify inputs, apply rubrics, and estimate probabilities.
|
|
287
|
+
|
|
288
|
+
```ts
|
|
289
|
+
import {
|
|
290
|
+
AiGatewayLanguageClient,
|
|
291
|
+
AiGatewayLanguageModel,
|
|
292
|
+
} from "@confect/server";
|
|
293
|
+
import * as Layer from "effect/Layer";
|
|
294
|
+
import * as FetchHttpClient from "effect/http/FetchHttpClient";
|
|
295
|
+
|
|
296
|
+
const Claude = AiGatewayLanguageModel.model(
|
|
297
|
+
"anthropic/claude-sonnet-4.5",
|
|
298
|
+
).pipe(
|
|
299
|
+
Layer.provide(AiGatewayLanguageClient.layer),
|
|
300
|
+
Layer.provide(FetchHttpClient.layer),
|
|
301
|
+
);
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Provide the model to Effect AI operations from `effect/ai`. Disabled or unavailable gateways report typed errors during client construction. Both gateway clients obtain current service credentials before each request, including when reused in long-running actions.
|
|
305
|
+
|
|
306
|
+
### Storage, metadata, logging, and authentication
|
|
307
|
+
- Use the unified generated `Storage` service for download URLs, upload URLs, deletion, blob reads, and blob writes. Each operation retains its context restrictions; the existing storage services remain supported.
|
|
308
|
+
- Cancel scheduled functions with `Scheduler.cancel(id)`, using the ID returned by `runAfter` or `runAt`.
|
|
309
|
+
- Read function and deployment information with `ExecutionMetadata`, request information with `RequestMetadata`, and transaction metrics with `TransactionMetadata`. Generated services expose them only in the contexts that support each capability.
|
|
310
|
+
- `Effect.log*` output uses matching Convex severities in functions and HTTP routes while preserving Effect metadata and custom loggers. `ConvexLogger` is available for explicit configuration, and logs remain associated with the current invocation when Node actions reuse a process.
|
|
311
|
+
- JavaScript `WebSocketClient` and Foldkit `Client` authentication callbacks can require Effect services. Supply them when running `setAuth` and keep scoped dependencies alive while authentication is registered; later token refreshes use the supplied services.
|
|
312
|
+
- JavaScript clients support per-module imports such as `@confect/js/WebSocketClient` and `@confect/js/HttpClient`; root imports are unchanged.
|
|
313
|
+
|
|
314
|
+
### Fixes and diagnostics
|
|
315
|
+
- Preserve precise function error types when `exactOptionalPropertyTypes` is disabled, rather than widening functions without declared errors to `any`.
|
|
316
|
+
- Exclude `_id` and `_creationTime` from patch value types derived from full documents.
|
|
317
|
+
- Preserve `ConvexError.data` when a handler throws a `ConvexError` inside an Effect.
|
|
318
|
+
- Reject non-finite values in Confect's schemas for system timestamps, stored file sizes, and pagination options. User-authored `Schema.Number` fields can still represent Convex's non-finite numbers.
|
|
319
|
+
- Keep queries, mutations, and module initialization compatible with Convex's timer restrictions during long Effect computations.
|
|
320
|
+
- Fail codegen with a descriptive error for malformed `convex.json` instead of silently ignoring it.
|
|
321
|
+
- Add tracing spans for client calls, server functions, database writes and pagination, stream consumers, and code-generation passes.
|
|
322
|
+
|
|
323
|
+
## 10.0.0-next.27
|
|
324
|
+
|
|
325
|
+
### Minor Changes
|
|
326
|
+
|
|
327
|
+
- 6424f03: Require stable `effect@^4.0.0` and matching Effect platform and AI provider packages. `@confect/foldkit` now requires `foldkit@^0.165.0`, which supports Effect 4.0.0 without a peer-dependency override.
|
|
328
|
+
|
|
329
|
+
## 10.0.0-next.26
|
|
330
|
+
|
|
331
|
+
No changes in this release.
|
|
332
|
+
|
|
333
|
+
## 10.0.0-next.25
|
|
334
|
+
|
|
335
|
+
### Patch Changes
|
|
336
|
+
|
|
337
|
+
- f9958b9: Require `effect@^4.0.0-rc.118` and matching Effect platform packages. Upgrade Effect alongside Confect and replace `effect/unstable/*` imports with `effect/*`, using `effect/http-api` for HTTP API imports.
|
|
338
|
+
|
|
339
|
+
## 10.0.0-next.24
|
|
340
|
+
|
|
341
|
+
### Patch Changes
|
|
342
|
+
|
|
343
|
+
- 850a3c3: Require `effect@^4.0.0-rc.117` across `@confect/*` and `@effect/platform-node@^4.0.0-rc.117` for `@confect/server`'s optional Node integration. Upgrade these dependencies alongside Confect; existing Confect call sites are unchanged.
|
|
344
|
+
|
|
345
|
+
## 10.0.0-next.23
|
|
346
|
+
|
|
347
|
+
No changes in this release.
|
|
348
|
+
|
|
349
|
+
## 10.0.0-next.22
|
|
350
|
+
|
|
351
|
+
### Minor Changes
|
|
352
|
+
|
|
353
|
+
- 6cc5834: Add experimental stream querying with reactive pagination, configurable middleware policies, and broader tracing.
|
|
354
|
+
|
|
355
|
+
### Stream queries and pagination
|
|
356
|
+
|
|
357
|
+
Create composable Effect streams with `reader.table(...).stream(index, range?, order?)` and `QueryStream` from `@confect/server`. Merge, filter, map, join, deduplicate, narrow, and reverse queries without losing cursor pagination. Order keys and directions are checked by the type system. Joins support left-join placeholders through `onEmpty`, and effectful filters and maps support ordered concurrency. Reversing a distinct stream preserves its chosen representatives.
|
|
358
|
+
|
|
359
|
+
`QueryStream.paginate` resumes from indexed cursor bounds and supports pinned page ranges, automatic split recommendations, and `maximumRowsRead`/`maximumBytesRead` budgets that count underlying query-stream reads, including filtered documents. Byte counts are estimates. If a budget prevents safe progress or splitting, pagination fails with `ReadBudgetExceededError`; increase the budget or reduce the query's read requirements.
|
|
360
|
+
|
|
361
|
+
Use React's new `useStreamPaginatedQuery` for these queries:
|
|
362
|
+
|
|
363
|
+
```ts
|
|
364
|
+
import { useStreamPaginatedQuery } from "@confect/react";
|
|
365
|
+
|
|
366
|
+
const { results, status, loadMore } = useStreamPaginatedQuery(
|
|
367
|
+
refs.public.notes.feed,
|
|
368
|
+
{},
|
|
369
|
+
{
|
|
370
|
+
initialNumItems: 10,
|
|
371
|
+
maximumRowsRead: 1000,
|
|
372
|
+
maximumBytesRead: 512 * 1024,
|
|
373
|
+
},
|
|
374
|
+
);
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
The hook pins loaded pages to fixed ranges, splits oversized or budget-limited pages, and restarts pagination on invalid cursors. Foldkit's `PaginatedQuery` also supports stream queries and preserves page ranges when navigating back and forward, avoiding skipped or repeated documents as data changes.
|
|
378
|
+
|
|
379
|
+
Stream cursors expose their order-key values. Do not paginate publicly over sensitive indexed fields unless they are pinned with `eq`. All `QueryStream` APIs are experimental.
|
|
380
|
+
|
|
381
|
+
### Middleware options
|
|
382
|
+
|
|
383
|
+
Declare a lazy `options` schema on `MiddlewareSpec.MiddlewareSpec`, then pass typed values with `.middleware(Policy, options)` on functions or groups. Options are validated without coercion during codegen and server registration; keep schemas and values client-safe because generated refs carry them.
|
|
384
|
+
|
|
385
|
+
The same policy can be attached repeatedly with non-equivalent options. Every attachment runs, with group policies before function policies. Equivalent options and duplicate policies without options are rejected. Register implementations against the same spec used for attachments.
|
|
386
|
+
|
|
387
|
+
### Breaking changes
|
|
388
|
+
|
|
389
|
+
Middleware callbacks passed to `MiddlewareImpl.make` or `MiddlewareImpl.makeByFunctionType` receive invocation metadata under `invocation`. To migrate, nest destructuring of `name`, `functionType`, `functionVisibility`, and decoded `args`:
|
|
390
|
+
|
|
391
|
+
**Before:**
|
|
392
|
+
|
|
393
|
+
```ts
|
|
394
|
+
(effect, { name, args }) => effect;
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
**After:**
|
|
398
|
+
|
|
399
|
+
```ts
|
|
400
|
+
(effect, { invocation: { name, args } }) => effect;
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
Middleware with an options schema also receives `options` alongside `invocation`; middleware without one keeps its single-argument attachment API and receives only `{ invocation }`.
|
|
404
|
+
|
|
405
|
+
### Fixes and tracing
|
|
406
|
+
- Preserve `ConvexError.data` when a handler throws a `ConvexError` inside an Effect instead of returning it as a typed failure.
|
|
407
|
+
- Add named tracing spans for JavaScript client calls, server function execution, database writes and pagination, `QueryStream.unique`/`QueryStream.paginate`, and `confect codegen`/`confect dev` code-generation passes.
|
|
408
|
+
|
|
409
|
+
### Patch Changes
|
|
410
|
+
|
|
411
|
+
- 9f4e2c0: Require `effect@^4.0.0-rc.113` across `@confect/*` and raise `@confect/server`'s optional `@effect/platform-node` peer to the same range. Upgrade Effect alongside Confect; existing Confect call sites are unchanged.
|
|
412
|
+
|
|
413
|
+
Effect's own APIs include breaking renames: use `Config.String` instead of `Config.string`, and `LanguageModel.LanguageModel` instead of `LanguageModel.Service` when annotating the result of `AiGatewayLanguageModel.make`. See the [Effect RC 113 release notes](https://github.com/Effect-TS/effect/releases/tag/effect%404.0.0-rc.113) for the complete migration guidance.
|
|
414
|
+
|
|
415
|
+
- 90c80e9: Require `effect@^4.0.0-rc.115` across `@confect/*` and `@effect/platform-node@^4.0.0-rc.115` when using `@confect/server`'s optional Node integration. Upgrade these dependencies alongside Confect; existing Confect call sites are unchanged.
|
|
416
|
+
- f721d2c: Remove spaces around em dashes and separator slashes in API documentation and `confect codegen` diagnostics.
|
|
417
|
+
|
|
418
|
+
## 10.0.0-next.21
|
|
419
|
+
|
|
420
|
+
### Major Changes
|
|
421
|
+
|
|
422
|
+
- a6425c5: Raise the minimum supported Node.js version to 24.
|
|
423
|
+
|
|
424
|
+
### Breaking Changes
|
|
425
|
+
- `engines.node` is now `>=24` on every `@confect/*` package, raised from `>=22`.
|
|
426
|
+
|
|
427
|
+
Node 22 has entered maintenance, so Confect now targets Node 24, the active LTS line. To migrate, move the Node version your project builds and runs on to 24 or later—on Node 22, installing `@confect/*` now fails your package manager's engine check. No API changes accompany the raise: code already running on Node 24 needs no edits.
|
|
428
|
+
|
|
429
|
+
## 10.0.0-next.20
|
|
430
|
+
|
|
431
|
+
## 10.0.0-next.19
|
|
432
|
+
|
|
433
|
+
## 10.0.0-next.18
|
|
434
|
+
|
|
435
|
+
## 10.0.0-next.17
|
|
436
|
+
|
|
437
|
+
### Patch Changes
|
|
438
|
+
|
|
439
|
+
- 8e4962e: Raise the required `effect` peer version to `^4.0.0-rc.111` (from `^4.0.0-rc.110`), and `@confect/server`'s optional `@effect/platform-node` peer version likewise.
|
|
440
|
+
|
|
441
|
+
No Confect API changed, and no call-site edits are needed. `rc.111` is a patch release of Effect with nothing removed or renamed, so upgrading is a matter of installing it alongside `@confect/*`.
|
|
442
|
+
|
|
443
|
+
## 10.0.0-next.16
|
|
444
|
+
|
|
445
|
+
### Major Changes
|
|
446
|
+
|
|
447
|
+
- Migrate to Effect v4. All `@confect/*` packages now require `effect@^4.0.0-beta.97`; `@effect/platform` and `@effect/cli` are no longer dependencies (their functionality moved into `effect` core and `effect/unstable/*`).
|
|
448
|
+
|
|
449
|
+
Breaking changes for users:
|
|
450
|
+
|
|
451
|
+
- **Schemas** follow Effect v4's Schema API: `Schema.Union([a, b])` (array form), `Schema.Literals([...])` for literal unions, `Schema.optionalKey` in place of `optionalWith({ exact: true })`, and checks like `Schema.String.check(Schema.isMaxLength(...))` in place of piped filters.
|
|
452
|
+
- **Option-returning functions** must use a codec with a serializable encoded form, such as `Schema.OptionFromNullOr(...)`—v4's `Schema.Option` encodes to an `Option` instance, which is not a Convex value.
|
|
453
|
+
- **Table schemas** may now be transformations (`Schema.decodeTo` chains, `Schema.encodeKeys`), branded structs, suspended schemas, or unions of these—Convex's system fields are carried through the whole encoding chain. Schemas that do not resolve to an object shape at every step (such as `Schema.Class`) are rejected with a descriptive error when the table is defined.
|
|
454
|
+
- **Clients**: decode failures surface as `SchemaError` rather than `ParseError` in `@confect/js` and `@confect/react`, and `@confect/react`'s `useMutation`/`useAction` handles with an `error` schema now resolve to `Result` (v4's replacement for `Either`).
|
|
455
|
+
- **HTTP** is now mounted through the renamed `HttpRouter` module (formerly `HttpApi`). `HttpRouter.make(routes)` takes a single route-registering `Layer` composed from Effect's own `effect/unstable/http` and `effect/unstable/httpapi` modules—`HttpApiBuilder.layer(api)` (with group handler layers supplied via `Layer.provide`; a missing group is a compile-time error), `HttpApiScalar.layer` for docs, `HttpRouter.add` for plain routes, and `HttpRouter.middleware(fn, { global: true })` for middleware, merged with `Layer.mergeAll`. The per-path-prefix record and its `api`/`apiLive`/`middleware`/`scalar` options are gone; Confect registers one catch-all Convex HTTP action at `/`, and plain Convex routes added to the returned router still take precedence. Handlers, middleware, and route-layer construction all run with Confect's Convex-aware `ConfigProvider` in context.
|
|
456
|
+
- **Node actions** use `effect/unstable/process` (`ChildProcessSpawner`) and `@effect/platform-node`'s `NodeServices` in place of `@effect/platform` `Command`/`NodeContext`.
|
|
457
|
+
- **Configuration**: Confect's Convex-aware `ConfigProvider` treats empty-string environment variables as missing values (matching Effect v4's built-in providers), so `Config.withDefault` and `Config.option` recover from them.
|
|
458
|
+
- **CLI**: a malformed `convex.json` now fails codegen with a descriptive error instead of being silently ignored.
|
|
459
|
+
- Confect queries no longer stub the global `Date.now`. Queries run with a `Clock` whose unsafe accessors return constants, so Effect-internal reads (log timestamps, spans) never evict a query from Convex's cache; explicit time reads—`Clock.currentTimeMillis`/`currentTimeNanos` or a raw `Date.now()` call—opt the query out and evict as they honestly should.
|
|
460
|
+
|
|
461
|
+
### Patch Changes
|
|
462
|
+
|
|
463
|
+
- Raise the required `effect` peer version to `^4.0.0-beta.100` (from `^4.0.0-beta.99`).
|
|
464
|
+
|
|
465
|
+
This is a peer-range-only change with no consumer-visible API consequences. The `beta.100` release only touches `Cron` internals (month/weekday alias normalization, day/weekday rollover, and equality/hashing), CLI error message formatting (`InvalidValue` prefixes), and `Schema.toTaggedUnion` discriminants that Confect doesn't use.
|
|
466
|
+
|
|
467
|
+
- Raise the required `effect` peer version to `^4.0.0-beta.101` (from `^4.0.0-beta.100`).
|
|
468
|
+
|
|
469
|
+
This is a peer-range-only change with no consumer-visible API consequences. The `beta.101` release only touches fiber/concurrency internals (interrupt handling in concurrent traversal, stack frame annotations, `awaitAllChildren` linearization, `interruptibleMask` interrupt delivery), a `MutableList.filter` fix for empty buckets, a `Schema.Struct` required-readonly-field type display simplification, and an `HttpRouter.toWebHandler` middleware type-inference tightening that Confect doesn't need to accommodate.
|
|
470
|
+
|
|
471
|
+
- Raise the required `effect` peer version to `^4.0.0-beta.102` (from `^4.0.0-beta.101`), and `@confect/server`'s optional `@effect/platform-node` peer version likewise.
|
|
472
|
+
- Raise the required `effect` peer version to `^4.0.0-beta.105` (from `^4.0.0-beta.102`), and `@confect/server`'s optional `@effect/platform-node` peer version likewise.
|
|
473
|
+
|
|
474
|
+
`beta.103` separates wall-clock time from monotonic elapsed time: `Clock.Clock` now also requires `monotonicTimeNanos` and `monotonicTimeNanosUnsafe`, so a custom `Clock` provided to a Confect function has to supply both. Effects that measure elapsed time—`Effect.timed`, duration metrics, `Sink.withDuration`—read the monotonic accessors instead of the wall clock, and continue to report a zero duration inside queries and mutations, where Confect pins the unsafe accessors to constants to keep Convex's query cache from evicting on every logged span.
|
|
475
|
+
|
|
476
|
+
`beta.103` also moves synchronous Effect runs off `setImmediate`/`setTimeout` and onto the microtask queue, which Convex's query and mutation isolate permits. Confect no longer suppresses cooperative fiber yielding for the synchronous work it performs while your modules load—registration and schema-to-validator compilation—and relies on that scheduling instead. Neither the "Can't use `setTimeout` in queries and mutations" crash nor any other consumer-visible behavior changes, but this is the area to look at if module loading starts misbehaving.
|
|
477
|
+
|
|
478
|
+
`beta.104` renames Effect's schema error constructors to match their `Data` counterparts, which affects any error schema you declare for a Confect function:
|
|
479
|
+
|
|
480
|
+
**Before:**
|
|
481
|
+
|
|
482
|
+
```ts
|
|
483
|
+
export class NoteNotFound extends Schema.TaggedErrorClass<NoteNotFound>()(
|
|
484
|
+
"NoteNotFound",
|
|
485
|
+
{ noteId: Id("notes") },
|
|
486
|
+
) {}
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
**After:**
|
|
490
|
+
|
|
491
|
+
```ts
|
|
492
|
+
export class NoteNotFound extends Schema.TaggedError<NoteNotFound>()(
|
|
493
|
+
"NoteNotFound",
|
|
494
|
+
{ noteId: Id("notes") },
|
|
495
|
+
) {}
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
`Schema.ErrorClass` is likewise now `Schema.Error`; the schema for JavaScript `Error` instances that previously went by `Schema.Error` is now `Schema.ErrorInstance`, and `Schema.ErrorReviver` is now `Schema.ErrorInstanceReviver`. Confect's own error types—`DocumentDecodeError`, `BlobNotFoundError`, and the rest—are unchanged in name, shape, and message.
|
|
499
|
+
|
|
500
|
+
`beta.105` restructures how schema validation failures are reported, but not on the path Confect puts you on: decode and encode failures still surface as `Schema.SchemaError` with a formatted `message`, so error text from `@confect/js`, `@confect/react`, and document decoding is unchanged.
|
|
501
|
+
|
|
502
|
+
- Raise the required `effect` peer version to `^4.0.0-beta.106` (from `^4.0.0-beta.105`), and `@confect/server`'s optional `@effect/platform-node` peer version likewise.
|
|
503
|
+
|
|
504
|
+
`beta.106` is a patch-only Effect release. Nothing in Confect's own API changes, and your table, argument, and returns schemas still compile to the same Convex validators.
|
|
505
|
+
|
|
506
|
+
One Effect change needs a call-site edit if you derive property-test generators from those schemas: `Schema.toArbitrary` now returns a factory that takes the `fast-check` module instead of returning an arbitrary directly, and `Schema.toArbitraryLazy` and the `{ report: true }` option are gone.
|
|
507
|
+
|
|
508
|
+
**Before:**
|
|
509
|
+
|
|
510
|
+
```ts
|
|
511
|
+
const NoteArbitrary = Schema.toArbitrary(Note);
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
**After:**
|
|
515
|
+
|
|
516
|
+
```ts
|
|
517
|
+
import * as FastCheck from "fast-check";
|
|
518
|
+
|
|
519
|
+
const NoteArbitrary = Schema.toArbitrary(Note)(FastCheck);
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
HTTP actions written against `HttpRouter` also inherit Effect's stricter multipart handling: a request that exceeds the configured part count, part size, or field size limits now stops being parsed at the limit rather than being read to completion first.
|
|
523
|
+
|
|
524
|
+
- Raise the required `effect` peer version to `^4.0.0-beta.107` (from `^4.0.0-beta.106`), and `@confect/server`'s optional `@effect/platform-node` peer version likewise.
|
|
525
|
+
|
|
526
|
+
`beta.107` is a patch-only Effect release, so no Confect API changes and no call-site edits are needed—upgrade `effect` alongside `@confect/*` and everything you have written keeps compiling. Your table, argument, and returns schemas still produce the same Convex validators.
|
|
527
|
+
|
|
528
|
+
Two Effect fixes are worth knowing about if they touch your code. HTTP actions written with `HttpRouter` now collect uploaded file contents far faster on large multipart bodies, and a file part whose stream is cut short—because a parser limit was exceeded or the request body ended early—now fails instead of hanging. Separately, `Duration` values that are equal now hash equally, so a `Duration` used as a `HashMap` key or a `HashSet` member is found regardless of which constructor built it.
|
|
529
|
+
|
|
530
|
+
- Raise the required `effect` peer version to `^4.0.0-beta.98` (from `^4.0.0-beta.97`).
|
|
531
|
+
|
|
532
|
+
`effect`'s `SchemaError` is now exposed as its own public module (`effect/SchemaError`), which changes the import path TypeScript picks when Confect emits `.d.ts` declarations that reference `Schema.SchemaError` (for example in generated `services.d.ts`). Existing `Schema.SchemaError`/`Schema.isSchemaError` usage is unaffected—this is purely a declaration-emit detail that consumers relying on generated types may notice.
|
|
533
|
+
|
|
534
|
+
- Raise the required `effect` peer version to `^4.0.0-beta.99` (from `^4.0.0-beta.98`).
|
|
535
|
+
|
|
536
|
+
This is a peer-range-only change with no consumer-visible API consequences. The `beta.99` release only touches `Graph`, CLI (`Command`/`CliConfig`/wizard mode), `Tool` cloning, Redis script eval, and multipart parser internals that Confect doesn't use.
|
|
537
|
+
|
|
538
|
+
- Raise the required `effect` peer version to `^4.0.0-rc.108` (from `^4.0.0-beta.107`), and `@confect/server`'s optional `@effect/platform-node` peer version likewise. Effect v4 has left beta for release candidates, so `effect@rc` is now the tag to install alongside `@confect/*`.
|
|
539
|
+
|
|
540
|
+
No Confect API changed, and no call-site edits are needed for Confect itself. One Effect change can reach your code: the standalone `effect/SchemaError` module is gone, and `SchemaError` is now exported from `Schema`. Confect still fails decoding with the same error, so this only matters if you name the type when handling it.
|
|
541
|
+
|
|
542
|
+
Before:
|
|
543
|
+
|
|
544
|
+
```ts
|
|
545
|
+
import type { SchemaError } from "effect/SchemaError";
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
After:
|
|
549
|
+
|
|
550
|
+
```ts
|
|
551
|
+
import type { SchemaError } from "effect/Schema";
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
Also worth knowing if you serve an `HttpApi`: a query parameter declared as an array now decodes correctly when a request supplies exactly one value for it.
|
|
555
|
+
|
|
556
|
+
One internal change rides along. Queries and mutations that run long enough to trigger a cooperative fiber yield now take that yield from Effect's own scheduler, which `rc.108` made usable inside Convex's isolate for the first time. The underlying microtask primitive is identical, so behavior should not change—but it is the thing to look at if a long-running query or mutation regresses on this release.
|
|
557
|
+
|
|
558
|
+
- Raise the required `effect` peer version to `^4.0.0-rc.109` (from `^4.0.0-rc.108`), and `@confect/server`'s optional `@effect/platform-node` peer version likewise.
|
|
559
|
+
|
|
560
|
+
No Confect API changed, and no call-site edits are needed. `rc.109` is a patch release of Effect with nothing removed or renamed, so upgrading is a matter of installing it alongside `@confect/*`.
|
|
561
|
+
|
|
562
|
+
- 8e4962e: Raise the required `effect` peer version to `^4.0.0-rc.110` (from `^4.0.0-rc.109`), and `@confect/server`'s optional `@effect/platform-node` peer version likewise.
|
|
563
|
+
|
|
564
|
+
No Confect API changed, and no call-site edits are needed. `rc.110` is a patch release of Effect with nothing removed or renamed, so upgrading is a matter of installing it alongside `@confect/*`.
|
|
565
|
+
|
|
566
|
+
- 3f0255c: Build and test against `convex` 1.44.0. The published `convex` peer ranges are unchanged, so no consumer action is required.
|
|
567
|
+
- Sync with `main`: this prerelease line now includes all changes released in `@confect/*` 9.2.2–9.2.4—see those versions' changelog entries.
|
|
568
|
+
- Sync with `main`: this prerelease line now includes all changes released in `@confect/*` 9.2.5—see that version's changelog entries.
|
|
569
|
+
- Sync with `main`: this prerelease line now includes all changes released in `@confect/*` 9.3.0—see that version's changelog entries.
|
|
570
|
+
- Sync with `main`: this prerelease line now includes all changes released in `@confect/*` 9.4.0—see that version's changelog entries.
|
|
571
|
+
|
|
572
|
+
The `@effect/platform` and `@effect/cli` peer and dependency floors that 9.4.0 raises do not apply here: this line runs on Effect v4, where those packages are not dependencies at all.
|
|
573
|
+
|
|
574
|
+
- The published type declarations are now emitted by TypeScript 7 rather than TypeScript 6. No API changed, but the declaration text differs in places, so an inferred type printed in your editor or in a type error may read slightly differently than before.
|
|
575
|
+
|
|
576
|
+
## 10.0.0-next.15
|
|
577
|
+
|
|
578
|
+
### Patch Changes
|
|
579
|
+
|
|
580
|
+
- 8e4962e: Raise the required `effect` peer version to `^4.0.0-rc.109` (from `^4.0.0-rc.108`), and `@confect/server`'s optional `@effect/platform-node` peer version likewise.
|
|
581
|
+
|
|
582
|
+
No Confect API changed, and no call-site edits are needed. `rc.109` is a patch release of Effect with nothing removed or renamed, so upgrading is a matter of installing it alongside `@confect/*`.
|
|
583
|
+
|
|
584
|
+
## 10.0.0-next.14
|
|
585
|
+
|
|
586
|
+
### Patch Changes
|
|
587
|
+
|
|
588
|
+
- 9d51bd3: Raise the required `effect` peer version to `^4.0.0-rc.108` (from `^4.0.0-beta.107`), and `@confect/server`'s optional `@effect/platform-node` peer version likewise. Effect v4 has left beta for release candidates, so `effect@rc` is now the tag to install alongside `@confect/*`.
|
|
589
|
+
|
|
590
|
+
No Confect API changed, and no call-site edits are needed for Confect itself. One Effect change can reach your code: the standalone `effect/SchemaError` module is gone, and `SchemaError` is now exported from `Schema`. Confect still fails decoding with the same error, so this only matters if you name the type when handling it.
|
|
591
|
+
|
|
592
|
+
Before:
|
|
593
|
+
|
|
594
|
+
```ts
|
|
595
|
+
import type { SchemaError } from "effect/SchemaError";
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
After:
|
|
599
|
+
|
|
600
|
+
```ts
|
|
601
|
+
import type { SchemaError } from "effect/Schema";
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
Also worth knowing if you serve an `HttpApi`: a query parameter declared as an array now decodes correctly when a request supplies exactly one value for it.
|
|
605
|
+
|
|
606
|
+
One internal change rides along. Queries and mutations that run long enough to trigger a cooperative fiber yield now take that yield from Effect's own scheduler, which `rc.108` made usable inside Convex's isolate for the first time. The underlying microtask primitive is identical, so behavior should not change—but it is the thing to look at if a long-running query or mutation regresses on this release.
|
|
607
|
+
|
|
608
|
+
- a4054ab: The published type declarations are now emitted by TypeScript 7 rather than TypeScript 6. No API changed, but the declaration text differs in places, so an inferred type printed in your editor or in a type error may read slightly differently than before.
|
|
609
|
+
|
|
610
|
+
## 10.0.0-next.13
|
|
611
|
+
|
|
612
|
+
### Patch Changes
|
|
613
|
+
|
|
614
|
+
- 5a73763: Raise the required `effect` peer version to `^4.0.0-beta.107` (from `^4.0.0-beta.106`), and `@confect/server`'s optional `@effect/platform-node` peer version likewise.
|
|
615
|
+
|
|
616
|
+
`beta.107` is a patch-only Effect release, so no Confect API changes and no call-site edits are needed—upgrade `effect` alongside `@confect/*` and everything you have written keeps compiling. Your table, argument, and returns schemas still produce the same Convex validators.
|
|
617
|
+
|
|
618
|
+
Two Effect fixes are worth knowing about if they touch your code. HTTP actions written with `HttpRouter` now collect uploaded file contents far faster on large multipart bodies, and a file part whose stream is cut short—because a parser limit was exceeded or the request body ended early—now fails instead of hanging. Separately, `Duration` values that are equal now hash equally, so a `Duration` used as a `HashMap` key or a `HashSet` member is found regardless of which constructor built it.
|
|
619
|
+
|
|
620
|
+
## 10.0.0-next.12
|
|
621
|
+
|
|
622
|
+
### Patch Changes
|
|
623
|
+
|
|
624
|
+
- 661ee9b: Raise the required `effect` peer version to `^4.0.0-beta.106` (from `^4.0.0-beta.105`), and `@confect/server`'s optional `@effect/platform-node` peer version likewise.
|
|
625
|
+
|
|
626
|
+
`beta.106` is a patch-only Effect release. Nothing in Confect's own API changes, and your table, argument, and returns schemas still compile to the same Convex validators.
|
|
627
|
+
|
|
628
|
+
One Effect change needs a call-site edit if you derive property-test generators from those schemas: `Schema.toArbitrary` now returns a factory that takes the `fast-check` module instead of returning an arbitrary directly, and `Schema.toArbitraryLazy` and the `{ report: true }` option are gone.
|
|
629
|
+
|
|
630
|
+
**Before:**
|
|
631
|
+
|
|
632
|
+
```ts
|
|
633
|
+
const NoteArbitrary = Schema.toArbitrary(Note);
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
**After:**
|
|
637
|
+
|
|
638
|
+
```ts
|
|
639
|
+
import * as FastCheck from "fast-check";
|
|
640
|
+
|
|
641
|
+
const NoteArbitrary = Schema.toArbitrary(Note)(FastCheck);
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
HTTP actions written against `HttpRouter` also inherit Effect's stricter multipart handling: a request that exceeds the configured part count, part size, or field size limits now stops being parsed at the limit rather than being read to completion first.
|
|
645
|
+
|
|
646
|
+
## 10.0.0-next.11
|
|
647
|
+
|
|
648
|
+
### Patch Changes
|
|
649
|
+
|
|
650
|
+
- f782cdd: Raise the required `effect` peer version to `^4.0.0-beta.105` (from `^4.0.0-beta.102`), and `@confect/server`'s optional `@effect/platform-node` peer version likewise.
|
|
651
|
+
|
|
652
|
+
`beta.103` separates wall-clock time from monotonic elapsed time: `Clock.Clock` now also requires `monotonicTimeNanos` and `monotonicTimeNanosUnsafe`, so a custom `Clock` provided to a Confect function has to supply both. Effects that measure elapsed time—`Effect.timed`, duration metrics, `Sink.withDuration`—read the monotonic accessors instead of the wall clock, and continue to report a zero duration inside queries and mutations, where Confect pins the unsafe accessors to constants to keep Convex's query cache from evicting on every logged span.
|
|
653
|
+
|
|
654
|
+
`beta.103` also moves synchronous Effect runs off `setImmediate`/`setTimeout` and onto the microtask queue, which Convex's query and mutation isolate permits. Confect no longer suppresses cooperative fiber yielding for the synchronous work it performs while your modules load—registration and schema-to-validator compilation—and relies on that scheduling instead. Neither the "Can't use `setTimeout` in queries and mutations" crash nor any other consumer-visible behavior changes, but this is the area to look at if module loading starts misbehaving.
|
|
655
|
+
|
|
656
|
+
`beta.104` renames Effect's schema error constructors to match their `Data` counterparts, which affects any error schema you declare for a Confect function:
|
|
657
|
+
|
|
658
|
+
**Before:**
|
|
659
|
+
|
|
660
|
+
```ts
|
|
661
|
+
export class NoteNotFound extends Schema.TaggedErrorClass<NoteNotFound>()(
|
|
662
|
+
"NoteNotFound",
|
|
663
|
+
{ noteId: Id("notes") },
|
|
664
|
+
) {}
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
**After:**
|
|
668
|
+
|
|
669
|
+
```ts
|
|
670
|
+
export class NoteNotFound extends Schema.TaggedError<NoteNotFound>()(
|
|
671
|
+
"NoteNotFound",
|
|
672
|
+
{ noteId: Id("notes") },
|
|
673
|
+
) {}
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
`Schema.ErrorClass` is likewise now `Schema.Error`; the schema for JavaScript `Error` instances that previously went by `Schema.Error` is now `Schema.ErrorInstance`, and `Schema.ErrorReviver` is now `Schema.ErrorInstanceReviver`. Confect's own error types—`DocumentDecodeError`, `BlobNotFoundError`, and the rest—are unchanged in name, shape, and message.
|
|
677
|
+
|
|
678
|
+
`beta.105` restructures how schema validation failures are reported, but not on the path Confect puts you on: decode and encode failures still surface as `Schema.SchemaError` with a formatted `message`, so error text from `@confect/js`, `@confect/react`, and document decoding is unchanged.
|
|
679
|
+
|
|
680
|
+
- Sync with `main`: this prerelease line now includes all changes released in `@confect/*` 9.4.0—see that version's changelog entries.
|
|
681
|
+
|
|
682
|
+
The `@effect/platform` and `@effect/cli` peer and dependency floors that 9.4.0 raises do not apply here: this line runs on Effect v4, where those packages are not dependencies at all.
|
|
683
|
+
|
|
684
|
+
## 10.0.0-next.10
|
|
685
|
+
|
|
686
|
+
### Patch Changes
|
|
687
|
+
|
|
688
|
+
- Sync with `main`: this prerelease line now includes all changes released in `@confect/*` 9.3.0—see that version's changelog entries.
|
|
689
|
+
|
|
690
|
+
## 10.0.0-next.9
|
|
691
|
+
|
|
692
|
+
### Patch Changes
|
|
693
|
+
|
|
694
|
+
- 0dcc0fb: Raise the required `effect` peer version to `^4.0.0-beta.102` (from `^4.0.0-beta.101`), and `@confect/server`'s optional `@effect/platform-node` peer version likewise.
|
|
695
|
+
- 25e8d19: Sync with `main`: this prerelease line now includes all changes released in `@confect/*` 9.2.5—see that version's changelog entries.
|
|
696
|
+
|
|
697
|
+
## 10.0.0-next.8
|
|
698
|
+
|
|
699
|
+
### Patch Changes
|
|
700
|
+
|
|
701
|
+
- 913d0e5: Raise the required `effect` peer version to `^4.0.0-beta.101` (from `^4.0.0-beta.100`).
|
|
702
|
+
|
|
703
|
+
This is a peer-range-only change with no consumer-visible API consequences. The `beta.101` release only touches fiber/concurrency internals (interrupt handling in concurrent traversal, stack frame annotations, `awaitAllChildren` linearization, `interruptibleMask` interrupt delivery), a `MutableList.filter` fix for empty buckets, a `Schema.Struct` required-readonly-field type display simplification, and an `HttpRouter.toWebHandler` middleware type-inference tightening that Confect doesn't need to accommodate.
|
|
704
|
+
|
|
705
|
+
## 10.0.0-next.7
|
|
706
|
+
|
|
707
|
+
## 10.0.0-next.6
|
|
708
|
+
|
|
709
|
+
## 10.0.0-next.5
|
|
710
|
+
|
|
711
|
+
## 10.0.0-next.4
|
|
712
|
+
|
|
713
|
+
## 10.0.0-next.3
|
|
714
|
+
|
|
715
|
+
### Patch Changes
|
|
716
|
+
|
|
717
|
+
- 5b63546: Raise the required `effect` peer version to `^4.0.0-beta.100` (from `^4.0.0-beta.99`).
|
|
718
|
+
|
|
719
|
+
This is a peer-range-only change with no consumer-visible API consequences. The `beta.100` release only touches `Cron` internals (month/weekday alias normalization, day/weekday rollover, and equality/hashing), CLI error message formatting (`InvalidValue` prefixes), and `Schema.toTaggedUnion` discriminants that Confect doesn't use.
|
|
720
|
+
|
|
721
|
+
## 10.0.0-next.2
|
|
722
|
+
|
|
723
|
+
### Patch Changes
|
|
724
|
+
|
|
725
|
+
- 35f7515: Raise the required `effect` peer version to `^4.0.0-beta.99` (from `^4.0.0-beta.98`).
|
|
726
|
+
|
|
727
|
+
This is a peer-range-only change with no consumer-visible API consequences. The `beta.99` release only touches `Graph`, CLI (`Command`/`CliConfig`/wizard mode), `Tool` cloning, Redis script eval, and multipart parser internals that Confect doesn't use.
|
|
728
|
+
|
|
729
|
+
- 2aa7541: Sync with `main`: this prerelease line now includes all changes released in `@confect/*` 9.2.2–9.2.4—see those versions' changelog entries.
|
|
730
|
+
|
|
731
|
+
## 10.0.0-next.1
|
|
732
|
+
|
|
733
|
+
### Patch Changes
|
|
734
|
+
|
|
735
|
+
- 4d98ea8: Raise the required `effect` peer version to `^4.0.0-beta.98` (from `^4.0.0-beta.97`).
|
|
736
|
+
|
|
737
|
+
`effect`'s `SchemaError` is now exposed as its own public module (`effect/SchemaError`), which changes the import path TypeScript picks when Confect emits `.d.ts` declarations that reference `Schema.SchemaError` (for example in generated `services.d.ts`). Existing `Schema.SchemaError`/`Schema.isSchemaError` usage is unaffected—this is purely a declaration-emit detail that consumers relying on generated types may notice.
|
|
738
|
+
|
|
739
|
+
- Updated dependencies [4d98ea8]
|
|
740
|
+
- @confect/core@10.0.0-next.1
|
|
741
|
+
|
|
742
|
+
## 10.0.0-next.0
|
|
743
|
+
|
|
744
|
+
### Major Changes
|
|
745
|
+
|
|
746
|
+
- 70e313e: Migrate to Effect v4. All `@confect/*` packages now require `effect@^4.0.0-beta.97`; `@effect/platform` and `@effect/cli` are no longer dependencies (their functionality moved into `effect` core and `effect/unstable/*`).
|
|
747
|
+
|
|
748
|
+
Breaking changes for users:
|
|
749
|
+
- **Schemas** follow Effect v4's Schema API: `Schema.Union([a, b])` (array form), `Schema.Literals([...])` for literal unions, `Schema.optionalKey` in place of `optionalWith({ exact: true })`, `Schema.TaggedErrorClass` in place of `Schema.TaggedError`, and checks like `Schema.String.check(Schema.isMaxLength(...))` in place of piped filters.
|
|
750
|
+
- **Option-returning functions** must use a codec with a serializable encoded form, such as `Schema.OptionFromNullOr(...)`—v4's `Schema.Option` encodes to an `Option` instance, which is not a Convex value.
|
|
751
|
+
- **Table schemas** may now be transformations (`Schema.decodeTo` chains, `Schema.encodeKeys`), branded structs, suspended schemas, or unions of these—Convex's system fields are carried through the whole encoding chain. Schemas that do not resolve to an object shape at every step (such as `Schema.Class`) are rejected with a descriptive error when the table is defined.
|
|
752
|
+
- **Clients**: decode failures surface as `SchemaError` rather than `ParseError` in `@confect/js` and `@confect/react`, and `@confect/react`'s `useMutation`/`useAction` handles with an `error` schema now resolve to `Result` (v4's replacement for `Either`).
|
|
753
|
+
- **HTTP** is now mounted through the renamed `HttpRouter` module (formerly `HttpApi`). `HttpRouter.make(routes)` takes a single route-registering `Layer` composed from Effect's own `effect/unstable/http` and `effect/unstable/httpapi` modules—`HttpApiBuilder.layer(api)` (with group handler layers supplied via `Layer.provide`; a missing group is a compile-time error), `HttpApiScalar.layer` for docs, `HttpRouter.add` for plain routes, and `HttpRouter.middleware(fn, { global: true })` for middleware, merged with `Layer.mergeAll`. The per-path-prefix record and its `api`/`apiLive`/`middleware`/`scalar` options are gone; Confect registers one catch-all Convex HTTP action at `/`, and plain Convex routes added to the returned router still take precedence. Handlers, middleware, and route-layer construction all run with Confect's Convex-aware `ConfigProvider` in context.
|
|
754
|
+
- **Node actions** use `effect/unstable/process` (`ChildProcessSpawner`) and `@effect/platform-node`'s `NodeServices` in place of `@effect/platform` `Command`/`NodeContext`.
|
|
755
|
+
- **Configuration**: Confect's Convex-aware `ConfigProvider` treats empty-string environment variables as missing values (matching Effect v4's built-in providers), so `Config.withDefault` and `Config.option` recover from them.
|
|
756
|
+
- **CLI**: a malformed `convex.json` now fails codegen with a descriptive error instead of being silently ignored.
|
|
757
|
+
- Confect queries no longer stub the global `Date.now`. Queries run with a `Clock` whose unsafe accessors return constants, so Effect-internal reads (log timestamps, spans) never evict a query from Convex's cache; explicit time reads—`Clock.currentTimeMillis`/`currentTimeNanos` or a raw `Date.now()` call—opt the query out and evict as they honestly should.
|
|
758
|
+
|
|
759
|
+
### Patch Changes
|
|
760
|
+
|
|
761
|
+
- Updated dependencies [70e313e]
|
|
762
|
+
- @confect/core@10.0.0-next.0
|
|
763
|
+
|
|
764
|
+
## 9.4.2
|
|
765
|
+
|
|
766
|
+
## 9.4.1
|
|
767
|
+
|
|
768
|
+
### Patch Changes
|
|
769
|
+
|
|
770
|
+
- a4054ab: The published type declarations are now emitted by TypeScript 7 rather than TypeScript 6. No API changed, but the declaration text differs in places, so an inferred type printed in your editor or in a type error may read slightly differently than before.
|
|
771
|
+
|
|
772
|
+
## 9.4.0
|
|
773
|
+
|
|
774
|
+
## 9.3.0
|
|
775
|
+
|
|
776
|
+
### Minor Changes
|
|
777
|
+
|
|
778
|
+
- 16b5ad6: Add first-class paginated queries: declare one with `FunctionSpec.publicPaginatedQuery` (or `internalPaginatedQuery`) and read it with the new `usePaginatedQuery` hook from `@confect/react`.
|
|
779
|
+
|
|
780
|
+
Pass an `item` schema—the type of one element in a page—in place of `returns`, plus an optional `args` struct for your own arguments. The handler receives `paginationOpts` alongside them and forwards it to `paginate`.
|
|
781
|
+
|
|
782
|
+
```ts
|
|
783
|
+
// confect/notes.spec.ts
|
|
784
|
+
FunctionSpec.publicPaginatedQuery({
|
|
785
|
+
name: "listByAuthor",
|
|
786
|
+
args: () => Schema.Struct({ author: Schema.String }),
|
|
787
|
+
item: () => notes.Doc,
|
|
788
|
+
});
|
|
789
|
+
|
|
790
|
+
// confect/notes.impl.ts
|
|
791
|
+
({ author, paginationOpts }) =>
|
|
792
|
+
Effect.gen(function* () {
|
|
793
|
+
const reader = yield* DatabaseReader;
|
|
794
|
+
|
|
795
|
+
return yield* reader
|
|
796
|
+
.table("notes")
|
|
797
|
+
.index("by_creation_time", "desc")
|
|
798
|
+
.paginate(paginationOpts, (q) => q.eq(q.field("author"), author));
|
|
799
|
+
}).pipe(Effect.orDie);
|
|
800
|
+
```
|
|
801
|
+
|
|
802
|
+
Declaring `paginationOpts` in `args` yourself is a type and runtime error.
|
|
803
|
+
|
|
804
|
+
```tsx
|
|
805
|
+
import { PaginatedQueryResult, usePaginatedQuery } from "@confect/react";
|
|
806
|
+
|
|
807
|
+
const notes = usePaginatedQuery(
|
|
808
|
+
refs.public.notes.listByAuthor,
|
|
809
|
+
{ author },
|
|
810
|
+
{ initialNumItems: 10 },
|
|
811
|
+
);
|
|
812
|
+
|
|
813
|
+
// `notes.results` holds the pages decoded through `item`.
|
|
814
|
+
if (PaginatedQueryResult.isCanLoadMore(notes)) {
|
|
815
|
+
notes.loadMore(10);
|
|
816
|
+
}
|
|
817
|
+
```
|
|
818
|
+
|
|
819
|
+
The hook returns a `PaginatedQueryResult<Item, E>`. `LoadingFirstPage`, `LoadingMore`, `CanLoadMore`, and `Exhausted` all carry `results` and `isLoading`; `loadMore` lives only on `CanLoadMore`, the one state it can make progress from. A declared `error` schema surfaces as a `Failure` variant carrying the decoded error instead of throwing during render, and `Failure` carries `results` too, so the pages loaded before it can still be rendered. Without an `error` schema, `Failure` is absent from the type entirely.
|
|
820
|
+
|
|
821
|
+
`paginate` in `@confect/server` now accepts Convex's full `PaginationOptions`, so a handler's `paginationOpts` passes straight through. `@confect/react` now requires `convex` >= 1.36.0.
|
|
822
|
+
|
|
823
|
+
## 9.2.5
|
|
824
|
+
|
|
825
|
+
## 9.2.4
|
|
826
|
+
|
|
827
|
+
## 9.2.3
|
|
828
|
+
|
|
829
|
+
### Patch Changes
|
|
830
|
+
|
|
831
|
+
- @confect/core@9.2.3
|
|
832
|
+
|
|
833
|
+
## 9.2.2
|
|
834
|
+
|
|
835
|
+
### Patch Changes
|
|
836
|
+
|
|
837
|
+
- @confect/core@9.2.2
|
|
838
|
+
|
|
839
|
+
## 9.2.1
|
|
840
|
+
|
|
841
|
+
### Patch Changes
|
|
842
|
+
|
|
843
|
+
- @confect/core@9.2.1
|
|
844
|
+
|
|
845
|
+
## 9.2.0
|
|
846
|
+
|
|
847
|
+
### Patch Changes
|
|
848
|
+
|
|
849
|
+
- @confect/core@9.2.0
|
|
850
|
+
|
|
851
|
+
## 9.1.5
|
|
852
|
+
|
|
853
|
+
### Patch Changes
|
|
854
|
+
|
|
855
|
+
- @confect/core@9.1.5
|
|
856
|
+
|
|
857
|
+
## 9.1.4
|
|
858
|
+
|
|
859
|
+
### Patch Changes
|
|
860
|
+
|
|
861
|
+
- @confect/core@9.1.4
|
|
862
|
+
|
|
863
|
+
## 9.1.3
|
|
864
|
+
|
|
865
|
+
### Patch Changes
|
|
866
|
+
|
|
867
|
+
- Updated dependencies [8d63382]
|
|
868
|
+
- @confect/core@9.1.3
|
|
869
|
+
|
|
870
|
+
## 9.1.2
|
|
871
|
+
|
|
872
|
+
### Patch Changes
|
|
873
|
+
|
|
874
|
+
- @confect/core@9.1.2
|
|
875
|
+
|
|
876
|
+
## 9.1.1
|
|
877
|
+
|
|
878
|
+
### Patch Changes
|
|
879
|
+
|
|
880
|
+
- @confect/core@9.1.1
|
|
881
|
+
|
|
882
|
+
## 9.1.0
|
|
883
|
+
|
|
884
|
+
### Minor Changes
|
|
885
|
+
|
|
886
|
+
- 4d8a568: Add `withOptimisticUpdate` to `@confect/react`'s `useMutation`, mirroring Convex's API. The mutation handle returned by `useMutation` is now both callable and exposes `.withOptimisticUpdate(fn)` for attaching an optimistic update. Inside the callback, the `OptimisticLocalStore`'s `getQuery`/`setQuery`/`getAllQueries` accept Confect query `Ref`s and operate on decoded (Effect Schema) values wrapped in `Option`; the wrapper handles encoding/decoding against Convex's local store.
|
|
887
|
+
|
|
888
|
+
### Patch Changes
|
|
889
|
+
|
|
890
|
+
- Updated dependencies [4d8a568]
|
|
891
|
+
- @confect/core@9.1.0
|
|
892
|
+
|
|
893
|
+
## 9.0.2
|
|
894
|
+
|
|
895
|
+
### Patch Changes
|
|
896
|
+
|
|
897
|
+
- @confect/core@9.0.2
|
|
898
|
+
|
|
899
|
+
## 9.0.1
|
|
900
|
+
|
|
901
|
+
### Patch Changes
|
|
902
|
+
|
|
903
|
+
- 445ea9b: Loosen and align dependency ranges across all packages:
|
|
904
|
+
- The `convex` peer dependency is now `^1.32.0` in every package (previously pinned exactly to `1.39.1`, or `^1.30.0` in `@confect/react`). The range is validated against convex 1.32.0 through 1.40.0.
|
|
905
|
+
- `@confect/server`'s `@effect/platform-node` peer dependency is now optional—it is only needed when using the `@confect/server/node` entrypoint.
|
|
906
|
+
- `@confect/cli` now uses caret ranges for its `@effect/platform` and `@effect/platform-node` dependencies so they can deduplicate with the versions resolved for `@confect/server`, and no longer declares an unused direct dependency on `@effect/platform-node-shared`.
|
|
907
|
+
- `@confect/test` now accepts any `convex-test` release in `>=0.0.50 <0.1.0` instead of exactly 0.0.50.
|
|
908
|
+
|
|
909
|
+
- Updated dependencies [445ea9b]
|
|
910
|
+
- @confect/core@9.0.1
|
|
911
|
+
|
|
912
|
+
## 9.0.0
|
|
913
|
+
|
|
914
|
+
### Major Changes
|
|
915
|
+
|
|
916
|
+
- a905072: Rearchitect Confect so that cold-starting a Convex function only evaluates its own group's module graph, cutting cold-start execution time on large projects. The change touches how you author tables, specs, and impls, and removes the project-wide aggregation that used to make every function evaluate every other function's code—and every table's schema—the first time it ran.
|
|
917
|
+
|
|
918
|
+
Convex bundles a deployment into a single artifact, but a function's cold start only _evaluates_ the module graph reachable from its own entry point. Previously, all impls were assembled into a single root `confect/impl.ts` that every generated `convex/` module imported, so cold-starting any one query, mutation, or action transitively evaluated the impl of every other function in the project, plus every function spec and every table schema, at module-load time. Cold-start execution time scaled with the size of the whole project. In v9, `confect codegen` emits one registry per group and each generated `convex/` module imports only its own group—so a function's cold-start work scales with its own group, not the project.
|
|
919
|
+
|
|
920
|
+
### Filesystem-driven groups
|
|
921
|
+
|
|
922
|
+
Your API is now authored as colocated `*.spec.ts`/`*.impl.ts` pairs, one pair per group, and **the file's path within `confect/` is the group's name** (its stem for top-level groups, the dot-joined directory path for nested groups). `GroupSpec.make()` and `GroupSpec.makeNode()` no longer take a name argument.
|
|
923
|
+
- Each `*.spec.ts` `export default`s its `GroupSpec` (named co-exports like error classes are still allowed).
|
|
924
|
+
- Each `*.impl.ts` default-imports its sibling spec, passes it to `FunctionImpl.make`/`GroupImpl.make`, and ends the layer pipeline with `GroupImpl.finalize`—a compile-time completeness check that only typechecks once every function the spec declares has a `FunctionImpl` provided.
|
|
925
|
+
- The root `confect/spec.ts`, `confect/impl.ts`, `confect/nodeSpec.ts`, and `confect/nodeImpl.ts` files are gone, along with `Impl.make` and `Impl.finalize`. `confect codegen` deletes any of these (and the stale aggregate `_generated/registeredFunctions.ts`/`_generated/nodeRegisteredFunctions.ts`) on upgrade.
|
|
926
|
+
|
|
927
|
+
### Tables are the source of truth, named by their filename
|
|
928
|
+
|
|
929
|
+
Your schema now lives entirely in `confect/tables/`, one `Table` per file, and **the filename is the table name**—`confect/tables/notes.ts` defines the `notes` table. `Table.make` no longer takes a name argument. The user-authored `confect/schema.ts` is removed; codegen scans `confect/tables/*.ts` and generates everything else.
|
|
930
|
+
|
|
931
|
+
Each table file is a default-export-only module, and its field schema is wrapped in a `() =>` callback so it is built lazily—a function only pays a table's schema-construction cost at cold start for tables it actually reads.
|
|
932
|
+
|
|
933
|
+
```ts confect/tables/notes.ts
|
|
934
|
+
import { Table } from "@confect/server";
|
|
935
|
+
import { Schema } from "effect";
|
|
936
|
+
import { Id } from "../_generated/id";
|
|
937
|
+
|
|
938
|
+
export default Table.make(() =>
|
|
939
|
+
Schema.Struct({
|
|
940
|
+
userId: Schema.optional(Id("users")),
|
|
941
|
+
text: Schema.String,
|
|
942
|
+
}),
|
|
943
|
+
);
|
|
944
|
+
```
|
|
945
|
+
|
|
946
|
+
Codegen emits, alongside it:
|
|
947
|
+
- `_generated/schema.ts`—the runtime `DatabaseSchema`. Never imports `convex/server`, so a runtime cold start no longer evaluates `defineSchema(...)`.
|
|
948
|
+
- `_generated/convexSchema.ts`—the Convex deploy `SchemaDefinition`, re-exported from `convex/schema.ts`.
|
|
949
|
+
- `_generated/id.ts`—a type-safe `Id` constructor whose argument is constrained to your table names. Use `Id("notes")` everywhere you previously wrote `GenericId.GenericId("notes")`; cross-table `_id` typos are now caught at compile time.
|
|
950
|
+
- `_generated/tables/<name>.ts`—a thin wrapper that binds the filename to the table. Read a table's `Doc`, `Fields`, and `tableName` from this wrapper (`import notes from "../_generated/tables/notes"`), not from `confect/tables/`.
|
|
951
|
+
|
|
952
|
+
A bound table's `name` property is renamed to `tableName` (avoiding a collision with `Function.prototype.name`).
|
|
953
|
+
|
|
954
|
+
### Specs and impls: lazy schemas, and impls take the `DatabaseSchema`
|
|
955
|
+
|
|
956
|
+
`FunctionSpec.*` constructors now take `args`, `returns`, and the optional `error` as `() => Schema` thunks, so importing a spec builds no schemas until a function is invoked. `FunctionImpl.make` and `GroupImpl.make` take the runtime `DatabaseSchema` (the default export of `_generated/schema`) as their first argument instead of the whole `Api`—which keeps the project-wide spec graph out of a function's cold-start module graph. The `Api` module (`Api.make`, the `Api` type) and the generated `_generated/api.ts`/`_generated/nodeApi.ts` files are removed.
|
|
957
|
+
|
|
958
|
+
**Before:**
|
|
959
|
+
|
|
960
|
+
```ts confect/notes.spec.ts
|
|
961
|
+
export const notes = GroupSpec.make("notes").addFunction(
|
|
962
|
+
FunctionSpec.publicQuery({
|
|
963
|
+
name: "list",
|
|
964
|
+
args: Schema.Struct({}),
|
|
965
|
+
returns: Schema.Array(Notes.Doc),
|
|
966
|
+
}),
|
|
967
|
+
);
|
|
968
|
+
```
|
|
969
|
+
|
|
970
|
+
```ts confect/notes.impl.ts
|
|
971
|
+
const list = FunctionImpl.make(api, "notes", "list", handler);
|
|
972
|
+
export const notes = GroupImpl.make(api, "notes").pipe(Layer.provide(list));
|
|
973
|
+
```
|
|
974
|
+
|
|
975
|
+
**After:**
|
|
976
|
+
|
|
977
|
+
```ts confect/notes.spec.ts
|
|
978
|
+
import notes from "./_generated/tables/notes";
|
|
979
|
+
|
|
980
|
+
export default GroupSpec.make().addFunction(
|
|
981
|
+
FunctionSpec.publicQuery({
|
|
982
|
+
name: "list",
|
|
983
|
+
args: () => Schema.Struct({}),
|
|
984
|
+
returns: () => Schema.Array(notes.Doc),
|
|
985
|
+
}),
|
|
986
|
+
);
|
|
987
|
+
```
|
|
988
|
+
|
|
989
|
+
```ts confect/notes.impl.ts
|
|
990
|
+
import databaseSchema from "./_generated/schema";
|
|
991
|
+
import notes from "./notes.spec";
|
|
992
|
+
|
|
993
|
+
const list = FunctionImpl.make(databaseSchema, notes, "list", handler);
|
|
994
|
+
export default GroupImpl.make(databaseSchema, notes).pipe(
|
|
995
|
+
Layer.provide(list),
|
|
996
|
+
GroupImpl.finalize,
|
|
997
|
+
);
|
|
998
|
+
```
|
|
999
|
+
|
|
1000
|
+
### Node functions are first-class
|
|
1001
|
+
|
|
1002
|
+
A group's runtime is now declared solely by its spec—`GroupSpec.makeNode()` for a Node action group, `GroupSpec.make()` otherwise—mirroring vanilla Convex's per-file `"use node"` directive. The separate `node` namespace is gone: Node specs/impls are ordinary colocated pairs that can live anywhere in `confect/`, and codegen emits the `"use node"` directive based on the spec.
|
|
1003
|
+
- A Node group at `confect/email.spec.ts` is now reached at `refs.public.email.send` instead of `refs.public.node.email.send`.
|
|
1004
|
+
- `@confect/core` removes `Spec.makeNode`, `Spec.merge`, and `Spec.isConvexSpec`/`Spec.isNodeSpec`; `Spec.make()` is a single mixed-runtime container and `Refs.make(spec)` takes one argument. `GroupSpec.makeNode()`, `FunctionSpec.publicNodeAction()`/`internalNodeAction()` are unchanged.
|
|
1005
|
+
|
|
1006
|
+
### Less work at cold start
|
|
1007
|
+
|
|
1008
|
+
Confect's own packages now import Effect from its submodule paths (`import * as Schema from "effect/Schema"`) instead of the `"effect"` barrel. A barrel import of a namespace re-export pulls the entire namespace into the module graph a function evaluates at cold start, even when only a small part is used; importing the submodule path evaluates only what's needed. On a minimal function this cut cold-start module-evaluation time by ~35%. This is an internal change with no effect on your code—but to get the full win, import Effect from its submodule paths in your own `confect/` files too, since a single barrel import anywhere in a function's module graph re-pins the whole namespace.
|
|
1009
|
+
|
|
1010
|
+
### Stable React hook results
|
|
1011
|
+
|
|
1012
|
+
`@confect/react` hooks now hold stable identities across renders, matching Convex's own hooks. `useQuery` memoizes the decoded `QueryResult` by the (referentially stable) Convex result, so unchanged data keeps the same `QueryResult` instead of a fresh one each render—fixing effect/memo loops (including `Maximum update depth exceeded`) for code that derives off the result. `useMutation` and `useAction` return a stable `useCallback`, and `Ref.getFunctionReference` caches the Convex function reference per function name.
|
|
1013
|
+
|
|
1014
|
+
### Codegen robustness
|
|
1015
|
+
|
|
1016
|
+
The codegen bundler now uses [`bundle-require`](https://github.com/egoist/bundle-require), so impls may import third-party packages and use `tsconfig.json` `paths` aliases (`~/*`, `@/*`, …) for their own source. A parent `confect/{path}.spec.ts` may now declare functions alongside a sibling `confect/{path}/` subdirectory of further specs, and codegen reports a clear error on a name collision between the two.
|
|
1017
|
+
|
|
1018
|
+
### Migration
|
|
1019
|
+
1. **Tables.** Delete `confect/schema.ts`. Rename each table file to a valid JS identifier (e.g. `confect/tables/notes.ts`); the basename becomes the table name. Drop the name argument from `Table.make`, wrap the field struct in `() =>`, and replace `GenericId.GenericId("x")` with `Id("x")` from `_generated/id`. If you read `table.name` off a bound table, rename it to `table.tableName`.
|
|
1020
|
+
2. **Specs.** Split each group into a colocated `*.spec.ts` that `export default`s `GroupSpec.make()` (no name). Wrap every `args`/`returns`/`error` in `() =>`. Import a table's `Doc`/`Fields` from its wrapper, `import notes from "./_generated/tables/notes"`.
|
|
1021
|
+
3. **Impls.** In each `*.impl.ts`, default-import the sibling spec, import `databaseSchema` from `_generated/schema`, pass it to `FunctionImpl.make`/`GroupImpl.make` in place of `api`, end the pipeline with `GroupImpl.finalize`, and `export default` it. Delete the root `confect/spec.ts`, `impl.ts`, `nodeSpec.ts`, and `nodeImpl.ts` (codegen will also remove them).
|
|
1022
|
+
4. **Node groups.** Move any `confect/node/<path>` files anywhere you like under `confect/`; the `node/` directory no longer has special meaning. Drop the `node` segment from call sites (`refs.public.node.<group>` → `refs.public.<group>`) and replace `Refs.make(spec, nodeSpec)` with `Refs.make(spec)`.
|
|
1023
|
+
5. **Tests.** If you use `@confect/test`, import `confectSchema` from `_generated/schema`, import the generated `convexSchema` from `_generated/convexSchema`, and pass `convexSchema` as the new second argument to `TestConfect.layer`.
|
|
1024
|
+
6. **Optional.** Adopt submodule Effect imports (`import * as Schema from "effect/Schema"`) in your own `confect/` files for the full cold-start savings.
|
|
1025
|
+
7. Run `confect codegen`. It re-emits the entire `convex/` tree and `confect/_generated/`, deleting any stale files from earlier versions.
|
|
1026
|
+
|
|
1027
|
+
### Patch Changes
|
|
1028
|
+
|
|
1029
|
+
- 9eec71c: Generate the published `.d.ts` declarations with the TypeScript compiler instead of tsdown's declaration bundler. tsdown now emits JavaScript only (`dts: false`); each package has a composite `tsconfig.src.json`, and `tsc -b` emits the declarations into `dist/` as part of the build. (`@confect/cli` is the exception: it ships only a binary, so it emits no declarations at all.)
|
|
1030
|
+
|
|
1031
|
+
The emitted types are equivalent to before—same exported surface, same inferred shapes—so no consumer-facing type changes. One incidental improvement comes with the switch: declaration maps (`.d.ts.map`) now ship alongside the types (with `src/` included in the published files, so "go to definition" lands on the original source).
|
|
1032
|
+
|
|
1033
|
+
- Updated dependencies [9eec71c]
|
|
1034
|
+
- Updated dependencies [a905072]
|
|
1035
|
+
- @confect/core@9.0.0
|
|
1036
|
+
|
|
1037
|
+
## 9.0.0-next.10
|
|
1038
|
+
|
|
1039
|
+
### Patch Changes
|
|
1040
|
+
|
|
1041
|
+
- 9eec71c: Generate the published `.d.ts` declarations with the TypeScript compiler instead of tsdown's declaration bundler. tsdown now emits JavaScript only (`dts: false`); each package has a composite `tsconfig.src.json`, and `tsc -b` emits the declarations into `dist/` as part of the build. (`@confect/cli` is the exception: it ships only a binary, so it emits no declarations at all.)
|
|
1042
|
+
|
|
1043
|
+
The emitted types are equivalent to before—same exported surface, same inferred shapes—so no consumer-facing type changes. One incidental improvement comes with the switch: declaration maps (`.d.ts.map`) now ship alongside the types (with `src/` included in the published files, so "go to definition" lands on the original source).
|
|
1044
|
+
|
|
1045
|
+
- Updated dependencies [9eec71c]
|
|
1046
|
+
- @confect/core@9.0.0-next.10
|
|
1047
|
+
|
|
1048
|
+
## 9.0.0-next.9
|
|
1049
|
+
|
|
1050
|
+
### Patch Changes
|
|
1051
|
+
|
|
1052
|
+
- Updated dependencies [4894959]
|
|
1053
|
+
- @confect/core@9.0.0-next.9
|
|
1054
|
+
|
|
1055
|
+
## 9.0.0-next.8
|
|
1056
|
+
|
|
1057
|
+
### Patch Changes
|
|
1058
|
+
|
|
1059
|
+
- 3fec285: Import Effect from its submodule paths internally to shrink per-function cold-start bundles.
|
|
1060
|
+
|
|
1061
|
+
Confect's packages now import Effect modules from their submodule paths (`import * as Schema from "effect/Schema"`) instead of the `"effect"` barrel (`import { Schema } from "effect"`).
|
|
1062
|
+
|
|
1063
|
+
### Why
|
|
1064
|
+
|
|
1065
|
+
A barrel import of a namespace re-export defeats esbuild's tree-shaking: accessing `Schema.X` from `import { Schema } from "effect"` retains the _entire_ `Schema` namespace, because the bundler can't prune property access on the barrel's `export * as Schema`. So every Convex function's cold-start bundle was pulling all of `effect/Schema` and `effect/Stream`—and, transitively through Schema's `Arbitrary`, `fast-check`—whether the function used them or not.
|
|
1066
|
+
|
|
1067
|
+
Importing from the submodule path tree-shakes normally. On a minimal function this cut the bundle esbuild produces by ~54% (the `effect/Schema` module alone by ~75%) and its cold-start module-evaluation time by ~35%, with `fast-check` dropped entirely. This is also the import style Effect v4 recommends, so it's forward-compatible. A `no-restricted-imports` ESLint rule now enforces it across the codebase (type-only imports and `@effect/vitest` are exempt).
|
|
1068
|
+
|
|
1069
|
+
No API changes—your existing code keeps working.
|
|
1070
|
+
|
|
1071
|
+
### Getting the full win in your own code
|
|
1072
|
+
|
|
1073
|
+
This change shrinks the Confect code in every function bundle, but a function's bundle also includes your own `confect/tables/*` and `*.spec.ts` files. esbuild retains the union across all importers, so a single barrel import anywhere in a function's module graph re-pins the whole `effect/Schema` namespace and undoes the reduction. To get the full bundle/cold-start savings, import Effect from its submodule paths in your own Confect files too:
|
|
1074
|
+
|
|
1075
|
+
```diff
|
|
1076
|
+
- import { Schema } from "effect";
|
|
1077
|
+
+ import * as Schema from "effect/Schema";
|
|
1078
|
+
```
|
|
1079
|
+
|
|
1080
|
+
Bare helpers (`pipe`, `flow`, `identity`) come from `"effect/Function"`.
|
|
1081
|
+
|
|
1082
|
+
- Updated dependencies [3fec285]
|
|
1083
|
+
- @confect/core@9.0.0-next.8
|
|
1084
|
+
|
|
1085
|
+
## 9.0.0-next.7
|
|
1086
|
+
|
|
1087
|
+
### Patch Changes
|
|
1088
|
+
|
|
1089
|
+
- 5d19484: Stabilize the identity of `@confect/react` hook results across renders.
|
|
1090
|
+
|
|
1091
|
+
`useQuery` previously decoded and wrapped the Convex result on every render, handing consumers a brand new `QueryResult` even when the underlying Convex data was unchanged. Effects and memoization that depend on the result's identity (e.g. `useEffect(..., [user])` derived via `QueryResult.match`) would re-run on every render, which could escalate into `Maximum update depth exceeded`. The decoded `QueryResult` is now memoized by the (referentially stable) Convex result, so unchanged data keeps a stable identity.
|
|
1092
|
+
|
|
1093
|
+
`useMutation` and `useAction` now return a stable callback via `useCallback`, matching the identity contract of Convex's own hooks, instead of allocating a fresh function each render.
|
|
1094
|
+
|
|
1095
|
+
`Ref.getFunctionReference` now caches the Convex function reference by function name, so repeated calls for the same ref return the same reference.
|
|
1096
|
+
|
|
1097
|
+
- Updated dependencies [5d19484]
|
|
1098
|
+
- @confect/core@9.0.0-next.7
|
|
1099
|
+
|
|
1100
|
+
## 9.0.0-next.6
|
|
1101
|
+
|
|
1102
|
+
### Patch Changes
|
|
1103
|
+
|
|
1104
|
+
- Updated dependencies [46045a9]
|
|
1105
|
+
- Updated dependencies [762f7eb]
|
|
1106
|
+
- @confect/core@9.0.0-next.6
|
|
1107
|
+
|
|
1108
|
+
## 9.0.0-next.5
|
|
1109
|
+
|
|
1110
|
+
### Patch Changes
|
|
1111
|
+
|
|
1112
|
+
- @confect/core@9.0.0-next.5
|
|
1113
|
+
|
|
1114
|
+
## 9.0.0-next.4
|
|
1115
|
+
|
|
1116
|
+
### Patch Changes
|
|
1117
|
+
|
|
1118
|
+
- @confect/core@9.0.0-next.4
|
|
1119
|
+
|
|
1120
|
+
## 9.0.0-next.3
|
|
1121
|
+
|
|
1122
|
+
### Patch Changes
|
|
1123
|
+
|
|
1124
|
+
- Updated dependencies [6d85210]
|
|
1125
|
+
- @confect/core@9.0.0-next.3
|
|
1126
|
+
|
|
1127
|
+
## 9.0.0-next.2
|
|
1128
|
+
|
|
1129
|
+
### Patch Changes
|
|
1130
|
+
|
|
1131
|
+
- @confect/core@9.0.0-next.2
|
|
1132
|
+
|
|
1133
|
+
## 9.0.0-next.1
|
|
1134
|
+
|
|
1135
|
+
### Patch Changes
|
|
1136
|
+
|
|
1137
|
+
- @confect/core@9.0.0-next.1
|
|
1138
|
+
|
|
1139
|
+
## 9.0.0-next.0
|
|
1140
|
+
|
|
1141
|
+
### Patch Changes
|
|
1142
|
+
|
|
1143
|
+
- Updated dependencies [6db3a3a]
|
|
1144
|
+
- @confect/core@9.0.0-next.0
|
|
1145
|
+
|
|
1146
|
+
## 8.0.0
|
|
1147
|
+
|
|
1148
|
+
### Minor Changes
|
|
1149
|
+
|
|
1150
|
+
- 4bb2722: Bump Effect ecosystem to latest. `@effect/platform` is now `^0.96.1` and `@effect/platform-node` is now `^0.106.0` in `@confect/server`'s peer dependencies; `effect` peer is now `^3.21.2` across packages. Consumers must upgrade `@effect/platform`, `@effect/platform-node`, and `effect` in lockstep when bumping `@confect/server`.
|
|
1151
|
+
|
|
1152
|
+
### Patch Changes
|
|
1153
|
+
|
|
1154
|
+
- 40c1cff: Switch sibling `@confect/*` peer-dependency specifiers from `workspace:*` to `workspace:^`. Published peer ranges are now caret-based (e.g. `^7.0.0`) instead of exact-pinned, so non-major upgrades of one `@confect/*` package no longer fall out of range for its peer dependents.
|
|
1155
|
+
|
|
1156
|
+
Paired with the Changesets `onlyUpdatePeerDependentsWhenOutOfRange` flag, this prevents the entire `@confect/*` family from being promoted to a major bump on every release when only minor/patch changes are present.
|
|
1157
|
+
|
|
1158
|
+
`@confect/cli` additionally moves `@effect/platform` from `peerDependencies` to `dependencies`, since the CLI consumes it as an internal implementation detail (for `FileSystem`/`Path`) rather than exposing it in its public API. Consumers no longer need to install `@effect/platform` themselves to use the CLI.
|
|
1159
|
+
|
|
1160
|
+
- Updated dependencies [4bb2722]
|
|
1161
|
+
- Updated dependencies [40c1cff]
|
|
1162
|
+
- @confect/core@8.0.0
|
|
1163
|
+
|
|
1164
|
+
## 7.0.0
|
|
1165
|
+
|
|
1166
|
+
### Major Changes
|
|
1167
|
+
|
|
1168
|
+
- 90094d0: Add typed errors to Confect functions (queries, mutations, and actions). Declare an optional `error` schema in `FunctionSpec` and recover it as a typed value at every call site—`useQuery`, `useMutation`, `useAction`, `HttpClient`, `WebSocketClient`, and `TestConfect`—without paying for it on functions that don't fail.
|
|
1169
|
+
|
|
1170
|
+
Typed errors travel across the function boundary as Convex's native [`ConvexError`](https://docs.convex.dev/functions/error-handling/application-errors#throwing-application-errors): the encoded error sits in `ConvexError.data`, leaving the `returns` channel unsullied and preserving native Convex semantics for non-Confect callers of the same API.
|
|
1171
|
+
|
|
1172
|
+
### Authoring a function with typed errors
|
|
1173
|
+
|
|
1174
|
+
`FunctionSpec` constructors now accept an optional `error` schema. To support multiple error shapes, combine them with `Schema.Union`.
|
|
1175
|
+
|
|
1176
|
+
```ts
|
|
1177
|
+
import { FunctionSpec, GenericId, GroupSpec } from "@confect/core";
|
|
1178
|
+
import { Schema } from "effect";
|
|
1179
|
+
|
|
1180
|
+
export class NoteNotFound extends Schema.TaggedError<NoteNotFound>()(
|
|
1181
|
+
"NoteNotFound",
|
|
1182
|
+
{ noteId: GenericId.GenericId("notes") },
|
|
1183
|
+
) {}
|
|
1184
|
+
|
|
1185
|
+
export const notes = GroupSpec.make("notes").addFunction(
|
|
1186
|
+
FunctionSpec.publicQuery({
|
|
1187
|
+
name: "getOrFail",
|
|
1188
|
+
args: Schema.Struct({ noteId: GenericId.GenericId("notes") }),
|
|
1189
|
+
returns: Notes.Doc,
|
|
1190
|
+
error: NoteNotFound,
|
|
1191
|
+
}),
|
|
1192
|
+
);
|
|
1193
|
+
```
|
|
1194
|
+
|
|
1195
|
+
The `FunctionImpl` for that ref can now `Effect.fail` (or `mapError` to) any value matching the declared schema. Whichever invocation path the caller takes—`useQuery`/`useMutation`/`useAction`, `HttpClient`, `WebSocketClient`, or `TestConfect`—Confect encodes the failure, transports it via `ConvexError`, and surfaces the decoded value in the appropriate channel for that call site.
|
|
1196
|
+
|
|
1197
|
+
```ts
|
|
1198
|
+
import { FunctionImpl } from "@confect/server";
|
|
1199
|
+
import { Effect } from "effect";
|
|
1200
|
+
import api from "../_generated/api";
|
|
1201
|
+
import { DatabaseReader } from "../_generated/services";
|
|
1202
|
+
import { NoteNotFound } from "./notes.spec";
|
|
1203
|
+
|
|
1204
|
+
const getOrFail = FunctionImpl.make(api, "notes", "getOrFail", ({ noteId }) =>
|
|
1205
|
+
Effect.gen(function* () {
|
|
1206
|
+
const reader = yield* DatabaseReader;
|
|
1207
|
+
return yield* reader
|
|
1208
|
+
.table("notes")
|
|
1209
|
+
.get(noteId)
|
|
1210
|
+
.pipe(Effect.mapError(() => new NoteNotFound({ noteId })));
|
|
1211
|
+
}),
|
|
1212
|
+
);
|
|
1213
|
+
```
|
|
1214
|
+
|
|
1215
|
+
### Consuming a typed error
|
|
1216
|
+
|
|
1217
|
+
`@confect/js` (`HttpClient`, `WebSocketClient`) and `@confect/test` (`TestConfect`) surface the decoded error in the `Effect` error channel alongside the existing `HttpClientError`/`WebSocketClientError`/`ParseError`:
|
|
1218
|
+
|
|
1219
|
+
```ts
|
|
1220
|
+
HttpClient.query(refs.public.notes.getOrFail, { noteId });
|
|
1221
|
+
// Effect.Effect<Note, NoteNotFound | HttpClientError | ParseError>
|
|
1222
|
+
```
|
|
1223
|
+
|
|
1224
|
+
### `@confect/react`—breaking changes
|
|
1225
|
+
|
|
1226
|
+
`useQuery`, `useMutation`, and `useAction` now expose typed errors, and `useQuery` returns a tagged result type instead of `Returns | undefined`.
|
|
1227
|
+
|
|
1228
|
+
**`useQuery` now returns `QueryResult<A, E>`.** Loading and (when an `error` schema is declared) failure are reified as variants alongside success. Match on the result with `QueryResult.match`:
|
|
1229
|
+
|
|
1230
|
+
Before:
|
|
1231
|
+
|
|
1232
|
+
```tsx
|
|
1233
|
+
const notes = useQuery(refs.public.notes.list, {});
|
|
1234
|
+
if (notes === undefined) return <p>Loading…</p>;
|
|
1235
|
+
return <NoteList notes={notes} />;
|
|
1236
|
+
```
|
|
1237
|
+
|
|
1238
|
+
After:
|
|
1239
|
+
|
|
1240
|
+
```tsx
|
|
1241
|
+
import { QueryResult, useQuery } from "@confect/react";
|
|
1242
|
+
|
|
1243
|
+
const notes = useQuery(refs.public.notes.list, {});
|
|
1244
|
+
return QueryResult.match(notes, {
|
|
1245
|
+
onLoading: (skipped) => (skipped ? null : <p>Loading…</p>),
|
|
1246
|
+
onSuccess: (notes) => <NoteList notes={notes} />,
|
|
1247
|
+
});
|
|
1248
|
+
```
|
|
1249
|
+
|
|
1250
|
+
The `Loading` variant carries a `skipped: boolean` flag, exposed as the argument to `onLoading`. It distinguishes a query that is genuinely in flight (`skipped: false`) from one that is sitting idle because `"skip"` was passed as its args (`skipped: true`)—a distinction `convex/react`'s plain `undefined` return value cannot make. Use it to render a loading indicator only when work is actually happening, and an empty/placeholder state otherwise.
|
|
1251
|
+
|
|
1252
|
+
When the ref declares an `error` schema, `onFailure` becomes required and receives the decoded typed error:
|
|
1253
|
+
|
|
1254
|
+
```tsx
|
|
1255
|
+
const lookup = useQuery(refs.public.notes.getOrFail, { noteId });
|
|
1256
|
+
QueryResult.match(lookup, {
|
|
1257
|
+
onLoading: (skipped) => (skipped ? null : "Looking up…"),
|
|
1258
|
+
onSuccess: (note) => `Found: ${note.text}`,
|
|
1259
|
+
onFailure: (error) => `Note ${error.noteId} not found.`,
|
|
1260
|
+
});
|
|
1261
|
+
```
|
|
1262
|
+
|
|
1263
|
+
`QueryResult` is a Confect-native type exported from `@confect/react`.
|
|
1264
|
+
|
|
1265
|
+
**`useMutation` and `useAction` return `Promise<Either<A, E>>` when the ref declares an `error` schema.** Refs without an `error` schema continue to resolve to `Promise<A>`, matching the prior shape and `convex/react`'s behavior.
|
|
1266
|
+
|
|
1267
|
+
```ts
|
|
1268
|
+
const deleteOrFail = useMutation(refs.public.notes.deleteOrFail);
|
|
1269
|
+
const result = await deleteOrFail({ noteId });
|
|
1270
|
+
// Either.Either<null, NoteNotFound | Forbidden>
|
|
1271
|
+
Either.match(result, {
|
|
1272
|
+
onLeft: (error) => /* typed error */,
|
|
1273
|
+
onRight: (value) => /* success */,
|
|
1274
|
+
});
|
|
1275
|
+
|
|
1276
|
+
const deleteNote = useMutation(refs.public.notes.delete_); // no `error` schema
|
|
1277
|
+
await deleteNote({ noteId }); // Promise<null>, as before
|
|
1278
|
+
```
|
|
1279
|
+
|
|
1280
|
+
Unspecified failures continue to reject the promise.
|
|
1281
|
+
|
|
1282
|
+
### Migration
|
|
1283
|
+
- For each `useQuery` call site, replace `result === undefined` checks and direct property access with `QueryResult.match` (or the lower-level `QueryResult.isLoading`/`isSuccess`/`isFailure` predicates).
|
|
1284
|
+
- For each `useMutation`/`useAction` call site whose ref now declares an `error` schema, unwrap the resolved `Either` (e.g. with `Either.match`); call sites against refs without an `error` schema need no change.
|
|
1285
|
+
|
|
1286
|
+
### Patch Changes
|
|
1287
|
+
|
|
1288
|
+
- Updated dependencies [90094d0]
|
|
1289
|
+
- @confect/core@7.0.0
|
|
1290
|
+
|
|
1291
|
+
## 6.0.0
|
|
1292
|
+
|
|
1293
|
+
### Minor Changes
|
|
1294
|
+
|
|
1295
|
+
- df95ce7: Add `Ref.OptionalArgs` type utility to `@confect/core` for conditionally optional function args. `QueryRunner`, `MutationRunner`, and `ActionRunner` now accept optional args for no-arg Confect functions. `useQuery`, `useMutation`, and `useAction` now accept optional args for no-arg Confect functions. `TestConfect` `query`/`mutation`/`action` helpers now accept optional args for no-arg Confect functions.
|
|
1296
|
+
|
|
1297
|
+
### Patch Changes
|
|
1298
|
+
|
|
1299
|
+
- Updated dependencies [df95ce7]
|
|
1300
|
+
- Updated dependencies [a8083e8]
|
|
1301
|
+
- @confect/core@6.0.0
|
|
1302
|
+
|
|
1303
|
+
## 5.0.0
|
|
1304
|
+
|
|
1305
|
+
### Minor Changes
|
|
1306
|
+
|
|
1307
|
+
- 5ddb437: Support passing `"skip"` as args to `useQuery` to disable query subscription.
|
|
1308
|
+
|
|
1309
|
+
### Patch Changes
|
|
1310
|
+
|
|
1311
|
+
- @confect/core@5.0.0
|
|
1312
|
+
|
|
1313
|
+
## 4.0.0
|
|
1314
|
+
|
|
1315
|
+
### Patch Changes
|
|
1316
|
+
|
|
1317
|
+
- @confect/core@4.0.0
|
|
1318
|
+
|
|
1319
|
+
## 3.0.0
|
|
1320
|
+
|
|
1321
|
+
### Minor Changes
|
|
1322
|
+
|
|
1323
|
+
- 5fb6a61: Add support for plain Convex functions. Plain Convex queries, mutations, and actions can now be included in your Confect spec and impl tree using new `FunctionSpec.convexPublic*` and `FunctionSpec.convexInternal*` constructors. This enables interop with Convex components and libraries (such as Workpool, Workflow, Migrations, and Better Auth) that require user-defined or -provided Convex functions.
|
|
1324
|
+
|
|
1325
|
+
### Patch Changes
|
|
1326
|
+
|
|
1327
|
+
- Updated dependencies [5fb6a61]
|
|
1328
|
+
- @confect/core@3.0.0
|
|
1329
|
+
|
|
1330
|
+
## 2.0.0
|
|
1331
|
+
|
|
1332
|
+
### Major Changes
|
|
1333
|
+
|
|
1334
|
+
- 7861159: Replace Effect-native return types with Convex-equivalent return types in React hooks. `useQuery` now returns `T | undefined` instead of `Option<T>`. `useMutation` and `useAction` now return `(args) => Promise<T>` instead of `(args) => Effect<T>`. The hooks still encode args and decode return values via the spec's Effect Schemas automatically.
|
|
1335
|
+
|
|
1336
|
+
### Patch Changes
|
|
1337
|
+
|
|
1338
|
+
- @confect/core@2.0.0
|
|
1339
|
+
|
|
1340
|
+
## 1.0.3
|
|
1341
|
+
|
|
1342
|
+
### Patch Changes
|
|
1343
|
+
|
|
1344
|
+
- @confect/core@1.0.3
|
|
1345
|
+
|
|
1346
|
+
## 1.0.2
|
|
1347
|
+
|
|
1348
|
+
### Patch Changes
|
|
1349
|
+
|
|
1350
|
+
- @confect/core@1.0.2
|
|
1351
|
+
|
|
1352
|
+
## 1.0.1
|
|
1353
|
+
|
|
1354
|
+
### Patch Changes
|
|
1355
|
+
|
|
1356
|
+
- Updated dependencies [00b12a0]
|
|
1357
|
+
- @confect/core@1.0.1
|
|
1358
|
+
|
|
1359
|
+
## 1.0.0
|
|
1360
|
+
|
|
1361
|
+
### Major Changes
|
|
1362
|
+
|
|
1363
|
+
- 2ff70a7: Initial release.
|
|
1364
|
+
|
|
1365
|
+
## 1.0.0-next.4
|
|
1366
|
+
|
|
1367
|
+
### Patch Changes
|
|
1368
|
+
|
|
1369
|
+
- Updated dependencies [46109fb]
|
|
1370
|
+
- @confect/core@1.0.0-next.4
|
|
1371
|
+
|
|
1372
|
+
## 1.0.0-next.3
|
|
1373
|
+
|
|
1374
|
+
### Patch Changes
|
|
1375
|
+
|
|
1376
|
+
- Updated dependencies [9cd3cda]
|
|
1377
|
+
- Updated dependencies [186c130]
|
|
1378
|
+
- @confect/core@1.0.0-next.3
|
|
1379
|
+
|
|
1380
|
+
## 1.0.0-next.2
|
|
1381
|
+
|
|
1382
|
+
### Patch Changes
|
|
1383
|
+
|
|
1384
|
+
- 071b6ed: Upgrade deps
|
|
1385
|
+
- Updated dependencies [071b6ed]
|
|
1386
|
+
- @confect/core@1.0.0-next.2
|
|
1387
|
+
|
|
1388
|
+
## 1.0.0-next.1
|
|
1389
|
+
|
|
1390
|
+
### Patch Changes
|
|
1391
|
+
|
|
1392
|
+
- Updated dependencies [5a4127f]
|
|
1393
|
+
- @confect/core@1.0.0-next.1
|
|
1394
|
+
|
|
1395
|
+
## 1.0.0-next.0
|
|
1396
|
+
|
|
1397
|
+
### Major Changes
|
|
1398
|
+
|
|
1399
|
+
- 2ff70a7: Initial release.
|
|
1400
|
+
|
|
1401
|
+
### Patch Changes
|
|
1402
|
+
|
|
1403
|
+
- Updated dependencies [2ff70a7]
|
|
1404
|
+
- @confect/core@1.0.0-next.0
|