@fragno-dev/corpus 0.0.5 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -53,8 +53,10 @@ Optional ID syntax (`:schema`) helps identify code blocks for agent references.
53
53
 
54
54
  Test-only initialization code (not shown to users, only used in generated tests):
55
55
 
56
- \`\`\`typescript @fragno-test-init const { fragment } = await
57
- createDatabaseFragmentForTest(testFragmentDef, []); const orm = fragment.services.orm; \`\`\`
56
+ \`\`\`typescript @fragno-test-init const { fragments } = await buildDatabaseFragmentsTest()
57
+ .withTestAdapter({ type: "kysely-sqlite" }) .withFragment("test",
58
+ instantiate(testFragmentDef).withRoutes([]), { definition: testFragmentDef }) .build(); const db =
59
+ fragments.test.db; \`\`\`
58
60
 
59
61
  ### @fragno-test
60
62
 
@@ -5,12 +5,8 @@ that integrate with React, Vue, Svelte, and vanilla JavaScript. The `ClientBuild
5
5
  hooks and mutators for your routes.
6
6
 
7
7
  ```typescript @fragno-imports
8
- import {
9
- defineFragment,
10
- defineRoute,
11
- defineRoutes,
12
- type FragnoPublicClientConfig,
13
- } from "@fragno-dev/core";
8
+ import { defineFragment, defineRoute, defineRoutes } from "@fragno-dev/core";
9
+ import type { FragnoPublicClientConfig } from "@fragno-dev/core/client";
14
10
  import { createClientBuilder } from "@fragno-dev/core/client";
15
11
  import { computed } from "nanostores";
16
12
  import { z } from "zod";
@@ -23,7 +19,7 @@ interface TodoConfig {
23
19
 
24
20
  const todoFragment = defineFragment<TodoConfig>("todos");
25
21
 
26
- const routes = defineRoutes<TodoConfig>().create(() => [
22
+ const routes = defineRoutes(todoFragment).create(({ defineRoute }) => [
27
23
  defineRoute({
28
24
  method: "GET",
29
25
  path: "/todos",
@@ -4,10 +4,11 @@ Fragno provides a unified database query API that works across different ORMs. T
4
4
  CRUD operations and querying with conditions.
5
5
 
6
6
  ```typescript @fragno-imports
7
- import { defineFragmentWithDatabase } from "@fragno-dev/db/fragment";
7
+ import { defineFragment, instantiate } from "@fragno-dev/core";
8
+ import { withDatabase } from "@fragno-dev/db";
8
9
  import { schema, idColumn, column } from "@fragno-dev/db/schema";
9
- import type { AbstractQuery } from "@fragno-dev/db/query";
10
- import { createDatabaseFragmentForTest } from "@fragno-dev/test";
10
+ import type { SimpleQueryInterface } from "@fragno-dev/db/query";
11
+ import { buildDatabaseFragmentsTest } from "@fragno-dev/test";
11
12
  ```
12
13
 
13
14
  ```typescript @fragno-prelude:schema
@@ -38,16 +39,17 @@ type UserSchema = typeof userSchema;
38
39
 
39
40
  ```typescript @fragno-test-init
40
41
  // Create a test fragment with database
41
- const testFragmentDef = defineFragmentWithDatabase("test-db-fragment").withDatabase(userSchema);
42
+ const testFragmentDef = defineFragment<{}>("test-fragment")
43
+ .extend(withDatabase(userSchema))
44
+ .providesBaseService(() => ({}))
45
+ .build();
42
46
 
43
- const { fragment, test } = await createDatabaseFragmentForTest(
44
- { definition: testFragmentDef, routes: [] },
45
- {
46
- adapter: { type: "kysely-sqlite" },
47
- },
48
- );
47
+ const { fragments, test } = await buildDatabaseFragmentsTest()
48
+ .withTestAdapter({ type: "kysely-sqlite" })
49
+ .withFragment("test", instantiate(testFragmentDef).withConfig({}).withRoutes([]))
50
+ .build();
49
51
 
50
- const db = fragment.db;
52
+ const db = fragments.test.db;
51
53
  ```
52
54
 
53
55
  ## Create
