### Install Confect Package Source: https://rjdellecese.gitbook.io/confect/getting-started Instructions for installing the Confect package using common JavaScript package managers: npm, yarn, or pnpm. ```npm npm install @rjdellecese/confect ``` ```yarn yarn add @rjdellecese/confect ``` ```pnpm pnpm add @rjdellecese/confect ``` -------------------------------- ### Define Confect Database Schema with Effect Schema Source: https://rjdellecese.gitbook.io/confect/getting-started Illustrates how to define a database schema for Confect using `defineSchema` and `defineTable` from `@rjdellecese/confect/server` in conjunction with Effect Schema for robust data validation. This example defines 'notes', 'users', and 'tags' tables, including complex nested types, optional fields, and various index types like `index`, `searchIndex`, and `vectorIndex` for efficient data querying. ```TypeScript import { Id, defineSchema, defineTable } from "@rjdellecese/confect/server"; import { Schema } from "effect"; type Tag = { readonly name: string; readonly tags: readonly Tag[]; }; const Tag = Schema.Struct({ name: Schema.String, tags: Schema.Array(Schema.suspend((): Schema.Schema => Tag)), }); export const confectSchema = defineSchema({ notes: defineTable( Schema.Struct({ userId: Schema.optional(Id.Id("users")), text: Schema.String.pipe(Schema.maxLength(100)), tag: Schema.optional(Schema.String), author: Schema.optional( Schema.Struct({ role: Schema.Literal("admin", "user"), name: Schema.String, }), ), embedding: Schema.optional(Schema.Array(Schema.Number)), }), ) .index("by_text", ["text"]) .index("by_role", ["author.role"]) .searchIndex("text", { searchField: "text", filterFields: ["tag"] }) .vectorIndex("embedding", { vectorField: "embedding", filterFields: ["author.name", "tag"], dimensions: 1536 }), users: defineTable( Schema.Struct({ username: Schema.String, }), ), tags: defineTable(Tag), }); export default confectSchema.convexSchemaDefinition; ``` -------------------------------- ### Generate Convex Function Constructors and Context Types (TypeScript) Source: https://rjdellecese.gitbook.io/confect/getting-started This TypeScript code snippet illustrates the initial setup for Convex functions using the `confect` library. It imports core services and types, then uses `makeFunctions` to create `action`, `mutation`, and `query` constructors based on a defined schema. Additionally, it exports typed context objects (`ConfectQueryCtx`, `ConfectMutationCtx`, `ConfectActionCtx`) for use within Convex handlers, ensuring type safety for database interactions. ```typescript import { ConfectActionCtx as ConfectActionCtxService, type ConfectActionCtx as ConfectActionCtxType, type ConfectDataModelFromConfectSchemaDefinition, type ConfectDoc as ConfectDocType, ConfectMutationCtx as ConfectMutationCtxService, type ConfectMutationCtx as ConfectMutationCtxType, ConfectQueryCtx as ConfectQueryCtxService, type ConfectQueryCtx as ConfectQueryCtxType, type TableNamesInConfectDataModel, makeFunctions, } from "@rjdellecese/confect/server"; import { confectSchema } from "./schema"; export const { action, internalAction, internalMutation, internalQuery, mutation, query, } = makeFunctions(confectSchema); type ConfectSchema = typeof confectSchema; type ConfectDataModel = ConfectDataModelFromConfectSchemaDefinition; export type ConfectDoc< TableName extends TableNamesInConfectDataModel, > = ConfectDocType; export const ConfectQueryCtx = ConfectQueryCtxService(); export type ConfectQueryCtx = ConfectQueryCtxType; export const ConfectMutationCtx = ConfectMutationCtxService(); export type ConfectMutationCtx = ConfectMutationCtxType; export const ConfectActionCtx = ConfectActionCtxService(); export type ConfectActionCtx = ConfectActionCtxType; ``` -------------------------------- ### Implement Convex Mutations, Queries, and Actions (TypeScript) Source: https://rjdellecese.gitbook.io/confect/getting-started This TypeScript example demonstrates how to write various Convex functions: `mutation` for data modification (e.g., `insertNote`, `deleteNote`), `query` for data retrieval (e.g., `listNotes`, `getFirst`), and `action` for side effects (e.g., `getRandom`). It showcases the use of `Effect` for functional error handling and interaction with the Convex database context (`db`) within handler functions. ```typescript import { Effect } from "effect"; import { ConfectMutationCtx, ConfectQueryCtx, action, mutation, query, } from "./confect"; import { DeleteNoteArgs, DeleteNoteResult, GetFirstArgs, GetFirstResult, GetRandomArgs, GetRandomResult, InsertNoteArgs, InsertNoteResult, ListNotesArgs, ListNotesResult, } from "./functions.schemas"; export const insertNote = mutation({ args: InsertNoteArgs, returns: InsertNoteResult, handler: ({ text }) => Effect.gen(function* () { const { db } = yield* ConfectMutationCtx; return yield* db.insert("notes", { text }); }), }); export const listNotes = query({ args: ListNotesArgs, returns: ListNotesResult, handler: () => Effect.gen(function* () { const { db } = yield* ConfectQueryCtx; return yield* db.query("notes").order("desc").collect(); }), }); export const deleteNote = mutation({ args: DeleteNoteArgs, returns: DeleteNoteResult, handler: ({ noteId }) => Effect.gen(function* () { const { db } = yield* ConfectMutationCtx; return yield* db.delete(noteId).pipe(Effect.as(null)); }), }); export const getRandom = action({ args: GetRandomArgs, returns: GetRandomResult, handler: () => Effect.succeed(Math.random()), }); export const getFirst = query({ args: GetFirstArgs, returns: GetFirstResult, handler: () => Effect.gen(function* () { const { db } = yield* ConfectQueryCtx; return yield* db.query("notes").first(); }), }); ``` -------------------------------- ### Mount Confect Effect HTTP API to Convex Router Source: https://rjdellecese.gitbook.io/confect/http-apis This TypeScript snippet demonstrates how to integrate the previously defined Effect HTTP API (ApiLive) into a Convex HTTP router using @rjdellecese/confect/server. It shows how to mount the API to a specific path prefix (/path-prefix/) and apply Effect's HttpMiddleware for CORS and logging. ```typescript import { makeHttpRouter } from "@rjdellecese/confect/server"; import { HttpMiddleware } from "@effect/platform"; import { flow } from "effect"; import { ApiLive } from "./http/api"; export default makeHttpRouter({ "/path-prefix/": { apiLive: ApiLive, middleware: flow(HttpMiddleware.cors(), HttpMiddleware.logger), }, }); ``` -------------------------------- ### Define a Confect HTTP API with Effect-TS Source: https://rjdellecese.gitbook.io/confect/http-apis This TypeScript code defines a Confect HTTP API using Effect-TS's @effect/platform module. It illustrates how to create an HttpApiGroup for 'notes' with a 'getFirst' endpoint, apply OpenAPI annotations for documentation, and define the API's overall structure and prefix. It also shows how to implement the handler for the 'getFirst' endpoint, integrating with Convex queries and Effect's schema decoding. ```typescript import { HttpApi, HttpApiBuilder, HttpApiEndpoint, HttpApiGroup, OpenApi, } from "@effect/platform"; import type { HttpApiDecodeError } from "@effect/platform/HttpApiError"; import { Effect, Layer, Option, Schema } from "effect"; import { api } from "../_generated/api"; import { ConfectActionCtx } from "../confect"; import { GetFirstResult } from "../functions.schemas"; import { confectSchema } from "../schema"; class ApiGroup extends HttpApiGroup.make("notes") .add( HttpApiEndpoint.get("getFirst", "/get-first") .annotate(OpenApi.Description, "Get the first note, if there is one.") .addSuccess( Schema.NullOr(confectSchema.tableSchemas.notes.withSystemFields), ), ) .annotate(OpenApi.Title, "Notes") .annotate(OpenApi.Description, "Operations on notes.") {} export class Api extends HttpApi.make("Api") .annotate(OpenApi.Title, "Confect Example") .annotate( OpenApi.Description, ` An example API built with Confect and powered by [Scalar](https://github.com/scalar/scalar). # Learn More See Scalar's documentation on [markdown support](https://github.com/scalar/scalar/blob/main/documentation/markdown.md) and [OpenAPI spec extensions](https://github.com/scalar/scalar/blob/main/documentation/openapi.md). `, ) .add(ApiGroup) .prefix("/path-prefix") {} const ApiGroupLive = HttpApiBuilder.group(Api, "notes", (handlers) => handlers.handle( "getFirst", (): Effect.Effect< (typeof confectSchema.tableSchemas.notes.withSystemFields)["Type"] | null, HttpApiDecodeError, ConfectActionCtx > => Effect.gen(function* () { const { runQuery } = yield* ConfectActionCtx; const firstNote = yield* runQuery(api.functions.getFirst, {}).pipe( Effect.andThen(Schema.decode(GetFirstResult)), Effect.map(Option.getOrNull), Effect.orDie, ); return firstNote; }), ), ); export const ApiLive = HttpApiBuilder.api(Api).pipe( Layer.provide(ApiGroupLive), ); ``` -------------------------------- ### Convex Query with Void Return (Not Recommended) Source: https://rjdellecese.gitbook.io/confect/schema-restrictions Shows another incorrect approach for defining a Convex query function in Confect. Using `Schema.Void` for the return type and `Effect.void` in the handler is discouraged due to Convex's implicit coercion of void returns to `null`. ```TypeScript export const myQuery = query({ args: Schema.Struct({}), returns: Schema.Void, handler: () => Effect.void, }) ``` -------------------------------- ### Convex Query with Null Return (Recommended) Source: https://rjdellecese.gitbook.io/confect/schema-restrictions Demonstrates the correct way to define a Convex query function in Confect that returns a no-op value. It explicitly uses `Schema.Null` for the return type and `null` in the handler, aligning with Convex's coercion behavior. ```TypeScript export const myQuery = query({ args: Schema.Struct({}), returns: Schema.Null, handler: () => Effect.succeed(null), }) ``` -------------------------------- ### Convex Query with Undefined Return (Not Recommended) Source: https://rjdellecese.gitbook.io/confect/schema-restrictions Illustrates an incorrect way to define a Convex query function in Confect. Using `Schema.Undefined` for the return type and `undefined` in the handler is discouraged because Convex implicitly coerces `undefined` returns to `null`. ```TypeScript export const myQuery = query({ args: Schema.Struct({}), returns: Schema.Undefined, handler: () => Effect.succeed(undefined), }) ``` -------------------------------- ### Effect Schema Generic Type Definition Source: https://rjdellecese.gitbook.io/confect/schema-restrictions Illustrates the generic type definition for an Effect Schema, showing its three type parameters: Type, Encoded, and Context, which are subject to specific restrictions when used with Confect. ```TypeScript type Schema ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.