@confect/server 8.0.0 → 9.0.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +47 -0
- package/dist/Auth.d.ts +1 -1
- package/dist/DatabaseReader.d.ts +4 -4
- package/dist/DatabaseSchema.d.ts +9 -4
- package/dist/DatabaseSchema.d.ts.map +1 -1
- package/dist/DatabaseSchema.js +4 -3
- package/dist/DatabaseSchema.js.map +1 -1
- package/dist/DatabaseWriter.d.ts +4 -4
- package/dist/DatabaseWriter.d.ts.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/QueryInitializer.d.ts +1 -1
- package/dist/QueryInitializer.d.ts.map +1 -1
- package/dist/RegisteredConvexFunction.d.ts +8 -8
- package/dist/RegisteredConvexFunction.d.ts.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/index.d.ts +1 -3
- package/dist/index.js +1 -3
- package/package.json +4 -6
- package/src/DatabaseSchema.ts +10 -7
- package/src/FunctionImpl.ts +27 -36
- package/src/GroupImpl.ts +168 -32
- package/src/GroupPath.ts +43 -0
- 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,52 @@
|
|
|
1
1
|
# @confect/server
|
|
2
2
|
|
|
3
|
+
## 9.0.0-next.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- @confect/core@9.0.0-next.1
|
|
8
|
+
|
|
9
|
+
## 9.0.0-next.0
|
|
10
|
+
|
|
11
|
+
### Major Changes
|
|
12
|
+
|
|
13
|
+
- 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.
|
|
14
|
+
|
|
15
|
+
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.
|
|
16
|
+
|
|
17
|
+
### Why
|
|
18
|
+
|
|
19
|
+
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.
|
|
20
|
+
|
|
21
|
+
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.
|
|
22
|
+
|
|
23
|
+
### Breaking changes
|
|
24
|
+
- `GroupSpec.make()` and `GroupSpec.makeNode()` no longer take a name argument; the group name is derived from the spec file's path within `confect/`.
|
|
25
|
+
- `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.
|
|
26
|
+
- 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.
|
|
27
|
+
- 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`.
|
|
28
|
+
- 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`.
|
|
29
|
+
- 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.
|
|
30
|
+
|
|
31
|
+
### Migration
|
|
32
|
+
1. For each existing group, create a colocated `confect/{path}.spec.ts` and `confect/{path}.impl.ts` pair (under a subdirectory for nested groups).
|
|
33
|
+
- In each spec, call `GroupSpec.make()` (or `GroupSpec.makeNode()`) without a name and `export default` the result.
|
|
34
|
+
- 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:
|
|
35
|
+
```ts
|
|
36
|
+
export default GroupImpl.make(api, notes).pipe(
|
|
37
|
+
Layer.provide(list),
|
|
38
|
+
Layer.provide(insert),
|
|
39
|
+
GroupImpl.finalize,
|
|
40
|
+
);
|
|
41
|
+
```
|
|
42
|
+
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.)
|
|
43
|
+
3. Run `confect codegen`. Every module under `convex/` will be re-emitted.
|
|
44
|
+
|
|
45
|
+
### Patch Changes
|
|
46
|
+
|
|
47
|
+
- Updated dependencies [6db3a3a]
|
|
48
|
+
- @confect/core@9.0.0-next.0
|
|
49
|
+
|
|
3
50
|
## 8.0.0
|
|
4
51
|
|
|
5
52
|
### Major 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, R | Auth> : [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>;
|
package/dist/DatabaseReader.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ declare namespace DatabaseReader_d_exports {
|
|
|
19
19
|
declare const make: <DatabaseSchema_ extends AnyWithProps>(databaseSchema: DatabaseSchema_, convexDatabaseReader: GenericDatabaseReader<ToConvex<FromSchema<DatabaseSchema_>>>) => {
|
|
20
20
|
table: <const TableName extends Name<IncludeSystemTables<Tables<DatabaseSchema_>>>>(tableName: TableName) => {
|
|
21
21
|
readonly get: {
|
|
22
|
-
(id: convex_values0.GenericId<TableName>): effect_Effect0.Effect<TableInfo<WithName<IncludeSystemTables<Tables<DatabaseSchema_>>, TableName>>["document"],
|
|
22
|
+
(id: convex_values0.GenericId<TableName>): effect_Effect0.Effect<TableInfo<WithName<IncludeSystemTables<Tables<DatabaseSchema_>>, TableName>>["document"], GetByIdFailure | DocumentDecodeError, never>;
|
|
23
23
|
<IndexName extends keyof TableInfo<WithName<IncludeSystemTables<Tables<DatabaseSchema_>>, TableName>>["indexes"]>(indexName: IndexName, ...indexFieldValues: _confect_core_Types0.IndexFieldTypesForEq<ToConvex<DataModel<IncludeSystemTables<Tables<DatabaseSchema_>>>>, TableName, TableInfo<WithName<IncludeSystemTables<Tables<DatabaseSchema_>>, TableName>>["indexes"][IndexName]>): effect_Effect0.Effect<TableInfo<WithName<IncludeSystemTables<Tables<DatabaseSchema_>>, TableName>>["document"], DocumentDecodeError | GetByIndexFailure, never>;
|
|
24
24
|
};
|
|
25
25
|
readonly index: {
|
|
@@ -32,7 +32,7 @@ declare const make: <DatabaseSchema_ extends AnyWithProps>(databaseSchema: Datab
|
|
|
32
32
|
declare const DatabaseReader: <DatabaseSchema_ extends AnyWithProps>() => Context.Tag<{
|
|
33
33
|
table: <const TableName extends Name<IncludeSystemTables<Tables<DatabaseSchema_>>>>(tableName: TableName) => {
|
|
34
34
|
readonly get: {
|
|
35
|
-
(id: convex_values0.GenericId<TableName>): effect_Effect0.Effect<TableInfo<WithName<IncludeSystemTables<Tables<DatabaseSchema_>>, TableName>>["document"],
|
|
35
|
+
(id: convex_values0.GenericId<TableName>): effect_Effect0.Effect<TableInfo<WithName<IncludeSystemTables<Tables<DatabaseSchema_>>, TableName>>["document"], GetByIdFailure | DocumentDecodeError, never>;
|
|
36
36
|
<IndexName extends keyof TableInfo<WithName<IncludeSystemTables<Tables<DatabaseSchema_>>, TableName>>["indexes"]>(indexName: IndexName, ...indexFieldValues: _confect_core_Types0.IndexFieldTypesForEq<ToConvex<DataModel<IncludeSystemTables<Tables<DatabaseSchema_>>>>, TableName, TableInfo<WithName<IncludeSystemTables<Tables<DatabaseSchema_>>, TableName>>["indexes"][IndexName]>): effect_Effect0.Effect<TableInfo<WithName<IncludeSystemTables<Tables<DatabaseSchema_>>, TableName>>["document"], DocumentDecodeError | GetByIndexFailure, never>;
|
|
37
37
|
};
|
|
38
38
|
readonly index: {
|
|
@@ -44,7 +44,7 @@ declare const DatabaseReader: <DatabaseSchema_ extends AnyWithProps>() => Contex
|
|
|
44
44
|
}, {
|
|
45
45
|
table: <const TableName extends Name<IncludeSystemTables<Tables<DatabaseSchema_>>>>(tableName: TableName) => {
|
|
46
46
|
readonly get: {
|
|
47
|
-
(id: convex_values0.GenericId<TableName>): effect_Effect0.Effect<TableInfo<WithName<IncludeSystemTables<Tables<DatabaseSchema_>>, TableName>>["document"],
|
|
47
|
+
(id: convex_values0.GenericId<TableName>): effect_Effect0.Effect<TableInfo<WithName<IncludeSystemTables<Tables<DatabaseSchema_>>, TableName>>["document"], GetByIdFailure | DocumentDecodeError, never>;
|
|
48
48
|
<IndexName extends keyof TableInfo<WithName<IncludeSystemTables<Tables<DatabaseSchema_>>, TableName>>["indexes"]>(indexName: IndexName, ...indexFieldValues: _confect_core_Types0.IndexFieldTypesForEq<ToConvex<DataModel<IncludeSystemTables<Tables<DatabaseSchema_>>>>, TableName, TableInfo<WithName<IncludeSystemTables<Tables<DatabaseSchema_>>, TableName>>["indexes"][IndexName]>): effect_Effect0.Effect<TableInfo<WithName<IncludeSystemTables<Tables<DatabaseSchema_>>, TableName>>["document"], DocumentDecodeError | GetByIndexFailure, never>;
|
|
49
49
|
};
|
|
50
50
|
readonly index: {
|
|
@@ -58,7 +58,7 @@ type DatabaseReader<DatabaseSchema_ extends AnyWithProps> = ReturnType<typeof Da
|
|
|
58
58
|
declare const layer: <DatabaseSchema_ extends AnyWithProps>(databaseSchema: DatabaseSchema_, convexDatabaseReader: GenericDatabaseReader<ToConvex<FromSchema<DatabaseSchema_>>>) => Layer.Layer<{
|
|
59
59
|
table: <const TableName extends Name<IncludeSystemTables<Tables<DatabaseSchema_>>>>(tableName: TableName) => {
|
|
60
60
|
readonly get: {
|
|
61
|
-
(id: convex_values0.GenericId<TableName>): effect_Effect0.Effect<TableInfo<WithName<IncludeSystemTables<Tables<DatabaseSchema_>>, TableName>>["document"],
|
|
61
|
+
(id: convex_values0.GenericId<TableName>): effect_Effect0.Effect<TableInfo<WithName<IncludeSystemTables<Tables<DatabaseSchema_>>, TableName>>["document"], GetByIdFailure | DocumentDecodeError, never>;
|
|
62
62
|
<IndexName extends keyof TableInfo<WithName<IncludeSystemTables<Tables<DatabaseSchema_>>, TableName>>["indexes"]>(indexName: IndexName, ...indexFieldValues: _confect_core_Types0.IndexFieldTypesForEq<ToConvex<DataModel<IncludeSystemTables<Tables<DatabaseSchema_>>>>, TableName, TableInfo<WithName<IncludeSystemTables<Tables<DatabaseSchema_>>, TableName>>["indexes"][IndexName]>): effect_Effect0.Effect<TableInfo<WithName<IncludeSystemTables<Tables<DatabaseSchema_>>, TableName>>["document"], DocumentDecodeError | GetByIndexFailure, never>;
|
|
63
63
|
};
|
|
64
64
|
readonly index: {
|
package/dist/DatabaseSchema.d.ts
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
import { AnyWithProps as AnyWithProps$1, Name, SystemTables, Table, TablesRecord, WithName } from "./Table.js";
|
|
2
2
|
import { Expand, GenericSchema, SchemaDefinition } from "convex/server";
|
|
3
3
|
import * as convex_values0 from "convex/values";
|
|
4
|
-
import { Any, TypeId, TypeId as TypeId$1, isDatabaseSchema } from "@confect/core/DatabaseSchema";
|
|
5
4
|
import * as effect_Schema0 from "effect/Schema";
|
|
6
5
|
|
|
7
6
|
//#region src/DatabaseSchema.d.ts
|
|
8
7
|
declare namespace DatabaseSchema_d_exports {
|
|
9
8
|
export { Any, AnyWithProps, ConvexDatabaseSchemaFromTables, DatabaseSchema, ExtendWithSystemTables, IncludeSystemTables, TableNames, TableWithName, Tables, TypeId, extendWithSystemTables, isDatabaseSchema, make, systemSchema };
|
|
10
9
|
}
|
|
10
|
+
declare const TypeId = "@confect/server/DatabaseSchema";
|
|
11
|
+
type TypeId = typeof TypeId;
|
|
12
|
+
interface Any {
|
|
13
|
+
readonly [TypeId]: TypeId;
|
|
14
|
+
}
|
|
15
|
+
declare const isDatabaseSchema: (u: unknown) => u is Any;
|
|
11
16
|
/**
|
|
12
17
|
* A schema definition tracks the schema and its Convex schema definition.
|
|
13
18
|
*/
|
|
14
19
|
interface DatabaseSchema<Tables_ extends AnyWithProps$1 = never> {
|
|
15
|
-
readonly [TypeId
|
|
20
|
+
readonly [TypeId]: TypeId;
|
|
16
21
|
readonly tables: TablesRecord<Tables_>;
|
|
17
22
|
readonly convexSchemaDefinition: SchemaDefinition<ConvexDatabaseSchemaFromTables<Tables_>, true>;
|
|
18
23
|
/**
|
|
@@ -21,7 +26,7 @@ interface DatabaseSchema<Tables_ extends AnyWithProps$1 = never> {
|
|
|
21
26
|
addTable<TableDef extends AnyWithProps$1>(table: TableDef): DatabaseSchema<Tables_ | TableDef>;
|
|
22
27
|
}
|
|
23
28
|
interface AnyWithProps {
|
|
24
|
-
readonly [TypeId
|
|
29
|
+
readonly [TypeId]: TypeId;
|
|
25
30
|
readonly tables: Record<string, AnyWithProps$1>;
|
|
26
31
|
readonly convexSchemaDefinition: SchemaDefinition<GenericSchema, true>;
|
|
27
32
|
addTable<TableDef extends AnyWithProps$1>(table: TableDef): AnyWithProps;
|
|
@@ -130,5 +135,5 @@ declare const extendWithSystemTables: <Tables_ extends AnyWithProps$1>(tables: T
|
|
|
130
135
|
type ExtendWithSystemTables<Tables_ extends AnyWithProps$1> = TablesRecord<Tables_ | SystemTables>;
|
|
131
136
|
type IncludeSystemTables<Tables_ extends AnyWithProps$1> = Tables_ | SystemTables extends infer T ? T extends AnyWithProps$1 ? T : never : never;
|
|
132
137
|
//#endregion
|
|
133
|
-
export {
|
|
138
|
+
export { Any, AnyWithProps, ConvexDatabaseSchemaFromTables, DatabaseSchema, DatabaseSchema_d_exports, ExtendWithSystemTables, IncludeSystemTables, TableNames, TableWithName, Tables, TypeId, extendWithSystemTables, isDatabaseSchema, make, systemSchema };
|
|
134
139
|
//# sourceMappingURL=DatabaseSchema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatabaseSchema.d.ts","names":[],"sources":["../src/DatabaseSchema.ts"],"mappings":"
|
|
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
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { __exportAll } from "./_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { scheduledFunctionsTable, storageTable, systemTables } from "./Table.js";
|
|
3
|
-
import { Array, Record, pipe } from "effect";
|
|
3
|
+
import { Array, Predicate, Record, pipe } from "effect";
|
|
4
4
|
import { defineSchema } from "convex/server";
|
|
5
|
-
import { TypeId, TypeId as TypeId$1, isDatabaseSchema } from "@confect/core/DatabaseSchema";
|
|
6
5
|
|
|
7
6
|
//#region src/DatabaseSchema.ts
|
|
8
7
|
var DatabaseSchema_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -12,8 +11,10 @@ var DatabaseSchema_exports = /* @__PURE__ */ __exportAll({
|
|
|
12
11
|
make: () => make,
|
|
13
12
|
systemSchema: () => systemSchema
|
|
14
13
|
});
|
|
14
|
+
const TypeId = "@confect/server/DatabaseSchema";
|
|
15
|
+
const isDatabaseSchema = (u) => Predicate.hasProperty(u, TypeId);
|
|
15
16
|
const Proto = {
|
|
16
|
-
[TypeId
|
|
17
|
+
[TypeId]: TypeId,
|
|
17
18
|
addTable(table) {
|
|
18
19
|
const newTablesArray = [...Object.values(this.tables), table];
|
|
19
20
|
return makeProto({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatabaseSchema.js","names":["
|
|
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/DatabaseWriter.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ declare namespace DatabaseWriter_d_exports {
|
|
|
13
13
|
declare const make: <DatabaseSchema_ extends AnyWithProps>(databaseSchema: DatabaseSchema_, convexDatabaseWriter: GenericDatabaseWriter<ToConvex<FromSchema<DatabaseSchema_>>>) => {
|
|
14
14
|
table: <const TableName extends TableNames<FromSchema<DatabaseSchema_>>>(tableName: TableName) => {
|
|
15
15
|
insert: (document: WithoutSystemFields$1<DocumentByName<FromSchema<DatabaseSchema_>, TableName>>) => Effect.Effect<GenericId<TableName>, DocumentEncodeError, never>;
|
|
16
|
-
patch: (id: GenericId<TableName>, patchedValues: Partial<WithoutSystemFields<DocumentByName<FromSchema<DatabaseSchema_>, TableName>>>) => Effect.Effect<void,
|
|
16
|
+
patch: (id: GenericId<TableName>, patchedValues: Partial<WithoutSystemFields<DocumentByName<FromSchema<DatabaseSchema_>, TableName>>>) => Effect.Effect<void, GetByIdFailure | DocumentDecodeError | DocumentEncodeError, never>;
|
|
17
17
|
replace: (id: GenericId<TableName>, value: WithoutSystemFields<DocumentByName<FromSchema<DatabaseSchema_>, TableName>>) => Effect.Effect<void, DocumentEncodeError, never>;
|
|
18
18
|
delete: (id: GenericId<TableName>) => Effect.Effect<void, never, never>;
|
|
19
19
|
};
|
|
@@ -21,14 +21,14 @@ declare const make: <DatabaseSchema_ extends AnyWithProps>(databaseSchema: Datab
|
|
|
21
21
|
declare const DatabaseWriter: <DatabaseSchema_ extends AnyWithProps>() => Context.Tag<{
|
|
22
22
|
table: <const TableName extends TableNames<FromSchema<DatabaseSchema_>>>(tableName: TableName) => {
|
|
23
23
|
insert: (document: WithoutSystemFields$1<DocumentByName<FromSchema<DatabaseSchema_>, TableName>>) => Effect.Effect<GenericId<TableName>, DocumentEncodeError, never>;
|
|
24
|
-
patch: (id: GenericId<TableName>, patchedValues: Partial<Expand<BetterOmit<DocumentByName<FromSchema<DatabaseSchema_>, TableName>, "_id" | "_creationTime">>>) => Effect.Effect<void,
|
|
24
|
+
patch: (id: GenericId<TableName>, patchedValues: Partial<Expand<BetterOmit<DocumentByName<FromSchema<DatabaseSchema_>, TableName>, "_id" | "_creationTime">>>) => Effect.Effect<void, GetByIdFailure | DocumentDecodeError | DocumentEncodeError, never>;
|
|
25
25
|
replace: (id: GenericId<TableName>, value: Expand<BetterOmit<DocumentByName<FromSchema<DatabaseSchema_>, TableName>, "_id" | "_creationTime">>) => Effect.Effect<void, DocumentEncodeError, never>;
|
|
26
26
|
delete: (id: GenericId<TableName>) => Effect.Effect<void, never, never>;
|
|
27
27
|
};
|
|
28
28
|
}, {
|
|
29
29
|
table: <const TableName extends TableNames<FromSchema<DatabaseSchema_>>>(tableName: TableName) => {
|
|
30
30
|
insert: (document: WithoutSystemFields$1<DocumentByName<FromSchema<DatabaseSchema_>, TableName>>) => Effect.Effect<GenericId<TableName>, DocumentEncodeError, never>;
|
|
31
|
-
patch: (id: GenericId<TableName>, patchedValues: Partial<Expand<BetterOmit<DocumentByName<FromSchema<DatabaseSchema_>, TableName>, "_id" | "_creationTime">>>) => Effect.Effect<void,
|
|
31
|
+
patch: (id: GenericId<TableName>, patchedValues: Partial<Expand<BetterOmit<DocumentByName<FromSchema<DatabaseSchema_>, TableName>, "_id" | "_creationTime">>>) => Effect.Effect<void, GetByIdFailure | DocumentDecodeError | DocumentEncodeError, never>;
|
|
32
32
|
replace: (id: GenericId<TableName>, value: Expand<BetterOmit<DocumentByName<FromSchema<DatabaseSchema_>, TableName>, "_id" | "_creationTime">>) => Effect.Effect<void, DocumentEncodeError, never>;
|
|
33
33
|
delete: (id: GenericId<TableName>) => Effect.Effect<void, never, never>;
|
|
34
34
|
};
|
|
@@ -37,7 +37,7 @@ type DatabaseWriter<DatabaseSchema_ extends AnyWithProps> = ReturnType<typeof Da
|
|
|
37
37
|
declare const layer: <DatabaseSchema_ extends AnyWithProps>(databaseSchema: DatabaseSchema_, convexDatabaseWriter: GenericDatabaseWriter<ToConvex<FromSchema<DatabaseSchema_>>>) => Layer.Layer<{
|
|
38
38
|
table: <const TableName extends TableNames<FromSchema<DatabaseSchema_>>>(tableName: TableName) => {
|
|
39
39
|
insert: (document: WithoutSystemFields$1<DocumentByName<FromSchema<DatabaseSchema_>, TableName>>) => Effect.Effect<GenericId<TableName>, DocumentEncodeError, never>;
|
|
40
|
-
patch: (id: GenericId<TableName>, patchedValues: Partial<Expand<BetterOmit<DocumentByName<FromSchema<DatabaseSchema_>, TableName>, "_id" | "_creationTime">>>) => Effect.Effect<void,
|
|
40
|
+
patch: (id: GenericId<TableName>, patchedValues: Partial<Expand<BetterOmit<DocumentByName<FromSchema<DatabaseSchema_>, TableName>, "_id" | "_creationTime">>>) => Effect.Effect<void, GetByIdFailure | DocumentDecodeError | DocumentEncodeError, never>;
|
|
41
41
|
replace: (id: GenericId<TableName>, value: Expand<BetterOmit<DocumentByName<FromSchema<DatabaseSchema_>, TableName>, "_id" | "_creationTime">>) => Effect.Effect<void, DocumentEncodeError, never>;
|
|
42
42
|
delete: (id: GenericId<TableName>) => Effect.Effect<void, never, never>;
|
|
43
43
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatabaseWriter.d.ts","names":[],"sources":["../src/DatabaseWriter.ts"],"mappings":";;;;;;;;;;;;cAiBa,IAAA,2BAAgC,YAAA,EAC3C,cAAA,EAAgB,eAAA,EAChB,oBAAA,EAAsB,qBAAA,CACpB,QAAA,CAAmB,UAAA,CAAqB,eAAA;kCAMH,UAAA,CAAoB,UAAA,CAAA,eAAA,IAAY,SAAA,EAC1D,SAAA;uBAQC,qBAAA,CACR,cAAA,CAAe,UAAA,CAAA,eAAA,GAAa,SAAA,OAC7B,MAAA,CAAA,MAAA,CAAA,SAAA,CAAA,SAAA,GAAA,mBAAA;gBAsBG,SAAA,CAAU,SAAA,GAAU,aAAA,EACT,OAAA,CACb,mBAAA,CAAoB,cAAA,CAAe,UAAA,CAAA,eAAA,GAAa,SAAA,QACjD,MAAA,CAAA,MAAA,OAAA,
|
|
1
|
+
{"version":3,"file":"DatabaseWriter.d.ts","names":[],"sources":["../src/DatabaseWriter.ts"],"mappings":";;;;;;;;;;;;cAiBa,IAAA,2BAAgC,YAAA,EAC3C,cAAA,EAAgB,eAAA,EAChB,oBAAA,EAAsB,qBAAA,CACpB,QAAA,CAAmB,UAAA,CAAqB,eAAA;kCAMH,UAAA,CAAoB,UAAA,CAAA,eAAA,IAAY,SAAA,EAC1D,SAAA;uBAQC,qBAAA,CACR,cAAA,CAAe,UAAA,CAAA,eAAA,GAAa,SAAA,OAC7B,MAAA,CAAA,MAAA,CAAA,SAAA,CAAA,SAAA,GAAA,mBAAA;gBAsBG,SAAA,CAAU,SAAA,GAAU,aAAA,EACT,OAAA,CACb,mBAAA,CAAoB,cAAA,CAAe,UAAA,CAAA,eAAA,GAAa,SAAA,QACjD,MAAA,CAAA,MAAA,OAAA,cAAA,GAAA,mBAAA,GAAA,mBAAA;kBAiCG,SAAA,CAAU,SAAA,GAAU,KAAA,EACjB,mBAAA,CAAoB,cAAA,CAAe,UAAA,CAAA,eAAA,GAAa,SAAA,OAAW,MAAA,CAAA,MAAA,OAAA,mBAAA;iBAsB/C,SAAA,CAAU,SAAA,MAAU,MAAA,CAAA,MAAA;EAAA;AAAA;AAAA,cAgBhC,cAAA,2BACa,YAAA,OAA2B,OAAA,CAAA,GAAA;kCA7GrB,UAAA,CAAA,UAAA,CAAA,eAAA,IAAA,SAAA,EAAA,SAAA;;;;;;;kCAAA,UAAA,CAAA,UAAA,CAAA,eAAA,IAAA,SAAA,EAAA,SAAA;;;;;;;KAmHpB,cAAA,yBACc,YAAA,IACtB,UAAA,QAAkB,cAAA,CAAe,eAAA;AAAA,cAExB,KAAA,2BAAiC,YAAA,EAC5C,cAAA,EAAgB,eAAA,EAChB,oBAAA,EAAsB,qBAAA,CACpB,QAAA,CAAmB,UAAA,CAAqB,eAAA,QACzC,KAAA,CAAA,KAAA;kCA3H6B,UAAA,CAAA,UAAA,CAAA,eAAA,IAAA,SAAA,EAAA,SAAA"}
|
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
|
package/dist/GroupImpl.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GroupImpl.js","names":[],"sources":["../src/GroupImpl.ts"],"sourcesContent":["import type * as
|
|
1
|
+
{"version":3,"file":"GroupImpl.js","names":[],"sources":["../src/GroupImpl.ts"],"sourcesContent":["import type * as GroupSpec from \"@confect/core/GroupSpec\";\nimport * as Registry from \"@confect/core/Registry\";\nimport {\n Array,\n Context,\n Effect,\n Layer,\n Option,\n pipe,\n Predicate,\n Record,\n Ref,\n String,\n} from \"effect\";\nimport type * as Api from \"./Api\";\nimport type * as FunctionImpl from \"./FunctionImpl\";\nimport { resolveGroupPathUnsafe } from \"./GroupPath\";\n\nexport const TypeId = \"@confect/server/GroupImpl\";\nexport type TypeId = typeof TypeId;\n\nexport type FinalizationStatus = \"Unfinalized\" | \"Finalized\";\n\nexport interface GroupImpl<\n GroupPath_ extends string,\n FinalizationStatus_ extends FinalizationStatus = \"Unfinalized\",\n> {\n readonly [TypeId]: TypeId;\n readonly groupPath: GroupPath_;\n readonly finalizationStatus: FinalizationStatus_;\n /**\n * Names of every function registered into this group's layer scope by\n * `FunctionImpl.make`. Authoritative only when `finalizationStatus` is\n * `\"Finalized\"`; the `\"Unfinalized\"` value is set to `[]` at `make`-time\n * since the list is only known once `finalize` snapshots the registry.\n */\n readonly registeredFunctionNames: ReadonlyArray<string>;\n}\n\nexport interface Any extends GroupImpl<string, FinalizationStatus> {}\n\nexport const isGroupImpl = (u: unknown): u is Any =>\n Predicate.hasProperty(u, TypeId);\n\nexport interface AnyFinalized extends GroupImpl<string, \"Finalized\"> {}\nexport interface AnyUnfinalized extends GroupImpl<string, \"Unfinalized\"> {}\n\nexport const isFinalizedGroupImpl = (u: unknown): u is AnyFinalized =>\n isGroupImpl(u) && u.finalizationStatus === \"Finalized\";\n\nexport const isUnfinalizedGroupImpl = (u: unknown): u is AnyUnfinalized =>\n isGroupImpl(u) && u.finalizationStatus === \"Unfinalized\";\n\n/**\n * Build the runtime tag for a `GroupImpl` service. The finalization status is\n * embedded in the tag string so that `Unfinalized` and `Finalized` are distinct\n * services at runtime; consumers of a finalized layer (the server's\n * `RegisteredFunctions.buildForGroup` and the CLI's `implValidation`) retrieve\n * the typed `Finalized` service directly rather than scanning the context.\n */\nexport const GroupImpl = <\n GroupPath_ extends string,\n FinalizationStatus_ extends FinalizationStatus,\n>({\n groupPath,\n finalizationStatus,\n}: {\n groupPath: GroupPath_;\n finalizationStatus: FinalizationStatus_;\n}) =>\n Context.GenericTag<GroupImpl<GroupPath_, FinalizationStatus_>>(\n `@confect/server/GroupImpl/${finalizationStatus}/${groupPath}`,\n );\n\nexport const make = <\n Api_ extends Api.AnyWithProps,\n Group extends GroupSpec.AnyWithProps,\n>(\n api: Api_,\n group: Group,\n): Layer.Layer<\n GroupImpl<string, \"Unfinalized\">,\n never,\n FunctionImpl.FromGroupSpec<Group>\n> => {\n const groupPath = resolveGroupPathUnsafe(api.spec, group);\n\n return Layer.succeed(\n GroupImpl<string, \"Unfinalized\">({\n groupPath,\n finalizationStatus: \"Unfinalized\",\n }),\n {\n [TypeId]: TypeId,\n groupPath,\n finalizationStatus: \"Unfinalized\" as const,\n registeredFunctionNames: [],\n },\n ) as Layer.Layer<\n GroupImpl<string, \"Unfinalized\">,\n never,\n FunctionImpl.FromGroupSpec<Group>\n >;\n};\n\nconst isFunctionShaped = (value: unknown): boolean =>\n Predicate.isRecord(value) && \"functionSpec\" in value;\n\n/**\n * Walk a `RegistryItems` tree to the entries at `groupPath` and return the\n * names of the function-shaped leaves directly underneath.\n */\nconst collectFunctionNamesAtPath = (\n items: Registry.RegistryItems,\n groupPath: string,\n): ReadonlyArray<string> =>\n pipe(\n String.split(groupPath, \".\"),\n Array.reduce(Option.some<unknown>(items), (acc, segment) =>\n acc.pipe(\n Option.filter(Predicate.isRecord),\n Option.flatMap((node) =>\n segment in node ? Option.some(node[segment]) : Option.none(),\n ),\n ),\n ),\n Option.filter(Predicate.isRecord),\n Option.map(Record.toEntries),\n Option.map(\n Array.filterMap(([name, value]) =>\n isFunctionShaped(value) ? Option.some(name) : Option.none(),\n ),\n ),\n Option.getOrElse((): ReadonlyArray<string> => []),\n );\n\nconst findUnfinalizedGroupImpl = <S>(\n context: Context.Context<S>,\n): Option.Option<AnyUnfinalized> =>\n Array.findFirst(context.unsafeMap.values(), isUnfinalizedGroupImpl);\n\n/**\n * Mark a `GroupImpl` layer as fully implemented. The parameter type defaults\n * `RIn = never`, so passing a layer that still requires any `FunctionImpl`\n * service produces a type error at the impl author's site. The codegen\n * boundary requires the resulting `\"Finalized\"` brand, so omitting this call\n * is also rejected downstream.\n *\n * As a side effect of finalization, the names of every `FunctionImpl` that\n * registered into this group's scope are snapshotted onto the produced\n * service value's `registeredFunctionNames` field, so consumers can verify\n * impl completeness against a `GroupSpec`'s expected functions without\n * having to inspect the `Registry` themselves.\n */\nexport const finalize = <GroupPath_ extends string>(\n group: Layer.Layer<GroupImpl<GroupPath_, \"Unfinalized\">>,\n): Layer.Layer<GroupImpl<GroupPath_, \"Finalized\">> =>\n Layer.flatMap(\n group,\n (context): Layer.Layer<GroupImpl<GroupPath_, \"Finalized\">> =>\n findUnfinalizedGroupImpl(context).pipe(\n Option.match({\n onNone: () =>\n Layer.die(\n new Error(\n \"GroupImpl.finalize: no Unfinalized GroupImpl service was found in the layer's context.\",\n ),\n ),\n onSome: (unfinalized) => {\n const groupPath = unfinalized.groupPath as GroupPath_;\n return Layer.effect(\n GroupImpl<GroupPath_, \"Finalized\">({\n groupPath,\n finalizationStatus: \"Finalized\",\n }),\n Effect.gen(function* () {\n const registry = yield* Registry.Registry;\n const items = yield* Ref.get(registry);\n return {\n [TypeId]: TypeId,\n groupPath,\n finalizationStatus: \"Finalized\" as const,\n registeredFunctionNames: collectFunctionNamesAtPath(\n items,\n groupPath,\n ),\n };\n }),\n );\n },\n }),\n ),\n );\n\nexport type FromGroupSpec<Group extends GroupSpec.AnyWithProps> =\n FunctionImpl.FromGroupSpec<Group>;\n"],"mappings":";;;;;;;;;;;;;;;AAkBA,MAAa,SAAS;AAuBtB,MAAa,eAAe,MAC1B,UAAU,YAAY,GAAG,OAAO;AAKlC,MAAa,wBAAwB,MACnC,YAAY,EAAE,IAAI,EAAE,uBAAuB;AAE7C,MAAa,0BAA0B,MACrC,YAAY,EAAE,IAAI,EAAE,uBAAuB;;;;;;;;AAS7C,MAAa,aAGX,EACA,WACA,yBAKA,QAAQ,WACN,6BAA6B,mBAAmB,GAAG,YACpD;AAEH,MAAa,QAIX,KACA,UAKG;CACH,MAAM,YAAY,uBAAuB,IAAI,MAAM,MAAM;AAEzD,QAAO,MAAM,QACX,UAAiC;EAC/B;EACA,oBAAoB;EACrB,CAAC,EACF;GACG,SAAS;EACV;EACA,oBAAoB;EACpB,yBAAyB,EAAE;EAC5B,CACF;;AAOH,MAAM,oBAAoB,UACxB,UAAU,SAAS,MAAM,IAAI,kBAAkB;;;;;AAMjD,MAAM,8BACJ,OACA,cAEA,KACE,OAAO,MAAM,WAAW,IAAI,EAC5B,MAAM,OAAO,OAAO,KAAc,MAAM,GAAG,KAAK,YAC9C,IAAI,KACF,OAAO,OAAO,UAAU,SAAS,EACjC,OAAO,SAAS,SACd,WAAW,OAAO,OAAO,KAAK,KAAK,SAAS,GAAG,OAAO,MAAM,CAC7D,CACF,CACF,EACD,OAAO,OAAO,UAAU,SAAS,EACjC,OAAO,IAAI,OAAO,UAAU,EAC5B,OAAO,IACL,MAAM,WAAW,CAAC,MAAM,WACtB,iBAAiB,MAAM,GAAG,OAAO,KAAK,KAAK,GAAG,OAAO,MAAM,CAC5D,CACF,EACD,OAAO,gBAAuC,EAAE,CAAC,CAClD;AAEH,MAAM,4BACJ,YAEA,MAAM,UAAU,QAAQ,UAAU,QAAQ,EAAE,uBAAuB;;;;;;;;;;;;;;AAerE,MAAa,YACX,UAEA,MAAM,QACJ,QACC,YACC,yBAAyB,QAAQ,CAAC,KAChC,OAAO,MAAM;CACX,cACE,MAAM,oBACJ,IAAI,MACF,yFACD,CACF;CACH,SAAS,gBAAgB;EACvB,MAAM,YAAY,YAAY;AAC9B,SAAO,MAAM,OACX,UAAmC;GACjC;GACA,oBAAoB;GACrB,CAAC,EACF,OAAO,IAAI,aAAa;GACtB,MAAM,WAAW,OAAO,SAAS;GACjC,MAAM,QAAQ,OAAO,IAAI,IAAI,SAAS;AACtC,UAAO;KACJ,SAAS;IACV;IACA,oBAAoB;IACpB,yBAAyB,2BACvB,OACA,UACD;IACF;IACD,CACH;;CAEJ,CAAC,CACH,CACJ"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as Spec from "@confect/core/Spec";
|
|
2
|
+
import * as GroupSpec from "@confect/core/GroupSpec";
|
|
3
|
+
|
|
4
|
+
//#region src/GroupPath.d.ts
|
|
5
|
+
declare const resolveGroupPathUnsafe: (spec: Spec.AnyWithProps, target: GroupSpec.AnyWithProps) => string;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { resolveGroupPathUnsafe };
|
|
8
|
+
//# sourceMappingURL=GroupPath.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GroupPath.d.ts","names":[],"sources":["../src/GroupPath.ts"],"mappings":";;;;cA+Ba,sBAAA,GACX,IAAA,EAAM,IAAA,CAAK,YAAA,EACX,MAAA,EAAQ,SAAA,CAAU,YAAA"}
|