@cibule/db-sqlite 0.1.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/README.md ADDED
@@ -0,0 +1,132 @@
1
+ # @cibule/db-sqlite
2
+
3
+ SQLite driver for `@cibule/db`, built on better-sqlite3 and Kysely.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @cibule/db-sqlite
9
+ # or
10
+ bun add @cibule/db-sqlite
11
+ # or
12
+ pnpm add @cibule/db-sqlite
13
+ # or
14
+ yarn add @cibule/db-sqlite
15
+ ```
16
+
17
+ Dependencies `@cibule/db`, `@cibule/di`, `kysely`, and `better-sqlite3` are installed automatically.
18
+
19
+ > **Node.js only** — `better-sqlite3` is a native addon and requires a Node.js runtime. For Cloudflare Workers, use `@cibule/db-d1` instead.
20
+
21
+ ## Quick Start
22
+
23
+ ### With DI (recommended)
24
+
25
+ ```typescript
26
+ import { Injector } from '@cibule/di';
27
+ import { DB_ACCESSOR, UNIT_OF_WORK_FACTORY } from '@cibule/db';
28
+ import { provideSqliteDb } from '@cibule/db-sqlite';
29
+
30
+ interface MySchema {
31
+ users: { id: number; name: string; email: string };
32
+ }
33
+
34
+ const injector = Injector.create({
35
+ providers: provideSqliteDb('./data.db'),
36
+ });
37
+
38
+ await injector.runInContext(async () => {
39
+ const dbAccessor = injector.get(DB_ACCESSOR);
40
+ const db = dbAccessor();
41
+
42
+ const users = await db.selectFrom('users').selectAll().execute();
43
+ });
44
+ ```
45
+
46
+ ### Without DI
47
+
48
+ ```typescript
49
+ import { createSqliteDb } from '@cibule/db-sqlite';
50
+
51
+ interface MySchema {
52
+ users: { id: number; name: string; email: string };
53
+ }
54
+
55
+ const db = createSqliteDb<MySchema>('./data.db');
56
+
57
+ const users = await db.selectFrom('users').selectAll().execute();
58
+
59
+ await db.destroy();
60
+ ```
61
+
62
+ ## API Reference
63
+
64
+ ### createSqliteDb\<Schema\>(filename)
65
+
66
+ Creates a `Db<Schema>` instance backed by a SQLite file via better-sqlite3. Pass `':memory:'` for an in-memory database.
67
+
68
+ ```typescript
69
+ import { createSqliteDb } from '@cibule/db-sqlite';
70
+
71
+ const db = createSqliteDb<MySchema>('./data.db');
72
+ const memoryDb = createSqliteDb<MySchema>(':memory:');
73
+ ```
74
+
75
+ ### SqliteUnitOfWork
76
+
77
+ Implements the `UnitOfWork` interface from `@cibule/db`. Executes batched queries atomically inside a Kysely transaction — all queries succeed or all are rolled back.
78
+
79
+ ```typescript
80
+ import { createSqliteDb, SqliteUnitOfWork } from '@cibule/db-sqlite';
81
+
82
+ const db = createSqliteDb<MySchema>(':memory:');
83
+ const uow = new SqliteUnitOfWork(db);
84
+
85
+ uow.add(db.insertInto('users').values({ id: 1, name: 'Alice', email: 'a@b.com' }).compile());
86
+ uow.add(db.insertInto('users').values({ id: 2, name: 'Bob', email: 'b@b.com' }).compile());
87
+
88
+ await uow.execute(); // atomic — both inserts succeed or both roll back
89
+ ```
90
+
91
+ Key behaviors:
92
+
93
+ - Empty batch: `execute()` returns immediately without opening a transaction
94
+ - Queries are cleared before execution begins, preventing accidental double-execution
95
+ - On failure: the transaction is rolled back (no partial writes); queries are already cleared and cannot be retried — callers must re-add queries if retry is needed
96
+
97
+ ### provideSqliteDb(filename)
98
+
99
+ Returns a `Provider[]` that registers both `DB_ACCESSOR` and `UNIT_OF_WORK_FACTORY` with the DI container.
100
+
101
+ ```typescript
102
+ import { Injector } from '@cibule/di';
103
+ import { DB_ACCESSOR, UNIT_OF_WORK_FACTORY } from '@cibule/db';
104
+ import { provideSqliteDb } from '@cibule/db-sqlite';
105
+
106
+ const injector = Injector.create({
107
+ providers: provideSqliteDb('./data.db'),
108
+ });
109
+
110
+ injector.runInContext(() => {
111
+ const dbAccessor = injector.get(DB_ACCESSOR);
112
+ const db = dbAccessor(); // Kysely<any> instance
113
+
114
+ const uowFactory = injector.get(UNIT_OF_WORK_FACTORY);
115
+ const uow = uowFactory(); // fresh SqliteUnitOfWork per call
116
+ });
117
+ ```
118
+
119
+ The `DB_ACCESSOR` returns the same Kysely instance on every call (singleton). The `UNIT_OF_WORK_FACTORY` returns a fresh `SqliteUnitOfWork` on every call (double-factory pattern).
120
+
121
+ ## Related Packages
122
+
123
+ | Package | Description | Heavy dependency |
124
+ | -------------------- | ---------------------------- | -------------------- |
125
+ | `@cibule/db` | Core types + mock driver | None (built-in) |
126
+ | `@cibule/db-sqlite` | SQLite driver (this package) | `better-sqlite3` |
127
+ | `@cibule/db-d1` | Cloudflare D1 driver | `kysely-d1` |
128
+ | `@cibule/db-migrate` | Migration orchestrator | `prisma`, `wrangler` |
129
+
130
+ ## License
131
+
132
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ SqliteUnitOfWork: () => SqliteUnitOfWork,
34
+ createSqliteDb: () => createSqliteDb,
35
+ provideSqliteDb: () => provideSqliteDb
36
+ });
37
+ module.exports = __toCommonJS(index_exports);
38
+
39
+ // src/lib/create-sqlite-db.ts
40
+ var import_better_sqlite3 = __toESM(require("better-sqlite3"), 1);
41
+ var import_kysely = require("kysely");
42
+ function createSqliteDb(filename) {
43
+ return new import_kysely.Kysely({
44
+ dialect: new import_kysely.SqliteDialect({
45
+ database: new import_better_sqlite3.default(filename)
46
+ })
47
+ });
48
+ }
49
+
50
+ // ../di/src/lib/context.ts
51
+ var currentInjector = null;
52
+ function getCurrentInjector() {
53
+ return currentInjector;
54
+ }
55
+
56
+ // ../di/src/lib/inject.ts
57
+ function inject(token, options) {
58
+ const injector = getCurrentInjector();
59
+ if (!injector) {
60
+ throw new Error("inject() must be called within an injection context (runInContext)");
61
+ }
62
+ return options ? injector.get(token, options) : injector.get(token);
63
+ }
64
+
65
+ // ../di/src/lib/injection-token.ts
66
+ var InjectionToken = class {
67
+ constructor(description) {
68
+ this.description = description;
69
+ }
70
+ };
71
+
72
+ // ../db/src/lib/db-accessor.ts
73
+ var DB_ACCESSOR = new InjectionToken("DB_ACCESSOR");
74
+
75
+ // ../db/src/lib/provider.ts
76
+ function provideDbAccessor(factory) {
77
+ return { provide: DB_ACCESSOR, useFactory: factory };
78
+ }
79
+
80
+ // ../db/src/lib/unit-of-work.ts
81
+ var UNIT_OF_WORK_FACTORY = new InjectionToken("UNIT_OF_WORK_FACTORY");
82
+
83
+ // src/lib/sqlite-unit-of-work.ts
84
+ var SqliteUnitOfWork = class {
85
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
86
+ constructor(db) {
87
+ this.db = db;
88
+ }
89
+ queries = [];
90
+ add(query) {
91
+ this.queries.push(query);
92
+ }
93
+ async execute() {
94
+ if (this.queries.length === 0) return;
95
+ const batch = [...this.queries];
96
+ this.queries = [];
97
+ try {
98
+ await this.db.transaction().execute(async (trx) => {
99
+ for (const query of batch) {
100
+ await trx.executeQuery(query);
101
+ }
102
+ });
103
+ } catch (error) {
104
+ this.queries = [...batch, ...this.queries];
105
+ throw error;
106
+ }
107
+ }
108
+ };
109
+
110
+ // src/lib/provider.ts
111
+ function provideSqliteDb(filename) {
112
+ return [
113
+ provideDbAccessor(() => {
114
+ const db = createSqliteDb(filename);
115
+ return () => db;
116
+ }),
117
+ {
118
+ provide: UNIT_OF_WORK_FACTORY,
119
+ useFactory: () => {
120
+ const dbAccessor = inject(DB_ACCESSOR);
121
+ return () => new SqliteUnitOfWork(dbAccessor());
122
+ }
123
+ }
124
+ ];
125
+ }
126
+ // Annotate the CommonJS export names for ESM import in node:
127
+ 0 && (module.exports = {
128
+ SqliteUnitOfWork,
129
+ createSqliteDb,
130
+ provideSqliteDb
131
+ });
132
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts", "../src/lib/create-sqlite-db.ts", "../../di/src/lib/context.ts", "../../di/src/lib/inject.ts", "../../di/src/lib/injection-token.ts", "../../db/src/lib/db-accessor.ts", "../../db/src/lib/provider.ts", "../../db/src/lib/unit-of-work.ts", "../src/lib/sqlite-unit-of-work.ts", "../src/lib/provider.ts"],
4
+ "sourcesContent": ["export { createSqliteDb } from './lib/create-sqlite-db';\nexport { provideSqliteDb } from './lib/provider';\nexport { SqliteUnitOfWork } from './lib/sqlite-unit-of-work';\n", "import type { Db } from '@cibule/db';\nimport Database from 'better-sqlite3';\nimport { Kysely, SqliteDialect } from 'kysely';\n\nexport function createSqliteDb<Schema>(filename: string): Db<Schema> {\n return new Kysely<Schema>({\n dialect: new SqliteDialect({\n database: new Database(filename),\n }),\n });\n}\n", "import type { Injector } from './injector';\n\nlet currentInjector: Injector | null = null;\n\nexport function getCurrentInjector(): Injector | null {\n return currentInjector;\n}\n\nexport function setCurrentInjector(injector: Injector | null): Injector | null {\n const previous = currentInjector;\n currentInjector = injector;\n return previous;\n}\n", "import { getCurrentInjector } from './context';\nimport type { InjectOptions } from './provider';\nimport type { Token } from './token';\n\nexport function inject<T>(token: Token<T>): T;\nexport function inject<T>(token: Token<T>, options: InjectOptions): T | null;\nexport function inject<T>(token: Token<T>, options?: InjectOptions): T | null {\n const injector = getCurrentInjector();\n\n if (!injector) {\n throw new Error('inject() must be called within an injection context (runInContext)');\n }\n\n return options ? injector.get(token, options) : injector.get(token);\n}\n", "export class InjectionToken<T> {\n declare readonly _brand: T;\n constructor(public readonly description: string) {}\n}\n", "import { InjectionToken } from '@cibule/di';\n\nimport type { Db } from './db';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type DbAccessor<Schema = any> = () => Db<Schema>;\n\nexport const DB_ACCESSOR = new InjectionToken<DbAccessor>('DB_ACCESSOR');\n", "import type { Provider } from '@cibule/di';\n\nimport type { DbAccessor } from './db-accessor';\nimport { DB_ACCESSOR } from './db-accessor';\n\nexport function provideDbAccessor<S>(factory: () => DbAccessor<S>): Provider {\n return { provide: DB_ACCESSOR, useFactory: factory };\n}\n", "import { InjectionToken } from '@cibule/di';\nimport type { CompiledQuery } from 'kysely';\n\nexport interface UnitOfWork {\n add<T>(query: CompiledQuery<T>): void;\n execute(): Promise<void>;\n}\n\nexport type UnitOfWorkFactory = () => UnitOfWork;\n\nexport const UNIT_OF_WORK_FACTORY = new InjectionToken<UnitOfWorkFactory>('UNIT_OF_WORK_FACTORY');\n", "import type { UnitOfWork } from '@cibule/db';\nimport type { CompiledQuery, Kysely } from 'kysely';\n\nexport class SqliteUnitOfWork implements UnitOfWork {\n private queries: CompiledQuery[] = [];\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public constructor(private readonly db: Kysely<any>) {}\n\n public add<T>(query: CompiledQuery<T>): void {\n this.queries.push(query);\n }\n\n public async execute(): Promise<void> {\n if (this.queries.length === 0) return;\n\n const batch = [...this.queries];\n this.queries = [];\n\n try {\n await this.db.transaction().execute(async trx => {\n for (const query of batch) {\n await trx.executeQuery(query);\n }\n });\n } catch (error: unknown) {\n this.queries = [...batch, ...this.queries];\n throw error;\n }\n }\n}\n", "import { DB_ACCESSOR, provideDbAccessor, UNIT_OF_WORK_FACTORY } from '@cibule/db';\nimport type { Provider } from '@cibule/di';\nimport { inject } from '@cibule/di';\n\nimport { createSqliteDb } from './create-sqlite-db';\nimport { SqliteUnitOfWork } from './sqlite-unit-of-work';\n\nexport function provideSqliteDb(filename: string): Provider[] {\n return [\n provideDbAccessor(() => {\n const db = createSqliteDb(filename);\n return () => db;\n }),\n {\n provide: UNIT_OF_WORK_FACTORY,\n useFactory: () => {\n const dbAccessor = inject(DB_ACCESSOR);\n return () => new SqliteUnitOfWork(dbAccessor());\n },\n },\n ];\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,4BAAqB;AACrB,oBAAsC;AAE/B,SAAS,eAAuB,UAA8B;AACnE,SAAO,IAAI,qBAAe;AAAA,IACxB,SAAS,IAAI,4BAAc;AAAA,MACzB,UAAU,IAAI,sBAAAA,QAAS,QAAQ;AAAA,IACjC,CAAC;AAAA,EACH,CAAC;AACH;;;ACRA,IAAI,kBAAmC;AAEhC,SAAS,qBAAsC;AACpD,SAAO;AACT;;;ACAO,SAAS,OAAU,OAAiB,SAAmC;AAC5E,QAAM,WAAW,mBAAmB;AAEpC,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,MAAM,oEAAoE;AAAA,EACtF;AAEA,SAAO,UAAU,SAAS,IAAI,OAAO,OAAO,IAAI,SAAS,IAAI,KAAK;AACpE;;;ACdO,IAAM,iBAAN,MAAwB;AAAA,EAE7B,YAA4B,aAAqB;AAArB;AAAA,EAAsB;AACpD;;;ACIO,IAAM,cAAc,IAAI,eAA2B,aAAa;;;ACFhE,SAAS,kBAAqB,SAAwC;AAC3E,SAAO,EAAE,SAAS,aAAa,YAAY,QAAQ;AACrD;;;ACGO,IAAM,uBAAuB,IAAI,eAAkC,sBAAsB;;;ACPzF,IAAM,mBAAN,MAA6C;AAAA;AAAA,EAI3C,YAA6B,IAAiB;AAAjB;AAAA,EAAkB;AAAA,EAH9C,UAA2B,CAAC;AAAA,EAK7B,IAAO,OAA+B;AAC3C,SAAK,QAAQ,KAAK,KAAK;AAAA,EACzB;AAAA,EAEA,MAAa,UAAyB;AACpC,QAAI,KAAK,QAAQ,WAAW,EAAG;AAE/B,UAAM,QAAQ,CAAC,GAAG,KAAK,OAAO;AAC9B,SAAK,UAAU,CAAC;AAEhB,QAAI;AACF,YAAM,KAAK,GAAG,YAAY,EAAE,QAAQ,OAAM,QAAO;AAC/C,mBAAW,SAAS,OAAO;AACzB,gBAAM,IAAI,aAAa,KAAK;AAAA,QAC9B;AAAA,MACF,CAAC;AAAA,IACH,SAAS,OAAgB;AACvB,WAAK,UAAU,CAAC,GAAG,OAAO,GAAG,KAAK,OAAO;AACzC,YAAM;AAAA,IACR;AAAA,EACF;AACF;;;ACvBO,SAAS,gBAAgB,UAA8B;AAC5D,SAAO;AAAA,IACL,kBAAkB,MAAM;AACtB,YAAM,KAAK,eAAe,QAAQ;AAClC,aAAO,MAAM;AAAA,IACf,CAAC;AAAA,IACD;AAAA,MACE,SAAS;AAAA,MACT,YAAY,MAAM;AAChB,cAAM,aAAa,OAAO,WAAW;AACrC,eAAO,MAAM,IAAI,iBAAiB,WAAW,CAAC;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AACF;",
6
+ "names": ["Database"]
7
+ }
@@ -0,0 +1,4 @@
1
+ export { createSqliteDb } from './lib/create-sqlite-db';
2
+ export { provideSqliteDb } from './lib/provider';
3
+ export { SqliteUnitOfWork } from './lib/sqlite-unit-of-work';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,93 @@
1
+ // src/lib/create-sqlite-db.ts
2
+ import Database from "better-sqlite3";
3
+ import { Kysely, SqliteDialect } from "kysely";
4
+ function createSqliteDb(filename) {
5
+ return new Kysely({
6
+ dialect: new SqliteDialect({
7
+ database: new Database(filename)
8
+ })
9
+ });
10
+ }
11
+
12
+ // ../di/src/lib/context.ts
13
+ var currentInjector = null;
14
+ function getCurrentInjector() {
15
+ return currentInjector;
16
+ }
17
+
18
+ // ../di/src/lib/inject.ts
19
+ function inject(token, options) {
20
+ const injector = getCurrentInjector();
21
+ if (!injector) {
22
+ throw new Error("inject() must be called within an injection context (runInContext)");
23
+ }
24
+ return options ? injector.get(token, options) : injector.get(token);
25
+ }
26
+
27
+ // ../di/src/lib/injection-token.ts
28
+ var InjectionToken = class {
29
+ constructor(description) {
30
+ this.description = description;
31
+ }
32
+ };
33
+
34
+ // ../db/src/lib/db-accessor.ts
35
+ var DB_ACCESSOR = new InjectionToken("DB_ACCESSOR");
36
+
37
+ // ../db/src/lib/provider.ts
38
+ function provideDbAccessor(factory) {
39
+ return { provide: DB_ACCESSOR, useFactory: factory };
40
+ }
41
+
42
+ // ../db/src/lib/unit-of-work.ts
43
+ var UNIT_OF_WORK_FACTORY = new InjectionToken("UNIT_OF_WORK_FACTORY");
44
+
45
+ // src/lib/sqlite-unit-of-work.ts
46
+ var SqliteUnitOfWork = class {
47
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
48
+ constructor(db) {
49
+ this.db = db;
50
+ }
51
+ queries = [];
52
+ add(query) {
53
+ this.queries.push(query);
54
+ }
55
+ async execute() {
56
+ if (this.queries.length === 0) return;
57
+ const batch = [...this.queries];
58
+ this.queries = [];
59
+ try {
60
+ await this.db.transaction().execute(async (trx) => {
61
+ for (const query of batch) {
62
+ await trx.executeQuery(query);
63
+ }
64
+ });
65
+ } catch (error) {
66
+ this.queries = [...batch, ...this.queries];
67
+ throw error;
68
+ }
69
+ }
70
+ };
71
+
72
+ // src/lib/provider.ts
73
+ function provideSqliteDb(filename) {
74
+ return [
75
+ provideDbAccessor(() => {
76
+ const db = createSqliteDb(filename);
77
+ return () => db;
78
+ }),
79
+ {
80
+ provide: UNIT_OF_WORK_FACTORY,
81
+ useFactory: () => {
82
+ const dbAccessor = inject(DB_ACCESSOR);
83
+ return () => new SqliteUnitOfWork(dbAccessor());
84
+ }
85
+ }
86
+ ];
87
+ }
88
+ export {
89
+ SqliteUnitOfWork,
90
+ createSqliteDb,
91
+ provideSqliteDb
92
+ };
93
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/lib/create-sqlite-db.ts", "../../di/src/lib/context.ts", "../../di/src/lib/inject.ts", "../../di/src/lib/injection-token.ts", "../../db/src/lib/db-accessor.ts", "../../db/src/lib/provider.ts", "../../db/src/lib/unit-of-work.ts", "../src/lib/sqlite-unit-of-work.ts", "../src/lib/provider.ts"],
4
+ "sourcesContent": ["import type { Db } from '@cibule/db';\nimport Database from 'better-sqlite3';\nimport { Kysely, SqliteDialect } from 'kysely';\n\nexport function createSqliteDb<Schema>(filename: string): Db<Schema> {\n return new Kysely<Schema>({\n dialect: new SqliteDialect({\n database: new Database(filename),\n }),\n });\n}\n", "import type { Injector } from './injector';\n\nlet currentInjector: Injector | null = null;\n\nexport function getCurrentInjector(): Injector | null {\n return currentInjector;\n}\n\nexport function setCurrentInjector(injector: Injector | null): Injector | null {\n const previous = currentInjector;\n currentInjector = injector;\n return previous;\n}\n", "import { getCurrentInjector } from './context';\nimport type { InjectOptions } from './provider';\nimport type { Token } from './token';\n\nexport function inject<T>(token: Token<T>): T;\nexport function inject<T>(token: Token<T>, options: InjectOptions): T | null;\nexport function inject<T>(token: Token<T>, options?: InjectOptions): T | null {\n const injector = getCurrentInjector();\n\n if (!injector) {\n throw new Error('inject() must be called within an injection context (runInContext)');\n }\n\n return options ? injector.get(token, options) : injector.get(token);\n}\n", "export class InjectionToken<T> {\n declare readonly _brand: T;\n constructor(public readonly description: string) {}\n}\n", "import { InjectionToken } from '@cibule/di';\n\nimport type { Db } from './db';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type DbAccessor<Schema = any> = () => Db<Schema>;\n\nexport const DB_ACCESSOR = new InjectionToken<DbAccessor>('DB_ACCESSOR');\n", "import type { Provider } from '@cibule/di';\n\nimport type { DbAccessor } from './db-accessor';\nimport { DB_ACCESSOR } from './db-accessor';\n\nexport function provideDbAccessor<S>(factory: () => DbAccessor<S>): Provider {\n return { provide: DB_ACCESSOR, useFactory: factory };\n}\n", "import { InjectionToken } from '@cibule/di';\nimport type { CompiledQuery } from 'kysely';\n\nexport interface UnitOfWork {\n add<T>(query: CompiledQuery<T>): void;\n execute(): Promise<void>;\n}\n\nexport type UnitOfWorkFactory = () => UnitOfWork;\n\nexport const UNIT_OF_WORK_FACTORY = new InjectionToken<UnitOfWorkFactory>('UNIT_OF_WORK_FACTORY');\n", "import type { UnitOfWork } from '@cibule/db';\nimport type { CompiledQuery, Kysely } from 'kysely';\n\nexport class SqliteUnitOfWork implements UnitOfWork {\n private queries: CompiledQuery[] = [];\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public constructor(private readonly db: Kysely<any>) {}\n\n public add<T>(query: CompiledQuery<T>): void {\n this.queries.push(query);\n }\n\n public async execute(): Promise<void> {\n if (this.queries.length === 0) return;\n\n const batch = [...this.queries];\n this.queries = [];\n\n try {\n await this.db.transaction().execute(async trx => {\n for (const query of batch) {\n await trx.executeQuery(query);\n }\n });\n } catch (error: unknown) {\n this.queries = [...batch, ...this.queries];\n throw error;\n }\n }\n}\n", "import { DB_ACCESSOR, provideDbAccessor, UNIT_OF_WORK_FACTORY } from '@cibule/db';\nimport type { Provider } from '@cibule/di';\nimport { inject } from '@cibule/di';\n\nimport { createSqliteDb } from './create-sqlite-db';\nimport { SqliteUnitOfWork } from './sqlite-unit-of-work';\n\nexport function provideSqliteDb(filename: string): Provider[] {\n return [\n provideDbAccessor(() => {\n const db = createSqliteDb(filename);\n return () => db;\n }),\n {\n provide: UNIT_OF_WORK_FACTORY,\n useFactory: () => {\n const dbAccessor = inject(DB_ACCESSOR);\n return () => new SqliteUnitOfWork(dbAccessor());\n },\n },\n ];\n}\n"],
5
+ "mappings": ";AACA,OAAO,cAAc;AACrB,SAAS,QAAQ,qBAAqB;AAE/B,SAAS,eAAuB,UAA8B;AACnE,SAAO,IAAI,OAAe;AAAA,IACxB,SAAS,IAAI,cAAc;AAAA,MACzB,UAAU,IAAI,SAAS,QAAQ;AAAA,IACjC,CAAC;AAAA,EACH,CAAC;AACH;;;ACRA,IAAI,kBAAmC;AAEhC,SAAS,qBAAsC;AACpD,SAAO;AACT;;;ACAO,SAAS,OAAU,OAAiB,SAAmC;AAC5E,QAAM,WAAW,mBAAmB;AAEpC,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,MAAM,oEAAoE;AAAA,EACtF;AAEA,SAAO,UAAU,SAAS,IAAI,OAAO,OAAO,IAAI,SAAS,IAAI,KAAK;AACpE;;;ACdO,IAAM,iBAAN,MAAwB;AAAA,EAE7B,YAA4B,aAAqB;AAArB;AAAA,EAAsB;AACpD;;;ACIO,IAAM,cAAc,IAAI,eAA2B,aAAa;;;ACFhE,SAAS,kBAAqB,SAAwC;AAC3E,SAAO,EAAE,SAAS,aAAa,YAAY,QAAQ;AACrD;;;ACGO,IAAM,uBAAuB,IAAI,eAAkC,sBAAsB;;;ACPzF,IAAM,mBAAN,MAA6C;AAAA;AAAA,EAI3C,YAA6B,IAAiB;AAAjB;AAAA,EAAkB;AAAA,EAH9C,UAA2B,CAAC;AAAA,EAK7B,IAAO,OAA+B;AAC3C,SAAK,QAAQ,KAAK,KAAK;AAAA,EACzB;AAAA,EAEA,MAAa,UAAyB;AACpC,QAAI,KAAK,QAAQ,WAAW,EAAG;AAE/B,UAAM,QAAQ,CAAC,GAAG,KAAK,OAAO;AAC9B,SAAK,UAAU,CAAC;AAEhB,QAAI;AACF,YAAM,KAAK,GAAG,YAAY,EAAE,QAAQ,OAAM,QAAO;AAC/C,mBAAW,SAAS,OAAO;AACzB,gBAAM,IAAI,aAAa,KAAK;AAAA,QAC9B;AAAA,MACF,CAAC;AAAA,IACH,SAAS,OAAgB;AACvB,WAAK,UAAU,CAAC,GAAG,OAAO,GAAG,KAAK,OAAO;AACzC,YAAM;AAAA,IACR;AAAA,EACF;AACF;;;ACvBO,SAAS,gBAAgB,UAA8B;AAC5D,SAAO;AAAA,IACL,kBAAkB,MAAM;AACtB,YAAM,KAAK,eAAe,QAAQ;AAClC,aAAO,MAAM;AAAA,IACf,CAAC;AAAA,IACD;AAAA,MACE,SAAS;AAAA,MACT,YAAY,MAAM;AAChB,cAAM,aAAa,OAAO,WAAW;AACrC,eAAO,MAAM,IAAI,iBAAiB,WAAW,CAAC;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,3 @@
1
+ import type { Db } from '@cibule/db';
2
+ export declare function createSqliteDb<Schema>(filename: string): Db<Schema>;
3
+ //# sourceMappingURL=create-sqlite-db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-sqlite-db.d.ts","sourceRoot":"","sources":["../../../../../../src/lib/create-sqlite-db.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAIrC,wBAAgB,cAAc,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,CAMnE"}
@@ -0,0 +1,3 @@
1
+ import type { Provider } from '@cibule/di';
2
+ export declare function provideSqliteDb(filename: string): Provider[];
3
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../../../../src/lib/provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAM3C,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,EAAE,CAc5D"}
@@ -0,0 +1,10 @@
1
+ import type { UnitOfWork } from '@cibule/db';
2
+ import type { CompiledQuery, Kysely } from 'kysely';
3
+ export declare class SqliteUnitOfWork implements UnitOfWork {
4
+ private readonly db;
5
+ private queries;
6
+ constructor(db: Kysely<any>);
7
+ add<T>(query: CompiledQuery<T>): void;
8
+ execute(): Promise<void>;
9
+ }
10
+ //# sourceMappingURL=sqlite-unit-of-work.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-unit-of-work.d.ts","sourceRoot":"","sources":["../../../../../../src/lib/sqlite-unit-of-work.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEpD,qBAAa,gBAAiB,YAAW,UAAU;IAI9B,OAAO,CAAC,QAAQ,CAAC,EAAE;IAHtC,OAAO,CAAC,OAAO,CAAuB;gBAGF,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC;IAE5C,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI;IAI/B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAiBtC"}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@cibule/db-sqlite",
3
+ "version": "0.1.1",
4
+ "license": "MIT",
5
+ "type": "module",
6
+ "main": "dist/index.cjs",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.ts",
17
+ "default": "./dist/index.cjs"
18
+ }
19
+ }
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "sideEffects": false,
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "https://gitlab.com/LadaBr/cibule",
28
+ "directory": "packages/db-sqlite"
29
+ },
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
33
+ "dependencies": {
34
+ "@cibule/db": "workspace:*",
35
+ "@cibule/di": "workspace:*",
36
+ "better-sqlite3": "^11.0.0",
37
+ "kysely": "^0.28.0"
38
+ }
39
+ }