@effect/sql-sqlite-do 4.0.0-beta.1 → 4.0.0-beta.100
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 +1 -1
- package/dist/SqliteClient.d.ts +58 -17
- package/dist/SqliteClient.d.ts.map +1 -1
- package/dist/SqliteClient.js +91 -25
- package/dist/SqliteClient.js.map +1 -1
- package/dist/SqliteMigrator.d.ts +33 -6
- package/dist/SqliteMigrator.d.ts.map +1 -1
- package/dist/SqliteMigrator.js +9 -5
- package/dist/SqliteMigrator.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/package.json +6 -7
- package/src/SqliteClient.ts +174 -49
- package/src/SqliteMigrator.ts +33 -6
- package/src/index.ts +3 -3
package/README.md
CHANGED
package/dist/SqliteClient.d.ts
CHANGED
|
@@ -1,27 +1,52 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Connects Effect SQL to SQLite storage inside Cloudflare Durable Objects.
|
|
3
|
+
*
|
|
4
|
+
* This module adapts a Durable Object `SqlStorage` handle into both the
|
|
5
|
+
* Durable Object-specific `SqliteClient` service and the generic Effect
|
|
6
|
+
* `SqlClient` service. Use it from inside a Durable Object to run local
|
|
7
|
+
* per-object queries, repositories, migrations, transactional read/write
|
|
8
|
+
* workflows, and tests that exercise Cloudflare's SQLite-backed storage API.
|
|
9
|
+
*
|
|
10
|
+
* Durable Object SQLite storage is scoped to one object id, so each object
|
|
11
|
+
* instance has its own database. Callers can pass the `SqlStorage` handle for
|
|
12
|
+
* normal queries, or the full `DurableObjectStorage` when `withTransaction` or
|
|
13
|
+
* migrations need Cloudflare-managed transactions. This adapter serializes
|
|
14
|
+
* Effect SQL access through one connection; a transaction holds that permit for
|
|
15
|
+
* the lifetime of its scope, so keep transactions short, avoid suspending them
|
|
16
|
+
* across unrelated work, and use them when multi-statement writes must commit
|
|
17
|
+
* atomically. `SqlStorage.exec` returns `ArrayBuffer` values
|
|
18
|
+
* for SQLite blobs, which this client normalizes to `Uint8Array`, and SQLite
|
|
19
|
+
* does not support `updateValues`.
|
|
20
|
+
*
|
|
21
|
+
* @since 4.0.0
|
|
3
22
|
*/
|
|
4
|
-
import type { SqlStorage } from "@cloudflare/workers-types";
|
|
23
|
+
import type { DurableObjectStorage, SqlStorage } from "@cloudflare/workers-types";
|
|
5
24
|
import * as Config from "effect/Config";
|
|
25
|
+
import * as Context from "effect/Context";
|
|
6
26
|
import * as Effect from "effect/Effect";
|
|
7
27
|
import * as Layer from "effect/Layer";
|
|
8
28
|
import * as Scope from "effect/Scope";
|
|
9
|
-
import * as ServiceMap from "effect/ServiceMap";
|
|
10
29
|
import * as Reactivity from "effect/unstable/reactivity/Reactivity";
|
|
11
30
|
import * as Client from "effect/unstable/sql/SqlClient";
|
|
12
31
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
32
|
+
* Runtime type identifier used to mark Cloudflare Durable Object `SqliteClient` values.
|
|
33
|
+
*
|
|
34
|
+
* @category type IDs
|
|
35
|
+
* @since 4.0.0
|
|
15
36
|
*/
|
|
16
37
|
export declare const TypeId: TypeId;
|
|
17
38
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
39
|
+
* Type-level identifier used to mark Cloudflare Durable Object `SqliteClient` values.
|
|
40
|
+
*
|
|
41
|
+
* @category type IDs
|
|
42
|
+
* @since 4.0.0
|
|
20
43
|
*/
|
|
21
44
|
export type TypeId = "~@effect/sql-sqlite-do/SqliteClient";
|
|
22
45
|
/**
|
|
46
|
+
* Cloudflare Durable Object SQLite client service, extending `SqlClient` with its configuration. `updateValues` is not supported.
|
|
47
|
+
*
|
|
23
48
|
* @category models
|
|
24
|
-
* @since
|
|
49
|
+
* @since 4.0.0
|
|
25
50
|
*/
|
|
26
51
|
export interface SqliteClient extends Client.SqlClient {
|
|
27
52
|
readonly [TypeId]: TypeId;
|
|
@@ -30,33 +55,49 @@ export interface SqliteClient extends Client.SqlClient {
|
|
|
30
55
|
readonly updateValues: never;
|
|
31
56
|
}
|
|
32
57
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
58
|
+
* Service tag for the Cloudflare Durable Object SQLite client service.
|
|
59
|
+
*
|
|
60
|
+
* **When to use**
|
|
61
|
+
*
|
|
62
|
+
* Use to access or provide a Durable Object SQLite client through the Effect
|
|
63
|
+
* context.
|
|
64
|
+
*
|
|
65
|
+
* @category services
|
|
66
|
+
* @since 4.0.0
|
|
35
67
|
*/
|
|
36
|
-
export declare const SqliteClient:
|
|
68
|
+
export declare const SqliteClient: Context.Service<SqliteClient, SqliteClient>;
|
|
37
69
|
/**
|
|
70
|
+
* Configuration for a Cloudflare Durable Object SQLite client, including either a `SqlStorage` handle or the full `DurableObjectStorage` for transaction support, span attributes, and query/result name transforms.
|
|
71
|
+
*
|
|
38
72
|
* @category models
|
|
39
|
-
* @since
|
|
73
|
+
* @since 4.0.0
|
|
40
74
|
*/
|
|
41
75
|
export interface SqliteClientConfig {
|
|
42
|
-
readonly db
|
|
76
|
+
readonly db?: SqlStorage | undefined;
|
|
77
|
+
readonly storage?: DurableObjectStorage | undefined;
|
|
43
78
|
readonly spanAttributes?: Record<string, unknown> | undefined;
|
|
44
79
|
readonly transformResultNames?: ((str: string) => string) | undefined;
|
|
45
80
|
readonly transformQueryNames?: ((str: string) => string) | undefined;
|
|
46
81
|
}
|
|
47
82
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
83
|
+
* Creates a scoped Cloudflare Durable Object SQLite client around Durable Object SQLite storage, serializing access and converting returned `ArrayBuffer` values to `Uint8Array`.
|
|
84
|
+
*
|
|
85
|
+
* @category constructors
|
|
86
|
+
* @since 4.0.0
|
|
50
87
|
*/
|
|
51
88
|
export declare const make: (options: SqliteClientConfig) => Effect.Effect<SqliteClient, never, Scope.Scope | Reactivity.Reactivity>;
|
|
52
89
|
/**
|
|
90
|
+
* Creates a layer from a `Config`-wrapped Durable Object SQLite client configuration, providing both `SqliteClient` and `SqlClient`.
|
|
91
|
+
*
|
|
53
92
|
* @category layers
|
|
54
|
-
* @since
|
|
93
|
+
* @since 4.0.0
|
|
55
94
|
*/
|
|
56
95
|
export declare const layerConfig: (config: Config.Wrap<SqliteClientConfig>) => Layer.Layer<SqliteClient | Client.SqlClient, Config.ConfigError>;
|
|
57
96
|
/**
|
|
97
|
+
* Creates a layer from a concrete Durable Object SQLite client configuration, providing both `SqliteClient` and `SqlClient`.
|
|
98
|
+
*
|
|
58
99
|
* @category layers
|
|
59
|
-
* @since
|
|
100
|
+
* @since 4.0.0
|
|
60
101
|
*/
|
|
61
102
|
export declare const layer: (config: SqliteClientConfig) => Layer.Layer<SqliteClient | Client.SqlClient>;
|
|
62
103
|
//# sourceMappingURL=SqliteClient.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqliteClient.d.ts","sourceRoot":"","sources":["../src/SqliteClient.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"SqliteClient.d.ts","sourceRoot":"","sources":["../src/SqliteClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AACjF,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAIvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAGrC,OAAO,KAAK,UAAU,MAAM,uCAAuC,CAAA;AACnE,OAAO,KAAK,MAAM,MAAM,+BAA+B,CAAA;AAUvD;;;;;GAKG;AACH,eAAO,MAAM,MAAM,EAAE,MAA8C,CAAA;AAEnE;;;;;GAKG;AACH,MAAM,MAAM,MAAM,GAAG,qCAAqC,CAAA;AAE1D;;;;;GAKG;AACH,MAAM,WAAW,YAAa,SAAQ,MAAM,CAAC,SAAS;IACpD,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAA;IAEnC,8BAA8B;IAC9B,QAAQ,CAAC,YAAY,EAAE,KAAK,CAAA;CAC7B;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,6CAAsE,CAAA;AAM/F;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,CAAC,EAAE,UAAU,GAAG,SAAS,CAAA;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAA;IACnD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAA;IAE7D,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,SAAS,CAAA;IACrE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,SAAS,CAAA;CACrE;AAiED;;;;;GAKG;AACH,eAAO,MAAM,IAAI,YACN,kBAAkB,KAC1B,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC,UAAU,CA+HrE,CAAA;AAEJ;;;;;GAKG;AACH,eAAO,MAAM,WAAW,WACd,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,KACtC,KAAK,CAAC,KAAK,CAAC,YAAY,GAAG,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,WAAW,CAUzB,CAAA;AAEzC;;;;;GAKG;AACH,eAAO,MAAM,KAAK,WACR,kBAAkB,KACzB,KAAK,CAAC,KAAK,CAAC,YAAY,GAAG,MAAM,CAAC,SAAS,CAML,CAAA"}
|
package/dist/SqliteClient.js
CHANGED
|
@@ -1,37 +1,95 @@
|
|
|
1
1
|
import * as Config from "effect/Config";
|
|
2
|
+
import * as Context from "effect/Context";
|
|
2
3
|
import * as Effect from "effect/Effect";
|
|
4
|
+
import * as Exit from "effect/Exit";
|
|
3
5
|
import * as Fiber from "effect/Fiber";
|
|
4
6
|
import { identity } from "effect/Function";
|
|
5
7
|
import * as Layer from "effect/Layer";
|
|
6
8
|
import * as Scope from "effect/Scope";
|
|
7
|
-
import * as
|
|
9
|
+
import * as Semaphore from "effect/Semaphore";
|
|
8
10
|
import * as Stream from "effect/Stream";
|
|
9
11
|
import * as Reactivity from "effect/unstable/reactivity/Reactivity";
|
|
10
12
|
import * as Client from "effect/unstable/sql/SqlClient";
|
|
11
|
-
import { SqlError } from "effect/unstable/sql/SqlError";
|
|
13
|
+
import { classifySqliteError, SqlError, UnknownError } from "effect/unstable/sql/SqlError";
|
|
12
14
|
import * as Statement from "effect/unstable/sql/Statement";
|
|
13
15
|
const ATTR_DB_SYSTEM_NAME = "db.system.name";
|
|
16
|
+
const classifyError = (cause, message, operation) => classifySqliteError(cause, {
|
|
17
|
+
message,
|
|
18
|
+
operation
|
|
19
|
+
});
|
|
14
20
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
21
|
+
* Runtime type identifier used to mark Cloudflare Durable Object `SqliteClient` values.
|
|
22
|
+
*
|
|
23
|
+
* @category type IDs
|
|
24
|
+
* @since 4.0.0
|
|
17
25
|
*/
|
|
18
26
|
export const TypeId = "~@effect/sql-sqlite-do/SqliteClient";
|
|
19
27
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
28
|
+
* Service tag for the Cloudflare Durable Object SQLite client service.
|
|
29
|
+
*
|
|
30
|
+
* **When to use**
|
|
31
|
+
*
|
|
32
|
+
* Use to access or provide a Durable Object SQLite client through the Effect
|
|
33
|
+
* context.
|
|
34
|
+
*
|
|
35
|
+
* @category services
|
|
36
|
+
* @since 4.0.0
|
|
22
37
|
*/
|
|
23
|
-
export const SqliteClient = /*#__PURE__*/
|
|
38
|
+
export const SqliteClient = /*#__PURE__*/Context.Service("@effect/sql-sqlite-do/SqliteClient");
|
|
39
|
+
const SqliteTransaction = /*#__PURE__*/Context.Service("@effect/sql-sqlite-do/SqliteClient/SqliteTransaction");
|
|
40
|
+
const unsupportedTransaction = (message, operation) => new SqlError({
|
|
41
|
+
reason: new UnknownError({
|
|
42
|
+
cause: new Error(message),
|
|
43
|
+
message,
|
|
44
|
+
operation
|
|
45
|
+
})
|
|
46
|
+
});
|
|
47
|
+
const makeUnsupportedWithTransaction = message => _effect => Effect.fail(unsupportedTransaction(message, "transaction"));
|
|
48
|
+
const makeStorageBackedWithTransaction = (storage, connection, semaphore) => effect => Effect.withFiber(fiber => {
|
|
49
|
+
const services = fiber.context;
|
|
50
|
+
const connOption = Context.getOption(services, SqliteTransaction);
|
|
51
|
+
if (connOption._tag === "Some") {
|
|
52
|
+
return Effect.fail(unsupportedTransaction("Nested transactions are not supported by Cloudflare Durable Object SQLite storage", "transaction"));
|
|
53
|
+
}
|
|
54
|
+
const effectWithTxn = Effect.provideContext(effect, Context.add(services, SqliteTransaction, [connection, 0]));
|
|
55
|
+
return semaphore.withPermits(1)(Effect.callback(resume => {
|
|
56
|
+
let interrupted = false;
|
|
57
|
+
const promise = storage.transaction(txn => new Promise(resolve => {
|
|
58
|
+
if (interrupted) return resolve();
|
|
59
|
+
resume(Effect.onExit(effectWithTxn, exit => {
|
|
60
|
+
if (Exit.isFailure(exit)) {
|
|
61
|
+
txn.rollback();
|
|
62
|
+
}
|
|
63
|
+
resolve();
|
|
64
|
+
// wait for the transaction to complete
|
|
65
|
+
return Effect.promise(() => promise);
|
|
66
|
+
}));
|
|
67
|
+
})).catch(cause => resume(Effect.fail(new SqlError({
|
|
68
|
+
reason: classifyError(cause, "Failed transaction", "transaction")
|
|
69
|
+
}))));
|
|
70
|
+
return Effect.suspend(() => {
|
|
71
|
+
interrupted = true;
|
|
72
|
+
return Effect.promise(() => promise);
|
|
73
|
+
});
|
|
74
|
+
}));
|
|
75
|
+
});
|
|
24
76
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
77
|
+
* Creates a scoped Cloudflare Durable Object SQLite client around Durable Object SQLite storage, serializing access and converting returned `ArrayBuffer` values to `Uint8Array`.
|
|
78
|
+
*
|
|
79
|
+
* @category constructors
|
|
80
|
+
* @since 4.0.0
|
|
27
81
|
*/
|
|
28
82
|
export const make = options => Effect.gen(function* () {
|
|
29
83
|
const compiler = Statement.makeCompilerSqlite(options.transformQueryNames);
|
|
30
84
|
const transformRows = options.transformResultNames ? Statement.defaultTransforms(options.transformResultNames).array : undefined;
|
|
85
|
+
const db = options.storage?.sql ?? options.db;
|
|
86
|
+
if (db === undefined) {
|
|
87
|
+
return yield* Effect.die("SqliteClient.make requires either a Durable Object storage or sql storage");
|
|
88
|
+
}
|
|
89
|
+
const sqlStorage = db;
|
|
31
90
|
const makeConnection = Effect.gen(function* () {
|
|
32
|
-
const db = options.db;
|
|
33
91
|
function* runIterator(sql, params = []) {
|
|
34
|
-
const cursor =
|
|
92
|
+
const cursor = sqlStorage.exec(sql, ...params);
|
|
35
93
|
const columns = cursor.columnNames;
|
|
36
94
|
for (const result of cursor.raw()) {
|
|
37
95
|
const obj = {};
|
|
@@ -45,12 +103,11 @@ export const make = options => Effect.gen(function* () {
|
|
|
45
103
|
const runStatement = (sql, params = []) => Effect.try({
|
|
46
104
|
try: () => Array.from(runIterator(sql, params)),
|
|
47
105
|
catch: cause => new SqlError({
|
|
48
|
-
cause,
|
|
49
|
-
message: `Failed to execute statement`
|
|
106
|
+
reason: classifyError(cause, "Failed to execute statement", "execute")
|
|
50
107
|
})
|
|
51
108
|
});
|
|
52
109
|
const runValues = (sql, params = []) => Effect.try({
|
|
53
|
-
try: () => Array.from(
|
|
110
|
+
try: () => Array.from(sqlStorage.exec(sql, ...params).raw(), row => {
|
|
54
111
|
for (let i = 0; i < row.length; i++) {
|
|
55
112
|
const value = row[i];
|
|
56
113
|
if (value instanceof ArrayBuffer) {
|
|
@@ -60,8 +117,7 @@ export const make = options => Effect.gen(function* () {
|
|
|
60
117
|
return row;
|
|
61
118
|
}),
|
|
62
119
|
catch: cause => new SqlError({
|
|
63
|
-
cause,
|
|
64
|
-
message: `Failed to execute statement`
|
|
120
|
+
reason: classifyError(cause, "Failed to execute statement", "execute")
|
|
65
121
|
})
|
|
66
122
|
});
|
|
67
123
|
return identity({
|
|
@@ -74,6 +130,9 @@ export const make = options => Effect.gen(function* () {
|
|
|
74
130
|
executeValues(sql, params) {
|
|
75
131
|
return runValues(sql, params);
|
|
76
132
|
},
|
|
133
|
+
executeValuesUnprepared(sql, params) {
|
|
134
|
+
return runValues(sql, params);
|
|
135
|
+
},
|
|
77
136
|
executeUnprepared(sql, params, transformRows) {
|
|
78
137
|
return transformRows ? Effect.map(runStatement(sql, params), transformRows) : runStatement(sql, params);
|
|
79
138
|
},
|
|
@@ -85,33 +144,40 @@ export const make = options => Effect.gen(function* () {
|
|
|
85
144
|
}
|
|
86
145
|
});
|
|
87
146
|
});
|
|
88
|
-
const semaphore = yield*
|
|
147
|
+
const semaphore = yield* Semaphore.make(1);
|
|
89
148
|
const connection = yield* makeConnection;
|
|
90
149
|
const acquirer = semaphore.withPermits(1)(Effect.succeed(connection));
|
|
91
150
|
const transactionAcquirer = Effect.uninterruptibleMask(restore => {
|
|
92
151
|
const fiber = Fiber.getCurrent();
|
|
93
|
-
const scope =
|
|
152
|
+
const scope = Context.getUnsafe(fiber.context, Scope.Scope);
|
|
94
153
|
return Effect.as(Effect.tap(restore(semaphore.take(1)), () => Scope.addFinalizer(scope, semaphore.release(1))), connection);
|
|
95
154
|
});
|
|
96
|
-
|
|
155
|
+
const client = yield* Client.make({
|
|
97
156
|
acquirer,
|
|
98
157
|
compiler,
|
|
99
158
|
transactionAcquirer,
|
|
159
|
+
transactionService: SqliteTransaction,
|
|
100
160
|
spanAttributes: [...(options.spanAttributes ? Object.entries(options.spanAttributes) : []), [ATTR_DB_SYSTEM_NAME, "sqlite"]],
|
|
101
161
|
transformRows
|
|
102
|
-
})
|
|
162
|
+
});
|
|
163
|
+
return Object.assign(client, {
|
|
103
164
|
[TypeId]: TypeId,
|
|
104
|
-
config: options
|
|
165
|
+
config: options,
|
|
166
|
+
withTransaction: options.storage ? makeStorageBackedWithTransaction(options.storage, connection, semaphore) : makeUnsupportedWithTransaction("Transactions require Durable Object storage; pass ctx.storage as the storage option")
|
|
105
167
|
});
|
|
106
168
|
});
|
|
107
169
|
/**
|
|
170
|
+
* Creates a layer from a `Config`-wrapped Durable Object SQLite client configuration, providing both `SqliteClient` and `SqlClient`.
|
|
171
|
+
*
|
|
108
172
|
* @category layers
|
|
109
|
-
* @since
|
|
173
|
+
* @since 4.0.0
|
|
110
174
|
*/
|
|
111
|
-
export const layerConfig = config => Layer.
|
|
175
|
+
export const layerConfig = config => Layer.effectContext(Config.unwrap(config).pipe(Effect.flatMap(make), Effect.map(client => Context.make(SqliteClient, client).pipe(Context.add(Client.SqlClient, client))))).pipe(Layer.provide(Reactivity.layer));
|
|
112
176
|
/**
|
|
177
|
+
* Creates a layer from a concrete Durable Object SQLite client configuration, providing both `SqliteClient` and `SqlClient`.
|
|
178
|
+
*
|
|
113
179
|
* @category layers
|
|
114
|
-
* @since
|
|
180
|
+
* @since 4.0.0
|
|
115
181
|
*/
|
|
116
|
-
export const layer = config => Layer.
|
|
182
|
+
export const layer = config => Layer.effectContext(Effect.map(make(config), client => Context.make(SqliteClient, client).pipe(Context.add(Client.SqlClient, client)))).pipe(Layer.provide(Reactivity.layer));
|
|
117
183
|
//# sourceMappingURL=SqliteClient.js.map
|
package/dist/SqliteClient.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqliteClient.js","names":["Config","Effect","Fiber","identity","Layer","Scope","
|
|
1
|
+
{"version":3,"file":"SqliteClient.js","names":["Config","Context","Effect","Exit","Fiber","identity","Layer","Scope","Semaphore","Stream","Reactivity","Client","classifySqliteError","SqlError","UnknownError","Statement","ATTR_DB_SYSTEM_NAME","classifyError","cause","message","operation","TypeId","SqliteClient","Service","SqliteTransaction","unsupportedTransaction","reason","Error","makeUnsupportedWithTransaction","_effect","fail","makeStorageBackedWithTransaction","storage","connection","semaphore","effect","withFiber","fiber","services","context","connOption","getOption","_tag","effectWithTxn","provideContext","add","withPermits","callback","resume","interrupted","promise","transaction","txn","Promise","resolve","onExit","exit","isFailure","rollback","catch","suspend","make","options","gen","compiler","makeCompilerSqlite","transformQueryNames","transformRows","transformResultNames","defaultTransforms","array","undefined","db","sql","die","sqlStorage","makeConnection","runIterator","params","cursor","exec","columns","columnNames","result","raw","obj","i","length","value","ArrayBuffer","Uint8Array","runStatement","try","Array","from","runValues","row","execute","map","executeRaw","executeValues","executeValuesUnprepared","executeUnprepared","executeStream","iterator","fromIteratorSucceed","pipe","mapArray","chunk","acquirer","succeed","transactionAcquirer","uninterruptibleMask","restore","getCurrent","scope","getUnsafe","as","tap","take","addFinalizer","release","client","transactionService","spanAttributes","Object","entries","assign","config","withTransaction","layerConfig","effectContext","unwrap","flatMap","SqlClient","provide","layer"],"sources":["../src/SqliteClient.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
package/dist/SqliteMigrator.d.ts
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Runs database migrations for Durable Object SQLite storage that uses Effect
|
|
3
|
+
* SQL.
|
|
4
|
+
*
|
|
5
|
+
* This module re-exports the shared `Migrator` loaders and error types, then
|
|
6
|
+
* provides `run` and `layer` helpers that execute ordered migrations through the
|
|
7
|
+
* current Durable Object SQLite `SqlClient`. Use it when a Durable
|
|
8
|
+
* Object needs to create or upgrade its local schema during construction, before
|
|
9
|
+
* repositories or request handlers use the object storage, or in tests that
|
|
10
|
+
* exercise Durable Object persistence.
|
|
11
|
+
*
|
|
12
|
+
* Migrations are recorded in `effect_sql_migrations` by default and are loaded
|
|
13
|
+
* using the shared `<id>_<name>` file or record-key convention. The underlying
|
|
14
|
+
* storage is scoped to a Durable Object id, so running migrations for one object
|
|
15
|
+
* does not update any other object instance; run the migrator against the same
|
|
16
|
+
* `DurableObjectStorage`-backed client that the object uses for normal queries
|
|
17
|
+
* so migrations can run in Cloudflare-managed transactions. These SQL
|
|
18
|
+
* migrations are separate from Cloudflare's Durable Object class migrations, and
|
|
19
|
+
* the Durable Object must already be configured with SQLite storage before this
|
|
20
|
+
* module can apply schema changes. Repeated startup runs are expected and are
|
|
21
|
+
* guarded by the migrations table, but request handling should wait until the
|
|
22
|
+
* migration layer has finished. This adapter does not currently write SQLite
|
|
23
|
+
* schema dumps for `schemaDirectory`.
|
|
24
|
+
*
|
|
25
|
+
* @since 4.0.0
|
|
3
26
|
*/
|
|
4
27
|
import type * as Effect from "effect/Effect";
|
|
5
28
|
import * as Layer from "effect/Layer";
|
|
@@ -7,17 +30,21 @@ import * as Migrator from "effect/unstable/sql/Migrator";
|
|
|
7
30
|
import type * as Client from "effect/unstable/sql/SqlClient";
|
|
8
31
|
import type { SqlError } from "effect/unstable/sql/SqlError";
|
|
9
32
|
/**
|
|
10
|
-
* @since
|
|
33
|
+
* @since 4.0.0
|
|
11
34
|
*/
|
|
12
35
|
export * from "effect/unstable/sql/Migrator";
|
|
13
36
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
37
|
+
* Runs SQL migrations using the configured `SqlClient`, returning the migrations that were applied.
|
|
38
|
+
*
|
|
39
|
+
* @category constructors
|
|
40
|
+
* @since 4.0.0
|
|
16
41
|
*/
|
|
17
42
|
export declare const run: <R2 = never>({ loader, schemaDirectory, table }: Migrator.MigratorOptions<R2>) => Effect.Effect<ReadonlyArray<readonly [id: number, name: string]>, Migrator.MigrationError | SqlError, Client.SqlClient | R2>;
|
|
18
43
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
44
|
+
* Creates a layer that runs the configured SQL migrations during layer construction.
|
|
45
|
+
*
|
|
46
|
+
* @category constructors
|
|
47
|
+
* @since 4.0.0
|
|
21
48
|
*/
|
|
22
49
|
export declare const layer: <R>(options: Migrator.MigratorOptions<R>) => Layer.Layer<never, Migrator.MigrationError | SqlError, Client.SqlClient | R>;
|
|
23
50
|
//# sourceMappingURL=SqliteMigrator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqliteMigrator.d.ts","sourceRoot":"","sources":["../src/SqliteMigrator.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"SqliteMigrator.d.ts","sourceRoot":"","sources":["../src/SqliteMigrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,KAAK,MAAM,MAAM,eAAe,CAAA;AAC5C,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,KAAK,QAAQ,MAAM,8BAA8B,CAAA;AACxD,OAAO,KAAK,KAAK,MAAM,MAAM,+BAA+B,CAAA;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAA;AAE5D;;GAEG;AACH,cAAc,8BAA8B,CAAA;AAE5C;;;;;GAKG;AACH,eAAO,MAAM,GAAG,EAAE,CAAC,EAAE,GAAG,KAAK,EAC3B,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,KAC7D,MAAM,CAAC,MAAM,CAChB,aAAa,CAAC,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,EAClD,QAAQ,CAAC,cAAc,GAAG,QAAQ,EAClC,MAAM,CAAC,SAAS,GAAG,EAAE,CACF,CAAA;AAErB;;;;;GAKG;AACH,eAAO,MAAM,KAAK,GAAI,CAAC,WACZ,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,KACnC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,cAAc,GAAG,QAAQ,EAAE,MAAM,CAAC,SAAS,GAAG,CAAC,CAAsC,CAAA"}
|
package/dist/SqliteMigrator.js
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import * as Layer from "effect/Layer";
|
|
2
2
|
import * as Migrator from "effect/unstable/sql/Migrator";
|
|
3
3
|
/**
|
|
4
|
-
* @since
|
|
4
|
+
* @since 4.0.0
|
|
5
5
|
*/
|
|
6
6
|
export * from "effect/unstable/sql/Migrator";
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
* Runs SQL migrations using the configured `SqlClient`, returning the migrations that were applied.
|
|
9
|
+
*
|
|
10
|
+
* @category constructors
|
|
11
|
+
* @since 4.0.0
|
|
10
12
|
*/
|
|
11
13
|
export const run = /*#__PURE__*/Migrator.make({});
|
|
12
14
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
+
* Creates a layer that runs the configured SQL migrations during layer construction.
|
|
16
|
+
*
|
|
17
|
+
* @category constructors
|
|
18
|
+
* @since 4.0.0
|
|
15
19
|
*/
|
|
16
20
|
export const layer = options => Layer.effectDiscard(run(options));
|
|
17
21
|
//# sourceMappingURL=SqliteMigrator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqliteMigrator.js","names":["Layer","Migrator","run","make","layer","options","effectDiscard"],"sources":["../src/SqliteMigrator.ts"],"sourcesContent":[null],"mappings":"
|
|
1
|
+
{"version":3,"file":"SqliteMigrator.js","names":["Layer","Migrator","run","make","layer","options","effectDiscard"],"sources":["../src/SqliteMigrator.ts"],"sourcesContent":[null],"mappings":"AA2BA,OAAO,KAAKA,KAAK,MAAM,cAAc;AACrC,OAAO,KAAKC,QAAQ,MAAM,8BAA8B;AAIxD;;;AAGA,cAAc,8BAA8B;AAE5C;;;;;;AAMA,OAAO,MAAMC,GAAG,gBAMZD,QAAQ,CAACE,IAAI,CAAC,EAAE,CAAC;AAErB;;;;;;AAMA,OAAO,MAAMC,KAAK,GAChBC,OAAoC,IAC6CL,KAAK,CAACM,aAAa,CAACJ,GAAG,CAACG,OAAO,CAAC,CAAC","ignoreList":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @since
|
|
2
|
+
* @since 4.0.0
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
|
-
* @since
|
|
5
|
+
* @since 4.0.0
|
|
6
6
|
*/
|
|
7
7
|
export * as SqliteClient from "./SqliteClient.ts";
|
|
8
8
|
/**
|
|
9
|
-
* @since
|
|
9
|
+
* @since 4.0.0
|
|
10
10
|
*/
|
|
11
11
|
export * as SqliteMigrator from "./SqliteMigrator.ts";
|
|
12
12
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @since
|
|
2
|
+
* @since 4.0.0
|
|
3
3
|
*/
|
|
4
4
|
// @barrel: Auto-generated exports. Do not edit manually.
|
|
5
5
|
/**
|
|
6
|
-
* @since
|
|
6
|
+
* @since 4.0.0
|
|
7
7
|
*/
|
|
8
8
|
export * as SqliteClient from "./SqliteClient.js";
|
|
9
9
|
/**
|
|
10
|
-
* @since
|
|
10
|
+
* @since 4.0.0
|
|
11
11
|
*/
|
|
12
12
|
export * as SqliteMigrator from "./SqliteMigrator.js";
|
|
13
13
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect/sql-sqlite-do",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.100",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "A SQLite toolkit for Effect",
|
|
7
7
|
"homepage": "https://effect.website",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "https://github.com/Effect-TS/effect
|
|
10
|
+
"url": "https://github.com/Effect-TS/effect.git",
|
|
11
11
|
"directory": "packages/sql/sqlite-do"
|
|
12
12
|
},
|
|
13
13
|
"bugs": {
|
|
14
|
-
"url": "https://github.com/Effect-TS/effect
|
|
14
|
+
"url": "https://github.com/Effect-TS/effect/issues"
|
|
15
15
|
},
|
|
16
16
|
"tags": [
|
|
17
17
|
"typescript",
|
|
@@ -43,16 +43,15 @@
|
|
|
43
43
|
"provenance": true
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@cloudflare/workers-types": "^
|
|
47
|
-
"effect": "^4.0.0-beta.
|
|
46
|
+
"@cloudflare/workers-types": "^5.20260708.1",
|
|
47
|
+
"effect": "^4.0.0-beta.100"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"effect": "^4.0.0-beta.
|
|
50
|
+
"effect": "^4.0.0-beta.100"
|
|
51
51
|
},
|
|
52
52
|
"scripts": {
|
|
53
53
|
"codegen": "effect-utils codegen",
|
|
54
54
|
"build": "tsc -b tsconfig.json && pnpm babel",
|
|
55
|
-
"build:tsgo": "tsgo -b tsconfig.json && pnpm babel",
|
|
56
55
|
"babel": "babel dist --plugins annotate-pure-calls --out-dir dist --source-maps",
|
|
57
56
|
"check": "tsc -b tsconfig.json",
|
|
58
57
|
"test": "vitest",
|
package/src/SqliteClient.ts
CHANGED
|
@@ -1,38 +1,68 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Connects Effect SQL to SQLite storage inside Cloudflare Durable Objects.
|
|
3
|
+
*
|
|
4
|
+
* This module adapts a Durable Object `SqlStorage` handle into both the
|
|
5
|
+
* Durable Object-specific `SqliteClient` service and the generic Effect
|
|
6
|
+
* `SqlClient` service. Use it from inside a Durable Object to run local
|
|
7
|
+
* per-object queries, repositories, migrations, transactional read/write
|
|
8
|
+
* workflows, and tests that exercise Cloudflare's SQLite-backed storage API.
|
|
9
|
+
*
|
|
10
|
+
* Durable Object SQLite storage is scoped to one object id, so each object
|
|
11
|
+
* instance has its own database. Callers can pass the `SqlStorage` handle for
|
|
12
|
+
* normal queries, or the full `DurableObjectStorage` when `withTransaction` or
|
|
13
|
+
* migrations need Cloudflare-managed transactions. This adapter serializes
|
|
14
|
+
* Effect SQL access through one connection; a transaction holds that permit for
|
|
15
|
+
* the lifetime of its scope, so keep transactions short, avoid suspending them
|
|
16
|
+
* across unrelated work, and use them when multi-statement writes must commit
|
|
17
|
+
* atomically. `SqlStorage.exec` returns `ArrayBuffer` values
|
|
18
|
+
* for SQLite blobs, which this client normalizes to `Uint8Array`, and SQLite
|
|
19
|
+
* does not support `updateValues`.
|
|
20
|
+
*
|
|
21
|
+
* @since 4.0.0
|
|
3
22
|
*/
|
|
4
|
-
import type { SqlStorage } from "@cloudflare/workers-types"
|
|
23
|
+
import type { DurableObjectStorage, SqlStorage } from "@cloudflare/workers-types"
|
|
5
24
|
import * as Config from "effect/Config"
|
|
25
|
+
import * as Context from "effect/Context"
|
|
6
26
|
import * as Effect from "effect/Effect"
|
|
27
|
+
import * as Exit from "effect/Exit"
|
|
7
28
|
import * as Fiber from "effect/Fiber"
|
|
8
29
|
import { identity } from "effect/Function"
|
|
9
30
|
import * as Layer from "effect/Layer"
|
|
10
31
|
import * as Scope from "effect/Scope"
|
|
11
|
-
import * as
|
|
32
|
+
import * as Semaphore from "effect/Semaphore"
|
|
12
33
|
import * as Stream from "effect/Stream"
|
|
13
34
|
import * as Reactivity from "effect/unstable/reactivity/Reactivity"
|
|
14
35
|
import * as Client from "effect/unstable/sql/SqlClient"
|
|
15
36
|
import type { Connection } from "effect/unstable/sql/SqlConnection"
|
|
16
|
-
import { SqlError } from "effect/unstable/sql/SqlError"
|
|
37
|
+
import { classifySqliteError, SqlError, UnknownError } from "effect/unstable/sql/SqlError"
|
|
17
38
|
import * as Statement from "effect/unstable/sql/Statement"
|
|
18
39
|
|
|
19
40
|
const ATTR_DB_SYSTEM_NAME = "db.system.name"
|
|
20
41
|
|
|
42
|
+
const classifyError = (cause: unknown, message: string, operation: string) =>
|
|
43
|
+
classifySqliteError(cause, { message, operation })
|
|
44
|
+
|
|
21
45
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
46
|
+
* Runtime type identifier used to mark Cloudflare Durable Object `SqliteClient` values.
|
|
47
|
+
*
|
|
48
|
+
* @category type IDs
|
|
49
|
+
* @since 4.0.0
|
|
24
50
|
*/
|
|
25
51
|
export const TypeId: TypeId = "~@effect/sql-sqlite-do/SqliteClient"
|
|
26
52
|
|
|
27
53
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
54
|
+
* Type-level identifier used to mark Cloudflare Durable Object `SqliteClient` values.
|
|
55
|
+
*
|
|
56
|
+
* @category type IDs
|
|
57
|
+
* @since 4.0.0
|
|
30
58
|
*/
|
|
31
59
|
export type TypeId = "~@effect/sql-sqlite-do/SqliteClient"
|
|
32
60
|
|
|
33
61
|
/**
|
|
62
|
+
* Cloudflare Durable Object SQLite client service, extending `SqlClient` with its configuration. `updateValues` is not supported.
|
|
63
|
+
*
|
|
34
64
|
* @category models
|
|
35
|
-
* @since
|
|
65
|
+
* @since 4.0.0
|
|
36
66
|
*/
|
|
37
67
|
export interface SqliteClient extends Client.SqlClient {
|
|
38
68
|
readonly [TypeId]: TypeId
|
|
@@ -43,26 +73,105 @@ export interface SqliteClient extends Client.SqlClient {
|
|
|
43
73
|
}
|
|
44
74
|
|
|
45
75
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
76
|
+
* Service tag for the Cloudflare Durable Object SQLite client service.
|
|
77
|
+
*
|
|
78
|
+
* **When to use**
|
|
79
|
+
*
|
|
80
|
+
* Use to access or provide a Durable Object SQLite client through the Effect
|
|
81
|
+
* context.
|
|
82
|
+
*
|
|
83
|
+
* @category services
|
|
84
|
+
* @since 4.0.0
|
|
48
85
|
*/
|
|
49
|
-
export const SqliteClient =
|
|
86
|
+
export const SqliteClient = Context.Service<SqliteClient>("@effect/sql-sqlite-do/SqliteClient")
|
|
87
|
+
|
|
88
|
+
const SqliteTransaction = Context.Service<Client.TransactionConnection, Client.TransactionConnection.Service>(
|
|
89
|
+
"@effect/sql-sqlite-do/SqliteClient/SqliteTransaction"
|
|
90
|
+
)
|
|
50
91
|
|
|
51
92
|
/**
|
|
93
|
+
* Configuration for a Cloudflare Durable Object SQLite client, including either a `SqlStorage` handle or the full `DurableObjectStorage` for transaction support, span attributes, and query/result name transforms.
|
|
94
|
+
*
|
|
52
95
|
* @category models
|
|
53
|
-
* @since
|
|
96
|
+
* @since 4.0.0
|
|
54
97
|
*/
|
|
55
98
|
export interface SqliteClientConfig {
|
|
56
|
-
readonly db
|
|
99
|
+
readonly db?: SqlStorage | undefined
|
|
100
|
+
readonly storage?: DurableObjectStorage | undefined
|
|
57
101
|
readonly spanAttributes?: Record<string, unknown> | undefined
|
|
58
102
|
|
|
59
103
|
readonly transformResultNames?: ((str: string) => string) | undefined
|
|
60
104
|
readonly transformQueryNames?: ((str: string) => string) | undefined
|
|
61
105
|
}
|
|
62
106
|
|
|
107
|
+
const unsupportedTransaction = (message: string, operation: string) =>
|
|
108
|
+
new SqlError({
|
|
109
|
+
reason: new UnknownError({
|
|
110
|
+
cause: new Error(message),
|
|
111
|
+
message,
|
|
112
|
+
operation
|
|
113
|
+
})
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
const makeUnsupportedWithTransaction =
|
|
117
|
+
(message: string): Client.SqlClient["withTransaction"] =>
|
|
118
|
+
<R, E, A>(_effect: Effect.Effect<A, E, R>): Effect.Effect<A, E | SqlError, R> =>
|
|
119
|
+
Effect.fail(unsupportedTransaction(message, "transaction"))
|
|
120
|
+
|
|
121
|
+
const makeStorageBackedWithTransaction = (
|
|
122
|
+
storage: DurableObjectStorage,
|
|
123
|
+
connection: Connection,
|
|
124
|
+
semaphore: Semaphore.Semaphore
|
|
125
|
+
): Client.SqlClient["withTransaction"] =>
|
|
126
|
+
<R, E, A>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E | SqlError, R> =>
|
|
127
|
+
Effect.withFiber((fiber) => {
|
|
128
|
+
const services = fiber.context
|
|
129
|
+
const connOption = Context.getOption(services, SqliteTransaction)
|
|
130
|
+
if (connOption._tag === "Some") {
|
|
131
|
+
return Effect.fail(
|
|
132
|
+
unsupportedTransaction(
|
|
133
|
+
"Nested transactions are not supported by Cloudflare Durable Object SQLite storage",
|
|
134
|
+
"transaction"
|
|
135
|
+
)
|
|
136
|
+
)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const effectWithTxn = Effect.provideContext(
|
|
140
|
+
effect,
|
|
141
|
+
Context.add(services, SqliteTransaction, [connection, 0] as const)
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
return semaphore.withPermits(1)(
|
|
145
|
+
Effect.callback((resume) => {
|
|
146
|
+
let interrupted = false
|
|
147
|
+
const promise = storage.transaction((txn) =>
|
|
148
|
+
new Promise<void>((resolve) => {
|
|
149
|
+
if (interrupted) return resolve()
|
|
150
|
+
resume(Effect.onExit(effectWithTxn, (exit) => {
|
|
151
|
+
if (Exit.isFailure(exit)) {
|
|
152
|
+
txn.rollback()
|
|
153
|
+
}
|
|
154
|
+
resolve()
|
|
155
|
+
// wait for the transaction to complete
|
|
156
|
+
return Effect.promise(() => promise)
|
|
157
|
+
}))
|
|
158
|
+
})
|
|
159
|
+
).catch((cause) =>
|
|
160
|
+
resume(Effect.fail(new SqlError({ reason: classifyError(cause, "Failed transaction", "transaction") })))
|
|
161
|
+
)
|
|
162
|
+
return Effect.suspend(() => {
|
|
163
|
+
interrupted = true
|
|
164
|
+
return Effect.promise(() => promise)
|
|
165
|
+
})
|
|
166
|
+
})
|
|
167
|
+
)
|
|
168
|
+
})
|
|
169
|
+
|
|
63
170
|
/**
|
|
64
|
-
*
|
|
65
|
-
*
|
|
171
|
+
* Creates a scoped Cloudflare Durable Object SQLite client around Durable Object SQLite storage, serializing access and converting returned `ArrayBuffer` values to `Uint8Array`.
|
|
172
|
+
*
|
|
173
|
+
* @category constructors
|
|
174
|
+
* @since 4.0.0
|
|
66
175
|
*/
|
|
67
176
|
export const make = (
|
|
68
177
|
options: SqliteClientConfig
|
|
@@ -72,15 +181,19 @@ export const make = (
|
|
|
72
181
|
const transformRows = options.transformResultNames
|
|
73
182
|
? Statement.defaultTransforms(options.transformResultNames).array
|
|
74
183
|
: undefined
|
|
184
|
+
const db = options.storage?.sql ?? options.db
|
|
75
185
|
|
|
76
|
-
|
|
77
|
-
|
|
186
|
+
if (db === undefined) {
|
|
187
|
+
return yield* Effect.die("SqliteClient.make requires either a Durable Object storage or sql storage")
|
|
188
|
+
}
|
|
189
|
+
const sqlStorage = db
|
|
78
190
|
|
|
191
|
+
const makeConnection = Effect.gen(function*() {
|
|
79
192
|
function* runIterator(
|
|
80
193
|
sql: string,
|
|
81
194
|
params: ReadonlyArray<unknown> = []
|
|
82
195
|
) {
|
|
83
|
-
const cursor =
|
|
196
|
+
const cursor = sqlStorage.exec(sql, ...params)
|
|
84
197
|
const columns = cursor.columnNames
|
|
85
198
|
for (const result of cursor.raw()) {
|
|
86
199
|
const obj: any = {}
|
|
@@ -98,7 +211,7 @@ export const make = (
|
|
|
98
211
|
): Effect.Effect<ReadonlyArray<any>, SqlError, never> =>
|
|
99
212
|
Effect.try({
|
|
100
213
|
try: () => Array.from(runIterator(sql, params)),
|
|
101
|
-
catch: (cause) => new SqlError({ cause,
|
|
214
|
+
catch: (cause) => new SqlError({ reason: classifyError(cause, "Failed to execute statement", "execute") })
|
|
102
215
|
})
|
|
103
216
|
|
|
104
217
|
const runValues = (
|
|
@@ -107,7 +220,7 @@ export const make = (
|
|
|
107
220
|
): Effect.Effect<ReadonlyArray<any>, SqlError, never> =>
|
|
108
221
|
Effect.try({
|
|
109
222
|
try: () =>
|
|
110
|
-
Array.from(
|
|
223
|
+
Array.from(sqlStorage.exec(sql, ...params).raw(), (row) => {
|
|
111
224
|
for (let i = 0; i < row.length; i++) {
|
|
112
225
|
const value = row[i]
|
|
113
226
|
if (value instanceof ArrayBuffer) {
|
|
@@ -116,7 +229,7 @@ export const make = (
|
|
|
116
229
|
}
|
|
117
230
|
return row
|
|
118
231
|
}),
|
|
119
|
-
catch: (cause) => new SqlError({ cause,
|
|
232
|
+
catch: (cause) => new SqlError({ reason: classifyError(cause, "Failed to execute statement", "execute") })
|
|
120
233
|
})
|
|
121
234
|
|
|
122
235
|
return identity<Connection>({
|
|
@@ -131,6 +244,9 @@ export const make = (
|
|
|
131
244
|
executeValues(sql, params) {
|
|
132
245
|
return runValues(sql, params)
|
|
133
246
|
},
|
|
247
|
+
executeValuesUnprepared(sql, params) {
|
|
248
|
+
return runValues(sql, params)
|
|
249
|
+
},
|
|
134
250
|
executeUnprepared(sql, params, transformRows) {
|
|
135
251
|
return transformRows
|
|
136
252
|
? Effect.map(runStatement(sql, params), transformRows)
|
|
@@ -149,13 +265,13 @@ export const make = (
|
|
|
149
265
|
})
|
|
150
266
|
})
|
|
151
267
|
|
|
152
|
-
const semaphore = yield*
|
|
268
|
+
const semaphore = yield* Semaphore.make(1)
|
|
153
269
|
const connection = yield* makeConnection
|
|
154
270
|
|
|
155
271
|
const acquirer = semaphore.withPermits(1)(Effect.succeed(connection))
|
|
156
272
|
const transactionAcquirer = Effect.uninterruptibleMask((restore) => {
|
|
157
273
|
const fiber = Fiber.getCurrent()!
|
|
158
|
-
const scope =
|
|
274
|
+
const scope = Context.getUnsafe(fiber.context, Scope.Scope)
|
|
159
275
|
return Effect.as(
|
|
160
276
|
Effect.tap(
|
|
161
277
|
restore(semaphore.take(1)),
|
|
@@ -165,52 +281,61 @@ export const make = (
|
|
|
165
281
|
)
|
|
166
282
|
})
|
|
167
283
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
284
|
+
const client = (yield* Client.make({
|
|
285
|
+
acquirer,
|
|
286
|
+
compiler,
|
|
287
|
+
transactionAcquirer,
|
|
288
|
+
transactionService: SqliteTransaction,
|
|
289
|
+
spanAttributes: [
|
|
290
|
+
...(options.spanAttributes ? Object.entries(options.spanAttributes) : []),
|
|
291
|
+
[ATTR_DB_SYSTEM_NAME, "sqlite"]
|
|
292
|
+
],
|
|
293
|
+
transformRows
|
|
294
|
+
})) as SqliteClient
|
|
295
|
+
|
|
296
|
+
return Object.assign(client, {
|
|
297
|
+
[TypeId]: TypeId as TypeId,
|
|
298
|
+
config: options,
|
|
299
|
+
withTransaction: options.storage
|
|
300
|
+
? makeStorageBackedWithTransaction(options.storage, connection, semaphore)
|
|
301
|
+
: makeUnsupportedWithTransaction(
|
|
302
|
+
"Transactions require Durable Object storage; pass ctx.storage as the storage option"
|
|
303
|
+
)
|
|
304
|
+
})
|
|
184
305
|
})
|
|
185
306
|
|
|
186
307
|
/**
|
|
308
|
+
* Creates a layer from a `Config`-wrapped Durable Object SQLite client configuration, providing both `SqliteClient` and `SqlClient`.
|
|
309
|
+
*
|
|
187
310
|
* @category layers
|
|
188
|
-
* @since
|
|
311
|
+
* @since 4.0.0
|
|
189
312
|
*/
|
|
190
313
|
export const layerConfig = (
|
|
191
314
|
config: Config.Wrap<SqliteClientConfig>
|
|
192
315
|
): Layer.Layer<SqliteClient | Client.SqlClient, Config.ConfigError> =>
|
|
193
|
-
Layer.
|
|
194
|
-
Config.unwrap(config).
|
|
316
|
+
Layer.effectContext(
|
|
317
|
+
Config.unwrap(config).pipe(
|
|
195
318
|
Effect.flatMap(make),
|
|
196
319
|
Effect.map((client) =>
|
|
197
|
-
|
|
198
|
-
|
|
320
|
+
Context.make(SqliteClient, client).pipe(
|
|
321
|
+
Context.add(Client.SqlClient, client)
|
|
199
322
|
)
|
|
200
323
|
)
|
|
201
324
|
)
|
|
202
325
|
).pipe(Layer.provide(Reactivity.layer))
|
|
203
326
|
|
|
204
327
|
/**
|
|
328
|
+
* Creates a layer from a concrete Durable Object SQLite client configuration, providing both `SqliteClient` and `SqlClient`.
|
|
329
|
+
*
|
|
205
330
|
* @category layers
|
|
206
|
-
* @since
|
|
331
|
+
* @since 4.0.0
|
|
207
332
|
*/
|
|
208
333
|
export const layer = (
|
|
209
334
|
config: SqliteClientConfig
|
|
210
335
|
): Layer.Layer<SqliteClient | Client.SqlClient> =>
|
|
211
|
-
Layer.
|
|
336
|
+
Layer.effectContext(
|
|
212
337
|
Effect.map(make(config), (client) =>
|
|
213
|
-
|
|
214
|
-
|
|
338
|
+
Context.make(SqliteClient, client).pipe(
|
|
339
|
+
Context.add(Client.SqlClient, client)
|
|
215
340
|
))
|
|
216
341
|
).pipe(Layer.provide(Reactivity.layer))
|
package/src/SqliteMigrator.ts
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Runs database migrations for Durable Object SQLite storage that uses Effect
|
|
3
|
+
* SQL.
|
|
4
|
+
*
|
|
5
|
+
* This module re-exports the shared `Migrator` loaders and error types, then
|
|
6
|
+
* provides `run` and `layer` helpers that execute ordered migrations through the
|
|
7
|
+
* current Durable Object SQLite `SqlClient`. Use it when a Durable
|
|
8
|
+
* Object needs to create or upgrade its local schema during construction, before
|
|
9
|
+
* repositories or request handlers use the object storage, or in tests that
|
|
10
|
+
* exercise Durable Object persistence.
|
|
11
|
+
*
|
|
12
|
+
* Migrations are recorded in `effect_sql_migrations` by default and are loaded
|
|
13
|
+
* using the shared `<id>_<name>` file or record-key convention. The underlying
|
|
14
|
+
* storage is scoped to a Durable Object id, so running migrations for one object
|
|
15
|
+
* does not update any other object instance; run the migrator against the same
|
|
16
|
+
* `DurableObjectStorage`-backed client that the object uses for normal queries
|
|
17
|
+
* so migrations can run in Cloudflare-managed transactions. These SQL
|
|
18
|
+
* migrations are separate from Cloudflare's Durable Object class migrations, and
|
|
19
|
+
* the Durable Object must already be configured with SQLite storage before this
|
|
20
|
+
* module can apply schema changes. Repeated startup runs are expected and are
|
|
21
|
+
* guarded by the migrations table, but request handling should wait until the
|
|
22
|
+
* migration layer has finished. This adapter does not currently write SQLite
|
|
23
|
+
* schema dumps for `schemaDirectory`.
|
|
24
|
+
*
|
|
25
|
+
* @since 4.0.0
|
|
3
26
|
*/
|
|
4
27
|
import type * as Effect from "effect/Effect"
|
|
5
28
|
import * as Layer from "effect/Layer"
|
|
@@ -8,13 +31,15 @@ import type * as Client from "effect/unstable/sql/SqlClient"
|
|
|
8
31
|
import type { SqlError } from "effect/unstable/sql/SqlError"
|
|
9
32
|
|
|
10
33
|
/**
|
|
11
|
-
* @since
|
|
34
|
+
* @since 4.0.0
|
|
12
35
|
*/
|
|
13
36
|
export * from "effect/unstable/sql/Migrator"
|
|
14
37
|
|
|
15
38
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
39
|
+
* Runs SQL migrations using the configured `SqlClient`, returning the migrations that were applied.
|
|
40
|
+
*
|
|
41
|
+
* @category constructors
|
|
42
|
+
* @since 4.0.0
|
|
18
43
|
*/
|
|
19
44
|
export const run: <R2 = never>(
|
|
20
45
|
{ loader, schemaDirectory, table }: Migrator.MigratorOptions<R2>
|
|
@@ -25,8 +50,10 @@ export const run: <R2 = never>(
|
|
|
25
50
|
> = Migrator.make({})
|
|
26
51
|
|
|
27
52
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
53
|
+
* Creates a layer that runs the configured SQL migrations during layer construction.
|
|
54
|
+
*
|
|
55
|
+
* @category constructors
|
|
56
|
+
* @since 4.0.0
|
|
30
57
|
*/
|
|
31
58
|
export const layer = <R>(
|
|
32
59
|
options: Migrator.MigratorOptions<R>
|
package/src/index.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @since
|
|
2
|
+
* @since 4.0.0
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
// @barrel: Auto-generated exports. Do not edit manually.
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* @since
|
|
8
|
+
* @since 4.0.0
|
|
9
9
|
*/
|
|
10
10
|
export * as SqliteClient from "./SqliteClient.ts"
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
* @since
|
|
13
|
+
* @since 4.0.0
|
|
14
14
|
*/
|
|
15
15
|
export * as SqliteMigrator from "./SqliteMigrator.ts"
|