@confect/server 7.0.0 → 9.0.0-next.0
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 +70 -0
- package/dist/DatabaseSchema.d.ts +6 -6
- package/dist/DatabaseSchema.d.ts.map +1 -1
- package/dist/DatabaseSchema.js +3 -3
- package/dist/DatabaseSchema.js.map +1 -1
- package/dist/Document.d.ts.map +1 -1
- package/dist/Document.js +35 -23
- package/dist/Document.js.map +1 -1
- package/dist/FunctionImpl.d.ts +10 -7
- package/dist/FunctionImpl.d.ts.map +1 -1
- package/dist/FunctionImpl.js +8 -8
- package/dist/FunctionImpl.js.map +1 -1
- package/dist/GroupImpl.d.ts +51 -12
- package/dist/GroupImpl.d.ts.map +1 -1
- package/dist/GroupImpl.js +72 -4
- package/dist/GroupImpl.js.map +1 -1
- package/dist/GroupPath.d.ts +8 -0
- package/dist/GroupPath.d.ts.map +1 -0
- package/dist/GroupPath.js +10 -0
- package/dist/GroupPath.js.map +1 -0
- package/dist/RegisteredConvexFunction.d.ts +6 -6
- package/dist/RegisteredConvexFunction.d.ts.map +1 -1
- package/dist/RegisteredConvexFunction.js +18 -7
- 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 +15 -4
- package/dist/RegisteredFunctions.d.ts.map +1 -1
- package/dist/RegisteredFunctions.js +20 -11
- package/dist/RegisteredFunctions.js.map +1 -1
- package/dist/SchemaToValidator.d.ts +8 -8
- package/dist/index.d.ts +1 -3
- package/dist/index.js +1 -3
- package/package.json +21 -19
- package/src/DatabaseSchema.ts +5 -5
- package/src/Document.ts +90 -58
- package/src/FunctionImpl.ts +27 -36
- package/src/GroupImpl.ts +168 -32
- package/src/GroupPath.ts +43 -0
- package/src/RegisteredConvexFunction.ts +18 -17
- package/src/RegisteredFunctions.ts +78 -28
- package/src/index.ts +0 -2
- package/dist/Impl.d.ts +0 -24
- package/dist/Impl.d.ts.map +0 -1
- package/dist/Impl.js +0 -28
- package/dist/Impl.js.map +0 -1
- package/dist/Registry.d.ts +0 -15
- package/dist/Registry.d.ts.map +0 -1
- package/dist/Registry.js +0 -10
- package/dist/Registry.js.map +0 -1
- package/src/Impl.ts +0 -59
- package/src/Registry.ts +0 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,75 @@
|
|
|
1
1
|
# @confect/server
|
|
2
2
|
|
|
3
|
+
## 9.0.0-next.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 6db3a3a: Derive Confect function paths from the filesystem layout of `confect/`. Each group lives in a colocated `*.spec.ts`/`*.impl.ts` pair, and the group's name is its path within `confect/` (file stem for top-level groups, dot-joined directory path for nested groups). See [Project Structure](https://confect.dev/concepts/project-structure), [File Naming Conventions](https://confect.dev/concepts/file-naming-conventions), and [The Spec/Impl Model](https://confect.dev/concepts/spec-impl-model) for the current model.
|
|
8
|
+
|
|
9
|
+
Each `*.spec.ts` default-exports its `GroupSpec`. Each `*.impl.ts` default-imports its sibling spec, builds its `GroupImpl`, and default-exports the result of `GroupImpl.finalize`. Named co-exports on `*.spec.ts` (such as error classes) remain allowed.
|
|
10
|
+
|
|
11
|
+
### Why
|
|
12
|
+
|
|
13
|
+
The previous model assembled every group's impl into a single root `confect/impl.ts` (plus `confect/nodeImpl.ts`), which `confect codegen` emitted as the aggregate `_generated/registeredFunctions.ts`. Every generated `convex/` module — one per Convex function — imported from that aggregate, so loading any single query, mutation, or action transitively loaded the impl module of every other Convex function in the project, along with all of their dependencies. For large projects this inflated each function's bundle and added meaningful cold-start cost on Convex.
|
|
14
|
+
|
|
15
|
+
Splitting impl across colocated `*.impl.ts` files is the vehicle for fixing that. With this change, `confect codegen` emits one `_generated/registeredFunctions/{path}.ts` per group, and each generated `convex/` module imports only its own group's per-group registry — which in turn imports only its own sibling `.impl.ts`. A Convex function's cold-start bundle now scales with its own group's impl rather than with the size of the whole project.
|
|
16
|
+
|
|
17
|
+
### Breaking changes
|
|
18
|
+
- `GroupSpec.make()` and `GroupSpec.makeNode()` no longer take a name argument; the group name is derived from the spec file's path within `confect/`.
|
|
19
|
+
- `FunctionImpl.make(api, groupSpec, fn, handler)` and `GroupImpl.make(api, groupSpec)` now take the imported sibling spec object as their second argument instead of a dot-path string.
|
|
20
|
+
- Every `GroupImpl` pipeline must end with `GroupImpl.finalize`, which only typechecks once every function declared by the spec has a corresponding `FunctionImpl` provided to the group layer. `GroupImpl.finalize` snapshots the names of every registered function onto the produced `Finalized` `GroupImpl` service value, and `confect codegen` reads those names to verify per-function coverage against the spec at runtime.
|
|
21
|
+
- The previously-exported `Impl.make` and `Impl.finalize` (used by the old root `impl.ts`/`nodeImpl.ts` files) are removed. Per-group completeness is now enforced by `GroupImpl.finalize`.
|
|
22
|
+
- Root `confect/spec.ts`, `confect/impl.ts`, `confect/nodeSpec.ts`, `confect/nodeImpl.ts`, and any parent aggregator `*.spec.ts`/`*.impl.ts` files are no longer used. `confect codegen` deletes any of these on upgrade, along with the stale `_generated/registeredFunctions.ts` and `_generated/nodeRegisteredFunctions.ts`.
|
|
23
|
+
- Every module under `convex/` is re-emitted to import from `_generated/registeredFunctions/{path}` instead of the previous aggregate file. Users who commit `convex/` to source control should expect a full rewrite of that directory on first codegen.
|
|
24
|
+
|
|
25
|
+
### Migration
|
|
26
|
+
1. For each existing group, create a colocated `confect/{path}.spec.ts` and `confect/{path}.impl.ts` pair (under a subdirectory for nested groups).
|
|
27
|
+
- In each spec, call `GroupSpec.make()` (or `GroupSpec.makeNode()`) without a name and `export default` the result.
|
|
28
|
+
- In each impl, default-import the sibling spec (e.g. `import notes from "./notes.spec"`), pass it to `FunctionImpl.make`/`GroupImpl.make` in place of the previous dot-path string, append `GroupImpl.finalize` to the pipeline, and `export default` the resulting `GroupImpl` layer:
|
|
29
|
+
```ts
|
|
30
|
+
export default GroupImpl.make(api, notes).pipe(
|
|
31
|
+
Layer.provide(list),
|
|
32
|
+
Layer.provide(insert),
|
|
33
|
+
GroupImpl.finalize,
|
|
34
|
+
);
|
|
35
|
+
```
|
|
36
|
+
2. Delete root `confect/spec.ts`, `confect/impl.ts`, `confect/nodeSpec.ts`, `confect/nodeImpl.ts`, and any parent aggregator spec/impl files. (`confect codegen` will also delete any of these it finds, plus the stale `_generated/registeredFunctions.ts` and `_generated/nodeRegisteredFunctions.ts`, so this step can be skipped.)
|
|
37
|
+
3. Run `confect codegen`. Every module under `convex/` will be re-emitted.
|
|
38
|
+
|
|
39
|
+
### Patch Changes
|
|
40
|
+
|
|
41
|
+
- Updated dependencies [6db3a3a]
|
|
42
|
+
- @confect/core@9.0.0-next.0
|
|
43
|
+
|
|
44
|
+
## 8.0.0
|
|
45
|
+
|
|
46
|
+
### Major Changes
|
|
47
|
+
|
|
48
|
+
- 87b7207: Renamed `DatabaseSchema.isSchema` to `DatabaseSchema.isDatabaseSchema` for consistency with the `is<TypeName>` predicate convention used elsewhere (e.g. `Spec.isSpec`). `TypeId` and `Any` are now defined in `@confect/core/DatabaseSchema` and re-exported from `@confect/server`; the underlying brand string is unchanged, so existing schema values continue to be recognized. Migration: replace `DatabaseSchema.isSchema(x)` with `DatabaseSchema.isDatabaseSchema(x)`.
|
|
49
|
+
|
|
50
|
+
Internally, this removes a cyclic workspace dependency between `@confect/cli` and `@confect/server` that triggered a pnpm install warning. `@confect/cli` no longer peer-depends on `@confect/server`.
|
|
51
|
+
|
|
52
|
+
### Minor Changes
|
|
53
|
+
|
|
54
|
+
- 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`.
|
|
55
|
+
|
|
56
|
+
### Patch Changes
|
|
57
|
+
|
|
58
|
+
- f308edd: Fix Convex query cache invalidation when handlers use `Effect.log`, `Effect.withSpan`, or other Effect features that read the clock through its `unsafe*` methods.
|
|
59
|
+
|
|
60
|
+
The `Clock` provided to confect-wrapped handlers previously implemented `unsafeCurrentTimeMillis`/`unsafeCurrentTimeNanos` by calling the real `Date.now`, so Effect internals (logging, span events, the default scheduler) would read real time during handler execution and invalidate Convex's per-query cache. Those unsafe methods now return constants (`0`/`0n`), making the only opt-in to cache invalidation the user-facing `Clock.currentTimeMillis`/`Clock.currentTimeNanos` effects, as originally intended.
|
|
61
|
+
|
|
62
|
+
- a02ef8a: Memoize `Document.decode` and `Document.encode` parsers in module-scoped `WeakMap` caches. Decoders are keyed by table schema and table name so shared schemas across tables get the correct `extendWithSystemFields` parser; encoders are keyed by schema only.
|
|
63
|
+
- 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.
|
|
64
|
+
|
|
65
|
+
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.
|
|
66
|
+
|
|
67
|
+
`@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.
|
|
68
|
+
|
|
69
|
+
- Updated dependencies [4bb2722]
|
|
70
|
+
- Updated dependencies [40c1cff]
|
|
71
|
+
- @confect/core@8.0.0
|
|
72
|
+
|
|
3
73
|
## 7.0.0
|
|
4
74
|
|
|
5
75
|
### Minor Changes
|
package/dist/DatabaseSchema.d.ts
CHANGED
|
@@ -5,11 +5,14 @@ import * as effect_Schema0 from "effect/Schema";
|
|
|
5
5
|
|
|
6
6
|
//#region src/DatabaseSchema.d.ts
|
|
7
7
|
declare namespace DatabaseSchema_d_exports {
|
|
8
|
-
export { Any, AnyWithProps, ConvexDatabaseSchemaFromTables, DatabaseSchema, ExtendWithSystemTables, IncludeSystemTables, TableNames, TableWithName, Tables, TypeId, extendWithSystemTables,
|
|
8
|
+
export { Any, AnyWithProps, ConvexDatabaseSchemaFromTables, DatabaseSchema, ExtendWithSystemTables, IncludeSystemTables, TableNames, TableWithName, Tables, TypeId, extendWithSystemTables, isDatabaseSchema, make, systemSchema };
|
|
9
9
|
}
|
|
10
10
|
declare const TypeId = "@confect/server/DatabaseSchema";
|
|
11
11
|
type TypeId = typeof TypeId;
|
|
12
|
-
|
|
12
|
+
interface Any {
|
|
13
|
+
readonly [TypeId]: TypeId;
|
|
14
|
+
}
|
|
15
|
+
declare const isDatabaseSchema: (u: unknown) => u is Any;
|
|
13
16
|
/**
|
|
14
17
|
* A schema definition tracks the schema and its Convex schema definition.
|
|
15
18
|
*/
|
|
@@ -22,9 +25,6 @@ interface DatabaseSchema<Tables_ extends AnyWithProps$1 = never> {
|
|
|
22
25
|
*/
|
|
23
26
|
addTable<TableDef extends AnyWithProps$1>(table: TableDef): DatabaseSchema<Tables_ | TableDef>;
|
|
24
27
|
}
|
|
25
|
-
interface Any {
|
|
26
|
-
readonly [TypeId]: TypeId;
|
|
27
|
-
}
|
|
28
28
|
interface AnyWithProps {
|
|
29
29
|
readonly [TypeId]: TypeId;
|
|
30
30
|
readonly tables: Record<string, AnyWithProps$1>;
|
|
@@ -135,5 +135,5 @@ declare const extendWithSystemTables: <Tables_ extends AnyWithProps$1>(tables: T
|
|
|
135
135
|
type ExtendWithSystemTables<Tables_ extends AnyWithProps$1> = TablesRecord<Tables_ | SystemTables>;
|
|
136
136
|
type IncludeSystemTables<Tables_ extends AnyWithProps$1> = Tables_ | SystemTables extends infer T ? T extends AnyWithProps$1 ? T : never : never;
|
|
137
137
|
//#endregion
|
|
138
|
-
export { Any, AnyWithProps, ConvexDatabaseSchemaFromTables, DatabaseSchema, DatabaseSchema_d_exports, ExtendWithSystemTables, IncludeSystemTables, TableNames, TableWithName, Tables, TypeId, extendWithSystemTables,
|
|
138
|
+
export { Any, AnyWithProps, ConvexDatabaseSchemaFromTables, DatabaseSchema, DatabaseSchema_d_exports, ExtendWithSystemTables, IncludeSystemTables, TableNames, TableWithName, Tables, TypeId, extendWithSystemTables, isDatabaseSchema, make, systemSchema };
|
|
139
139
|
//# sourceMappingURL=DatabaseSchema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatabaseSchema.d.ts","names":[],"sources":["../src/DatabaseSchema.ts"],"mappings":";;;;;;;;;cAQa,MAAA;AAAA,KACD,MAAA,UAAgB,MAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"DatabaseSchema.d.ts","names":[],"sources":["../src/DatabaseSchema.ts"],"mappings":";;;;;;;;;cAQa,MAAA;AAAA,KACD,MAAA,UAAgB,MAAA;AAAA,UAEX,GAAA;EAAA,UACL,MAAA,GAAS,MAAA;AAAA;AAAA,cAGR,gBAAA,GAAoB,CAAA,cAAa,CAAA,IAAK,GAAA;;;;UAMlC,cAAA,iBAA+B,cAAA;EAAA,UACpC,MAAA,GAAS,MAAA;EAAA,SACV,MAAA,EAAQ,YAAA,CAAmB,OAAA;EAAA,SAC3B,sBAAA,EAAwB,gBAAA,CAC/B,8BAAA,CAA+B,OAAA;;;;EAOjC,QAAA,kBAA0B,cAAA,EACxB,KAAA,EAAO,QAAA,GACN,cAAA,CAAe,OAAA,GAAU,QAAA;AAAA;AAAA,UAGb,YAAA;EAAA,UACL,MAAA,GAAS,MAAA;EAAA,SACV,MAAA,EAAQ,MAAA,SAAe,cAAA;EAAA,SACvB,sBAAA,EAAwB,gBAAA,CAAiB,aAAA;EAClD,QAAA,kBAA0B,cAAA,EAAoB,KAAA,EAAO,QAAA,GAAW,YAAA;AAAA;AAAA,KAGtD,MAAA,yBAA+B,YAAA,IACzC,eAAA,SAAwB,cAAA,kBAAgC,OAAA;AAAA,KAE9C,UAAA,yBAAmC,YAAA,IAAgB,IAAA,CAC7D,MAAA,CAAO,eAAA;AAAA,KAIG,aAAA,yBACc,YAAA,oBACN,UAAA,CAAW,eAAA,KAC3B,OAAA,CAAQ,MAAA,CAAO,eAAA;EAAA,SAA6B,IAAA,EAAM,SAAA;AAAA;;AA5CtD;;cAqFa,IAAA,QAAW,cAAA;AAAA,KAMZ,8BAAA,iBAA+C,cAAA,IACzD,MAAA,iBACgB,IAAA,CAAW,OAAA,aAAoB,QAAA,CAC3C,OAAA,EACA,SAAA;AAAA,cAMO,YAAA,EAAY,cAAA,CAAA,KAAA,wCAAA,MAAA;eAEM,cAAA,CAAA,MAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAFN,cAAA,CAAA,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAA,cAAA,CAAA,MAAA;;;;;;;;;;;;;;cAIZ,sBAAA,mBAA0C,cAAA,EACrD,MAAA,EAAQ,YAAA,CAAmB,OAAA,MAC1B,sBAAA,CAAuB,OAAA;AAAA,KAMd,sBAAA,iBAAuC,cAAA,IACjD,YAAA,CAAmB,OAAA,GAAU,YAAA;AAAA,KAEnB,mBAAA,iBAAoC,cAAA,IAC5C,OAAA,GACA,YAAA,mBACA,CAAA,SAAU,cAAA,GACR,CAAA"}
|
package/dist/DatabaseSchema.js
CHANGED
|
@@ -7,12 +7,12 @@ import { defineSchema } from "convex/server";
|
|
|
7
7
|
var DatabaseSchema_exports = /* @__PURE__ */ __exportAll({
|
|
8
8
|
TypeId: () => TypeId,
|
|
9
9
|
extendWithSystemTables: () => extendWithSystemTables,
|
|
10
|
-
|
|
10
|
+
isDatabaseSchema: () => isDatabaseSchema,
|
|
11
11
|
make: () => make,
|
|
12
12
|
systemSchema: () => systemSchema
|
|
13
13
|
});
|
|
14
14
|
const TypeId = "@confect/server/DatabaseSchema";
|
|
15
|
-
const
|
|
15
|
+
const isDatabaseSchema = (u) => Predicate.hasProperty(u, TypeId);
|
|
16
16
|
const Proto = {
|
|
17
17
|
[TypeId]: TypeId,
|
|
18
18
|
addTable(table) {
|
|
@@ -41,5 +41,5 @@ const extendWithSystemTables = (tables) => ({
|
|
|
41
41
|
});
|
|
42
42
|
|
|
43
43
|
//#endregion
|
|
44
|
-
export { DatabaseSchema_exports, TypeId, extendWithSystemTables,
|
|
44
|
+
export { DatabaseSchema_exports, TypeId, extendWithSystemTables, isDatabaseSchema, make, systemSchema };
|
|
45
45
|
//# sourceMappingURL=DatabaseSchema.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatabaseSchema.js","names":["defineConvexSchema","Table.scheduledFunctionsTable","Table.storageTable","Table.systemTables"],"sources":["../src/DatabaseSchema.ts"],"sourcesContent":["import type { Expand, GenericSchema } from \"convex/server\";\nimport {\n defineSchema as defineConvexSchema,\n type SchemaDefinition,\n} from \"convex/server\";\nimport { Array, pipe, Predicate, Record } from \"effect\";\nimport * as Table from \"./Table\";\n\nexport const TypeId = \"@confect/server/DatabaseSchema\";\nexport type TypeId = typeof TypeId;\n\nexport const
|
|
1
|
+
{"version":3,"file":"DatabaseSchema.js","names":["defineConvexSchema","Table.scheduledFunctionsTable","Table.storageTable","Table.systemTables"],"sources":["../src/DatabaseSchema.ts"],"sourcesContent":["import type { Expand, GenericSchema } from \"convex/server\";\nimport {\n defineSchema as defineConvexSchema,\n type SchemaDefinition,\n} from \"convex/server\";\nimport { Array, pipe, Predicate, Record } from \"effect\";\nimport * as Table from \"./Table\";\n\nexport const TypeId = \"@confect/server/DatabaseSchema\";\nexport type TypeId = typeof TypeId;\n\nexport interface Any {\n readonly [TypeId]: TypeId;\n}\n\nexport const isDatabaseSchema = (u: unknown): u is Any =>\n Predicate.hasProperty(u, TypeId);\n\n/**\n * A schema definition tracks the schema and its Convex schema definition.\n */\nexport interface DatabaseSchema<Tables_ extends Table.AnyWithProps = never> {\n readonly [TypeId]: TypeId;\n readonly tables: Table.TablesRecord<Tables_>;\n readonly convexSchemaDefinition: SchemaDefinition<\n ConvexDatabaseSchemaFromTables<Tables_>,\n true\n >;\n\n /**\n * Add a table definition to the schema.\n */\n addTable<TableDef extends Table.AnyWithProps>(\n table: TableDef,\n ): DatabaseSchema<Tables_ | TableDef>;\n}\n\nexport interface AnyWithProps {\n readonly [TypeId]: TypeId;\n readonly tables: Record<string, Table.AnyWithProps>;\n readonly convexSchemaDefinition: SchemaDefinition<GenericSchema, true>;\n addTable<TableDef extends Table.AnyWithProps>(table: TableDef): AnyWithProps;\n}\n\nexport type Tables<DatabaseSchema_ extends AnyWithProps> =\n DatabaseSchema_ extends DatabaseSchema<infer Tables_> ? Tables_ : never;\n\nexport type TableNames<DatabaseSchema_ extends AnyWithProps> = Table.Name<\n Tables<DatabaseSchema_>\n> &\n string;\n\nexport type TableWithName<\n DatabaseSchema_ extends AnyWithProps,\n TableName extends TableNames<DatabaseSchema_>,\n> = Extract<Tables<DatabaseSchema_>, { readonly name: TableName }>;\n\nconst Proto = {\n [TypeId]: TypeId,\n\n addTable<TableDef extends Table.AnyWithProps>(\n this: DatabaseSchema<Table.AnyWithProps>,\n table: TableDef,\n ) {\n const tablesArray = Object.values(this.tables) as Table.AnyWithProps[];\n const newTablesArray = [...tablesArray, table];\n\n return makeProto({\n tables: Record.set(this.tables, table.name, table),\n convexSchemaDefinition: pipe(\n newTablesArray,\n Array.map(\n ({ name, tableDefinition }) => [name, tableDefinition] as const,\n ),\n Record.fromEntries,\n defineConvexSchema,\n ),\n });\n },\n};\n\nconst makeProto = <Tables_ extends Table.AnyWithProps>({\n tables,\n convexSchemaDefinition,\n}: {\n tables: Record.ReadonlyRecord<string, Tables_>;\n convexSchemaDefinition: SchemaDefinition<GenericSchema, true>;\n}): DatabaseSchema<Tables_> =>\n Object.assign(Object.create(Proto), {\n tables,\n convexSchemaDefinition,\n });\n\n/**\n * Create an empty schema definition. Add tables incrementally via `addTable`.\n */\nexport const make = (): DatabaseSchema<never> =>\n makeProto({\n tables: Record.empty(),\n convexSchemaDefinition: defineConvexSchema({}),\n });\n\nexport type ConvexDatabaseSchemaFromTables<Tables_ extends Table.AnyWithProps> =\n Expand<{\n [TableName in Table.Name<Tables_> & string]: Table.WithName<\n Tables_,\n TableName\n >[\"tableDefinition\"];\n }>;\n\n// System tables\n\nexport const systemSchema = make()\n .addTable(Table.scheduledFunctionsTable)\n .addTable(Table.storageTable);\n\nexport const extendWithSystemTables = <Tables_ extends Table.AnyWithProps>(\n tables: Table.TablesRecord<Tables_>,\n): ExtendWithSystemTables<Tables_> =>\n ({\n ...tables,\n ...Table.systemTables,\n }) as ExtendWithSystemTables<Tables_>;\n\nexport type ExtendWithSystemTables<Tables_ extends Table.AnyWithProps> =\n Table.TablesRecord<Tables_ | Table.SystemTables>;\n\nexport type IncludeSystemTables<Tables_ extends Table.AnyWithProps> =\n | Tables_\n | Table.SystemTables extends infer T\n ? T extends Table.AnyWithProps\n ? T\n : never\n : never;\n"],"mappings":";;;;;;;;;;;;;AAQA,MAAa,SAAS;AAOtB,MAAa,oBAAoB,MAC/B,UAAU,YAAY,GAAG,OAAO;AAyClC,MAAM,QAAQ;EACX,SAAS;CAEV,SAEE,OACA;EAEA,MAAM,iBAAiB,CAAC,GADJ,OAAO,OAAO,KAAK,OAAO,EACN,MAAM;AAE9C,SAAO,UAAU;GACf,QAAQ,OAAO,IAAI,KAAK,QAAQ,MAAM,MAAM,MAAM;GAClD,wBAAwB,KACtB,gBACA,MAAM,KACH,EAAE,MAAM,sBAAsB,CAAC,MAAM,gBAAgB,CACvD,EACD,OAAO,aACPA,aACD;GACF,CAAC;;CAEL;AAED,MAAM,aAAiD,EACrD,QACA,6BAKA,OAAO,OAAO,OAAO,OAAO,MAAM,EAAE;CAClC;CACA;CACD,CAAC;;;;AAKJ,MAAa,aACX,UAAU;CACR,QAAQ,OAAO,OAAO;CACtB,wBAAwBA,aAAmB,EAAE,CAAC;CAC/C,CAAC;AAYJ,MAAa,eAAe,MAAM,CAC/B,SAASC,wBAA8B,CACvC,SAASC,aAAmB;AAE/B,MAAa,0BACX,YAEC;CACC,GAAG;CACH,GAAGC;CACJ"}
|
package/dist/Document.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Document.d.ts","names":[],"sources":["../src/Document.ts"],"mappings":";;;;;;;;;;KAOY,mBAAA,QAA2B,IAAA,CAAK,GAAA;AAAA,KAEhC,GAAA;AAAA,KACA,UAAA,GAAa,cAAA,SAAuB,aAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"Document.d.ts","names":[],"sources":["../src/Document.ts"],"mappings":";;;;;;;;;;KAOY,mBAAA,QAA2B,IAAA,CAAK,GAAA;AAAA,KAEhC,GAAA;AAAA,KACA,UAAA,GAAa,cAAA,SAAuB,aAAA;AAAA,cAiCnC,MAAA,uBAEU,YAAA,oBACD,UAAA,CAAqB,UAAA,GAAW,SAAA,EAEvC,SAAA,EAAS,WAAA,EACP,WAAA,CACX,kBAAA,CAA6B,UAAA,EAAY,SAAA,QAG3C,IAAA,EAAM,kBAAA,CAA6B,UAAA,EAAY,SAAA,wBAC5C,MAAA,CAAO,MAAA,CACV,kBAAA,CAA6B,UAAA,EAAY,SAAA,eACzC,mBAAA,0BAGmB,YAAA,oBACD,UAAA,CAAqB,UAAA,GAAW,IAAA,EAE5C,kBAAA,CAA6B,UAAA,EAAY,SAAA,qBAA4B,SAAA,EAChE,SAAA,EAAS,WAAA,EACP,WAAA,CACX,kBAAA,CAA6B,UAAA,EAAY,SAAA,OAExC,MAAA,CAAO,MAAA,CACV,kBAAA,CAA6B,UAAA,EAAY,SAAA,eACzC,mBAAA;AAAA,cAsDS,MAAA,uBAEU,YAAA,oBACD,UAAA,CAAqB,UAAA,GAAW,SAAA,EAEvC,SAAA,EAAS,WAAA,EACP,WAAA,CACX,kBAAA,CAA6B,UAAA,EAAY,SAAA,QAG3C,IAAA,EAAM,kBAAA,CAA6B,UAAA,EAAY,SAAA,kBAC5C,MAAA,CAAO,MAAA,CACV,kBAAA,CAA6B,UAAA,EAAY,SAAA,sBACzC,mBAAA,0BAGmB,YAAA,oBACD,UAAA,CAAqB,UAAA,GAAW,IAAA,EAE5C,kBAAA,CAA6B,UAAA,EAAY,SAAA,eAAsB,SAAA,EAC1D,SAAA,EAAS,WAAA,EACP,WAAA,CACX,kBAAA,CAA6B,UAAA,EAAY,SAAA,OAExC,MAAA,CAAO,MAAA,CACV,kBAAA,CAA6B,UAAA,EAAY,SAAA,sBACzC,mBAAA;AAAA,cAwCF,wBAAA;;;;;;;cAEW,mBAAA,SAA4B,wBAAA;EAAA,IAQ1B,OAAA,CAAA;AAAA;AAAA,cAOd,wBAAA;;;;;;;cAEY,mBAAA,SAA4B,wBAAA;EAAA,IAQ1B,OAAA,CAAA;AAAA;AAAA,cASF,oBAAA;EAAwB,EAAA;EAAA,SAAA;EAAA;AAAA;EAKnC,EAAA;EACA,SAAA;EACA,OAAA;AAAA"}
|
package/dist/Document.js
CHANGED
|
@@ -10,29 +10,41 @@ var Document_exports = /* @__PURE__ */ __exportAll({
|
|
|
10
10
|
documentErrorMessage: () => documentErrorMessage,
|
|
11
11
|
encode: () => encode
|
|
12
12
|
});
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
return
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}));
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
13
|
+
const decoderCache = /* @__PURE__ */ new WeakMap();
|
|
14
|
+
const getDecoder = (tableName, tableSchema) => {
|
|
15
|
+
const byTable = decoderCache.get(tableSchema) ?? (() => {
|
|
16
|
+
const map = /* @__PURE__ */ new Map();
|
|
17
|
+
decoderCache.set(tableSchema, map);
|
|
18
|
+
return map;
|
|
19
|
+
})();
|
|
20
|
+
return byTable.get(tableName) ?? (() => {
|
|
21
|
+
const decoder = Schema.decode(SystemFields.extendWithSystemFields(tableName, tableSchema));
|
|
22
|
+
byTable.set(tableName, decoder);
|
|
23
|
+
return decoder;
|
|
24
|
+
})();
|
|
25
|
+
};
|
|
26
|
+
const decode = Function.dual(3, (self, tableName, tableSchema) => pipe(self, getDecoder(tableName, tableSchema), Effect.catchIf(ParseResult.isParseError, (parseError) => Effect.gen(function* () {
|
|
27
|
+
const formattedParseError = yield* ParseResult.TreeFormatter.formatError(parseError);
|
|
28
|
+
return yield* new DocumentDecodeError({
|
|
29
|
+
tableName,
|
|
30
|
+
id: self._id,
|
|
31
|
+
parseError: formattedParseError
|
|
32
|
+
});
|
|
33
|
+
})), Effect.map((decodedDoc) => decodedDoc)));
|
|
34
|
+
const encoderCache = /* @__PURE__ */ new WeakMap();
|
|
35
|
+
const getEncoder = (tableSchema) => encoderCache.get(tableSchema) ?? (() => {
|
|
36
|
+
const encoder = Schema.encode(tableSchema);
|
|
37
|
+
encoderCache.set(tableSchema, encoder);
|
|
38
|
+
return encoder;
|
|
39
|
+
})();
|
|
40
|
+
const encode = Function.dual(3, (self, tableName, tableSchema) => pipe(self, getEncoder(tableSchema), Effect.catchIf(ParseResult.isParseError, (parseError) => Effect.gen(function* () {
|
|
41
|
+
const formattedParseError = yield* ParseResult.TreeFormatter.formatError(parseError);
|
|
42
|
+
return yield* new DocumentEncodeError({
|
|
43
|
+
tableName,
|
|
44
|
+
id: self._id,
|
|
45
|
+
parseError: formattedParseError
|
|
46
|
+
});
|
|
47
|
+
})), Effect.map((encodedDoc) => encodedDoc)));
|
|
36
48
|
var DocumentDecodeError = class extends Schema.TaggedError()("DocumentDecodeError", {
|
|
37
49
|
tableName: Schema.String,
|
|
38
50
|
id: Schema.String,
|
package/dist/Document.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Document.js","names":[],"sources":["../src/Document.ts"],"sourcesContent":["import { Effect, Function, ParseResult, pipe, Schema } from \"effect\";\nimport type { ReadonlyRecord } from \"effect/Record\";\nimport
|
|
1
|
+
{"version":3,"file":"Document.js","names":[],"sources":["../src/Document.ts"],"sourcesContent":["import * as SystemFields from \"@confect/core/SystemFields\";\nimport { Effect, Function, ParseResult, pipe, Schema } from \"effect\";\nimport type { ReadonlyRecord } from \"effect/Record\";\nimport type * as DataModel from \"./DataModel\";\nimport type { ReadonlyValue } from \"./SchemaToValidator\";\nimport type * as TableInfo from \"./TableInfo\";\n\nexport type WithoutSystemFields<Doc> = Omit<Doc, \"_creationTime\" | \"_id\">;\n\nexport type Any = any;\nexport type AnyEncoded = ReadonlyRecord<string, ReadonlyValue>;\n\ntype Decode = (doc: unknown) => Effect.Effect<unknown, ParseResult.ParseError>;\n\nconst decoderCache = new WeakMap<\n Schema.Schema.AnyNoContext,\n Map<string, Decode>\n>();\n\nconst getDecoder = (\n tableName: string,\n tableSchema: Schema.Schema.AnyNoContext,\n): Decode => {\n const byTable =\n decoderCache.get(tableSchema) ??\n (() => {\n const map = new Map<string, Decode>();\n decoderCache.set(tableSchema, map);\n return map;\n })();\n\n return (\n byTable.get(tableName) ??\n (() => {\n const decoder = Schema.decode(\n SystemFields.extendWithSystemFields(tableName, tableSchema),\n ) as Decode;\n byTable.set(tableName, decoder);\n return decoder;\n })()\n );\n};\n\nexport const decode = Function.dual<\n <\n DataModel_ extends DataModel.AnyWithProps,\n TableName extends DataModel.TableNames<DataModel_>,\n >(\n tableName: TableName,\n tableSchema: TableInfo.TableSchema<\n DataModel.TableInfoWithName_<DataModel_, TableName>\n >,\n ) => (\n self: DataModel.TableInfoWithName_<DataModel_, TableName>[\"convexDocument\"],\n ) => Effect.Effect<\n DataModel.TableInfoWithName_<DataModel_, TableName>[\"document\"],\n DocumentDecodeError\n >,\n <\n DataModel_ extends DataModel.AnyWithProps,\n TableName extends DataModel.TableNames<DataModel_>,\n >(\n self: DataModel.TableInfoWithName_<DataModel_, TableName>[\"convexDocument\"],\n tableName: TableName,\n tableSchema: TableInfo.TableSchema<\n DataModel.TableInfoWithName_<DataModel_, TableName>\n >,\n ) => Effect.Effect<\n DataModel.TableInfoWithName_<DataModel_, TableName>[\"document\"],\n DocumentDecodeError\n >\n>(\n 3,\n <\n DataModel_ extends DataModel.AnyWithProps,\n TableName extends DataModel.TableNames<DataModel_>,\n >(\n self: DataModel.TableInfoWithName_<DataModel_, TableName>[\"convexDocument\"],\n tableName: TableName,\n tableSchema: TableInfo.TableSchema<\n DataModel.TableInfoWithName_<DataModel_, TableName>\n >,\n ): Effect.Effect<\n DataModel.TableInfoWithName_<DataModel_, TableName>[\"document\"],\n DocumentDecodeError\n > =>\n pipe(\n self,\n getDecoder(tableName, tableSchema),\n Effect.catchIf(ParseResult.isParseError, (parseError) =>\n Effect.gen(function* () {\n const formattedParseError =\n yield* ParseResult.TreeFormatter.formatError(parseError);\n\n return yield* new DocumentDecodeError({\n tableName,\n id: self._id,\n parseError: formattedParseError,\n });\n }),\n ),\n Effect.map(\n (decodedDoc) =>\n decodedDoc as DataModel.TableInfoWithName_<\n DataModel_,\n TableName\n >[\"document\"],\n ),\n ),\n);\n\ntype Encode = (doc: unknown) => Effect.Effect<unknown, ParseResult.ParseError>;\n\nconst encoderCache = new WeakMap<Schema.Schema.AnyNoContext, Encode>();\n\nconst getEncoder = (tableSchema: Schema.Schema.AnyNoContext): Encode =>\n encoderCache.get(tableSchema) ??\n (() => {\n const encoder = Schema.encode(tableSchema) as Encode;\n encoderCache.set(tableSchema, encoder);\n return encoder;\n })();\n\nexport const encode = Function.dual<\n <\n DataModel_ extends DataModel.AnyWithProps,\n TableName extends DataModel.TableNames<DataModel_>,\n >(\n tableName: TableName,\n tableSchema: TableInfo.TableSchema<\n DataModel.TableInfoWithName_<DataModel_, TableName>\n >,\n ) => (\n self: DataModel.TableInfoWithName_<DataModel_, TableName>[\"document\"],\n ) => Effect.Effect<\n DataModel.TableInfoWithName_<DataModel_, TableName>[\"encodedDocument\"],\n DocumentEncodeError\n >,\n <\n DataModel_ extends DataModel.AnyWithProps,\n TableName extends DataModel.TableNames<DataModel_>,\n >(\n self: DataModel.TableInfoWithName_<DataModel_, TableName>[\"document\"],\n tableName: TableName,\n tableSchema: TableInfo.TableSchema<\n DataModel.TableInfoWithName_<DataModel_, TableName>\n >,\n ) => Effect.Effect<\n DataModel.TableInfoWithName_<DataModel_, TableName>[\"encodedDocument\"],\n DocumentEncodeError\n >\n>(\n 3,\n <\n DataModel_ extends DataModel.AnyWithProps,\n TableName extends DataModel.TableNames<DataModel_>,\n >(\n self: DataModel.TableInfoWithName_<DataModel_, TableName>[\"document\"],\n tableName: TableName,\n tableSchema: TableInfo.TableSchema<\n DataModel.TableInfoWithName_<DataModel_, TableName>\n >,\n ): Effect.Effect<\n DataModel.TableInfoWithName_<DataModel_, TableName>[\"encodedDocument\"],\n DocumentEncodeError\n > =>\n pipe(\n self,\n getEncoder(tableSchema),\n Effect.catchIf(ParseResult.isParseError, (parseError) =>\n Effect.gen(function* () {\n const formattedParseError =\n yield* ParseResult.TreeFormatter.formatError(parseError);\n\n return yield* new DocumentEncodeError({\n tableName,\n id: self._id,\n parseError: formattedParseError,\n });\n }),\n ),\n Effect.map(\n (encodedDoc) =>\n encodedDoc as DataModel.TableInfoWithName_<\n DataModel_,\n TableName\n >[\"encodedDocument\"],\n ),\n ),\n);\n\nexport class DocumentDecodeError extends Schema.TaggedError<DocumentDecodeError>()(\n \"DocumentDecodeError\",\n {\n tableName: Schema.String,\n id: Schema.String,\n parseError: Schema.String,\n },\n) {\n override get message(): string {\n return documentErrorMessage({\n id: this.id,\n tableName: this.tableName,\n message: `could not be decoded:\\n\\n${this.parseError}`,\n });\n }\n}\n\nexport class DocumentEncodeError extends Schema.TaggedError<DocumentEncodeError>()(\n \"DocumentEncodeError\",\n {\n tableName: Schema.String,\n id: Schema.String,\n parseError: Schema.String,\n },\n) {\n override get message(): string {\n return documentErrorMessage({\n id: this.id,\n tableName: this.tableName,\n message: `could not be encoded:\\n\\n${this.parseError}`,\n });\n }\n}\n\nexport const documentErrorMessage = ({\n id,\n tableName,\n message,\n}: {\n id: string;\n tableName: string;\n message: string;\n}) => `Document with ID '${id}' in table '${tableName}' ${message}`;\n"],"mappings":";;;;;;;;;;;;AAcA,MAAM,+BAAe,IAAI,SAGtB;AAEH,MAAM,cACJ,WACA,gBACW;CACX,MAAM,UACJ,aAAa,IAAI,YAAY,WACtB;EACL,MAAM,sBAAM,IAAI,KAAqB;AACrC,eAAa,IAAI,aAAa,IAAI;AAClC,SAAO;KACL;AAEN,QACE,QAAQ,IAAI,UAAU,WACf;EACL,MAAM,UAAU,OAAO,OACrB,aAAa,uBAAuB,WAAW,YAAY,CAC5D;AACD,UAAQ,IAAI,WAAW,QAAQ;AAC/B,SAAO;KACL;;AAIR,MAAa,SAAS,SAAS,KA6B7B,IAKE,MACA,WACA,gBAOA,KACE,MACA,WAAW,WAAW,YAAY,EAClC,OAAO,QAAQ,YAAY,eAAe,eACxC,OAAO,IAAI,aAAa;CACtB,MAAM,sBACJ,OAAO,YAAY,cAAc,YAAY,WAAW;AAE1D,QAAO,OAAO,IAAI,oBAAoB;EACpC;EACA,IAAI,KAAK;EACT,YAAY;EACb,CAAC;EACF,CACH,EACD,OAAO,KACJ,eACC,WAIH,CACF,CACJ;AAID,MAAM,+BAAe,IAAI,SAA6C;AAEtE,MAAM,cAAc,gBAClB,aAAa,IAAI,YAAY,WACtB;CACL,MAAM,UAAU,OAAO,OAAO,YAAY;AAC1C,cAAa,IAAI,aAAa,QAAQ;AACtC,QAAO;IACL;AAEN,MAAa,SAAS,SAAS,KA6B7B,IAKE,MACA,WACA,gBAOA,KACE,MACA,WAAW,YAAY,EACvB,OAAO,QAAQ,YAAY,eAAe,eACxC,OAAO,IAAI,aAAa;CACtB,MAAM,sBACJ,OAAO,YAAY,cAAc,YAAY,WAAW;AAE1D,QAAO,OAAO,IAAI,oBAAoB;EACpC;EACA,IAAI,KAAK;EACT,YAAY;EACb,CAAC;EACF,CACH,EACD,OAAO,KACJ,eACC,WAIH,CACF,CACJ;AAED,IAAa,sBAAb,cAAyC,OAAO,aAAkC,CAChF,uBACA;CACE,WAAW,OAAO;CAClB,IAAI,OAAO;CACX,YAAY,OAAO;CACpB,CACF,CAAC;CACA,IAAa,UAAkB;AAC7B,SAAO,qBAAqB;GAC1B,IAAI,KAAK;GACT,WAAW,KAAK;GAChB,SAAS,4BAA4B,KAAK;GAC3C,CAAC;;;AAIN,IAAa,sBAAb,cAAyC,OAAO,aAAkC,CAChF,uBACA;CACE,WAAW,OAAO;CAClB,IAAI,OAAO;CACX,YAAY,OAAO;CACpB,CACF,CAAC;CACA,IAAa,UAAkB;AAC7B,SAAO,qBAAqB;GAC1B,IAAI,KAAK;GACT,WAAW,KAAK;GAChB,SAAS,4BAA4B,KAAK;GAC3C,CAAC;;;AAIN,MAAa,wBAAwB,EACnC,IACA,WACA,cAKI,qBAAqB,GAAG,cAAc,UAAU,IAAI"}
|
package/dist/FunctionImpl.d.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import { AnyWithProps,
|
|
1
|
+
import { AnyWithProps, Schema as Schema$1 } from "./Api.js";
|
|
2
2
|
import { WithName } from "./Handler.js";
|
|
3
3
|
import { Context, Layer } from "effect";
|
|
4
4
|
import * as FunctionSpec from "@confect/core/FunctionSpec";
|
|
5
|
-
import * as GroupPath from "@confect/core/GroupPath";
|
|
6
5
|
import * as GroupSpec from "@confect/core/GroupSpec";
|
|
7
6
|
|
|
8
7
|
//#region src/FunctionImpl.d.ts
|
|
9
8
|
declare namespace FunctionImpl_d_exports {
|
|
10
|
-
export { ForGroupPathAndFunction, FromGroupAtPath, FunctionImpl, make };
|
|
9
|
+
export { ForGroupPathAndFunction, FromGroupAtPath, FromGroupSpec, FunctionImpl, make };
|
|
11
10
|
}
|
|
12
11
|
interface FunctionImpl<GroupPath_ extends string, FunctionName extends string> {
|
|
13
12
|
readonly groupPath: GroupPath_;
|
|
@@ -20,15 +19,19 @@ declare const FunctionImpl: <GroupPath_ extends string, FunctionName extends str
|
|
|
20
19
|
groupPath: GroupPath_;
|
|
21
20
|
functionName: FunctionName;
|
|
22
21
|
}) => Context.Tag<FunctionImpl<GroupPath_, FunctionName>, FunctionImpl<GroupPath_, FunctionName>>;
|
|
23
|
-
declare const make: <Api_ extends AnyWithProps,
|
|
22
|
+
declare const make: <Api_ extends AnyWithProps, Group extends GroupSpec.AnyWithProps, const FunctionName extends FunctionSpec.Name<GroupSpec.Functions<Group>>>(api: Api_, group: Group, functionName: FunctionName, handler: WithName<Schema$1<Api_>, GroupSpec.Functions<Group>, FunctionName>) => Layer.Layer<FunctionImpl<string, FunctionName>>;
|
|
24
23
|
/**
|
|
25
24
|
* Get the function implementation service type for a specific group path and function name.
|
|
26
25
|
*/
|
|
27
26
|
type ForGroupPathAndFunction<GroupPath_ extends string, FunctionName extends string> = FunctionImpl<GroupPath_, FunctionName>;
|
|
28
27
|
/**
|
|
29
|
-
* Get all function implementation services required for a group
|
|
28
|
+
* Get all function implementation services required for a group spec.
|
|
30
29
|
*/
|
|
31
|
-
type
|
|
30
|
+
type FromGroupSpec<Group extends GroupSpec.AnyWithProps> = FunctionSpec.Name<GroupSpec.Functions<Group>> extends infer FunctionNames extends string ? FunctionNames extends string ? FunctionImpl<string, FunctionNames> : never : never;
|
|
31
|
+
/**
|
|
32
|
+
* @deprecated Use {@link FromGroupSpec} instead.
|
|
33
|
+
*/
|
|
34
|
+
type FromGroupAtPath<_GroupPath extends string, Group extends GroupSpec.AnyWithProps> = FromGroupSpec<Group>;
|
|
32
35
|
//#endregion
|
|
33
|
-
export { ForGroupPathAndFunction, FromGroupAtPath, FunctionImpl, FunctionImpl_d_exports, make };
|
|
36
|
+
export { ForGroupPathAndFunction, FromGroupAtPath, FromGroupSpec, FunctionImpl, FunctionImpl_d_exports, make };
|
|
34
37
|
//# sourceMappingURL=FunctionImpl.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FunctionImpl.d.ts","names":[],"sources":["../src/FunctionImpl.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"FunctionImpl.d.ts","names":[],"sources":["../src/FunctionImpl.ts"],"mappings":";;;;;;;;;;UAUiB,YAAA;EAAA,SAIN,SAAA,EAAW,UAAA;EAAA,SACX,YAAA,EAAc,YAAA;AAAA;AAAA,cAGZ,YAAA;EAGX,SAAA;EAAA;AAAA;EAIA,SAAA,EAAW,UAAA;EACX,YAAA,EAAc,YAAA;AAAA,MACf,OAAA,CAAA,GAAA,CAAA,YAAA,CAAA,UAAA,EAAA,YAAA,GAAA,YAAA,CAAA,UAAA,EAAA,YAAA;AAAA,cAKY,IAAA,gBACE,YAAA,gBACC,SAAA,CAAU,YAAA,6BACG,YAAA,CAAa,IAAA,CAAK,SAAA,CAAU,SAAA,CAAU,KAAA,IAEjE,GAAA,EAAK,IAAA,EACL,KAAA,EAAO,KAAA,EACP,YAAA,EAAc,YAAA,EACd,OAAA,EAAS,QAAA,CACP,QAAA,CAAW,IAAA,GACX,SAAA,CAAU,SAAA,CAAU,KAAA,GACpB,YAAA,MAED,KAAA,CAAM,KAAA,CAAM,YAAA,SAAqB,YAAA;;AAnCpC;;KAqEY,uBAAA,2DAGR,YAAA,CAAa,UAAA,EAAY,YAAA;;;;KAKjB,aAAA,eAA4B,SAAA,CAAU,YAAA,IAChD,YAAA,CAAa,IAAA,CACX,SAAA,CAAU,SAAA,CAAU,KAAA,gDAElB,aAAA,kBACE,YAAA,SAAqB,aAAA;;;;KAOjB,eAAA,0CAEI,SAAA,CAAU,YAAA,IACtB,aAAA,CAAc,KAAA"}
|
package/dist/FunctionImpl.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { __exportAll } from "./_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { resolveGroupPathUnsafe } from "./GroupPath.js";
|
|
2
3
|
import { setNestedProperty } from "./internal/utils.js";
|
|
3
|
-
import { Registry } from "./Registry.js";
|
|
4
4
|
import { make as make$1 } from "./RegistryItem.js";
|
|
5
|
-
import {
|
|
5
|
+
import { Context, Effect, Layer, Ref, String } from "effect";
|
|
6
|
+
import * as Registry from "@confect/core/Registry";
|
|
6
7
|
|
|
7
8
|
//#region src/FunctionImpl.ts
|
|
8
9
|
var FunctionImpl_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -10,16 +11,15 @@ var FunctionImpl_exports = /* @__PURE__ */ __exportAll({
|
|
|
10
11
|
make: () => make
|
|
11
12
|
});
|
|
12
13
|
const FunctionImpl = ({ groupPath, functionName }) => Context.GenericTag(`@confect/server/FunctionImpl/${groupPath}/${functionName}`);
|
|
13
|
-
const make = (api,
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const functionSpec = Array.reduce(restGroupPathParts, api.spec.groups[firstGroupPathPart], (currentGroup, groupPathPart) => currentGroup.groups[groupPathPart]).functions[functionName];
|
|
14
|
+
const make = (api, group, functionName, handler) => {
|
|
15
|
+
const groupPath = resolveGroupPathUnsafe(api.spec, group);
|
|
16
|
+
const functionSpec = group.functions[functionName];
|
|
17
17
|
return Layer.effect(FunctionImpl({
|
|
18
18
|
groupPath,
|
|
19
19
|
functionName
|
|
20
20
|
}), Effect.gen(function* () {
|
|
21
|
-
const registry = yield* Registry;
|
|
22
|
-
yield* Ref.update(registry, (registryItems) => setNestedProperty(registryItems, [...
|
|
21
|
+
const registry = yield* Registry.Registry;
|
|
22
|
+
yield* Ref.update(registry, (registryItems) => setNestedProperty(registryItems, [...String.split(groupPath, "."), functionName], make$1({
|
|
23
23
|
functionSpec,
|
|
24
24
|
handler
|
|
25
25
|
})));
|
package/dist/FunctionImpl.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FunctionImpl.js","names":["
|
|
1
|
+
{"version":3,"file":"FunctionImpl.js","names":["RegistryItem.make"],"sources":["../src/FunctionImpl.ts"],"sourcesContent":["import type * as FunctionSpec from \"@confect/core/FunctionSpec\";\nimport type * as GroupSpec from \"@confect/core/GroupSpec\";\nimport * as Registry from \"@confect/core/Registry\";\nimport { Context, Effect, Layer, Ref, String } from \"effect\";\nimport type * as Api from \"./Api\";\nimport { resolveGroupPathUnsafe } from \"./GroupPath\";\nimport type * as Handler from \"./Handler\";\nimport { setNestedProperty } from \"./internal/utils\";\nimport * as RegistryItem from \"./RegistryItem\";\n\nexport interface FunctionImpl<\n GroupPath_ extends string,\n FunctionName extends string,\n> {\n readonly groupPath: GroupPath_;\n readonly functionName: FunctionName;\n}\n\nexport const FunctionImpl = <\n GroupPath_ extends string,\n FunctionName extends string,\n>({\n groupPath,\n functionName,\n}: {\n groupPath: GroupPath_;\n functionName: FunctionName;\n}) =>\n Context.GenericTag<FunctionImpl<GroupPath_, FunctionName>>(\n `@confect/server/FunctionImpl/${groupPath}/${functionName}`,\n );\n\nexport const make = <\n Api_ extends Api.AnyWithProps,\n Group extends GroupSpec.AnyWithProps,\n const FunctionName extends FunctionSpec.Name<GroupSpec.Functions<Group>>,\n>(\n api: Api_,\n group: Group,\n functionName: FunctionName,\n handler: Handler.WithName<\n Api.Schema<Api_>,\n GroupSpec.Functions<Group>,\n FunctionName\n >,\n): Layer.Layer<FunctionImpl<string, FunctionName>> => {\n const groupPath = resolveGroupPathUnsafe(api.spec, group);\n const functionSpec = group.functions[functionName]!;\n\n return Layer.effect(\n FunctionImpl<string, FunctionName>({\n groupPath,\n functionName,\n }),\n Effect.gen(function* () {\n const registry = yield* Registry.Registry;\n\n yield* Ref.update(registry, (registryItems) =>\n setNestedProperty(\n registryItems,\n [...String.split(groupPath, \".\"), functionName],\n RegistryItem.make({\n functionSpec,\n handler,\n }),\n ),\n );\n\n return {\n groupPath,\n functionName,\n };\n }),\n );\n};\n\n/**\n * Get the function implementation service type for a specific group path and function name.\n */\nexport type ForGroupPathAndFunction<\n GroupPath_ extends string,\n FunctionName extends string,\n> = FunctionImpl<GroupPath_, FunctionName>;\n\n/**\n * Get all function implementation services required for a group spec.\n */\nexport type FromGroupSpec<Group extends GroupSpec.AnyWithProps> =\n FunctionSpec.Name<\n GroupSpec.Functions<Group>\n > extends infer FunctionNames extends string\n ? FunctionNames extends string\n ? FunctionImpl<string, FunctionNames>\n : never\n : never;\n\n/**\n * @deprecated Use {@link FromGroupSpec} instead.\n */\nexport type FromGroupAtPath<\n _GroupPath extends string,\n Group extends GroupSpec.AnyWithProps,\n> = FromGroupSpec<Group>;\n"],"mappings":";;;;;;;;;;;;AAkBA,MAAa,gBAGX,EACA,WACA,mBAKA,QAAQ,WACN,gCAAgC,UAAU,GAAG,eAC9C;AAEH,MAAa,QAKX,KACA,OACA,cACA,YAKoD;CACpD,MAAM,YAAY,uBAAuB,IAAI,MAAM,MAAM;CACzD,MAAM,eAAe,MAAM,UAAU;AAErC,QAAO,MAAM,OACX,aAAmC;EACjC;EACA;EACD,CAAC,EACF,OAAO,IAAI,aAAa;EACtB,MAAM,WAAW,OAAO,SAAS;AAEjC,SAAO,IAAI,OAAO,WAAW,kBAC3B,kBACE,eACA,CAAC,GAAG,OAAO,MAAM,WAAW,IAAI,EAAE,aAAa,EAC/CA,OAAkB;GAChB;GACA;GACD,CAAC,CACH,CACF;AAED,SAAO;GACL;GACA;GACD;GACD,CACH"}
|
package/dist/GroupImpl.d.ts
CHANGED
|
@@ -1,24 +1,63 @@
|
|
|
1
|
-
import { AnyWithProps
|
|
2
|
-
import {
|
|
1
|
+
import { AnyWithProps } from "./Api.js";
|
|
2
|
+
import { FromGroupSpec as FromGroupSpec$1 } from "./FunctionImpl.js";
|
|
3
3
|
import { Context, Layer } from "effect";
|
|
4
|
-
import * as GroupPath from "@confect/core/GroupPath";
|
|
5
4
|
import * as GroupSpec from "@confect/core/GroupSpec";
|
|
6
5
|
|
|
7
6
|
//#region src/GroupImpl.d.ts
|
|
8
7
|
declare namespace GroupImpl_d_exports {
|
|
9
|
-
export {
|
|
8
|
+
export { Any, AnyFinalized, AnyUnfinalized, FinalizationStatus, FromGroupSpec, GroupImpl, TypeId, finalize, isFinalizedGroupImpl, isGroupImpl, isUnfinalizedGroupImpl, make };
|
|
10
9
|
}
|
|
11
|
-
|
|
10
|
+
declare const TypeId = "@confect/server/GroupImpl";
|
|
11
|
+
type TypeId = typeof TypeId;
|
|
12
|
+
type FinalizationStatus = "Unfinalized" | "Finalized";
|
|
13
|
+
interface GroupImpl<GroupPath_ extends string, FinalizationStatus_ extends FinalizationStatus = "Unfinalized"> {
|
|
14
|
+
readonly [TypeId]: TypeId;
|
|
12
15
|
readonly groupPath: GroupPath_;
|
|
16
|
+
readonly finalizationStatus: FinalizationStatus_;
|
|
17
|
+
/**
|
|
18
|
+
* Names of every function registered into this group's layer scope by
|
|
19
|
+
* `FunctionImpl.make`. Authoritative only when `finalizationStatus` is
|
|
20
|
+
* `"Finalized"`; the `"Unfinalized"` value is set to `[]` at `make`-time
|
|
21
|
+
* since the list is only known once `finalize` snapshots the registry.
|
|
22
|
+
*/
|
|
23
|
+
readonly registeredFunctionNames: ReadonlyArray<string>;
|
|
13
24
|
}
|
|
14
|
-
|
|
15
|
-
|
|
25
|
+
interface Any extends GroupImpl<string, FinalizationStatus> {}
|
|
26
|
+
declare const isGroupImpl: (u: unknown) => u is Any;
|
|
27
|
+
interface AnyFinalized extends GroupImpl<string, "Finalized"> {}
|
|
28
|
+
interface AnyUnfinalized extends GroupImpl<string, "Unfinalized"> {}
|
|
29
|
+
declare const isFinalizedGroupImpl: (u: unknown) => u is AnyFinalized;
|
|
30
|
+
declare const isUnfinalizedGroupImpl: (u: unknown) => u is AnyUnfinalized;
|
|
31
|
+
/**
|
|
32
|
+
* Build the runtime tag for a `GroupImpl` service. The finalization status is
|
|
33
|
+
* embedded in the tag string so that `Unfinalized` and `Finalized` are distinct
|
|
34
|
+
* services at runtime; consumers of a finalized layer (the server's
|
|
35
|
+
* `RegisteredFunctions.buildForGroup` and the CLI's `implValidation`) retrieve
|
|
36
|
+
* the typed `Finalized` service directly rather than scanning the context.
|
|
37
|
+
*/
|
|
38
|
+
declare const GroupImpl: <GroupPath_ extends string, FinalizationStatus_ extends FinalizationStatus>({
|
|
39
|
+
groupPath,
|
|
40
|
+
finalizationStatus
|
|
16
41
|
}: {
|
|
17
42
|
groupPath: GroupPath_;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
43
|
+
finalizationStatus: FinalizationStatus_;
|
|
44
|
+
}) => Context.Tag<GroupImpl<GroupPath_, FinalizationStatus_>, GroupImpl<GroupPath_, FinalizationStatus_>>;
|
|
45
|
+
declare const make: <Api_ extends AnyWithProps, Group extends GroupSpec.AnyWithProps>(api: Api_, group: Group) => Layer.Layer<GroupImpl<string, "Unfinalized">, never, FromGroupSpec$1<Group>>;
|
|
46
|
+
/**
|
|
47
|
+
* Mark a `GroupImpl` layer as fully implemented. The parameter type defaults
|
|
48
|
+
* `RIn = never`, so passing a layer that still requires any `FunctionImpl`
|
|
49
|
+
* service produces a type error at the impl author's site. The codegen
|
|
50
|
+
* boundary requires the resulting `"Finalized"` brand, so omitting this call
|
|
51
|
+
* is also rejected downstream.
|
|
52
|
+
*
|
|
53
|
+
* As a side effect of finalization, the names of every `FunctionImpl` that
|
|
54
|
+
* registered into this group's scope are snapshotted onto the produced
|
|
55
|
+
* service value's `registeredFunctionNames` field, so consumers can verify
|
|
56
|
+
* impl completeness against a `GroupSpec`'s expected functions without
|
|
57
|
+
* having to inspect the `Registry` themselves.
|
|
58
|
+
*/
|
|
59
|
+
declare const finalize: <GroupPath_ extends string>(group: Layer.Layer<GroupImpl<GroupPath_, "Unfinalized">>) => Layer.Layer<GroupImpl<GroupPath_, "Finalized">>;
|
|
60
|
+
type FromGroupSpec<Group extends GroupSpec.AnyWithProps> = FromGroupSpec$1<Group>;
|
|
22
61
|
//#endregion
|
|
23
|
-
export {
|
|
62
|
+
export { Any, AnyFinalized, AnyUnfinalized, FinalizationStatus, FromGroupSpec, GroupImpl, GroupImpl_d_exports, TypeId, finalize, isFinalizedGroupImpl, isGroupImpl, isUnfinalizedGroupImpl, make };
|
|
24
63
|
//# sourceMappingURL=GroupImpl.d.ts.map
|
package/dist/GroupImpl.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GroupImpl.d.ts","names":[],"sources":["../src/GroupImpl.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"GroupImpl.d.ts","names":[],"sources":["../src/GroupImpl.ts"],"mappings":";;;;;;;;;cAkBa,MAAA;AAAA,KACD,MAAA,UAAgB,MAAA;AAAA,KAEhB,kBAAA;AAAA,UAEK,SAAA,wDAEa,kBAAA;EAAA,UAElB,MAAA,GAAS,MAAA;EAAA,SACV,SAAA,EAAW,UAAA;EAAA,SACX,kBAAA,EAAoB,mBAAA;;;;;;;WAOpB,uBAAA,EAAyB,aAAA;AAAA;AAAA,UAGnB,GAAA,SAAY,SAAA,SAAkB,kBAAA;AAAA,cAElC,WAAA,GAAe,CAAA,cAAa,CAAA,IAAK,GAAA;AAAA,UAG7B,YAAA,SAAqB,SAAA;AAAA,UACrB,cAAA,SAAuB,SAAA;AAAA,cAE3B,oBAAA,GAAwB,CAAA,cAAa,CAAA,IAAK,YAAA;AAAA,cAG1C,sBAAA,GAA0B,CAAA,cAAa,CAAA,IAAK,cAAA;;;;AA7BzD;;;;cAuCa,SAAA,0DAEiB,kBAAA;EAC5B,SAAA;EAAA;AAAA;EAIA,SAAA,EAAW,UAAA;EACX,kBAAA,EAAoB,mBAAA;AAAA,MACrB,OAAA,CAAA,GAAA,CAAA,SAAA,CAAA,UAAA,EAAA,mBAAA,GAAA,SAAA,CAAA,UAAA,EAAA,mBAAA;AAAA,cAKY,IAAA,gBACE,YAAA,gBACC,SAAA,CAAU,YAAA,EAExB,GAAA,EAAK,IAAA,EACL,KAAA,EAAO,KAAA,KACN,KAAA,CAAM,KAAA,CACP,SAAA,gCAEA,eAAA,CAA2B,KAAA;;;;;;;;;;;;;;cAuEhB,QAAA,8BACX,KAAA,EAAO,KAAA,CAAM,KAAA,CAAM,SAAA,CAAU,UAAA,sBAC5B,KAAA,CAAM,KAAA,CAAM,SAAA,CAAU,UAAA;AAAA,KAsCb,aAAA,eAA4B,SAAA,CAAU,YAAA,IAChD,eAAA,CAA2B,KAAA"}
|
package/dist/GroupImpl.js
CHANGED
|
@@ -1,14 +1,82 @@
|
|
|
1
1
|
import { __exportAll } from "./_virtual/_rolldown/runtime.js";
|
|
2
|
-
import {
|
|
2
|
+
import { resolveGroupPathUnsafe } from "./GroupPath.js";
|
|
3
|
+
import { Array, Context, Effect, Layer, Option, Predicate, Record, Ref, String, pipe } from "effect";
|
|
4
|
+
import * as Registry from "@confect/core/Registry";
|
|
3
5
|
|
|
4
6
|
//#region src/GroupImpl.ts
|
|
5
7
|
var GroupImpl_exports = /* @__PURE__ */ __exportAll({
|
|
6
8
|
GroupImpl: () => GroupImpl,
|
|
9
|
+
TypeId: () => TypeId,
|
|
10
|
+
finalize: () => finalize,
|
|
11
|
+
isFinalizedGroupImpl: () => isFinalizedGroupImpl,
|
|
12
|
+
isGroupImpl: () => isGroupImpl,
|
|
13
|
+
isUnfinalizedGroupImpl: () => isUnfinalizedGroupImpl,
|
|
7
14
|
make: () => make
|
|
8
15
|
});
|
|
9
|
-
const
|
|
10
|
-
const
|
|
16
|
+
const TypeId = "@confect/server/GroupImpl";
|
|
17
|
+
const isGroupImpl = (u) => Predicate.hasProperty(u, TypeId);
|
|
18
|
+
const isFinalizedGroupImpl = (u) => isGroupImpl(u) && u.finalizationStatus === "Finalized";
|
|
19
|
+
const isUnfinalizedGroupImpl = (u) => isGroupImpl(u) && u.finalizationStatus === "Unfinalized";
|
|
20
|
+
/**
|
|
21
|
+
* Build the runtime tag for a `GroupImpl` service. The finalization status is
|
|
22
|
+
* embedded in the tag string so that `Unfinalized` and `Finalized` are distinct
|
|
23
|
+
* services at runtime; consumers of a finalized layer (the server's
|
|
24
|
+
* `RegisteredFunctions.buildForGroup` and the CLI's `implValidation`) retrieve
|
|
25
|
+
* the typed `Finalized` service directly rather than scanning the context.
|
|
26
|
+
*/
|
|
27
|
+
const GroupImpl = ({ groupPath, finalizationStatus }) => Context.GenericTag(`@confect/server/GroupImpl/${finalizationStatus}/${groupPath}`);
|
|
28
|
+
const make = (api, group) => {
|
|
29
|
+
const groupPath = resolveGroupPathUnsafe(api.spec, group);
|
|
30
|
+
return Layer.succeed(GroupImpl({
|
|
31
|
+
groupPath,
|
|
32
|
+
finalizationStatus: "Unfinalized"
|
|
33
|
+
}), {
|
|
34
|
+
[TypeId]: TypeId,
|
|
35
|
+
groupPath,
|
|
36
|
+
finalizationStatus: "Unfinalized",
|
|
37
|
+
registeredFunctionNames: []
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
const isFunctionShaped = (value) => Predicate.isRecord(value) && "functionSpec" in value;
|
|
41
|
+
/**
|
|
42
|
+
* Walk a `RegistryItems` tree to the entries at `groupPath` and return the
|
|
43
|
+
* names of the function-shaped leaves directly underneath.
|
|
44
|
+
*/
|
|
45
|
+
const collectFunctionNamesAtPath = (items, groupPath) => pipe(String.split(groupPath, "."), Array.reduce(Option.some(items), (acc, segment) => acc.pipe(Option.filter(Predicate.isRecord), Option.flatMap((node) => segment in node ? Option.some(node[segment]) : Option.none()))), Option.filter(Predicate.isRecord), Option.map(Record.toEntries), Option.map(Array.filterMap(([name, value]) => isFunctionShaped(value) ? Option.some(name) : Option.none())), Option.getOrElse(() => []));
|
|
46
|
+
const findUnfinalizedGroupImpl = (context) => Array.findFirst(context.unsafeMap.values(), isUnfinalizedGroupImpl);
|
|
47
|
+
/**
|
|
48
|
+
* Mark a `GroupImpl` layer as fully implemented. The parameter type defaults
|
|
49
|
+
* `RIn = never`, so passing a layer that still requires any `FunctionImpl`
|
|
50
|
+
* service produces a type error at the impl author's site. The codegen
|
|
51
|
+
* boundary requires the resulting `"Finalized"` brand, so omitting this call
|
|
52
|
+
* is also rejected downstream.
|
|
53
|
+
*
|
|
54
|
+
* As a side effect of finalization, the names of every `FunctionImpl` that
|
|
55
|
+
* registered into this group's scope are snapshotted onto the produced
|
|
56
|
+
* service value's `registeredFunctionNames` field, so consumers can verify
|
|
57
|
+
* impl completeness against a `GroupSpec`'s expected functions without
|
|
58
|
+
* having to inspect the `Registry` themselves.
|
|
59
|
+
*/
|
|
60
|
+
const finalize = (group) => Layer.flatMap(group, (context) => findUnfinalizedGroupImpl(context).pipe(Option.match({
|
|
61
|
+
onNone: () => Layer.die(/* @__PURE__ */ new Error("GroupImpl.finalize: no Unfinalized GroupImpl service was found in the layer's context.")),
|
|
62
|
+
onSome: (unfinalized) => {
|
|
63
|
+
const groupPath = unfinalized.groupPath;
|
|
64
|
+
return Layer.effect(GroupImpl({
|
|
65
|
+
groupPath,
|
|
66
|
+
finalizationStatus: "Finalized"
|
|
67
|
+
}), Effect.gen(function* () {
|
|
68
|
+
const registry = yield* Registry.Registry;
|
|
69
|
+
const items = yield* Ref.get(registry);
|
|
70
|
+
return {
|
|
71
|
+
[TypeId]: TypeId,
|
|
72
|
+
groupPath,
|
|
73
|
+
finalizationStatus: "Finalized",
|
|
74
|
+
registeredFunctionNames: collectFunctionNamesAtPath(items, groupPath)
|
|
75
|
+
};
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
})));
|
|
11
79
|
|
|
12
80
|
//#endregion
|
|
13
|
-
export { GroupImpl, GroupImpl_exports, make };
|
|
81
|
+
export { GroupImpl, GroupImpl_exports, TypeId, finalize, isFinalizedGroupImpl, isGroupImpl, isUnfinalizedGroupImpl, make };
|
|
14
82
|
//# sourceMappingURL=GroupImpl.js.map
|