@@ -4,8 +4,13 @@ Routes are the core of a Fragno fragment, defining HTTP endpoints that handle re
4
4
  responses. This guide covers the essential patterns for defining routes.
5
5
 
6
6
  ```typescript @fragno-imports
7
- import { defineRoute, defineRoutes, defineFragment, createFragment } from "@fragno-dev/core";
8
- import type { FragnoPublicConfig } from "@fragno-dev/core";
7
+ import {
8
+ defineFragment,
9
+ defineRoute,
10
+ defineRoutes,
11
+ instantiate,
12
+ type FragnoPublicConfig,
13
+ } from "@fragno-dev/core";
9
14
  import { z } from "zod";
10
15
  ```
11
16
 
@@ -151,15 +156,14 @@ Routes can access dependencies defined in `withDependencies` through route facto
151
156
 
152
157
  ```typescript @fragno-test:using-dependencies
153
158
  interface AppConfig {
154
- apiKey: string;
159
+ apiKey?: string;
155
160
  }
156
161
 
157
- interface AppDeps {
158
- config: AppConfig;
159
- timestamp: number;
160
- }
162
+ const definition = defineFragment<AppConfig>("test")
163
+ .withDependencies(({ config }) => ({ timestamp: Date.now() }))
164
+ .build();
161
165
 
162
- export const routesWithDeps = defineRoutes<AppConfig, AppDeps>().create(({ deps }) => {
166
+ export const routesWithDeps = defineRoutes<typeof definition>().create(({ config, deps }) => {
163
167
  return [
164
168
  defineRoute({
165
169
  method: "GET",
@@ -170,7 +174,7 @@ export const routesWithDeps = defineRoutes<AppConfig, AppDeps>().create(({ deps
170
174
  }),
171
175
  handler: async (_, { json }) => {
172
176
  return json({
173
- hasApiKey: !!deps.config.apiKey,
177
+ hasApiKey: !!config.apiKey,
174
178
  timestamp: deps.timestamp,
175
179
  });
176
180
  },
@@ -186,12 +190,17 @@ Dependencies are passed to the route factory function and can be used in route h
186
190
  Services defined in `providesService` can be used in routes for business logic.
187
191
 
188
192
  ```typescript @fragno-test:using-services
189
- interface DataService {
190
- getData: () => string;
191
- processData: (input: string) => Promise<string>;
192
- }
193
+ const definition = defineFragment("test")
194
+ .withDependencies(({ config }) => ({ timestamp: Date.now() }))
195
+ .providesBaseService(({ defineService }) =>
196
+ defineService({
197
+ getData: () => "Hello, World!",
198
+ processData: async (input: string) => input,
199
+ }),
200
+ )
201
+ .build();
193
202
 
