@confect/server 9.0.0-next.5 → 9.0.0-next.7
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 +163 -0
- package/dist/Auth.d.ts +1 -1
- package/dist/DatabaseReader.d.ts +4299 -26
- package/dist/DatabaseReader.d.ts.map +1 -1
- package/dist/DatabaseReader.js +5 -6
- package/dist/DatabaseReader.js.map +1 -1
- package/dist/DatabaseSchema.d.ts +25 -112
- package/dist/DatabaseSchema.d.ts.map +1 -1
- package/dist/DatabaseSchema.js +20 -30
- package/dist/DatabaseSchema.js.map +1 -1
- package/dist/DatabaseWriter.d.ts +4 -4
- package/dist/DatabaseWriter.d.ts.map +1 -1
- package/dist/DatabaseWriter.js +3 -4
- package/dist/DatabaseWriter.js.map +1 -1
- package/dist/FunctionImpl.d.ts +26 -17
- package/dist/FunctionImpl.d.ts.map +1 -1
- package/dist/FunctionImpl.js +22 -14
- package/dist/FunctionImpl.js.map +1 -1
- package/dist/GroupImpl.d.ts +22 -13
- package/dist/GroupImpl.d.ts.map +1 -1
- package/dist/GroupImpl.js +34 -35
- package/dist/GroupImpl.js.map +1 -1
- package/dist/Handler.d.ts +1 -1
- package/dist/QueryInitializer.d.ts.map +1 -1
- package/dist/QueryInitializer.js.map +1 -1
- package/dist/RegisteredConvexFunction.d.ts +1081 -14
- package/dist/RegisteredConvexFunction.d.ts.map +1 -1
- package/dist/RegisteredConvexFunction.js +4 -4
- package/dist/RegisteredConvexFunction.js.map +1 -1
- package/dist/RegisteredFunction.d.ts +3 -3
- package/dist/RegisteredFunction.d.ts.map +1 -1
- package/dist/RegisteredFunctions.d.ts +36 -12
- package/dist/RegisteredFunctions.d.ts.map +1 -1
- package/dist/RegisteredFunctions.js +21 -9
- package/dist/RegisteredFunctions.js.map +1 -1
- package/dist/RegisteredNodeFunction.d.ts +4 -4
- package/dist/RegisteredNodeFunction.d.ts.map +1 -1
- package/dist/RegisteredNodeFunction.js +2 -2
- package/dist/RegisteredNodeFunction.js.map +1 -1
- package/dist/Table.d.ts +39 -31
- package/dist/Table.d.ts.map +1 -1
- package/dist/Table.js +69 -60
- package/dist/Table.js.map +1 -1
- package/dist/index.d.ts +4 -5
- package/dist/index.js +4 -5
- package/package.json +51 -52
- package/src/DatabaseReader.ts +17 -21
- package/src/DatabaseSchema.ts +38 -98
- package/src/DatabaseWriter.ts +8 -5
- package/src/FunctionImpl.ts +33 -43
- package/src/GroupImpl.ts +45 -69
- package/src/QueryInitializer.ts +10 -2
- package/src/RegisteredConvexFunction.ts +5 -6
- package/src/RegisteredFunctions.ts +67 -93
- package/src/RegisteredNodeFunction.ts +3 -4
- package/src/Table.ts +251 -131
- package/src/index.ts +0 -1
- package/dist/Api.d.ts +0 -43
- package/dist/Api.d.ts.map +0 -1
- package/dist/Api.js +0 -43
- package/dist/Api.js.map +0 -1
- package/src/Api.ts +0 -102
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,168 @@
|
|
|
1
1
|
# @confect/server
|
|
2
2
|
|
|
3
|
+
## 9.0.0-next.7
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [5d19484]
|
|
8
|
+
- @confect/core@9.0.0-next.7
|
|
9
|
+
|
|
10
|
+
## 9.0.0-next.6
|
|
11
|
+
|
|
12
|
+
### Major Changes
|
|
13
|
+
|
|
14
|
+
- 46045a9: Reduce per-function cold-start cost: make `FunctionSpec` schemas lazy and keep each Convex function's bundle scoped to its own group.
|
|
15
|
+
|
|
16
|
+
Previously, loading a single Convex function still paid for the whole project — importing the codegen-assembled `_generated/spec.ts` ran `Schema.Struct(...)` / `Schema.Array(...)` for every function at module load, and each per-function bundle transitively imported `_generated/api.ts` → `_generated/spec.ts` (every spec). A function's cold-start cost now scales with its own group rather than the size of the project.
|
|
17
|
+
|
|
18
|
+
### Lazy `FunctionSpec` schemas
|
|
19
|
+
|
|
20
|
+
`FunctionSpec.*` (`publicQuery` / `internalQuery` / `publicMutation` / `internalMutation` / `publicAction` / `internalAction` / `publicNodeAction` / `internalNodeAction`) takes `args`, `returns`, and (optional) `error` as `() => Schema` thunks instead of bare schemas. The resulting provenance exposes them as sync lazy memoised getters (the same pattern `Table.make` uses), so importing `_generated/spec.ts` builds no schemas — construction is deferred to the first invocation that compiles validators or runs a codec.
|
|
21
|
+
|
|
22
|
+
Migration — wrap each schema in `() =>`:
|
|
23
|
+
|
|
24
|
+
```diff
|
|
25
|
+
FunctionSpec.publicQuery({
|
|
26
|
+
name: "list",
|
|
27
|
+
- args: Schema.Struct({}),
|
|
28
|
+
- returns: Schema.Array(notes.Doc),
|
|
29
|
+
+ args: () => Schema.Struct({}),
|
|
30
|
+
+ returns: () => Schema.Array(notes.Doc),
|
|
31
|
+
})
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Impls take the `DatabaseSchema`, and group paths resolve impl-side
|
|
35
|
+
|
|
36
|
+
`FunctionImpl.make` and `GroupImpl.make` now take the runtime `DatabaseSchema` (the default export of `_generated/schema.ts`) as their first argument instead of the whole `Api`. The handler's ctx-service types only ever depended on the database schema, and switching impls to import `_generated/schema` instead of `_generated/api` removes `_generated/spec.ts` (and the function specs it transitively imports) from every per-function bundle.
|
|
37
|
+
|
|
38
|
+
Each function also registers under a flat, single-segment key into a fresh, isolated `Registry` provided per group by `RegisteredFunctions.buildForGroup` (and the CLI's impl validation), so no group-path lookup against `api.spec` is needed. As a result `Spec#addPath`, `Spec#paths`, and `Api.resolveGroupPathUnsafe` are removed; `GroupImpl` / `FunctionImpl` drop their group-path type parameter; and the codegen-emitted `_generated/spec.ts` / `nodeSpec.ts` no longer contain a `.addPath(...)` chain (the `.addAt(...)` / `.addGroupAt(...)` assembly tree that `Refs.make` consumes is unchanged).
|
|
39
|
+
|
|
40
|
+
Migration — in each `*.impl.ts`, import the database schema and pass it where you passed `api` / `nodeApi`:
|
|
41
|
+
|
|
42
|
+
```diff
|
|
43
|
+
- import api from "../_generated/api"; // (or nodeApi from "../_generated/nodeApi")
|
|
44
|
+
+ import databaseSchema from "../_generated/schema";
|
|
45
|
+
|
|
46
|
+
- const insert = FunctionImpl.make(api, notes, "insert", handler);
|
|
47
|
+
+ const insert = FunctionImpl.make(databaseSchema, notes, "insert", handler);
|
|
48
|
+
|
|
49
|
+
- export default GroupImpl.make(api, notes).pipe(Layer.provide(insert), GroupImpl.finalize);
|
|
50
|
+
+ export default GroupImpl.make(databaseSchema, notes).pipe(Layer.provide(insert), GroupImpl.finalize);
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Node impls migrate identically (from `nodeApi` to the same `_generated/schema`); only their specs differ (`GroupSpec.makeNode()`). Hand-rolled tests that built a `Spec` via `.addPath(group, "dot.path")` should drop those calls.
|
|
54
|
+
|
|
55
|
+
### `buildForGroup` and the generated registries
|
|
56
|
+
|
|
57
|
+
`RegisteredFunctions.buildForGroup` takes the `DatabaseSchema` value plus the group's own `GroupSpec` as a single type argument (`buildForGroup<typeof groupSpec>(…)`, returning `RegisteredFunctionsForGroupSpec<Group>`); the `api` / `groupPath` parameters and the `ForGroupPath` dot-path navigation are gone. `RegisteredConvexFunction.make` / `RegisteredNodeFunction.make` take the `DatabaseSchema` rather than the `Api`. Each `_generated/registeredFunctions/{path}.ts` imports the runtime schema and references its group's leaf spec **type-only** (`typeof import("…/{group}.spec")["default"]`), so it never imports a spec module at runtime.
|
|
58
|
+
|
|
59
|
+
### `_generated/api.ts` / `nodeApi.ts` are no longer emitted, and `Api` is removed
|
|
60
|
+
|
|
61
|
+
Nothing imports them anymore, so `confect codegen` no longer emits `_generated/api.ts` / `_generated/nodeApi.ts` and deletes any copies left over from earlier versions. The `Api` module itself (`@confect/server/Api` — `Api.make`, the `Api` type, `Api.resolveGroupPathUnsafe`, etc.) is **removed entirely**: impls and the generated registries take the `DatabaseSchema` value and the spec directly, so the combined database-schema-plus-spec `Api` is no longer used anywhere.
|
|
62
|
+
|
|
63
|
+
### Net effect
|
|
64
|
+
|
|
65
|
+
A function's `convex/{path}.ts` bundle now imports only its own group's registry → its own `.impl` + `_generated/schema` (table schemas, built lazily) + its own group's spec. No `_generated/api.ts`, no project-wide `_generated/spec.ts`, and no sibling-group impls/specs. Re-run `confect codegen` after upgrading.
|
|
66
|
+
|
|
67
|
+
- 762f7eb: Split the deploy-time Convex schema from the runtime `DatabaseSchema`, make `confect/tables/` the single source of truth — including the table name, which is now derived from the filename — and make per-table schema construction lazy.
|
|
68
|
+
|
|
69
|
+
Previously, `confect/schema.ts` was user-authored and `DatabaseSchema` carried a `convexSchemaDefinition` field that was eagerly rebuilt on every `.addTable(...)`. That field was an `O(n²)` allocation for `n` tables, and it forced both the deploy CLI (which only needs `defineSchema(...)`) and the runtime (which only needs the table codec lookup) through the same module — so any runtime function bundle dragged in `convex/server`'s `defineSchema`. Issue 1.
|
|
70
|
+
|
|
71
|
+
Codegen now scans `confect/tables/*.ts` (every file must default-export a `Table`) and emits two siblings:
|
|
72
|
+
- `confect/_generated/schema.ts` — the runtime `DatabaseSchema`, consumed by `_generated/api.ts`. Imports `@confect/server` but never `convex/server`.
|
|
73
|
+
- `confect/_generated/convexSchema.ts` — the Convex deploy `SchemaDefinition`, re-exported one-line from `convex/schema.ts`. Imports `convex/server` but never `@confect/server`.
|
|
74
|
+
|
|
75
|
+
The `convexSchemaDefinition` field is removed from `DatabaseSchema` and `Api`. `TestConfect.layer` now takes the Convex schema definition as a separate argument so it can stay aligned with the deploy artifact without bringing the runtime schema along for the ride.
|
|
76
|
+
|
|
77
|
+
### Filename-derived table names
|
|
78
|
+
|
|
79
|
+
The table name is now derived from the file's basename — `confect/tables/notes.ts` defines a table called `notes`. `Table.make` no longer accepts a name argument and returns an _unnamed_ `Table` value; codegen invokes that value with the filename to produce the bound table.
|
|
80
|
+
|
|
81
|
+
This eliminates a class of subtle infelicities: the file basename and the table name can never drift out of sync, cross-table `_id` references are type-constrained against the actual set of declared tables (catching typos at compile time), and ESM cycle hazards for mutual cross-table `Id` references are gone because authoring files no longer transitively import each other.
|
|
82
|
+
|
|
83
|
+
Codegen now emits two new sets of files alongside `_generated/schema.ts` and `_generated/convexSchema.ts`:
|
|
84
|
+
- `confect/_generated/id.ts` — a single `Id` constructor whose argument is type-constrained to the union of your table names. Use `Id("notes")` everywhere you previously wrote `GenericId.GenericId("notes")`.
|
|
85
|
+
- `confect/_generated/tables/<name>.ts` — one thin wrapper per table that binds the unnamed value from `confect/tables/<name>.ts` to its filename. This is what other modules (specs, impls, HTTP handlers) default-import to reach a table's `Doc`, `Fields`, and `tableName`.
|
|
86
|
+
|
|
87
|
+
Table filenames must be valid JS identifiers, may not start with `_` (Convex reserves underscore-prefixed names for system tables), and may not collide with reserved JS keywords like `import.ts`. Pick a casing convention you like — Confect's example code uses `snake_case` (`notes.ts`, `user_profiles.ts`).
|
|
88
|
+
|
|
89
|
+
The bound `Table`'s `name` property has been renamed to `tableName`. This avoids a silent collision with the built-in `Function.prototype.name` that JavaScript carries on every function value (including the new unnamed-callable `UnnamedTable`).
|
|
90
|
+
|
|
91
|
+
### Lazy per-table schema construction
|
|
92
|
+
|
|
93
|
+
`Table.make` takes a `() => Schema.Struct({...})` callback rather than a bare struct, and a bound `Table`'s `Fields`, `Doc`, and `tableDefinition` are lazy memoised getters that only invoke that callback on first access.
|
|
94
|
+
|
|
95
|
+
Previously, every `confect/tables/<name>.ts` module ran `Schema.Struct({...})` (and the corresponding `compileTableSchema` / `defineTable` work) at module-load time. Because the codegen-emitted `_generated/schema.ts` is imported transitively from every per-group function bundle, loading any one function eagerly built _every_ table's schema graph — paying a cold-start cost proportional to the whole project, not just the function being invoked.
|
|
96
|
+
|
|
97
|
+
The bound `Table` now exposes `Fields` / `Doc` / `tableDefinition` as lazy getters that compute their value on first access, then replace themselves with a plain non-writable data property so second-and-subsequent accesses are observably indistinguishable from a plain property (and skip all function-call overhead). The result: a function bundle only pays the schema-construction cost for tables it actually touches via `db.table(name)` (which reaches `Fields` through `Document.decode`). The `UnnamedTable` callable no longer exposes `Fields` or `tableDefinition` — read these off the bound `Table` (the generated `_generated/tables/<name>.ts` wrapper already binds the name).
|
|
98
|
+
|
|
99
|
+
### Migration
|
|
100
|
+
1. Delete your `confect/schema.ts`. Codegen will refuse to run while a stray copy is present.
|
|
101
|
+
2. Rename each `confect/tables/<Name>.ts` to a valid JS identifier in your chosen casing convention (e.g. `confect/tables/notes.ts`). The basename becomes the table name; you no longer pass it as an argument.
|
|
102
|
+
3. Convert each table file to a **default-export-only** unnamed module: drop the name argument from `Table.make`, wrap the field-schema struct in a `() => ...` callback, and switch any `GenericId.GenericId("users")` references to `Id("users")` imported from `../_generated/id`:
|
|
103
|
+
|
|
104
|
+
```diff
|
|
105
|
+
- import { GenericId } from "@confect/core";
|
|
106
|
+
import { Table } from "@confect/server";
|
|
107
|
+
import { Schema } from "effect";
|
|
108
|
+
+ import { Id } from "../_generated/id";
|
|
109
|
+
|
|
110
|
+
- export default Table.make(
|
|
111
|
+
- "notes",
|
|
112
|
+
- Schema.Struct({
|
|
113
|
+
- userId: Schema.optional(GenericId.GenericId("users")),
|
|
114
|
+
- text: Schema.String,
|
|
115
|
+
- }),
|
|
116
|
+
- );
|
|
117
|
+
+ export default Table.make(() =>
|
|
118
|
+
+ Schema.Struct({
|
|
119
|
+
+ userId: Schema.optional(Id("users")),
|
|
120
|
+
+ text: Schema.String,
|
|
121
|
+
+ }),
|
|
122
|
+
+ );
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
4. Rewire every consumer site (specs, impls, integration tests, HTTP handlers, etc.) to import from the generated wrapper rather than directly from `tables/`. The wrapper is also where you now read `Doc` / `Fields` / `tableDefinition` (the unnamed `Table.make(...)` callable no longer exposes them):
|
|
126
|
+
|
|
127
|
+
```diff
|
|
128
|
+
- import Notes from "../tables/Notes";
|
|
129
|
+
+ import notes from "../_generated/tables/notes";
|
|
130
|
+
|
|
131
|
+
- returns: Schema.Array(Notes.Doc),
|
|
132
|
+
+ returns: Schema.Array(notes.Doc),
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
5. Replace every remaining `GenericId.GenericId("x")` call site with `Id("x")` from `_generated/id` (in spec `args`/`returns`, in `TaggedError` schemas, in `TestConfect.run`, etc.).
|
|
136
|
+
6. If you read `table.name` anywhere off a bound `Table`, rename it to `table.tableName`.
|
|
137
|
+
7. Re-run `confect codegen`. It will create `confect/_generated/schema.ts`, `confect/_generated/convexSchema.ts`, `confect/_generated/id.ts`, and one `confect/_generated/tables/<name>.ts` wrapper per table; and it will rewrite `convex/schema.ts` to a one-line re-export.
|
|
138
|
+
8. If you use `@confect/test`, pass the generated Convex schema definition to `TestConfect.layer`:
|
|
139
|
+
|
|
140
|
+
```diff
|
|
141
|
+
- import confectSchema from "./confect/schema";
|
|
142
|
+
+ import confectSchema from "./confect/_generated/schema";
|
|
143
|
+
+ import convexSchema from "./confect/_generated/convexSchema";
|
|
144
|
+
|
|
145
|
+
export const layer = TestConfect_.layer(
|
|
146
|
+
confectSchema,
|
|
147
|
+
+ convexSchema,
|
|
148
|
+
import.meta.glob("./convex/**/!(*.*.*)*.*s"),
|
|
149
|
+
);
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### New warning: no tables discovered
|
|
153
|
+
|
|
154
|
+
If a Confect project has no tables — either `confect/tables/` is missing entirely or it exists but contains no `.ts` files — codegen now emits a yellow `⚠` warning and continues, producing an empty `DatabaseSchema.make()` / `defineSchema({})`. Table-free backends (e.g. action-only proxies, webhook bridges) are still legal; the warning just catches the much more common case of a typoed directory name or files placed at the wrong path. To silence it, add at least one `Table.make(...)` module under `confect/tables/`.
|
|
155
|
+
|
|
156
|
+
### New error: invalid table filename
|
|
157
|
+
|
|
158
|
+
Codegen now rejects table files whose basename is not a valid JS identifier (e.g. `user-profiles.ts`), starts with `_` (reserved for Convex system tables), or shadows a reserved JS keyword (e.g. `import.ts`). Rename the offending file to fix it — for example, `user-profiles.ts` → `user_profiles.ts` or `userProfiles.ts`.
|
|
159
|
+
|
|
160
|
+
### Patch Changes
|
|
161
|
+
|
|
162
|
+
- Updated dependencies [46045a9]
|
|
163
|
+
- Updated dependencies [762f7eb]
|
|
164
|
+
- @confect/core@9.0.0-next.6
|
|
165
|
+
|
|
3
166
|
## 9.0.0-next.5
|
|
4
167
|
|
|
5
168
|
### Patch Changes
|
package/dist/Auth.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ declare const Auth_base: effect_Context0.TagClass<Auth, "@confect/server/Auth",
|
|
|
15
15
|
}> & {
|
|
16
16
|
use: <X>(body: (_: {
|
|
17
17
|
getUserIdentity: Effect.Effect<convex_server0.UserIdentity, NoUserIdentityFoundError, never>;
|
|
18
|
-
}) => X) => [X] extends [Effect.Effect<infer A, infer E, infer R>] ? Effect.Effect<A, E,
|
|
18
|
+
}) => X) => [X] extends [Effect.Effect<infer A, infer E, infer R>] ? Effect.Effect<A, E, Auth | R> : [X] extends [PromiseLike<infer A_1>] ? Effect.Effect<A_1, effect_Cause0.UnknownException, Auth> : Effect.Effect<X, never, Auth>;
|
|
19
19
|
};
|
|
20
20
|
declare class Auth extends Auth_base {}
|
|
21
21
|
declare const layer: (auth: Auth$1) => Layer.Layer<Auth, never, never>;
|