updated App options "seed", changed examples to file db

This commit is contained in:
dswbx
2025-02-18 20:01:08 +01:00
parent a4e46a2768
commit a01b99be27
8 changed files with 38 additions and 29 deletions

View File

@@ -3,7 +3,7 @@
"type": "module",
"sideEffects": false,
"bin": "./dist/cli/index.js",
"version": "0.8.0-rc.9",
"version": "0.8.0-rc.10",
"description": "Lightweight Firebase/Supabase alternative built to run anywhere — incl. Next.js, Remix, Astro, Cloudflare, Bun, Node, AWS Lambda & more.",
"homepage": "https://bknd.io",
"repository": {

View File

@@ -4,6 +4,7 @@ import { Connection, type LibSqlCredentials, LibsqlConnection } from "data";
import type { Hono } from "hono";
import {
type InitialModuleConfigs,
type ModuleBuildContext,
ModuleManager,
type ModuleManagerOptions,
type Modules
@@ -28,7 +29,8 @@ export const AppEvents = { AppConfigUpdatedEvent, AppBuiltEvent, AppFirstBoot }
export type AppOptions = {
plugins?: AppPlugin[];
manager?: Omit<ModuleManagerOptions, "initial" | "onUpdated">;
seed?: (ctx: ModuleBuildContext) => Promise<void>;
manager?: Omit<ModuleManagerOptions, "initial" | "onUpdated" | "seed">;
};
export type CreateAppConfig = {
connection?:
@@ -61,6 +63,7 @@ export class App {
this.modules = new ModuleManager(connection, {
...(options?.manager ?? {}),
initial: _initialConfig,
seed: options?.seed,
onUpdated: async (key, config) => {
// if the EventManager was disabled, we assume we shouldn't
// respond to events, such as "onUpdated".

View File

@@ -67,6 +67,7 @@ described above, or an class instance that extends from `Connection`:
```ts
import { createApp } from "bknd";
import { Connection } from "bknd/data";
import { Kysely } from "kysely";
class CustomConnection extends Connection {
constructor() {
@@ -85,6 +86,7 @@ const app = createApp({ connection })
To provide an initial database structure, you can pass `initialConfig` to the creation of an app. This will only be used if there isn't an existing configuration found in the database given. Here is a quick example:
```ts
import { createApp } from "bknd";
import { em, entity, text, number } from "bknd/data";
const schema = em({
@@ -142,9 +144,9 @@ All entity related functions use the types defined in `DB` from `bknd/core`. To
```ts
import { em } from "bknd/data";
import { Api } from "bknd";
import { Api } from "bknd/client";
// const schema = em({ ... });
const schema = em({ /* ... */ });
type Database = (typeof schema)["DB"];
declare module "bknd/core" {
@@ -160,7 +162,7 @@ The type completion is available for the API as well as all provided [React hook
### Seeding the database
To seed your database with initial data, you can pass a `seed` function to the configuration. It
provides the `ModuleBuildContext` ([reference](/usage/introduction#modulebuildcontext)) as the first argument.
provides the `ModuleBuildContext` as the first argument.
Note that the seed function will only be executed on app's first boot. If a configuration
already exists in the database, it will not be executed.

View File

@@ -157,7 +157,7 @@ npx bknd schema
To create an initial data structure, you can use helpers [described here](/usage/database#initial-structure).
### `plugins`
### `options.plugins`
The `plugins` property is an array of functions that are called after the app has been built,
but before its event is emitted. This is useful for adding custom routes or other functionality.
A simple plugin that adds a custom route looks like this:
@@ -174,23 +174,9 @@ Since each plugin has full access to the `app` instance, it can add routes, modi
structure, add custom middlewares, respond to or add events, etc. Plugins are very powerful, so
make sure to only run trusted ones.
### `options`
This object is passed to the `ModuleManager` which is responsible for:
- validating and maintaining configuration of all modules
- building all modules (data, auth, media, flows)
- maintaining the `ModuleBuildContext` used by the modules
### `options.seed`
The `seed` property is a function that is called when the app is booted for the first time. It is used to seed the database with initial data. The function is passed a `ModuleBuildContext` object:
The `options` object has the following properties:
- `basePath` (`string`): The base path for the Hono instance. This is used to prefix all routes.
- `trustFetched` (`boolean`): If set to `true`, the app will not perform any validity checks for
the given or fetched configuration.
- `onFirstBoot` (`() => Promise<void>`): A function that is called when the app is booted for
the first time.
- `seed` (`(ctx: ModuleBuildContext) => Promise<void>`): A function that is called when the app is
booted for the first time and an initial partial configuration is provided.
## `ModuleBuildContext`
```ts
type ModuleBuildContext = {
connection: Connection;
@@ -199,4 +185,25 @@ type ModuleBuildContext = {
emgr: EventManager;
guard: Guard;
};
const seed = async (ctx: ModuleBuildContext) => {
// seed the database
await ctx.em.mutator("todos").insertMany([
{ title: "Learn bknd", done: true },
{ title: "Build something cool", done: false }
]);
};
```
### `options.manager`
This object is passed to the `ModuleManager` which is responsible for:
- validating and maintaining configuration of all modules
- building all modules (data, auth, media, flows)
- maintaining the `ModuleBuildContext` used by the modules
The `options.manager` object has the following properties:
- `basePath` (`string`): The base path for the Hono instance. This is used to prefix all routes.
- `trustFetched` (`boolean`): If set to `true`, the app will not perform any validity checks for
the given or fetched configuration.
- `onFirstBoot` (`() => Promise<void>`): A function that is called when the app is booted for
the first time.

View File

@@ -27,7 +27,7 @@ declare module "bknd/core" {
export const ALL = serve<APIContext>({
// we can use any libsql config, and if omitted, uses in-memory
connection: {
url: "file:test.db"
url: "file:data.db"
},
// an initial config is only applied if the database is empty
initialConfig: {

View File

@@ -7,7 +7,7 @@ import { type BunBkndConfig, serve } from "bknd/adapter/bun";
// this is optional, if omitted, it uses an in-memory database
const config: BunBkndConfig = {
connection: {
url: ":memory:"
url: "file:data.db"
}
};

View File

@@ -7,7 +7,7 @@ import { serve } from "bknd/adapter/node";
/** @type {import("bknd/adapter/node").NodeBkndConfig} */
const config = {
connection: {
url: ":memory:"
url: "file:data.db"
}
};

View File

@@ -1,6 +1,5 @@
import { type MetaFunction, useLoaderData } from "@remix-run/react";
import type { LoaderFunctionArgs } from "@remix-run/server-runtime";
import { useAuth } from "bknd/client";
export const meta: MetaFunction = () => {
return [{ title: "Remix & bknd" }, { name: "description", content: "Welcome to Remix & bknd!" }];
@@ -13,8 +12,6 @@ export const loader = async ({ context: { api } }: LoaderFunctionArgs) => {
export default function Index() {
const { data, user } = useLoaderData<typeof loader>();
const auth = useAuth();
console.log("auth", auth);
return (
<div>