194
- export const routesWithServices = defineRoutes<{}, {}, DataService>().create(({ services }) => {
203
+ export const routesWithServices = defineRoutes<typeof definition>().create(({ services }) => {
195
204
  return [
196
205
  defineRoute({
197
206
  method: "GET",
@@ -218,55 +227,3 @@ export const routesWithServices = defineRoutes<{}, {}, DataService>().create(({
218
227
  ```
219
228
 
220
229
  Services provide reusable business logic that can be shared across multiple routes.
221
-
222
- ## Complete Fragment Example
223
-
224
- A complete example showing how routes integrate with fragment definition.
225
-
226
- ```typescript @fragno-test:complete-fragment
227
- interface MyFragmentConfig {
228
- apiKey: string;
229
- }
230
-
231
- interface MyFragmentDeps {
232
- config: MyFragmentConfig;
233
- }
234
-
235
- interface MyFragmentServices {
236
- getStatus: () => string;
237
- }
238
-
239
- const myFragmentDefinition = defineFragment<MyFragmentConfig>("my-fragment")
240
- .withDependencies(({ config }) => {
241
- return {
242
- config,
243
- };
244
- })
245
- .providesService(({ deps, defineService }) => {
246
- return defineService({
247
- getStatus: () => `API Key: ${deps.config.apiKey.substring(0, 3)}...`,
248
- });
249
- });
250
-
251
- const myRoutes = defineRoutes<MyFragmentConfig, MyFragmentDeps, MyFragmentServices>().create(
252
- ({ services }) => {
253
- return [
254
- defineRoute({
255
- method: "GET",
256
- path: "/status",
257
- outputSchema: z.string(),
258
- handler: async (_, { json }) => {
259
- return json(services.getStatus());
260
- },
261
- }),
262
- ];
263
- },
264
- );
265
-
266
- export function createMyFragment(config: MyFragmentConfig, options: FragnoPublicConfig = {}) {
267
- return createFragment(myFragmentDefinition, config, [myRoutes], options);
268
- }
269
- ```
270
-
271
- This example shows the complete flow: fragment definition with dependencies and services, route
272
- factory using those services, and the fragment creation function.
@@ -7,54 +7,3 @@ import { DrizzleAdapter } from "@fragno-dev/db/adapters/drizzle";
7
7
  import type { NodePgDatabase } from "drizzle-orm/node-postgres";
8
8
  import type { PgliteDatabase } from "drizzle-orm/pglite";
9
9
  ```
10
-
11
- ## Basic Setup
12
-
13
- Create a DrizzleAdapter with your Drizzle database instance and provider.
14
-
15
- ```typescript @fragno-test:basic-setup types-only
16
- interface MyDatabase extends Record<string, unknown> {
17
- users: {
18
- id: string;
19
- email: string;
20
- name: string;
21
- };
22
- posts: {
23
- id: string;
24
- title: string;
25
- content: string;
26
- authorId: string;
27
- };
28
- }
29
-
30
- declare const db: NodePgDatabase<MyDatabase>;
31
-
32
- export const adapter = new DrizzleAdapter({
33
- db,
34
- provider: "postgresql",
35
- });
36
- ```
37
-
38
- The adapter requires your Drizzle instance and the database provider (`"postgresql"`, `"mysql"`, or
39
- `"sqlite"`).
40
-
41
- ## Factory Function
42
-
43
- For async or sync database initialization, pass a factory function instead of a direct instance.
44
-
45
- ```typescript @fragno-test:factory-function types-only
46
- import type { PgliteDatabase } from "drizzle-orm/pglite";
47
-
48
- async function createDatabase(): Promise<PgliteDatabase> {
49
- // Async initialization logic
50
- const db = {} as PgliteDatabase;
51
- return db;
52
- }
53
-
54
- export const adapter = new DrizzleAdapter({
55
- db: createDatabase,
56
- provider: "postgresql",
57
- });
58
- ```
59
-
60
- Factory functions can also be synchronous for lazy initialization scenarios.
@@ -1,14 +1,13 @@
1
1
  # Fragment Instantiation
2
2
 
3
- Fragno provides the `instantiateFragment` function, which uses a builder pattern to help you and
4
- your user create Fragments.
3
+ Fragno provides the `instantiate` function, which uses a builder pattern to help you and your user
4
+ create Fragments.
5
5
 
6
6
  ```typescript @fragno-imports
7
7
  import {
8
8
  defineFragment,
9
- createFragment,
10
- instantiateFragment,
11
9
  defineRoute,
10
+ instantiate,
12
11
  type FragnoPublicConfig,
13
12
  } from "@fragno-dev/core";
14
13
  import { z } from "zod";
@@ -22,12 +21,12 @@ interface AppConfig {
22
21
  apiKey: string;
23
22
  }
24
23
 
25
- const fragment = defineFragment<AppConfig>("api-fragment");
24
+ const fragmentDefinition = defineFragment<AppConfig>("api-fragment").build();
26
25
 
27
26
  // User-facing fragment creator function. This is the main integration point for users of your fragment.
28
27
  export function createMyFragment(config: AppConfig, options: FragnoPublicConfig = {}) {
29
28
  return (
30
- instantiateFragment(fragment)
29
+ instantiate(fragmentDefinition)
31
30
  .withConfig(config)
32
31
  /** Options are passed to Fragno internally */
33
32
  .withOptions(options)
@@ -38,7 +37,7 @@ export function createMyFragment(config: AppConfig, options: FragnoPublicConfig
38
37
  // What your user will call to instantiate the fragment:
39
38
  const instance = createMyFragment({ apiKey: "my-secret-key" }, { mountRoute: "/api/v1" });
40
39
 
41
- expect(instance.config.name).toBe("api-fragment");
40
+ expect(instance.name).toBe("api-fragment");
42
41
  expect(instance.mountRoute).toBe("/api/v1");
43
42
  ```
44
43
 
@@ -51,7 +50,7 @@ Also see the `defining-routes` subject.
51
50
 
52
51
  ```typescript @fragno-test:builder-with-routes
53
52
  // should add routes using withRoutes
54
- const fragment = defineFragment<{}>("routes-fragment");
53
+ const fragmentDefinition = defineFragment("routes-fragment").build();
55
54
 
56
55
  const route1 = defineRoute({
57
56
  method: "GET",
@@ -67,11 +66,14 @@ const route2 = defineRoute({
67
66
  handler: async (_, { json }) => json("Goodbye"),
68
67
  });
69
68
 
70
- const instance = instantiateFragment(fragment).withConfig({}).withRoutes([route1, route2]).build();
69
+ const instance = instantiate(fragmentDefinition)
70
+ .withRoutes([route1, route2])
71
+ .withOptions({})
72
+ .build();
71
73
 
72
- expect(instance.config.routes).toHaveLength(2);
73
- expect(instance.config.routes[0].path).toBe("/hello");
74
- expect(instance.config.routes[1].path).toBe("/goodbye");
74
+ expect(instance.routes).toHaveLength(2);
75
+ expect(instance.routes[0].path).toBe("/hello");
76
+ expect(instance.routes[1].path).toBe("/goodbye");
75
77
  ```
76
78
 
77
79
  Routes can be added as an array using `withRoutes`.
@@ -94,19 +96,20 @@ const fragment = defineFragment<AppConfig>("service-fragment")
94
96
  .withDependencies(({ config }) => ({
95
97
  client: { key: config.apiKey },
96
98
  }))
97
- .usesService<"logger", ILogger>("logger");
99
+ .usesService<"logger", ILogger>("logger")
100
+ .build();
98
101
 
99
102
  const loggerImpl: ILogger = {
100
103
  log: (msg) => console.log(msg),
101
104
  };
102
105
 
103
- const instance = instantiateFragment(fragment)
106
+ const instance = instantiate(fragment)
104
107
  .withConfig({ apiKey: "my-key" })
105
108
  .withServices({ logger: loggerImpl })
109
+ .withOptions({})
106
110
  .build();
107
111
 
108
- expect(instance.deps.client.key).toBe("my-key");
109
- expect(instance.services.logger).toBeDefined();
112
+ expect(instance.$internal.deps.client.key).toBe("my-key");
110
113
  ```
111
114
 
112
115
  Use `withDependencies` to create dependencies from config, and `withServices` to provide required
@@ -7,8 +7,7 @@ Note that if the goal is to make your user provide certain functionality, it usu
7
7
  sense to add a required property to the fragment's config.
8
8
 
9
9
  ```typescript @fragno-imports
10
- import { defineFragment, instantiateFragment } from "@fragno-dev/core";
11
- import type { FragnoPublicConfig } from "@fragno-dev/core";
10
+ import { defineFragment, instantiate, type FragnoPublicConfig } from "@fragno-dev/core";
12
11
  ```
13
12
 
14
13
  ## Providing Services
@@ -17,23 +16,27 @@ Fragments provide services using `providesService()`. Services can be passed as
17
16
  via a factory function that receives context (`config`, `deps`, `fragnoConfig`, `defineService`).
18
17
 
19
18
  ```typescript @fragno-test:provide-direct-object
20
- // Object syntax is the simplest way to provide services.
21
- const fragment = defineFragment<{}>("email-fragment").providesService({
22
- sendEmail: async (to: string, subject: string) => {
23
- // Email sending logic here
24
- },
25
- });
19
+ // Object syntax is the simplest way to provide base services.
20
+ const fragmentDefinition = defineFragment("email-fragment")
21
+ .providesBaseService(() => ({
22
+ sendEmail: async (to: string, subject: string) => {
23
+ // Email sending logic here
24
+ },
25
+ }))
26
+ .build();
26
27
  ```
27
28
 
28
29
  ```typescript @fragno-test:provide-factory-function
29
30
  // The factory function receives the fragment's `config`, and `deps` (dependencies).
30
- const fragment = defineFragment<{}>("api-fragment").providesService(({ config }) => ({
31
- makeRequest: async (endpoint: string) => {
32
- return { data: "response" };
33
- },
34
- }));
31
+ const fragmentDefinition = defineFragment("api-fragment")
32
+ .providesBaseService(({ config }) => ({
33
+ makeRequest: async (endpoint: string) => {
34
+ return { data: "response" };
35
+ },
36
+ }))
37
+ .build();
35
38
 
36
- const instance = instantiateFragment(fragment).withConfig({}).build();
39
+ const instance = instantiate(fragmentDefinition).withOptions({}).build();
37
40
  expect(instance.services.makeRequest).toBeInstanceOf(Function);
38
41
  ```
39
42
 
@@ -45,16 +48,14 @@ required services.
45
48
 
46
49
  ```typescript @fragno-test:provide-named-services
47
50
  // should provide named services
48
- const fragment = defineFragment<{}>("logger-fragment").providesService(
49
- "logger",
50
- ({ defineService }) =>
51
- defineService({
52
- log: (message: string) => console.log(message),
53
- error: (message: string) => console.error(message),
54
- }),
55
- );
51
+ const fragmentDefinition = defineFragment("logger-fragment")
52
+ .providesService("logger", () => ({
53
+ log: (message: string) => console.log(message),
54
+ error: (message: string) => console.error(message),
55
+ }))
56
+ .build();
56
57
 
57
- const instance = instantiateFragment(fragment).withConfig({}).build();
58
+ const instance = instantiate(fragmentDefinition).withOptions({}).build();
58
59
  expect(instance.services.logger.log).toBeDefined();
59
60
  expect(instance.services.logger.error).toBeDefined();
60
61
  ```
@@ -66,7 +67,7 @@ for database fragments where methods need access to the current unit of work.
66
67
 
67
68
  ```typescript @fragno-test:chaining-services
68
69
  // should chain multiple service definitions
69
- const fragment = defineFragment<{}>("multi-service-fragment")
70
+ const fragmentDefinition = defineFragment("multi-service-fragment")
70
71
  .providesService("logger", ({ defineService }) =>
71
72
  defineService({
72
73
  log: (msg: string) => console.log(msg),
@@ -76,13 +77,14 @@ const fragment = defineFragment<{}>("multi-service-fragment")
76
77
  defineService({
77
78
  validate: (input: string) => input.length > 0,
78
79
  }),
79
- );
80
+ )
81
+ .build();
80
82
  ```
81
83
 
82
84
  ## Using Services
83
85
 
84
- Fragments specify required services using `usesService`. Services can be marked as optional with
85
- `{ optional: true }`, making them `undefined` if not provided.
86
+ Fragments specify required services using `usesService`. Services can be marked as optional using
87
+ `usesOptionalService`, making them `undefined` if not provided.
86
88
 
87
89
  ```typescript @fragno-test:declaring-required-service
88
90
  // should require a service from the user
@@ -90,9 +92,13 @@ interface IEmailService {
90
92
  sendEmail(to: string, subject: string, body: string): Promise<void>;
91
93
  }
92
94
 
93
- const fragment = defineFragment<{}>("notification-fragment").usesService<"email", IEmailService>(
94
- "email",
95
- );
95
+ const fragmentDefinition = defineFragment("notification-fragment")
96
+ .usesService<"email", IEmailService>("email")
97
+ .providesBaseService(({ serviceDeps }) => ({
98
+ sendNotification: (to: string, subject: string, body: string) =>
99
+ serviceDeps.email.sendEmail(to, subject, body),
100
+ }))
101
+ .build();
96
102
 
97
103
  const emailImpl: IEmailService = {
98
104
  sendEmail: async (to, subject, body) => {
@@ -100,13 +106,12 @@ const emailImpl: IEmailService = {
100
106
  },
101
107
  };
102
108
 
103
- const instance = instantiateFragment(fragment)
104
- .withConfig({})
109
+ const instance = instantiate(fragmentDefinition)
105
110
  .withServices({ email: emailImpl })
111
+ .withOptions({})
106
112
  .build();
107
113
 
108
- expect(instance.services.email).toBeDefined();
109
- expect(instance.services.email.sendEmail).toBeDefined();
114
+ expect(instance.services.sendNotification).toBeDefined();
110
115
  ```
111
116
 
112
117
  ### Optional Services
@@ -117,21 +122,27 @@ interface ILogger {
117
122
  log(message: string): void;
118
123
  }
119
124
 
120
- const fragment = defineFragment<{}>("app-fragment").usesService<"logger", ILogger>("logger", {
121
- optional: true,
122
- });
125
+ const fragmentDefinition = defineFragment("app-fragment")
126
+ .usesOptionalService<"logger", ILogger>("logger")
127
+ .providesBaseService(({ serviceDeps }) => ({
128
+ maybeLog: (message: string) => {
129
+ if (serviceDeps.logger) {
130
+ serviceDeps.logger.log(message);
131
+ }
132
+ },
133
+ }))
134
+ .build();
123
135
 
124
136
  // Can instantiate without providing the service
125
- const instance = instantiateFragment(fragment).withConfig({}).build();
137
+ const instance = instantiate(fragmentDefinition).withOptions({}).build();
126
138
 
127
139
  expect(instance).toBeDefined();
128
- // logger will be undefined
129
- expect(instance.services.logger).toBeUndefined();
140
+ expect(instance.services.maybeLog).toBeDefined();
130
141
  ```
131
142
 
132
143
  ### Using Services in Provided Services
133
144
 
134
- Used services are available via `deps` in the factory function context, enabling composition.
145
+ Used services are available via `serviceDeps` in the factory function context, enabling composition.
135
146
 
136
147
  ```typescript @fragno-test:using-in-provided
137
148
  // should use external services in provided services
@@ -139,25 +150,25 @@ interface IEmailService {
139
150
  sendEmail(to: string, subject: string, body: string): Promise<void>;
140
151
  }
141
152
 
142
- const fragment = defineFragment<{}>("welcome-fragment")
153
+ const fragmentDefinition = defineFragment("welcome-fragment")
143
154
  .usesService<"email", IEmailService>("email")
144
- .providesService(({ deps }) => ({
155
+ .providesBaseService(({ serviceDeps }) => ({
145
156
  sendWelcomeEmail: async (to: string) => {
146
- await deps.email.sendEmail(to, "Welcome!", "Welcome to our service!");
157
+ await serviceDeps.email.sendEmail(to, "Welcome!", "Welcome to our service!");
147
158
  },
148
- }));
159
+ }))
160
+ .build();
149
161
 
150
162
  const emailImpl: IEmailService = {
151
163
  sendEmail: async () => {},
152
164
  };
153
165
 
154
- const instance = instantiateFragment(fragment)
155
- .withConfig({})
166
+ const instance = instantiate(fragmentDefinition)
156
167
  .withServices({ email: emailImpl })
168
+ .withOptions({})
157
169
  .build();
158
170
 
159
171
  expect(instance.services.sendWelcomeEmail).toBeDefined();
160
- expect(instance.services.email).toBeDefined();
161
172
  ```
162
173
 
163
174
  ### Missing Required Services
@@ -168,11 +179,11 @@ interface IStorageService {
168
179
  save(key: string, value: string): Promise<void>;
169
180
  }
170
181
 
171
- const fragment = defineFragment<{}>("storage-fragment").usesService<"storage", IStorageService>(
172
- "storage",
173
- );
182
+ const fragmentDefinition = defineFragment("storage-fragment")
183
+ .usesService<"storage", IStorageService>("storage")
184
+ .build();
174
185
 
175
186
  expect(() => {
176
- instantiateFragment(fragment).withConfig({}).build();
187
+ instantiate(fragmentDefinition).withOptions({}).build();
177
188
  }).toThrow("Fragment 'storage-fragment' requires service 'storage' but it was not provided");
178
189
  ```
@@ -4,56 +4,54 @@ The KyselyAdapter connects Fragno's database API to your Kysely database instanc
4
4
 
5
5
  ```typescript @fragno-imports
6
6
  import { KyselyAdapter } from "@fragno-dev/db/adapters/kysely";
7
- import { Kysely } from "kysely";
8
- import type { Dialect } from "kysely";
7
+ import {
8
+ PGLiteDriverConfig,
9
+ SQLocalDriverConfig,
10
+ BetterSQLite3DriverConfig,
11
+ } from "@fragno-dev/db/drivers";
12
+ import { SqliteDialect, PostgresDialect, MysqlDialect } from "@fragno-dev/db/dialects";
13
+ import type { Dialect } from "@fragno-dev/db/sql-driver";
14
+ import SQLite from "better-sqlite3";
15
+ import { KyselyPGlite } from "kysely-pglite";
9
16
  ```
10
17
 
11
18
  ## Basic Setup
12
19
 
13
- Create a KyselyAdapter with your Kysely database instance and provider.
20
+ Create a KyselyAdapter with your Kysely dialect and driver configuration.
14
21
 
15
22
  ```typescript @fragno-test:basic-setup types-only
16
- interface MyDatabase {
17
- users: {
18
- id: string;
19
- email: string;
20
- name: string;
21
- };
22
- posts: {
23
- id: string;
24
- title: string;
25
- content: string;
26
- authorId: string;
27
- };
28
- }
29
-
30
- declare const dialect: Dialect;
31
-
32
- export const db = new Kysely<MyDatabase>({
33
- dialect,
23
+ const dialect = new SqliteDialect({
24
+ database: new SQLite(":memory:"),
34
25
  });
35
26
 
36
27
  export const adapter = new KyselyAdapter({
37
- db,
38
- provider: "postgresql",
28
+ dialect,
29
+ driverConfig: new BetterSQLite3DriverConfig(),
39
30
  });
40
31
  ```
41
32
 
42
- The adapter requires your Kysely instance and the database provider (`"postgresql"`, `"mysql"`, or
43
- `"sqlite"`).
33
+ The adapter requires:
44
34
 
45
- ## Factory Function
35
+ - `dialect`: A Kysely dialect instance for your database
36
+ - `driverConfig`: A driver configuration matching your database type (`PGLiteDriverConfig`,
37
+ `SQLocalDriverConfig`, or `BetterSQLite3DriverConfig`)
46
38
 
47
- For async database initialization, pass a factory function instead of a direct instance.
39
+ ## First Party Kysely Dialects
48
40
 
49
- ```typescript @fragno-test:factory-function types-only
50
- async function createDatabase() {
51
- // Async initialization logic
52
- return new Kysely({ dialect: {} as Dialect });
53
- }
41
+ Fragno re-exports the "first party" Kysely dialects for SQLite, PostgreSQL, and MySQL. This means
42
+ you can use these dialects without installing them yourself.
43
+
44
+ ```typescript @fragno-test:first-party-kysely-dialects types-only
45
+ import { SqliteDialect, PostgresDialect, MysqlDialect } from "@fragno-dev/db/dialects";
46
+ ```
47
+
48
+ ## PGLite Example
49
+
50
+ ```typescript @fragno-test:postgresql-example types-only
51
+ const { dialect } = await KyselyPGlite.create();
54
52
 
55
53
  export const adapter = new KyselyAdapter({
56
- db: createDatabase,
57
- provider: "postgresql",
54
+ dialect,
55
+ driverConfig: new PGLiteDriverConfig(),
58
56
  });
59
57
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fragno-dev/corpus",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -16,14 +16,17 @@
16
16
  "dist"
17
17
  ],
18
18
  "devDependencies": {
19
+ "@types/better-sqlite3": "^7.6.13",
19
20
  "@types/marked-terminal": "^6.1.1",
20
21
  "@types/node": "^22",
22
+ "better-sqlite3": "^12.5.0",
21
23
  "drizzle-orm": "^0.44.7",
22
24
  "kysely": "^0.28.0",
25
+ "kysely-pglite": "^0.6.1",
23
26
  "zod": "^4.0.5",
24
- "@fragno-dev/core": "0.1.8",
25
- "@fragno-dev/db": "0.1.14",
26
- "@fragno-dev/test": "0.1.12",
27
+ "@fragno-dev/core": "0.1.11",
28
+ "@fragno-dev/db": "0.2.0",
29
+ "@fragno-dev/test": "1.0.0",
27
30
  "@fragno-private/typescript-config": "0.0.1",
28
31
  "@fragno-private/vitest-config": "0.0.0"
29
32
  },