@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.
Files changed (62) hide show
  1. package/CHANGELOG.md +163 -0
  2. package/dist/Auth.d.ts +1 -1
  3. package/dist/DatabaseReader.d.ts +4299 -26
  4. package/dist/DatabaseReader.d.ts.map +1 -1
  5. package/dist/DatabaseReader.js +5 -6
  6. package/dist/DatabaseReader.js.map +1 -1
  7. package/dist/DatabaseSchema.d.ts +25 -112
  8. package/dist/DatabaseSchema.d.ts.map +1 -1
  9. package/dist/DatabaseSchema.js +20 -30
  10. package/dist/DatabaseSchema.js.map +1 -1
  11. package/dist/DatabaseWriter.d.ts +4 -4
  12. package/dist/DatabaseWriter.d.ts.map +1 -1
  13. package/dist/DatabaseWriter.js +3 -4
  14. package/dist/DatabaseWriter.js.map +1 -1
  15. package/dist/FunctionImpl.d.ts +26 -17
  16. package/dist/FunctionImpl.d.ts.map +1 -1
  17. package/dist/FunctionImpl.js +22 -14
  18. package/dist/FunctionImpl.js.map +1 -1
  19. package/dist/GroupImpl.d.ts +22 -13
  20. package/dist/GroupImpl.d.ts.map +1 -1
  21. package/dist/GroupImpl.js +34 -35
  22. package/dist/GroupImpl.js.map +1 -1
  23. package/dist/Handler.d.ts +1 -1
  24. package/dist/QueryInitializer.d.ts.map +1 -1
  25. package/dist/QueryInitializer.js.map +1 -1
  26. package/dist/RegisteredConvexFunction.d.ts +1081 -14
  27. package/dist/RegisteredConvexFunction.d.ts.map +1 -1
  28. package/dist/RegisteredConvexFunction.js +4 -4
  29. package/dist/RegisteredConvexFunction.js.map +1 -1
  30. package/dist/RegisteredFunction.d.ts +3 -3
  31. package/dist/RegisteredFunction.d.ts.map +1 -1
  32. package/dist/RegisteredFunctions.d.ts +36 -12
  33. package/dist/RegisteredFunctions.d.ts.map +1 -1
  34. package/dist/RegisteredFunctions.js +21 -9
  35. package/dist/RegisteredFunctions.js.map +1 -1
  36. package/dist/RegisteredNodeFunction.d.ts +4 -4
  37. package/dist/RegisteredNodeFunction.d.ts.map +1 -1
  38. package/dist/RegisteredNodeFunction.js +2 -2
  39. package/dist/RegisteredNodeFunction.js.map +1 -1
  40. package/dist/Table.d.ts +39 -31
  41. package/dist/Table.d.ts.map +1 -1
  42. package/dist/Table.js +69 -60
  43. package/dist/Table.js.map +1 -1
  44. package/dist/index.d.ts +4 -5
  45. package/dist/index.js +4 -5
  46. package/package.json +51 -52
  47. package/src/DatabaseReader.ts +17 -21
  48. package/src/DatabaseSchema.ts +38 -98
  49. package/src/DatabaseWriter.ts +8 -5
  50. package/src/FunctionImpl.ts +33 -43
  51. package/src/GroupImpl.ts +45 -69
  52. package/src/QueryInitializer.ts +10 -2
  53. package/src/RegisteredConvexFunction.ts +5 -6
  54. package/src/RegisteredFunctions.ts +67 -93
  55. package/src/RegisteredNodeFunction.ts +3 -4
  56. package/src/Table.ts +251 -131
  57. package/src/index.ts +0 -1
  58. package/dist/Api.d.ts +0 -43
  59. package/dist/Api.d.ts.map +0 -1
  60. package/dist/Api.js +0 -43
  61. package/dist/Api.js.map +0 -1
  62. 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, R | Auth> : [X] extends [PromiseLike<infer A_1>] ? Effect.Effect<A_1, effect_Cause0.UnknownException, Auth> : Effect.Effect<X, never, Auth>;
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>;