@lika85456/s3qlite 0.2.0 → 0.2.2

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
@@ -49,39 +49,43 @@ await db.close();
49
49
 
50
50
  ```ts
51
51
  import { connect } from "@lika85456/s3qlite/effect";
52
- import { Effect } from "effect";
53
-
54
- const program = Effect.gen(function* () {
55
- const db = yield* connect("user-123", {
56
- bucket: "s3qlite",
57
- localDirectory: "./.s3qlite",
58
- });
59
-
60
- yield* Effect.tryPromise(() =>
61
- db.exec(`
62
- CREATE TABLE IF NOT EXISTS users (
63
- id TEXT PRIMARY KEY,
64
- name TEXT NOT NULL
65
- )
66
- `),
67
- );
68
-
69
- yield* Effect.tryPromise(() =>
70
- db.run("INSERT INTO users (id, name) VALUES (?, ?)", "1", "alice"),
71
- );
72
-
73
- yield* db.sync();
74
-
75
- const users = yield* Effect.tryPromise(
76
- () => db.all("SELECT * FROM users ORDER BY id") as Promise<unknown[]>,
77
- );
78
-
79
- console.log(users);
52
+ import { S3 } from "@effect-aws/client-s3";
53
+ import { layer as fileSystemLayer } from "@effect/platform-node/NodeFileSystem";
54
+ import { Effect, Layer, ManagedRuntime } from "effect";
55
+
56
+ const program = Effect.scoped(
57
+ Effect.gen(function* () {
58
+ const db = yield* connect("user-123", {
59
+ bucket: "s3qlite",
60
+ localDirectory: "./.s3qlite",
61
+ });
62
+
63
+ yield* Effect.tryPromise(() =>
64
+ db.exec(`
65
+ CREATE TABLE IF NOT EXISTS users (
66
+ id TEXT PRIMARY KEY,
67
+ name TEXT NOT NULL
68
+ )
69
+ `),
70
+ );
71
+
72
+ yield* Effect.tryPromise(() =>
73
+ db.run("INSERT INTO users (id, name) VALUES (?, ?)", "1", "alice"),
74
+ );
75
+
76
+ yield* db.sync();
77
+
78
+ const users = yield* Effect.tryPromise(
79
+ () => db.all("SELECT * FROM users ORDER BY id") as Promise<unknown[]>,
80
+ );
81
+
82
+ console.log(users);
83
+ }),
84
+ );
80
85
 
81
- yield* Effect.tryPromise(() => db.close());
82
- });
86
+ const runtime = ManagedRuntime.make(Layer.mergeAll(fileSystemLayer, S3.layer({})));
83
87
 
84
- await Effect.runPromise(program);
88
+ await runtime.runPromise(program);
85
89
  ```
86
90
 
87
91
  ## Explicit S3 Config
@@ -116,6 +120,20 @@ Pulls changes from remote and applies them to the local database without pushing
116
120
 
117
121
  Uploads local changes to the remote. If the remote has any changes that are not present locally (the local database is not pulled to the latest remote state), this operation will fail - this might also happen when other instances push their changes between your pull & push operations - use sync to not worry about this.
118
122
 
123
+ Push fails with typed errors in the Effect API:
124
+
125
+ - `ConflictError` when the remote changed during push and the CAS update is rejected.
126
+
127
+ ## .fork(name: string): Promise<void>
128
+
129
+ Creates a new database name that starts from the current remote of the source database. This copies only the metadata, so the fork reuses the same referenced snapshot and batch objects already stored in S3. After the fork, both databases can diverge independently.
130
+
131
+ Fork fails with typed errors in the Effect API:
132
+
133
+ - `SameNameError` when the target name matches the source database name.
134
+ - `AlreadyExistsError` when the target database already exists.
135
+ - `SourceDoesNotExistError` when the source database does not exist remotely.
136
+
119
137
  # How does it work?
120
138
 
121
139
  S3Qlite uses Turso CDC to store locally created changes. During sync these changes are batched and synced to/from the provided S3 bucket and applied, so multiple instances can do work at the same time on the same database with minimal S3 requests and minimal transfered data. Thanks to this approach a point in-time state of the database can be reconstructed as well as easily forking the database without additional overhead.
@@ -123,4 +141,4 @@ S3Qlite uses Turso CDC to store locally created changes. During sync these chang
123
141
  # Limitations
124
142
 
125
143
  - Due to the last push wins strategy, a unwanted "corruption" of data might occur. Have in mind that the synchronization is just application of CDC rows - if two instances update the same row, the last pushed edit wins. Try to avoid autoincrement and prefer other databases for more transactional workloads. S3Qlite however does support fully transactional model - sync before & after every operation.
126
- - Currently fork or checkpointing is not implemented, it is planned for future.
144
+ - Checkpointing is not implemented yet.
package/cjs/index.js CHANGED
@@ -17,7 +17,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.connect = void 0;
18
18
  const client_s3_1 = require("@effect-aws/client-s3");
19
19
  const NodeFileSystem_1 = require("@effect/platform-node/NodeFileSystem");
20
- const NodePath_1 = require("@effect/platform-node/NodePath");
21
20
  const effect_1 = require("effect");
22
21
  const index_1 = require("./src/index");
23
22
  const toPromiseDatabase = (database) => {
@@ -34,7 +33,19 @@ const toPromiseDatabase = (database) => {
34
33
  checkpoint: () => effect_1.Effect.runPromise(checkpoint()),
35
34
  });
36
35
  };
37
- const connect = async (dbName, { s3, ...connectionOptions }) => effect_1.Effect.runPromise(effect_1.Effect.scoped((0, index_1.connect)(dbName, connectionOptions).pipe(effect_1.Effect.provide(NodeFileSystem_1.layer), effect_1.Effect.provide(NodePath_1.layer), effect_1.Effect.provide(client_s3_1.S3.layer(s3 ?? {})), effect_1.Effect.map(toPromiseDatabase))));
36
+ const connect = async (dbName, { s3, ...connectionOptions }) => {
37
+ const scope = await effect_1.Effect.runPromise(effect_1.Scope.make());
38
+ try {
39
+ const database = await effect_1.Effect.runPromise((0, index_1.connect)(dbName, connectionOptions).pipe(effect_1.Effect.provide(NodeFileSystem_1.layer), effect_1.Effect.provide(client_s3_1.S3.layer(s3 ?? {})), effect_1.Effect.provideService(effect_1.Scope.Scope, scope)));
40
+ const wrapped = toPromiseDatabase(database);
41
+ wrapped.close = () => effect_1.Effect.runPromise(effect_1.Scope.close(scope, effect_1.Exit.void));
42
+ return wrapped;
43
+ }
44
+ catch (error) {
45
+ await effect_1.Effect.runPromise(effect_1.Scope.close(scope, effect_1.Exit.void));
46
+ throw error;
47
+ }
48
+ };
38
49
  exports.connect = connect;
39
50
  __exportStar(require("./src/index.js"), exports);
40
51
  //# sourceMappingURL=index.js.map
package/cjs/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,qDAA2C;AAC3C,yEAAgF;AAChF,6DAAoE;AAEpE,mCAAgC;AAEhC,uCAAuD;AAiBvD,MAAM,iBAAiB,GAAG,CAAC,QAAyB,EAA0B,EAAE;IAC/E,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAEtD,OAAO,MAAM,CAAC,MAAM,CAAC,QAAoB,EAAE;QAC1C,IAAI,EAAE,GAAG,EAAE,CAAC,eAAM,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QACrC,IAAI,EAAE,GAAG,EAAE,CAAC,eAAM,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QACrC,IAAI,EAAE,GAAG,EAAE,CAAC,eAAM,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QACrC,IAAI,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,eAAM,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzD,UAAU,EAAE,GAAG,EAAE,CAAC,eAAM,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;KACjD,CAA2B,CAAC;AAC9B,CAAC,CAAC;AAEK,MAAM,OAAO,GAAG,KAAK,EAC3B,MAAc,EACd,EAAE,EAAE,EAAE,GAAG,iBAAiB,EAA4B,EACpB,EAAE,CACpC,eAAM,CAAC,UAAU,CAChB,eAAM,CAAC,MAAM,CACZ,IAAA,eAAa,EAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,IAAI,CAC5C,eAAM,CAAC,OAAO,CAAC,sBAAe,CAAC,EAC/B,eAAM,CAAC,OAAO,CAAC,gBAAS,CAAC,EACzB,eAAM,CAAC,OAAO,CAAC,cAAE,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAClC,eAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAC7B,CACD,CACD,CAAC;AAbU,QAAA,OAAO,WAajB;AAEH,iDAA+B","sourcesContent":["import { S3 } from \"@effect-aws/client-s3\";\nimport { layer as fileSystemLayer } from \"@effect/platform-node/NodeFileSystem\";\nimport { layer as pathLayer } from \"@effect/platform-node/NodePath\";\nimport type { Database } from \"@tursodatabase/database\";\nimport { Effect } from \"effect\";\n\nimport { connect as connectEffect } from \"./src/index\";\nimport type { ConnectionOptions, S3qliteDatabase } from \"./src/types\";\n\ntype PromiseMethods = {\n\tpull: () => Promise<void>;\n\tpush: () => Promise<void>;\n\tsync: () => Promise<void>;\n\tfork: (dbName: string) => Promise<void>;\n\tcheckpoint: () => Promise<void>;\n};\n\nexport type PromiseS3qliteDatabase = Database & PromiseMethods;\n\nexport type PromiseConnectionOptions = ConnectionOptions & {\n\ts3?: Parameters<typeof S3.layer>[0];\n};\n\nconst toPromiseDatabase = (database: S3qliteDatabase): PromiseS3qliteDatabase => {\n\tconst pull = database.pull.bind(database);\n\tconst push = database.push.bind(database);\n\tconst sync = database.sync.bind(database);\n\tconst fork = database.fork.bind(database);\n\tconst checkpoint = database.checkpoint.bind(database);\n\n\treturn Object.assign(database as Database, {\n\t\tpull: () => Effect.runPromise(pull()),\n\t\tpush: () => Effect.runPromise(push()),\n\t\tsync: () => Effect.runPromise(sync()),\n\t\tfork: (dbName: string) => Effect.runPromise(fork(dbName)),\n\t\tcheckpoint: () => Effect.runPromise(checkpoint()),\n\t}) as PromiseS3qliteDatabase;\n};\n\nexport const connect = async (\n\tdbName: string,\n\t{ s3, ...connectionOptions }: PromiseConnectionOptions,\n): Promise<PromiseS3qliteDatabase> =>\n\tEffect.runPromise(\n\t\tEffect.scoped(\n\t\t\tconnectEffect(dbName, connectionOptions).pipe(\n\t\t\t\tEffect.provide(fileSystemLayer),\n\t\t\t\tEffect.provide(pathLayer),\n\t\t\t\tEffect.provide(S3.layer(s3 ?? {})),\n\t\t\t\tEffect.map(toPromiseDatabase),\n\t\t\t),\n\t\t),\n\t);\n\nexport * from \"./src/index.js\";"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,qDAA2C;AAC3C,yEAAgF;AAEhF,mCAA6C;AAE7C,uCAAuD;AAiBvD,MAAM,iBAAiB,GAAG,CAAC,QAAyB,EAA0B,EAAE;IAC/E,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAEtD,OAAO,MAAM,CAAC,MAAM,CAAC,QAAoB,EAAE;QAC1C,IAAI,EAAE,GAAG,EAAE,CAAC,eAAM,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QACrC,IAAI,EAAE,GAAG,EAAE,CAAC,eAAM,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QACrC,IAAI,EAAE,GAAG,EAAE,CAAC,eAAM,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QACrC,IAAI,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,eAAM,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzD,UAAU,EAAE,GAAG,EAAE,CAAC,eAAM,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;KACjD,CAA2B,CAAC;AAC9B,CAAC,CAAC;AACK,MAAM,OAAO,GAAG,KAAK,EAC3B,MAAc,EACd,EAAE,EAAE,EAAE,GAAG,iBAAiB,EAA4B,EACpB,EAAE;IACpC,MAAM,KAAK,GAAG,MAAM,eAAM,CAAC,UAAU,CAAC,cAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAEpD,IAAI,CAAC;QACJ,MAAM,QAAQ,GAAG,MAAM,eAAM,CAAC,UAAU,CACvC,IAAA,eAAa,EAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,IAAI,CAC5C,eAAM,CAAC,OAAO,CAAC,sBAAe,CAAC,EAC/B,eAAM,CAAC,OAAO,CAAC,cAAE,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAClC,eAAM,CAAC,cAAc,CAAC,cAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CACzC,CACD,CAAC;QAEF,MAAM,OAAO,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAC5C,OAAO,CAAC,KAAK,GAAG,GAAG,EAAE,CAAC,eAAM,CAAC,UAAU,CAAC,cAAK,CAAC,KAAK,CAAC,KAAK,EAAE,aAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACvE,OAAO,OAAO,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,eAAM,CAAC,UAAU,CAAC,cAAK,CAAC,KAAK,CAAC,KAAK,EAAE,aAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACvD,MAAM,KAAK,CAAC;IACb,CAAC;AACF,CAAC,CAAC;AAtBW,QAAA,OAAO,WAsBlB;AAEF,iDAA+B","sourcesContent":["import { S3 } from \"@effect-aws/client-s3\";\nimport { layer as fileSystemLayer } from \"@effect/platform-node/NodeFileSystem\";\nimport type { Database } from \"@tursodatabase/database\";\nimport { Effect, Exit, Scope } from \"effect\";\n\nimport { connect as connectEffect } from \"./src/index\";\nimport type { ConnectionOptions, S3qliteDatabase } from \"./src/types\";\n\ntype PromiseMethods = {\n\tpull: () => Promise<void>;\n\tpush: () => Promise<void>;\n\tsync: () => Promise<void>;\n\tfork: (dbName: string) => Promise<void>;\n\tcheckpoint: () => Promise<void>;\n};\n\nexport type PromiseS3qliteDatabase = Database & PromiseMethods;\n\nexport type PromiseConnectionOptions = ConnectionOptions & {\n\ts3?: Parameters<typeof S3.layer>[0];\n};\n\nconst toPromiseDatabase = (database: S3qliteDatabase): PromiseS3qliteDatabase => {\n\tconst pull = database.pull.bind(database);\n\tconst push = database.push.bind(database);\n\tconst sync = database.sync.bind(database);\n\tconst fork = database.fork.bind(database);\n\tconst checkpoint = database.checkpoint.bind(database);\n\n\treturn Object.assign(database as Database, {\n\t\tpull: () => Effect.runPromise(pull()),\n\t\tpush: () => Effect.runPromise(push()),\n\t\tsync: () => Effect.runPromise(sync()),\n\t\tfork: (dbName: string) => Effect.runPromise(fork(dbName)),\n\t\tcheckpoint: () => Effect.runPromise(checkpoint()),\n\t}) as PromiseS3qliteDatabase;\n};\nexport const connect = async (\n\tdbName: string,\n\t{ s3, ...connectionOptions }: PromiseConnectionOptions,\n): Promise<PromiseS3qliteDatabase> => {\n\tconst scope = await Effect.runPromise(Scope.make());\n\n\ttry {\n\t\tconst database = await Effect.runPromise(\n\t\t\tconnectEffect(dbName, connectionOptions).pipe(\n\t\t\t\tEffect.provide(fileSystemLayer),\n\t\t\t\tEffect.provide(S3.layer(s3 ?? {})),\n\t\t\t\tEffect.provideService(Scope.Scope, scope),\n\t\t\t),\n\t\t);\n\n\t\tconst wrapped = toPromiseDatabase(database);\n\t\twrapped.close = () => Effect.runPromise(Scope.close(scope, Exit.void));\n\t\treturn wrapped;\n\t} catch (error) {\n\t\tawait Effect.runPromise(Scope.close(scope, Exit.void));\n\t\tthrow error;\n\t}\n};\n\nexport * from \"./src/index.js\";"]}
package/cjs/src/index.js CHANGED
@@ -26,6 +26,7 @@ __exportStar(require("./kv/fileKV"), exports);
26
26
  __exportStar(require("./kv/kv"), exports);
27
27
  __exportStar(require("./kv/memoryKV"), exports);
28
28
  __exportStar(require("./kv/s3KV"), exports);
29
+ __exportStar(require("./types"), exports);
29
30
  const connect = (dbName, connectionOptions) => (0, connection_1.initializeContexts)(connectionOptions).pipe(effect_1.Effect.flatMap((ctx) => (0, connection_1.connect)(dbName, connectionOptions).pipe(effect_1.Effect.provide(ctx))));
30
31
  exports.connect = connect;
31
32
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,mCAAgC;AAEhC,6CAA8E;AAY/C,6FAZM,+BAAkB,OAYZ;AAT3C,8CAA4B;AAC5B,gDAA8B;AAC9B,8CAA4B;AAC5B,yCAAuB;AACvB,8CAA4B;AAC5B,0CAAwB;AACxB,gDAA8B;AAC9B,4CAA0B;AAInB,MAAM,OAAO,GAAG,CAAC,MAAc,EAAE,iBAAoC,EAAE,EAAE,CAC/E,IAAA,+BAAkB,EAAC,iBAAiB,CAAC,CAAC,IAAI,CACzC,eAAM,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CACtB,IAAA,oBAAe,EAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,IAAI,CAAC,eAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CACpE,CACD,CAAC;AALU,QAAA,OAAO,WAKjB","sourcesContent":["import { Effect } from \"effect\";\n\nimport { connect as connectInternal, initializeContexts } from \"./connection\";\nimport type { ConnectionOptions } from \"./types\";\n\nexport * from \"./cdc/apply\";\nexport * from \"./cdc/extract\";\nexport * from \"./cdc/types\";\nexport * from \"./fork\";\nexport * from \"./kv/fileKV\";\nexport * from \"./kv/kv\";\nexport * from \"./kv/memoryKV\";\nexport * from \"./kv/s3KV\";\n\nexport { initializeContexts as initContexts };\n\nexport const connect = (dbName: string, connectionOptions: ConnectionOptions) =>\n\tinitializeContexts(connectionOptions).pipe(\n\t\tEffect.flatMap((ctx) =>\n\t\t\tconnectInternal(dbName, connectionOptions).pipe(Effect.provide(ctx)),\n\t\t),\n\t);"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAEA,mCAAgC;AAGhC,6CAA8E;AAa/C,6FAbM,+BAAkB,OAaZ;AAV3C,8CAA4B;AAC5B,gDAA8B;AAC9B,8CAA4B;AAC5B,yCAAuB;AACvB,8CAA4B;AAC5B,0CAAwB;AACxB,gDAA8B;AAC9B,4CAA0B;AAC1B,0CAAwB;AAIjB,MAAM,OAAO,GAAG,CACtB,MAAc,EACd,iBAAoC,EAC0C,EAAE,CAChF,IAAA,+BAAkB,EAAC,iBAAiB,CAAC,CAAC,IAAI,CACzC,eAAM,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CACtB,IAAA,oBAAe,EAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,IAAI,CAAC,eAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CACpE,CACD,CAAC;AARU,QAAA,OAAO,WAQjB","sourcesContent":["import type { S3Service } from \"@effect-aws/client-s3\";\nimport type { FileSystem } from \"@effect/platform/FileSystem\";\nimport { Effect } from \"effect\";\nimport type { Scope } from \"effect\";\n\nimport { connect as connectInternal, initializeContexts } from \"./connection\";\nimport type { ConnectionOptions, S3qliteDatabase } from \"./types\";\n\nexport * from \"./cdc/apply\";\nexport * from \"./cdc/extract\";\nexport * from \"./cdc/types\";\nexport * from \"./fork\";\nexport * from \"./kv/fileKV\";\nexport * from \"./kv/kv\";\nexport * from \"./kv/memoryKV\";\nexport * from \"./kv/s3KV\";\nexport * from \"./types\";\n\nexport { initializeContexts as initContexts };\n\nexport const connect = (\n\tdbName: string,\n\tconnectionOptions: ConnectionOptions,\n): Effect.Effect<S3qliteDatabase, Error, Scope.Scope | FileSystem | S3Service> =>\n\tinitializeContexts(connectionOptions).pipe(\n\t\tEffect.flatMap((ctx) =>\n\t\t\tconnectInternal(dbName, connectionOptions).pipe(Effect.provide(ctx)),\n\t\t),\n\t);\n"]}
@@ -14,6 +14,7 @@ const getEtag = (value) => effect_1.Effect.promise(async () => {
14
14
  }).pipe(effect_1.Effect.orDie);
15
15
  const makeFileKV = (rootDirectory) => effect_1.Effect.gen(function* () {
16
16
  const fs = yield* FileSystem_1.FileSystem;
17
+ yield* fs.makeDirectory(rootDirectory, { recursive: true }).pipe(effect_1.Effect.orDie);
17
18
  const writeBytes = (key, value) => effect_1.Effect.gen(function* () {
18
19
  const path = `${rootDirectory}/${key}`;
19
20
  const directory = path.split("/").slice(0, -1).join("/");
@@ -1 +1 @@
1
- {"version":3,"file":"fileKV.js","sourceRoot":"","sources":["../../../../src/kv/fileKV.ts"],"names":[],"mappings":"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","sourcesContent":["import { FileSystem } from \"@effect/platform/FileSystem\";\nimport { connect as connectTurso } from \"@tursodatabase/database\";\nimport type { Scope } from \"effect\";\nimport { Effect, Option, Stream } from \"effect\";\nimport { constants } from \"node:fs\";\nimport { copyFile as copyFilePromise } from \"node:fs/promises\";\n\nimport { ConflictError } from \"./kv\";\nimport type { CloneTrait, ConnectDatabaseTrait, KV } from \"./kv\";\n\n// TODO: in the future the etag should be probably cached\nconst getEtag = (value: Uint8Array): Effect.Effect<string> =>\n\tEffect.promise(async () => {\n\t\tconst digest = await crypto.subtle.digest(\"SHA-256\", Uint8Array.from(value).buffer);\n\t\treturn Array.from(new Uint8Array(digest), (byte) =>\n\t\t\tbyte.toString(16).padStart(2, \"0\"),\n\t\t).join(\"\");\n\t}).pipe(Effect.orDie);\n\nexport const makeFileKV = (\n\trootDirectory: string,\n): Effect.Effect<KV & CloneTrait & ConnectDatabaseTrait, never, FileSystem | Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem;\n\n\t\tconst writeBytes = (key: string, value: Uint8Array): Effect.Effect<{ etag: string }> =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\tconst directory = path.split(\"/\").slice(0, -1).join(\"/\");\n\t\t\t\tyield* fs.makeDirectory(directory, { recursive: true }).pipe(Effect.orDie);\n\t\t\t\tconst tempPath = `${path}.${crypto.randomUUID()}.tmp`;\n\t\t\t\tyield* fs.writeFile(tempPath, value).pipe(Effect.orDie);\n\t\t\t\tyield* fs.rename(tempPath, path).pipe(Effect.orDie);\n\t\t\t\treturn { etag: yield* getEtag(value) };\n\t\t\t});\n\n\t\treturn {\n\t\t\tget: (key) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.get(${key})`);\n\n\t\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\t\tif (!(yield* fs.exists(path).pipe(Effect.orDie))) {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.get(${key}) => None`);\n\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t}\n\n\t\t\t\t\tconst value = yield* fs.readFile(path).pipe(Effect.orDie);\n\t\t\t\t\tconst etag = yield* getEtag(value);\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.get(${key}) => Some(${etag})`);\n\t\t\t\t\treturn Option.some({ etag, value });\n\t\t\t\t}),\n\t\t\tgetIfChanged: (key, etag) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.getIfChanged(${key}, ${etag})`);\n\n\t\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\t\tif (!(yield* fs.exists(path).pipe(Effect.orDie))) {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.getIfChanged(${key}) => None`);\n\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t}\n\n\t\t\t\t\tconst value = yield* fs.readFile(path).pipe(Effect.orDie);\n\t\t\t\t\tconst currentEtag = yield* getEtag(value);\n\t\t\t\t\tif (currentEtag === etag) {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.getIfChanged(${key}) => None (not changed)`);\n\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t}\n\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.getIfChanged(${key}) => Some(${currentEtag})`);\n\t\t\t\t\treturn Option.some({ etag: currentEtag, value });\n\t\t\t\t}),\n\t\t\texists: (key) =>\n\t\t\t\tEffect.logDebug(`fileKV.exists(${key})`).pipe(\n\t\t\t\t\tEffect.flatMap(() => fs.exists(`${rootDirectory}/${key}`).pipe(Effect.orDie)),\n\t\t\t\t\tEffect.tap((result) => Effect.logDebug(`fileKV.exists(${key}) => ${result}`)),\n\t\t\t\t),\n\t\t\tset: (key, value) =>\n\t\t\t\tEffect.logDebug(`fileKV.set(${key}, ${value.length} bytes)`).pipe(\n\t\t\t\t\tEffect.flatMap(() => writeBytes(key, value)),\n\t\t\t\t\tEffect.tap((result) => Effect.logDebug(`fileKV.set(${key}) => ${result.etag}`)),\n\t\t\t\t),\n\t\t\tcas: (key, value, etag) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.cas(${key}, ${value.length} bytes, ${etag})`);\n\n\t\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\t\tif (!(yield* fs.exists(path).pipe(Effect.orDie))) {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.cas(${key}) => ConflictError (missing)`);\n\t\t\t\t\t\treturn yield* Effect.fail(new ConflictError({ key }));\n\t\t\t\t\t}\n\n\t\t\t\t\tconst existingValue = yield* fs.readFile(path).pipe(Effect.orDie);\n\t\t\t\t\tif ((yield* getEtag(existingValue)) !== etag) {\n\t\t\t\t\t\tyield* Effect.logDebug(\n\t\t\t\t\t\t\t`fileKV.cas(${key}) => ConflictError (etag mismatch)`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn yield* Effect.fail(new ConflictError({ key }));\n\t\t\t\t\t}\n\n\t\t\t\t\tconst result = yield* writeBytes(key, value);\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.cas(${key}) => ${result.etag}`);\n\t\t\t\t\treturn result;\n\t\t\t\t}),\n\t\t\tdelete: (key) =>\n\t\t\t\tEffect.logDebug(`fileKV.delete(${key})`).pipe(\n\t\t\t\t\tEffect.flatMap(() =>\n\t\t\t\t\t\tfs.remove(`${rootDirectory}/${key}`, { force: true }).pipe(Effect.orDie),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.tap(() => Effect.logDebug(`fileKV.delete(${key}) => void`)),\n\t\t\t\t),\n\t\t\treadStream: (key) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.readStream(${key})`);\n\n\t\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\t\tif (!(yield* fs.exists(path).pipe(Effect.orDie))) {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.readStream(${key}) => None`);\n\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t}\n\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.readStream(${key}) => Some(stream)`);\n\t\t\t\t\treturn Option.some(fs.stream(path).pipe(Stream.orDie));\n\t\t\t\t}),\n\t\t\twriteStream: (key, content) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.writeStream(${key}, stream)`);\n\n\t\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\t\tconst directory = path.split(\"/\").slice(0, -1).join(\"/\");\n\t\t\t\t\tyield* fs.makeDirectory(directory, { recursive: true }).pipe(Effect.orDie);\n\t\t\t\t\tconst tempPath = `${path}.${crypto.randomUUID()}.tmp`;\n\t\t\t\t\tyield* Stream.run(content, fs.sink(tempPath)).pipe(Effect.orDie);\n\t\t\t\t\tyield* fs.rename(tempPath, path).pipe(Effect.orDie);\n\t\t\t\t\tconst value = yield* fs.readFile(path).pipe(Effect.orDie);\n\t\t\t\t\tconst etag = yield* getEtag(value);\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.writeStream(${key}) => ${etag}`);\n\t\t\t\t\treturn { etag };\n\t\t\t\t}),\n\t\t\tclone: (from, to) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.clone(${from}, ${to})`);\n\n\t\t\t\t\tconst fromPath = `${rootDirectory}/${from}`;\n\t\t\t\t\tconst toPath = `${rootDirectory}/${to}`;\n\t\t\t\t\tconst directory = toPath.split(\"/\").slice(0, -1).join(\"/\");\n\t\t\t\t\tyield* fs.makeDirectory(directory, { recursive: true }).pipe(Effect.orDie);\n\t\t\t\t\tconst cloneAttempt = yield* Effect.either(\n\t\t\t\t\t\tEffect.promise(() =>\n\t\t\t\t\t\t\tcopyFilePromise(fromPath, toPath, constants.COPYFILE_FICLONE),\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\n\t\t\t\t\tif (cloneAttempt._tag === \"Right\") {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.clone(${from}, ${to}) => void (copied)`);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst errorOption =\n\t\t\t\t\t\ttypeof cloneAttempt.left === \"object\"\n\t\t\t\t\t\t\t? Option.fromNullable(cloneAttempt.left)\n\t\t\t\t\t\t\t: Option.none();\n\t\t\t\t\tconst currentError = Option.map(\n\t\t\t\t\t\terrorOption,\n\t\t\t\t\t\t(error) => error as { code?: unknown },\n\t\t\t\t\t);\n\n\t\t\t\t\tif (\n\t\t\t\t\t\tOption.isNone(currentError) ||\n\t\t\t\t\t\t!(\"code\" in currentError.value) ||\n\t\t\t\t\t\t![\"ENOTSUP\", \"EINVAL\", \"ENOSYS\", \"EXDEV\", \"EOPNOTSUPP\"].includes(\n\t\t\t\t\t\t\tString(currentError.value.code),\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn yield* Effect.die(cloneAttempt.left);\n\t\t\t\t\t}\n\n\t\t\t\t\tyield* fs.copyFile(fromPath, toPath).pipe(Effect.orDie);\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.clone(${from}, ${to}) => void (copied)`);\n\t\t\t\t}),\n\t\t\tconnect: (key) =>\n\t\t\t\tEffect.logDebug(`fileKV.connect(${key})`).pipe(\n\t\t\t\t\tEffect.flatMap(() =>\n\t\t\t\t\t\tEffect.acquireRelease(\n\t\t\t\t\t\t\tEffect.tryPromise({\n\t\t\t\t\t\t\t\ttry: async () => {\n\t\t\t\t\t\t\t\t\tconst connection = await connectTurso(\n\t\t\t\t\t\t\t\t\t\t`${rootDirectory}/${key}`,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\tawait connection.exec(\n\t\t\t\t\t\t\t\t\t\t\"PRAGMA capture_data_changes_conn('full')\",\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\treturn connection;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tcatch: (e) =>\n\t\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t\t`Failed to connect to database at key ${key}: ${String(e)}`,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(db) => Effect.promise(() => db.close()),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.tap(() => Effect.logDebug(`fileKV.connect(${key}) => database`)),\n\t\t\t\t),\n\t\t};\n\t});"]}
1
+ {"version":3,"file":"fileKV.js","sourceRoot":"","sources":["../../../../src/kv/fileKV.ts"],"names":[],"mappings":"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","sourcesContent":["import { FileSystem } from \"@effect/platform/FileSystem\";\nimport { connect as connectTurso } from \"@tursodatabase/database\";\nimport type { Scope } from \"effect\";\nimport { Effect, Option, Stream } from \"effect\";\nimport { constants } from \"node:fs\";\nimport { copyFile as copyFilePromise } from \"node:fs/promises\";\n\nimport { ConflictError } from \"./kv\";\nimport type { CloneTrait, ConnectDatabaseTrait, KV } from \"./kv\";\n\n// TODO: in the future the etag should be probably cached\nconst getEtag = (value: Uint8Array): Effect.Effect<string> =>\n\tEffect.promise(async () => {\n\t\tconst digest = await crypto.subtle.digest(\"SHA-256\", Uint8Array.from(value).buffer);\n\t\treturn Array.from(new Uint8Array(digest), (byte) =>\n\t\t\tbyte.toString(16).padStart(2, \"0\"),\n\t\t).join(\"\");\n\t}).pipe(Effect.orDie);\n\nexport const makeFileKV = (\n\trootDirectory: string,\n): Effect.Effect<KV & CloneTrait & ConnectDatabaseTrait, never, FileSystem | Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem;\n\t\tyield* fs.makeDirectory(rootDirectory, { recursive: true }).pipe(Effect.orDie);\n\n\t\tconst writeBytes = (key: string, value: Uint8Array): Effect.Effect<{ etag: string }> =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\tconst directory = path.split(\"/\").slice(0, -1).join(\"/\");\n\t\t\t\tyield* fs.makeDirectory(directory, { recursive: true }).pipe(Effect.orDie);\n\t\t\t\tconst tempPath = `${path}.${crypto.randomUUID()}.tmp`;\n\t\t\t\tyield* fs.writeFile(tempPath, value).pipe(Effect.orDie);\n\t\t\t\tyield* fs.rename(tempPath, path).pipe(Effect.orDie);\n\t\t\t\treturn { etag: yield* getEtag(value) };\n\t\t\t});\n\n\t\treturn {\n\t\t\tget: (key) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.get(${key})`);\n\n\t\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\t\tif (!(yield* fs.exists(path).pipe(Effect.orDie))) {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.get(${key}) => None`);\n\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t}\n\n\t\t\t\t\tconst value = yield* fs.readFile(path).pipe(Effect.orDie);\n\t\t\t\t\tconst etag = yield* getEtag(value);\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.get(${key}) => Some(${etag})`);\n\t\t\t\t\treturn Option.some({ etag, value });\n\t\t\t\t}),\n\t\t\tgetIfChanged: (key, etag) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.getIfChanged(${key}, ${etag})`);\n\n\t\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\t\tif (!(yield* fs.exists(path).pipe(Effect.orDie))) {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.getIfChanged(${key}) => None`);\n\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t}\n\n\t\t\t\t\tconst value = yield* fs.readFile(path).pipe(Effect.orDie);\n\t\t\t\t\tconst currentEtag = yield* getEtag(value);\n\t\t\t\t\tif (currentEtag === etag) {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.getIfChanged(${key}) => None (not changed)`);\n\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t}\n\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.getIfChanged(${key}) => Some(${currentEtag})`);\n\t\t\t\t\treturn Option.some({ etag: currentEtag, value });\n\t\t\t\t}),\n\t\t\texists: (key) =>\n\t\t\t\tEffect.logDebug(`fileKV.exists(${key})`).pipe(\n\t\t\t\t\tEffect.flatMap(() => fs.exists(`${rootDirectory}/${key}`).pipe(Effect.orDie)),\n\t\t\t\t\tEffect.tap((result) => Effect.logDebug(`fileKV.exists(${key}) => ${result}`)),\n\t\t\t\t),\n\t\t\tset: (key, value) =>\n\t\t\t\tEffect.logDebug(`fileKV.set(${key}, ${value.length} bytes)`).pipe(\n\t\t\t\t\tEffect.flatMap(() => writeBytes(key, value)),\n\t\t\t\t\tEffect.tap((result) => Effect.logDebug(`fileKV.set(${key}) => ${result.etag}`)),\n\t\t\t\t),\n\t\t\tcas: (key, value, etag) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.cas(${key}, ${value.length} bytes, ${etag})`);\n\n\t\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\t\tif (!(yield* fs.exists(path).pipe(Effect.orDie))) {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.cas(${key}) => ConflictError (missing)`);\n\t\t\t\t\t\treturn yield* Effect.fail(new ConflictError({ key }));\n\t\t\t\t\t}\n\n\t\t\t\t\tconst existingValue = yield* fs.readFile(path).pipe(Effect.orDie);\n\t\t\t\t\tif ((yield* getEtag(existingValue)) !== etag) {\n\t\t\t\t\t\tyield* Effect.logDebug(\n\t\t\t\t\t\t\t`fileKV.cas(${key}) => ConflictError (etag mismatch)`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn yield* Effect.fail(new ConflictError({ key }));\n\t\t\t\t\t}\n\n\t\t\t\t\tconst result = yield* writeBytes(key, value);\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.cas(${key}) => ${result.etag}`);\n\t\t\t\t\treturn result;\n\t\t\t\t}),\n\t\t\tdelete: (key) =>\n\t\t\t\tEffect.logDebug(`fileKV.delete(${key})`).pipe(\n\t\t\t\t\tEffect.flatMap(() =>\n\t\t\t\t\t\tfs.remove(`${rootDirectory}/${key}`, { force: true }).pipe(Effect.orDie),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.tap(() => Effect.logDebug(`fileKV.delete(${key}) => void`)),\n\t\t\t\t),\n\t\t\treadStream: (key) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.readStream(${key})`);\n\n\t\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\t\tif (!(yield* fs.exists(path).pipe(Effect.orDie))) {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.readStream(${key}) => None`);\n\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t}\n\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.readStream(${key}) => Some(stream)`);\n\t\t\t\t\treturn Option.some(fs.stream(path).pipe(Stream.orDie));\n\t\t\t\t}),\n\t\t\twriteStream: (key, content) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.writeStream(${key}, stream)`);\n\n\t\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\t\tconst directory = path.split(\"/\").slice(0, -1).join(\"/\");\n\t\t\t\t\tyield* fs.makeDirectory(directory, { recursive: true }).pipe(Effect.orDie);\n\t\t\t\t\tconst tempPath = `${path}.${crypto.randomUUID()}.tmp`;\n\t\t\t\t\tyield* Stream.run(content, fs.sink(tempPath)).pipe(Effect.orDie);\n\t\t\t\t\tyield* fs.rename(tempPath, path).pipe(Effect.orDie);\n\t\t\t\t\tconst value = yield* fs.readFile(path).pipe(Effect.orDie);\n\t\t\t\t\tconst etag = yield* getEtag(value);\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.writeStream(${key}) => ${etag}`);\n\t\t\t\t\treturn { etag };\n\t\t\t\t}),\n\t\t\tclone: (from, to) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.clone(${from}, ${to})`);\n\n\t\t\t\t\tconst fromPath = `${rootDirectory}/${from}`;\n\t\t\t\t\tconst toPath = `${rootDirectory}/${to}`;\n\t\t\t\t\tconst directory = toPath.split(\"/\").slice(0, -1).join(\"/\");\n\t\t\t\t\tyield* fs.makeDirectory(directory, { recursive: true }).pipe(Effect.orDie);\n\t\t\t\t\tconst cloneAttempt = yield* Effect.either(\n\t\t\t\t\t\tEffect.promise(() =>\n\t\t\t\t\t\t\tcopyFilePromise(fromPath, toPath, constants.COPYFILE_FICLONE),\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\n\t\t\t\t\tif (cloneAttempt._tag === \"Right\") {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.clone(${from}, ${to}) => void (copied)`);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst errorOption =\n\t\t\t\t\t\ttypeof cloneAttempt.left === \"object\"\n\t\t\t\t\t\t\t? Option.fromNullable(cloneAttempt.left)\n\t\t\t\t\t\t\t: Option.none();\n\t\t\t\t\tconst currentError = Option.map(\n\t\t\t\t\t\terrorOption,\n\t\t\t\t\t\t(error) => error as { code?: unknown },\n\t\t\t\t\t);\n\n\t\t\t\t\tif (\n\t\t\t\t\t\tOption.isNone(currentError) ||\n\t\t\t\t\t\t!(\"code\" in currentError.value) ||\n\t\t\t\t\t\t![\"ENOTSUP\", \"EINVAL\", \"ENOSYS\", \"EXDEV\", \"EOPNOTSUPP\"].includes(\n\t\t\t\t\t\t\tString(currentError.value.code),\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn yield* Effect.die(cloneAttempt.left);\n\t\t\t\t\t}\n\n\t\t\t\t\tyield* fs.copyFile(fromPath, toPath).pipe(Effect.orDie);\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.clone(${from}, ${to}) => void (copied)`);\n\t\t\t\t}),\n\t\t\tconnect: (key) =>\n\t\t\t\tEffect.logDebug(`fileKV.connect(${key})`).pipe(\n\t\t\t\t\tEffect.flatMap(() =>\n\t\t\t\t\t\tEffect.acquireRelease(\n\t\t\t\t\t\t\tEffect.tryPromise({\n\t\t\t\t\t\t\t\ttry: async () => {\n\t\t\t\t\t\t\t\t\tconst connection = await connectTurso(\n\t\t\t\t\t\t\t\t\t\t`${rootDirectory}/${key}`,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\tawait connection.exec(\n\t\t\t\t\t\t\t\t\t\t\"PRAGMA capture_data_changes_conn('full')\",\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\treturn connection;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tcatch: (e) =>\n\t\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t\t`Failed to connect to database at key ${key}: ${String(e)}`,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(db) => Effect.promise(() => db.close()),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.tap(() => Effect.logDebug(`fileKV.connect(${key}) => database`)),\n\t\t\t\t),\n\t\t};\n\t});"]}
@@ -1,10 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.makeS3KV = void 0;
3
+ exports.makeS3KV = exports.BucketDoesNotExistError = void 0;
4
4
  const client_s3_1 = require("@effect-aws/client-s3");
5
5
  const effect_1 = require("effect");
6
6
  const kv_1 = require("./kv");
7
- const isMissingObjectError = (error) => effect_1.Effect.runSync(effect_1.Effect.sync(() => {
7
+ class BucketDoesNotExistError extends effect_1.Data.TaggedError("BucketDoesNotExistError") {
8
+ }
9
+ exports.BucketDoesNotExistError = BucketDoesNotExistError;
10
+ const isNotModifiedError = (error) => {
8
11
  if (typeof error !== "object") {
9
12
  return false;
10
13
  }
@@ -13,11 +16,19 @@ const isMissingObjectError = (error) => effect_1.Effect.runSync(effect_1.Effect.
13
16
  return false;
14
17
  }
15
18
  const currentError = errorOption.value;
16
- return ((typeof currentError.Code === "string" && currentError.Code === "NoSuchKey") ||
17
- (typeof currentError.name === "string" &&
18
- (currentError.name === "NoSuchKey" || currentError.name === "NotFound")));
19
- }));
20
- const isNotModifiedError = (error) => effect_1.Effect.runSync(effect_1.Effect.sync(() => {
19
+ if (currentError.Code === "NotModified" || currentError.name === "NotModified") {
20
+ return true;
21
+ }
22
+ if (typeof currentError.$metadata !== "object") {
23
+ return false;
24
+ }
25
+ const metadataOption = effect_1.Option.fromNullable(currentError.$metadata);
26
+ if (effect_1.Option.isNone(metadataOption)) {
27
+ return false;
28
+ }
29
+ return metadataOption.value.httpStatusCode === 304;
30
+ };
31
+ const isMissingObjectError = (error) => {
21
32
  if (typeof error !== "object") {
22
33
  return false;
23
34
  }
@@ -26,14 +37,10 @@ const isNotModifiedError = (error) => effect_1.Effect.runSync(effect_1.Effect.sy
26
37
  return false;
27
38
  }
28
39
  const currentError = errorOption.value;
29
- const metadata = typeof currentError.$metadata === "object" &&
30
- effect_1.Option.isSome(effect_1.Option.fromNullable(currentError.$metadata))
31
- ? effect_1.Option.some(currentError.$metadata)
32
- : effect_1.Option.none();
33
- return ((typeof currentError.Code === "string" && currentError.Code === "NotModified") ||
34
- (typeof currentError.name === "string" && currentError.name === "NotModified") ||
35
- effect_1.Option.exists(metadata, (currentMetadata) => currentMetadata.httpStatusCode === 304));
36
- }));
40
+ return currentError.name === "NoSuchKey" || currentError.name === "NotFound"
41
+ ? true
42
+ : currentError.Code === "NoSuchKey";
43
+ };
37
44
  const getEtag = (result, key) => effect_1.Option.fromNullable(result.ETag).pipe(effect_1.Option.match({
38
45
  onNone: () => effect_1.Effect.die(new Error(`Expected ETag for ${key}`)),
39
46
  onSome: (etag) => effect_1.Effect.succeed({ etag }),
@@ -91,6 +98,10 @@ const combineChunks = (chunks, totalLength) => {
91
98
  };
92
99
  const makeS3KV = (bucket) => effect_1.Effect.gen(function* () {
93
100
  const s3 = yield* client_s3_1.S3;
101
+ yield* s3.headBucket({ Bucket: bucket }).pipe(effect_1.Effect.catchTag("NotFound", () => effect_1.Effect.fail(new BucketDoesNotExistError({
102
+ bucket,
103
+ message: `Bucket "${bucket}" does not exist`,
104
+ }))));
94
105
  return {
95
106
  get: (key) => effect_1.Effect.gen(function* () {
96
107
  yield* effect_1.Effect.logDebug(`s3KV.get(${key})`);
@@ -102,7 +113,7 @@ const makeS3KV = (bucket) => effect_1.Effect.gen(function* () {
102
113
  }
103
114
  return yield* effect_1.Effect.die(response.left instanceof Error
104
115
  ? response.left
105
- : new Error(`Failed to read ${key}: ${String(response.left)}`));
116
+ : new Error(`Failed to read ${key}: ${typeof response.left === "object" ? JSON.stringify(response.left) : String(response.left)}`));
106
117
  }
107
118
  const { etag } = yield* getEtag(response.right, key);
108
119
  const value = yield* readBodyBytes(response.right.Body, key);
@@ -120,7 +131,7 @@ const makeS3KV = (bucket) => effect_1.Effect.gen(function* () {
120
131
  }
121
132
  return yield* effect_1.Effect.die(response.left instanceof Error
122
133
  ? response.left
123
- : new Error(`Failed to read ${key}: ${String(response.left)}`));
134
+ : new Error(`Failed to read ${key}: ${typeof response.left === "object" ? JSON.stringify(response.left) : String(response.left)}`));
124
135
  }
125
136
  const { etag: currentEtag } = yield* getEtag(response.right, key);
126
137
  const value = yield* readBodyBytes(response.right.Body, key);
@@ -137,14 +148,14 @@ const makeS3KV = (bucket) => effect_1.Effect.gen(function* () {
137
148
  }
138
149
  return yield* effect_1.Effect.die(response.left instanceof Error
139
150
  ? response.left
140
- : new Error(`Failed to stat ${key}: ${String(response.left)}`));
151
+ : new Error(`Failed to stat ${key}: ${typeof response.left === "object" ? JSON.stringify(response.left) : String(response.left)}`));
141
152
  }
142
153
  yield* effect_1.Effect.logDebug(`s3KV.exists(${key}) => true`);
143
154
  return true;
144
155
  }),
145
156
  set: (key, value) => effect_1.Effect.logDebug(`s3KV.set(${key}, ${value.length} bytes)`).pipe(effect_1.Effect.flatMap(() => s3.putObject({ Body: value, Bucket: bucket, Key: key })), effect_1.Effect.orDieWith((error) => error instanceof Error
146
157
  ? error
147
- : new Error(`Failed to write ${key}: ${String(error)}`)), effect_1.Effect.flatMap((result) => getEtag(result, key)), effect_1.Effect.tap((result) => effect_1.Effect.logDebug(`s3KV.set(${key}) => ${result.etag}`))),
158
+ : new Error(`Failed to write ${key}: ${typeof error === "object" ? JSON.stringify(error) : String(error)}`)), effect_1.Effect.flatMap((result) => getEtag(result, key)), effect_1.Effect.tap((result) => effect_1.Effect.logDebug(`s3KV.set(${key}) => ${result.etag}`))),
148
159
  cas: (key, value, etag) => effect_1.Effect.logDebug(`s3KV.cas(${key}, ${value.length} bytes, ${etag})`).pipe(effect_1.Effect.flatMap(() => s3.putObject({ Body: value, Bucket: bucket, IfMatch: etag, Key: key })), effect_1.Effect.catchAll((error) => {
149
160
  const currentError = typeof error === "object" && effect_1.Option.isSome(effect_1.Option.fromNullable(error))
150
161
  ? effect_1.Option.some(error)
@@ -163,11 +174,11 @@ const makeS3KV = (bucket) => effect_1.Effect.gen(function* () {
163
174
  ? effect_1.Effect.fail(new kv_1.ConflictError({ key }))
164
175
  : effect_1.Effect.die(error instanceof Error
165
176
  ? error
166
- : new Error(`Failed to write ${key}: ${String(error)}`));
177
+ : new Error(`Failed to write ${key}: ${typeof error === "object" ? JSON.stringify(error) : String(error)}`));
167
178
  }), effect_1.Effect.flatMap((result) => getEtag(result, key)), effect_1.Effect.tap((result) => effect_1.Effect.logDebug(`s3KV.cas(${key}) => ${result.etag}`))),
168
179
  delete: (key) => effect_1.Effect.logDebug(`s3KV.delete(${key})`).pipe(effect_1.Effect.flatMap(() => s3.deleteObject({ Bucket: bucket, Key: key })), effect_1.Effect.asVoid, effect_1.Effect.orDieWith((error) => error instanceof Error
169
180
  ? error
170
- : new Error(`Failed to delete ${key}: ${String(error)}`)), effect_1.Effect.tap(() => effect_1.Effect.logDebug(`s3KV.delete(${key}) => void`))),
181
+ : new Error(`Failed to delete ${key}: ${typeof error === "object" ? JSON.stringify(error) : String(error)}`)), effect_1.Effect.tap(() => effect_1.Effect.logDebug(`s3KV.delete(${key}) => void`))),
171
182
  readStream: (key) => effect_1.Effect.gen(function* () {
172
183
  yield* effect_1.Effect.logDebug(`s3KV.readStream(${key})`);
173
184
  const response = yield* effect_1.Effect.either(s3.getObject({ Bucket: bucket, Key: key }));
@@ -178,7 +189,7 @@ const makeS3KV = (bucket) => effect_1.Effect.gen(function* () {
178
189
  }
179
190
  return yield* effect_1.Effect.die(response.left instanceof Error
180
191
  ? response.left
181
- : new Error(`Failed to stream ${key}: ${String(response.left)}`));
192
+ : new Error(`Failed to stream ${key}: ${typeof response.left === "object" ? JSON.stringify(response.left) : String(response.left)}`));
182
193
  }
183
194
  const stream = yield* readBodyStream(response.right.Body, key);
184
195
  yield* effect_1.Effect.logDebug(`s3KV.readStream(${key}) => Some(stream)`);
@@ -190,7 +201,7 @@ const makeS3KV = (bucket) => effect_1.Effect.gen(function* () {
190
201
  .createMultipartUpload({ Bucket: bucket, Key: key })
191
202
  .pipe(effect_1.Effect.orDieWith((error) => error instanceof Error
192
203
  ? error
193
- : new Error(`Failed to start upload ${key}: ${String(error)}`)));
204
+ : new Error(`Failed to start upload ${key}: ${typeof error === "object" ? JSON.stringify(error) : String(error)}`)));
194
205
  const uploadIdOption = effect_1.Option.fromNullable(multipartUpload.UploadId);
195
206
  if (effect_1.Option.isNone(uploadIdOption)) {
196
207
  return yield* effect_1.Effect.die(new Error(`Expected UploadId for ${key}`));
@@ -221,7 +232,7 @@ const makeS3KV = (bucket) => effect_1.Effect.gen(function* () {
221
232
  })
222
233
  .pipe(effect_1.Effect.orDieWith((error) => error instanceof Error
223
234
  ? error
224
- : new Error(`Failed to upload ${key} part ${partNumber}: ${String(error)}`)), effect_1.Effect.flatMap((result) => effect_1.Option.fromNullable(result.ETag).pipe(effect_1.Option.match({
235
+ : new Error(`Failed to upload part ${String(partNumber)} for ${key}: ${typeof error === "object" ? JSON.stringify(error) : String(error)}`)), effect_1.Effect.flatMap((result) => effect_1.Option.fromNullable(result.ETag).pipe(effect_1.Option.match({
225
236
  onNone: () => effect_1.Effect.die(new Error(`Expected ETag for ${key} part ${partNumber}`)),
226
237
  onSome: (etag) => effect_1.Effect.sync(() => {
227
238
  completedParts.push({
@@ -258,7 +269,7 @@ const makeS3KV = (bucket) => effect_1.Effect.gen(function* () {
258
269
  .putObject({ Body: new Uint8Array(), Bucket: bucket, Key: key })
259
270
  .pipe(effect_1.Effect.orDieWith((error) => error instanceof Error
260
271
  ? error
261
- : new Error(`Failed to upload ${key}: ${String(error)}`)));
272
+ : new Error(`Failed to upload ${key}: ${typeof error === "object" ? JSON.stringify(error) : String(error)}`)));
262
273
  const emptyEtagResult = yield* getEtag(emptyResult, key);
263
274
  yield* effect_1.Effect.logDebug(`s3KV.writeStream(${key}) => ${emptyEtagResult.etag}`);
264
275
  return emptyEtagResult;
@@ -272,7 +283,7 @@ const makeS3KV = (bucket) => effect_1.Effect.gen(function* () {
272
283
  })
273
284
  .pipe(effect_1.Effect.orDieWith((error) => error instanceof Error
274
285
  ? error
275
- : new Error(`Failed to upload ${key}: ${String(error)}`)));
286
+ : new Error(`Failed to upload ${key}: ${typeof error === "object" ? JSON.stringify(error) : String(error)}`)));
276
287
  const finalResult = yield* getEtag(result, key);
277
288
  yield* effect_1.Effect.logDebug(`s3KV.writeStream(${key}) => ${finalResult.etag}`);
278
289
  return finalResult;
@@ -1 +1 @@
1
- {"version":3,"file":"s3KV.js","sourceRoot":"","sources":["../../../../src/kv/s3KV.ts"],"names":[],"mappings":"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","sourcesContent":["import { S3 } from \"@effect-aws/client-s3\";\nimport type { S3Service } from \"@effect-aws/client-s3\";\nimport { Chunk, Effect, Option, Stream } from \"effect\";\n\nimport { ConflictError } from \"./kv\";\nimport type { KV } from \"./kv\";\n\nconst isMissingObjectError = (error: unknown): boolean =>\n\tEffect.runSync(\n\t\tEffect.sync(() => {\n\t\t\tif (typeof error !== \"object\") {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst errorOption = Option.fromNullable(error);\n\t\t\tif (Option.isNone(errorOption)) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst currentError = errorOption.value as { Code?: unknown; name?: unknown };\n\t\t\treturn (\n\t\t\t\t(typeof currentError.Code === \"string\" && currentError.Code === \"NoSuchKey\") ||\n\t\t\t\t(typeof currentError.name === \"string\" &&\n\t\t\t\t\t(currentError.name === \"NoSuchKey\" || currentError.name === \"NotFound\"))\n\t\t\t);\n\t\t}),\n\t);\n\nconst isNotModifiedError = (error: unknown): boolean =>\n\tEffect.runSync(\n\t\tEffect.sync(() => {\n\t\t\tif (typeof error !== \"object\") {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst errorOption = Option.fromNullable(error);\n\t\t\tif (Option.isNone(errorOption)) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst currentError = errorOption.value as {\n\t\t\t\tCode?: unknown;\n\t\t\t\tname?: unknown;\n\t\t\t\t$metadata?: unknown;\n\t\t\t};\n\t\t\tconst metadata =\n\t\t\t\ttypeof currentError.$metadata === \"object\" &&\n\t\t\t\tOption.isSome(Option.fromNullable(currentError.$metadata))\n\t\t\t\t\t? Option.some(currentError.$metadata as { httpStatusCode?: number })\n\t\t\t\t\t: Option.none<{ httpStatusCode?: number }>();\n\n\t\t\treturn (\n\t\t\t\t(typeof currentError.Code === \"string\" && currentError.Code === \"NotModified\") ||\n\t\t\t\t(typeof currentError.name === \"string\" && currentError.name === \"NotModified\") ||\n\t\t\t\tOption.exists(metadata, (currentMetadata) => currentMetadata.httpStatusCode === 304)\n\t\t\t);\n\t\t}),\n\t);\n\nconst getEtag = (result: { ETag?: string }, key: string): Effect.Effect<{ etag: string }> =>\n\tOption.fromNullable(result.ETag).pipe(\n\t\tOption.match({\n\t\t\tonNone: () => Effect.die(new Error(`Expected ETag for ${key}`)),\n\t\t\tonSome: (etag) => Effect.succeed({ etag }),\n\t\t}),\n\t);\n\nconst readBodyBytes = (body: unknown, key: string): Effect.Effect<Uint8Array> => {\n\tif (body instanceof Uint8Array) {\n\t\treturn Effect.succeed(body);\n\t}\n\n\tif (typeof body === \"object\") {\n\t\tconst bodyOption = Option.fromNullable(body);\n\t\tif (\n\t\t\tOption.isSome(bodyOption) &&\n\t\t\t\"transformToByteArray\" in bodyOption.value &&\n\t\t\ttypeof bodyOption.value.transformToByteArray === \"function\"\n\t\t) {\n\t\t\tconst currentBody = bodyOption.value as {\n\t\t\t\ttransformToByteArray: () => Promise<Uint8Array>;\n\t\t\t};\n\t\t\treturn Effect.promise(() => currentBody.transformToByteArray()).pipe(Effect.orDie);\n\t\t}\n\t}\n\n\treturn Effect.die(new Error(`Expected readable body for ${key}`));\n};\n\nconst readBodyStream = (body: unknown, key: string): Effect.Effect<Stream.Stream<Uint8Array>> => {\n\tif (body instanceof Uint8Array) {\n\t\treturn Effect.succeed(Stream.fromIterable([body]));\n\t}\n\n\tif (body instanceof ReadableStream) {\n\t\treturn Effect.succeed(\n\t\t\tStream.fromReadableStream<Uint8Array, Error>(\n\t\t\t\t() => body as ReadableStream<Uint8Array>,\n\t\t\t\t() => new Error(`Failed to stream ${key}`),\n\t\t\t).pipe(Stream.orDie),\n\t\t);\n\t}\n\n\tif (typeof body === \"object\") {\n\t\tconst bodyOption = Option.fromNullable(body);\n\t\tif (\n\t\t\tOption.isSome(bodyOption) &&\n\t\t\t\"transformToWebStream\" in bodyOption.value &&\n\t\t\ttypeof bodyOption.value.transformToWebStream === \"function\"\n\t\t) {\n\t\t\tconst currentBody = bodyOption.value as {\n\t\t\t\ttransformToWebStream: () => ReadableStream<Uint8Array>;\n\t\t\t};\n\t\t\treturn Effect.succeed(\n\t\t\t\tStream.fromReadableStream<Uint8Array, Error>(\n\t\t\t\t\t() => currentBody.transformToWebStream(),\n\t\t\t\t\t() => new Error(`Failed to stream ${key}`),\n\t\t\t\t).pipe(Stream.orDie),\n\t\t\t);\n\t\t}\n\t}\n\n\tif (typeof body === \"object\") {\n\t\tconst bodyOption = Option.fromNullable(body);\n\t\tif (\n\t\t\tOption.isSome(bodyOption) &&\n\t\t\t\"transformToByteArray\" in bodyOption.value &&\n\t\t\ttypeof bodyOption.value.transformToByteArray === \"function\"\n\t\t) {\n\t\t\treturn readBodyBytes(bodyOption.value, key).pipe(\n\t\t\t\tEffect.map((bytes) => Stream.fromIterable([bytes])),\n\t\t\t);\n\t\t}\n\t}\n\n\treturn Effect.die(new Error(`Expected streamable body for ${key}`));\n};\n\nconst minimumMultipartPartSize = 5 * 1024 * 1024;\n\nconst combineChunks = (chunks: readonly Uint8Array[], totalLength: number): Uint8Array => {\n\tconst combined = new Uint8Array(totalLength);\n\tlet offset = 0;\n\n\tfor (const chunk of chunks) {\n\t\tcombined.set(chunk, offset);\n\t\toffset += chunk.length;\n\t}\n\n\treturn combined;\n};\n\nexport const makeS3KV = (bucket: string): Effect.Effect<KV, never, S3Service> =>\n\tEffect.gen(function* () {\n\t\tconst s3 = yield* S3;\n\n\t\treturn {\n\t\t\tget: (key) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.get(${key})`);\n\n\t\t\t\t\tconst response = yield* Effect.either(\n\t\t\t\t\t\ts3.getObject({ Bucket: bucket, Key: key }),\n\t\t\t\t\t);\n\t\t\t\t\tif (response._tag === \"Left\") {\n\t\t\t\t\t\tif (isMissingObjectError(response.left)) {\n\t\t\t\t\t\t\tyield* Effect.logDebug(`s3KV.get(${key}) => None`);\n\t\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn yield* Effect.die(\n\t\t\t\t\t\t\tresponse.left instanceof Error\n\t\t\t\t\t\t\t\t? response.left\n\t\t\t\t\t\t\t\t: new Error(`Failed to read ${key}: ${String(response.left)}`),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { etag } = yield* getEtag(response.right, key);\n\t\t\t\t\tconst value = yield* readBodyBytes(response.right.Body, key);\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.get(${key}) => Some(${etag})`);\n\t\t\t\t\treturn Option.some({ etag, value });\n\t\t\t\t}),\n\t\t\tgetIfChanged: (key, etag) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.getIfChanged(${key}, ${etag})`);\n\n\t\t\t\t\tconst response = yield* Effect.either(\n\t\t\t\t\t\ts3.getObject({ Bucket: bucket, IfNoneMatch: etag, Key: key }),\n\t\t\t\t\t);\n\t\t\t\t\tif (response._tag === \"Left\") {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tisMissingObjectError(response.left) ||\n\t\t\t\t\t\t\tisNotModifiedError(response.left)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tyield* Effect.logDebug(`s3KV.getIfChanged(${key}) => None`);\n\t\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn yield* Effect.die(\n\t\t\t\t\t\t\tresponse.left instanceof Error\n\t\t\t\t\t\t\t\t? response.left\n\t\t\t\t\t\t\t\t: new Error(`Failed to read ${key}: ${String(response.left)}`),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { etag: currentEtag } = yield* getEtag(response.right, key);\n\t\t\t\t\tconst value = yield* readBodyBytes(response.right.Body, key);\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.getIfChanged(${key}) => Some(${currentEtag})`);\n\t\t\t\t\treturn Option.some({ etag: currentEtag, value });\n\t\t\t\t}),\n\t\t\texists: (key) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.exists(${key})`);\n\n\t\t\t\t\tconst response = yield* Effect.either(\n\t\t\t\t\t\ts3.headObject({ Bucket: bucket, Key: key }),\n\t\t\t\t\t);\n\t\t\t\t\tif (response._tag === \"Left\") {\n\t\t\t\t\t\tif (isMissingObjectError(response.left)) {\n\t\t\t\t\t\t\tyield* Effect.logDebug(`s3KV.exists(${key}) => false`);\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn yield* Effect.die(\n\t\t\t\t\t\t\tresponse.left instanceof Error\n\t\t\t\t\t\t\t\t? response.left\n\t\t\t\t\t\t\t\t: new Error(`Failed to stat ${key}: ${String(response.left)}`),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.exists(${key}) => true`);\n\t\t\t\t\treturn true;\n\t\t\t\t}),\n\t\t\tset: (key, value) =>\n\t\t\t\tEffect.logDebug(`s3KV.set(${key}, ${value.length} bytes)`).pipe(\n\t\t\t\t\tEffect.flatMap(() => s3.putObject({ Body: value, Bucket: bucket, Key: key })),\n\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t: new Error(`Failed to write ${key}: ${String(error)}`),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.flatMap((result) => getEtag(result, key)),\n\t\t\t\t\tEffect.tap((result) => Effect.logDebug(`s3KV.set(${key}) => ${result.etag}`)),\n\t\t\t\t),\n\t\t\tcas: (key, value, etag) =>\n\t\t\t\tEffect.logDebug(`s3KV.cas(${key}, ${value.length} bytes, ${etag})`).pipe(\n\t\t\t\t\tEffect.flatMap(() =>\n\t\t\t\t\t\ts3.putObject({ Body: value, Bucket: bucket, IfMatch: etag, Key: key }),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.catchAll((error) => {\n\t\t\t\t\t\tconst currentError =\n\t\t\t\t\t\t\ttypeof error === \"object\" && Option.isSome(Option.fromNullable(error))\n\t\t\t\t\t\t\t\t? Option.some(\n\t\t\t\t\t\t\t\t\t\terror as {\n\t\t\t\t\t\t\t\t\t\t\tCode?: unknown;\n\t\t\t\t\t\t\t\t\t\t\tname?: unknown;\n\t\t\t\t\t\t\t\t\t\t\t$metadata?: unknown;\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t: Option.none<{\n\t\t\t\t\t\t\t\t\t\tCode?: unknown;\n\t\t\t\t\t\t\t\t\t\tname?: unknown;\n\t\t\t\t\t\t\t\t\t\t$metadata?: unknown;\n\t\t\t\t\t\t\t\t\t}>();\n\t\t\t\t\t\tconst metadata =\n\t\t\t\t\t\t\tOption.isSome(currentError) &&\n\t\t\t\t\t\t\ttypeof currentError.value.$metadata === \"object\" &&\n\t\t\t\t\t\t\tOption.isSome(Option.fromNullable(currentError.value.$metadata))\n\t\t\t\t\t\t\t\t? Option.some(\n\t\t\t\t\t\t\t\t\t\tcurrentError.value.$metadata as { httpStatusCode?: number },\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t: Option.none<{ httpStatusCode?: number }>();\n\n\t\t\t\t\t\treturn Option.isSome(currentError) &&\n\t\t\t\t\t\t\t((typeof currentError.value.Code === \"string\" &&\n\t\t\t\t\t\t\t\tcurrentError.value.Code === \"PreconditionFailed\") ||\n\t\t\t\t\t\t\t\t(typeof currentError.value.name === \"string\" &&\n\t\t\t\t\t\t\t\t\tcurrentError.value.name === \"PreconditionFailed\")) &&\n\t\t\t\t\t\t\tOption.exists(\n\t\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t\t\t(currentMetadata) => currentMetadata.httpStatusCode === 412,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t? Effect.fail(new ConflictError({ key }))\n\t\t\t\t\t\t\t: Effect.die(\n\t\t\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t\t: new Error(`Failed to write ${key}: ${String(error)}`),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t}),\n\t\t\t\t\tEffect.flatMap((result) => getEtag(result, key)),\n\t\t\t\t\tEffect.tap((result) => Effect.logDebug(`s3KV.cas(${key}) => ${result.etag}`)),\n\t\t\t\t),\n\t\t\tdelete: (key) =>\n\t\t\t\tEffect.logDebug(`s3KV.delete(${key})`).pipe(\n\t\t\t\t\tEffect.flatMap(() => s3.deleteObject({ Bucket: bucket, Key: key })),\n\t\t\t\t\tEffect.asVoid,\n\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t: new Error(`Failed to delete ${key}: ${String(error)}`),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.tap(() => Effect.logDebug(`s3KV.delete(${key}) => void`)),\n\t\t\t\t),\n\t\t\treadStream: (key) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.readStream(${key})`);\n\n\t\t\t\t\tconst response = yield* Effect.either(\n\t\t\t\t\t\ts3.getObject({ Bucket: bucket, Key: key }),\n\t\t\t\t\t);\n\t\t\t\t\tif (response._tag === \"Left\") {\n\t\t\t\t\t\tif (isMissingObjectError(response.left)) {\n\t\t\t\t\t\t\tyield* Effect.logDebug(`s3KV.readStream(${key}) => None`);\n\t\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn yield* Effect.die(\n\t\t\t\t\t\t\tresponse.left instanceof Error\n\t\t\t\t\t\t\t\t? response.left\n\t\t\t\t\t\t\t\t: new Error(`Failed to stream ${key}: ${String(response.left)}`),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst stream = yield* readBodyStream(response.right.Body, key);\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.readStream(${key}) => Some(stream)`);\n\t\t\t\t\treturn Option.some(stream);\n\t\t\t\t}),\n\t\t\twriteStream: (key, content) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.writeStream(${key}, stream)`);\n\n\t\t\t\t\tconst multipartUpload = yield* s3\n\t\t\t\t\t\t.createMultipartUpload({ Bucket: bucket, Key: key })\n\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t: new Error(`Failed to start upload ${key}: ${String(error)}`),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\tconst uploadIdOption = Option.fromNullable(multipartUpload.UploadId);\n\t\t\t\t\tif (Option.isNone(uploadIdOption)) {\n\t\t\t\t\t\treturn yield* Effect.die(new Error(`Expected UploadId for ${key}`));\n\t\t\t\t\t}\n\n\t\t\t\t\tconst uploadId = uploadIdOption.value;\n\t\t\t\t\tconst uploadParts = Effect.scoped(\n\t\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\t\tconst pull = yield* Stream.toPull(content);\n\t\t\t\t\t\t\tconst completedParts: { ETag: string; PartNumber: number }[] = [];\n\t\t\t\t\t\t\tlet bufferedChunks: Uint8Array[] = [];\n\t\t\t\t\t\t\tlet bufferedLength = 0;\n\t\t\t\t\t\t\tlet partNumber = 1;\n\n\t\t\t\t\t\t\tconst uploadBufferedPart = (force: boolean): Effect.Effect<void> => {\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\tbufferedLength === 0 ||\n\t\t\t\t\t\t\t\t\t(!force && bufferedLength < minimumMultipartPartSize)\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\treturn Effect.void;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst body = combineChunks(bufferedChunks, bufferedLength);\n\t\t\t\t\t\t\t\tbufferedChunks = [];\n\t\t\t\t\t\t\t\tbufferedLength = 0;\n\n\t\t\t\t\t\t\t\treturn s3\n\t\t\t\t\t\t\t\t\t.uploadPart({\n\t\t\t\t\t\t\t\t\t\tBody: body,\n\t\t\t\t\t\t\t\t\t\tBucket: bucket,\n\t\t\t\t\t\t\t\t\t\tContentLength: body.length,\n\t\t\t\t\t\t\t\t\t\tKey: key,\n\t\t\t\t\t\t\t\t\t\tPartNumber: partNumber,\n\t\t\t\t\t\t\t\t\t\tUploadId: uploadId,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t`Failed to upload ${key} part ${partNumber}: ${String(error)}`,\n\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\tEffect.flatMap((result) =>\n\t\t\t\t\t\t\t\t\t\t\tOption.fromNullable(result.ETag).pipe(\n\t\t\t\t\t\t\t\t\t\t\t\tOption.match({\n\t\t\t\t\t\t\t\t\t\t\t\t\tonNone: () =>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tEffect.die(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t`Expected ETag for ${key} part ${partNumber}`,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\tonSome: (etag) =>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tEffect.sync(() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcompletedParts.push({\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tETag: etag,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tPartNumber: partNumber,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tpartNumber += 1;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\twhile (true) {\n\t\t\t\t\t\t\t\tconst nextChunk = yield* Effect.either(pull);\n\n\t\t\t\t\t\t\t\tif (nextChunk._tag === \"Left\") {\n\t\t\t\t\t\t\t\t\treturn yield* uploadBufferedPart(true).pipe(\n\t\t\t\t\t\t\t\t\t\tEffect.as(completedParts),\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tfor (const chunk of Chunk.toReadonlyArray(nextChunk.right)) {\n\t\t\t\t\t\t\t\t\tbufferedChunks.push(chunk);\n\t\t\t\t\t\t\t\t\tbufferedLength += chunk.length;\n\t\t\t\t\t\t\t\t\tif (bufferedLength >= minimumMultipartPartSize) {\n\t\t\t\t\t\t\t\t\t\tyield* uploadBufferedPart(false);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}),\n\t\t\t\t\t).pipe(\n\t\t\t\t\t\tEffect.catchAllCause((cause) =>\n\t\t\t\t\t\t\ts3\n\t\t\t\t\t\t\t\t.abortMultipartUpload({\n\t\t\t\t\t\t\t\t\tBucket: bucket,\n\t\t\t\t\t\t\t\t\tKey: key,\n\t\t\t\t\t\t\t\t\tUploadId: uploadId,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\t\t\tEffect.orDie,\n\t\t\t\t\t\t\t\t\tEffect.catchAll(() => Effect.void),\n\t\t\t\t\t\t\t\t\tEffect.zipRight(Effect.failCause(cause)),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\n\t\t\t\t\tconst completedParts = yield* uploadParts;\n\n\t\t\t\t\tif (completedParts.length === 0) {\n\t\t\t\t\t\tconst emptyResult = yield* s3\n\t\t\t\t\t\t\t.putObject({ Body: new Uint8Array(), Bucket: bucket, Key: key })\n\t\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t\t: new Error(`Failed to upload ${key}: ${String(error)}`),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\tconst emptyEtagResult = yield* getEtag(emptyResult, key);\n\t\t\t\t\t\tyield* Effect.logDebug(\n\t\t\t\t\t\t\t`s3KV.writeStream(${key}) => ${emptyEtagResult.etag}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn emptyEtagResult;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst result = yield* s3\n\t\t\t\t\t\t.completeMultipartUpload({\n\t\t\t\t\t\t\tBucket: bucket,\n\t\t\t\t\t\t\tKey: key,\n\t\t\t\t\t\t\tMultipartUpload: { Parts: completedParts },\n\t\t\t\t\t\t\tUploadId: uploadId,\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t: new Error(`Failed to upload ${key}: ${String(error)}`),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\n\t\t\t\t\tconst finalResult = yield* getEtag(result, key);\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.writeStream(${key}) => ${finalResult.etag}`);\n\t\t\t\t\treturn finalResult;\n\t\t\t\t}),\n\t\t} satisfies KV;\n\t});"]}
1
+ {"version":3,"file":"s3KV.js","sourceRoot":"","sources":["../../../../src/kv/s3KV.ts"],"names":[],"mappings":"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","sourcesContent":["import { S3 } from \"@effect-aws/client-s3\";\nimport { Chunk, Data, Effect, Option, Stream } from \"effect\";\n\nimport { ConflictError } from \"./kv\";\nimport type { KV } from \"./kv\";\n\nexport class BucketDoesNotExistError extends Data.TaggedError(\"BucketDoesNotExistError\")<{\n\treadonly bucket: string;\n\treadonly message: string;\n}> {}\n\nconst isNotModifiedError = (error: unknown): boolean => {\n\tif (typeof error !== \"object\") {\n\t\treturn false;\n\t}\n\n\tconst errorOption = Option.fromNullable(error);\n\tif (Option.isNone(errorOption)) {\n\t\treturn false;\n\t}\n\n\tconst currentError = errorOption.value as {\n\t\tCode?: unknown;\n\t\tname?: unknown;\n\t\t$metadata?: unknown;\n\t};\n\n\tif (currentError.Code === \"NotModified\" || currentError.name === \"NotModified\") {\n\t\treturn true;\n\t}\n\n\tif (typeof currentError.$metadata !== \"object\") {\n\t\treturn false;\n\t}\n\n\tconst metadataOption = Option.fromNullable(currentError.$metadata);\n\tif (Option.isNone(metadataOption)) {\n\t\treturn false;\n\t}\n\n\treturn (metadataOption.value as { httpStatusCode?: number }).httpStatusCode === 304;\n};\n\nconst isMissingObjectError = (error: unknown): boolean => {\n\tif (typeof error !== \"object\") {\n\t\treturn false;\n\t}\n\n\tconst errorOption = Option.fromNullable(error);\n\tif (Option.isNone(errorOption)) {\n\t\treturn false;\n\t}\n\n\tconst currentError = errorOption.value as { Code?: unknown; name?: unknown };\n\treturn currentError.name === \"NoSuchKey\" || currentError.name === \"NotFound\"\n\t\t? true\n\t\t: currentError.Code === \"NoSuchKey\";\n};\n\nconst getEtag = (result: { ETag?: string }, key: string): Effect.Effect<{ etag: string }> =>\n\tOption.fromNullable(result.ETag).pipe(\n\t\tOption.match({\n\t\t\tonNone: () => Effect.die(new Error(`Expected ETag for ${key}`)),\n\t\t\tonSome: (etag) => Effect.succeed({ etag }),\n\t\t}),\n\t);\n\nconst readBodyBytes = (body: unknown, key: string): Effect.Effect<Uint8Array> => {\n\tif (body instanceof Uint8Array) {\n\t\treturn Effect.succeed(body);\n\t}\n\n\tif (typeof body === \"object\") {\n\t\tconst bodyOption = Option.fromNullable(body);\n\t\tif (\n\t\t\tOption.isSome(bodyOption) &&\n\t\t\t\"transformToByteArray\" in bodyOption.value &&\n\t\t\ttypeof bodyOption.value.transformToByteArray === \"function\"\n\t\t) {\n\t\t\tconst currentBody = bodyOption.value as {\n\t\t\t\ttransformToByteArray: () => Promise<Uint8Array>;\n\t\t\t};\n\t\t\treturn Effect.promise(() => currentBody.transformToByteArray()).pipe(Effect.orDie);\n\t\t}\n\t}\n\n\treturn Effect.die(new Error(`Expected readable body for ${key}`));\n};\n\nconst readBodyStream = (body: unknown, key: string): Effect.Effect<Stream.Stream<Uint8Array>> => {\n\tif (body instanceof Uint8Array) {\n\t\treturn Effect.succeed(Stream.fromIterable([body]));\n\t}\n\n\tif (body instanceof ReadableStream) {\n\t\treturn Effect.succeed(\n\t\t\tStream.fromReadableStream<Uint8Array, Error>(\n\t\t\t\t() => body as ReadableStream<Uint8Array>,\n\t\t\t\t() => new Error(`Failed to stream ${key}`),\n\t\t\t).pipe(Stream.orDie),\n\t\t);\n\t}\n\n\tif (typeof body === \"object\") {\n\t\tconst bodyOption = Option.fromNullable(body);\n\t\tif (\n\t\t\tOption.isSome(bodyOption) &&\n\t\t\t\"transformToWebStream\" in bodyOption.value &&\n\t\t\ttypeof bodyOption.value.transformToWebStream === \"function\"\n\t\t) {\n\t\t\tconst currentBody = bodyOption.value as {\n\t\t\t\ttransformToWebStream: () => ReadableStream<Uint8Array>;\n\t\t\t};\n\t\t\treturn Effect.succeed(\n\t\t\t\tStream.fromReadableStream<Uint8Array, Error>(\n\t\t\t\t\t() => currentBody.transformToWebStream(),\n\t\t\t\t\t() => new Error(`Failed to stream ${key}`),\n\t\t\t\t).pipe(Stream.orDie),\n\t\t\t);\n\t\t}\n\t}\n\n\tif (typeof body === \"object\") {\n\t\tconst bodyOption = Option.fromNullable(body);\n\t\tif (\n\t\t\tOption.isSome(bodyOption) &&\n\t\t\t\"transformToByteArray\" in bodyOption.value &&\n\t\t\ttypeof bodyOption.value.transformToByteArray === \"function\"\n\t\t) {\n\t\t\treturn readBodyBytes(bodyOption.value, key).pipe(\n\t\t\t\tEffect.map((bytes) => Stream.fromIterable([bytes])),\n\t\t\t);\n\t\t}\n\t}\n\n\treturn Effect.die(new Error(`Expected streamable body for ${key}`));\n};\n\nconst minimumMultipartPartSize = 5 * 1024 * 1024;\n\nconst combineChunks = (chunks: readonly Uint8Array[], totalLength: number): Uint8Array => {\n\tconst combined = new Uint8Array(totalLength);\n\tlet offset = 0;\n\n\tfor (const chunk of chunks) {\n\t\tcombined.set(chunk, offset);\n\t\toffset += chunk.length;\n\t}\n\n\treturn combined;\n};\n\nexport const makeS3KV = (bucket: string) =>\n\tEffect.gen(function* () {\n\t\tconst s3 = yield* S3;\n\n\t\tyield* s3.headBucket({ Bucket: bucket }).pipe(\n\t\t\tEffect.catchTag(\"NotFound\", () =>\n\t\t\t\tEffect.fail(\n\t\t\t\t\tnew BucketDoesNotExistError({\n\t\t\t\t\t\tbucket,\n\t\t\t\t\t\tmessage: `Bucket \"${bucket}\" does not exist`,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\n\t\treturn {\n\t\t\tget: (key) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.get(${key})`);\n\n\t\t\t\t\tconst response = yield* Effect.either(\n\t\t\t\t\t\ts3.getObject({ Bucket: bucket, Key: key }),\n\t\t\t\t\t);\n\t\t\t\t\tif (response._tag === \"Left\") {\n\t\t\t\t\t\tif (isMissingObjectError(response.left)) {\n\t\t\t\t\t\t\tyield* Effect.logDebug(`s3KV.get(${key}) => None`);\n\t\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn yield* Effect.die(\n\t\t\t\t\t\t\tresponse.left instanceof Error\n\t\t\t\t\t\t\t\t? response.left\n\t\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t\t`Failed to read ${key}: ${typeof response.left === \"object\" ? JSON.stringify(response.left) : String(response.left)}`,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { etag } = yield* getEtag(response.right, key);\n\t\t\t\t\tconst value = yield* readBodyBytes(response.right.Body, key);\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.get(${key}) => Some(${etag})`);\n\t\t\t\t\treturn Option.some({ etag, value });\n\t\t\t\t}),\n\t\t\tgetIfChanged: (key, etag) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.getIfChanged(${key}, ${etag})`);\n\n\t\t\t\t\tconst response = yield* Effect.either(\n\t\t\t\t\t\ts3.getObject({ Bucket: bucket, IfNoneMatch: etag, Key: key }),\n\t\t\t\t\t);\n\t\t\t\t\tif (response._tag === \"Left\") {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tisMissingObjectError(response.left) ||\n\t\t\t\t\t\t\tisNotModifiedError(response.left)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tyield* Effect.logDebug(`s3KV.getIfChanged(${key}) => None`);\n\t\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn yield* Effect.die(\n\t\t\t\t\t\t\tresponse.left instanceof Error\n\t\t\t\t\t\t\t\t? response.left\n\t\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t\t`Failed to read ${key}: ${typeof response.left === \"object\" ? JSON.stringify(response.left) : String(response.left)}`,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { etag: currentEtag } = yield* getEtag(response.right, key);\n\t\t\t\t\tconst value = yield* readBodyBytes(response.right.Body, key);\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.getIfChanged(${key}) => Some(${currentEtag})`);\n\t\t\t\t\treturn Option.some({ etag: currentEtag, value });\n\t\t\t\t}),\n\t\t\texists: (key) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.exists(${key})`);\n\n\t\t\t\t\tconst response = yield* Effect.either(\n\t\t\t\t\t\ts3.headObject({ Bucket: bucket, Key: key }),\n\t\t\t\t\t);\n\t\t\t\t\tif (response._tag === \"Left\") {\n\t\t\t\t\t\tif (isMissingObjectError(response.left)) {\n\t\t\t\t\t\t\tyield* Effect.logDebug(`s3KV.exists(${key}) => false`);\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn yield* Effect.die(\n\t\t\t\t\t\t\tresponse.left instanceof Error\n\t\t\t\t\t\t\t\t? response.left\n\t\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t\t`Failed to stat ${key}: ${typeof response.left === \"object\" ? JSON.stringify(response.left) : String(response.left)}`,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.exists(${key}) => true`);\n\t\t\t\t\treturn true;\n\t\t\t\t}),\n\t\t\tset: (key, value) =>\n\t\t\t\tEffect.logDebug(`s3KV.set(${key}, ${value.length} bytes)`).pipe(\n\t\t\t\t\tEffect.flatMap(() => s3.putObject({ Body: value, Bucket: bucket, Key: key })),\n\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t`Failed to write ${key}: ${typeof error === \"object\" ? JSON.stringify(error) : String(error)}`,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.flatMap((result) => getEtag(result, key)),\n\t\t\t\t\tEffect.tap((result) => Effect.logDebug(`s3KV.set(${key}) => ${result.etag}`)),\n\t\t\t\t),\n\t\t\tcas: (key, value, etag) =>\n\t\t\t\tEffect.logDebug(`s3KV.cas(${key}, ${value.length} bytes, ${etag})`).pipe(\n\t\t\t\t\tEffect.flatMap(() =>\n\t\t\t\t\t\ts3.putObject({ Body: value, Bucket: bucket, IfMatch: etag, Key: key }),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.catchAll((error) => {\n\t\t\t\t\t\tconst currentError =\n\t\t\t\t\t\t\ttypeof error === \"object\" && Option.isSome(Option.fromNullable(error))\n\t\t\t\t\t\t\t\t? Option.some(\n\t\t\t\t\t\t\t\t\t\terror as {\n\t\t\t\t\t\t\t\t\t\t\tCode?: unknown;\n\t\t\t\t\t\t\t\t\t\t\tname?: unknown;\n\t\t\t\t\t\t\t\t\t\t\t$metadata?: unknown;\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t: Option.none<{\n\t\t\t\t\t\t\t\t\t\tCode?: unknown;\n\t\t\t\t\t\t\t\t\t\tname?: unknown;\n\t\t\t\t\t\t\t\t\t\t$metadata?: unknown;\n\t\t\t\t\t\t\t\t\t}>();\n\t\t\t\t\t\tconst metadata =\n\t\t\t\t\t\t\tOption.isSome(currentError) &&\n\t\t\t\t\t\t\ttypeof currentError.value.$metadata === \"object\" &&\n\t\t\t\t\t\t\tOption.isSome(Option.fromNullable(currentError.value.$metadata))\n\t\t\t\t\t\t\t\t? Option.some(\n\t\t\t\t\t\t\t\t\t\tcurrentError.value.$metadata as { httpStatusCode?: number },\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t: Option.none<{ httpStatusCode?: number }>();\n\n\t\t\t\t\t\treturn Option.isSome(currentError) &&\n\t\t\t\t\t\t\t((typeof currentError.value.Code === \"string\" &&\n\t\t\t\t\t\t\t\tcurrentError.value.Code === \"PreconditionFailed\") ||\n\t\t\t\t\t\t\t\t(typeof currentError.value.name === \"string\" &&\n\t\t\t\t\t\t\t\t\tcurrentError.value.name === \"PreconditionFailed\")) &&\n\t\t\t\t\t\t\tOption.exists(\n\t\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t\t\t(currentMetadata) => currentMetadata.httpStatusCode === 412,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t? Effect.fail(new ConflictError({ key }))\n\t\t\t\t\t\t\t: Effect.die(\n\t\t\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t\t\t\t`Failed to write ${key}: ${typeof error === \"object\" ? JSON.stringify(error) : String(error)}`,\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t}),\n\t\t\t\t\tEffect.flatMap((result) => getEtag(result, key)),\n\t\t\t\t\tEffect.tap((result) => Effect.logDebug(`s3KV.cas(${key}) => ${result.etag}`)),\n\t\t\t\t),\n\t\t\tdelete: (key) =>\n\t\t\t\tEffect.logDebug(`s3KV.delete(${key})`).pipe(\n\t\t\t\t\tEffect.flatMap(() => s3.deleteObject({ Bucket: bucket, Key: key })),\n\t\t\t\t\tEffect.asVoid,\n\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t`Failed to delete ${key}: ${typeof error === \"object\" ? JSON.stringify(error) : String(error)}`,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.tap(() => Effect.logDebug(`s3KV.delete(${key}) => void`)),\n\t\t\t\t),\n\t\t\treadStream: (key) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.readStream(${key})`);\n\n\t\t\t\t\tconst response = yield* Effect.either(\n\t\t\t\t\t\ts3.getObject({ Bucket: bucket, Key: key }),\n\t\t\t\t\t);\n\t\t\t\t\tif (response._tag === \"Left\") {\n\t\t\t\t\t\tif (isMissingObjectError(response.left)) {\n\t\t\t\t\t\t\tyield* Effect.logDebug(`s3KV.readStream(${key}) => None`);\n\t\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn yield* Effect.die(\n\t\t\t\t\t\t\tresponse.left instanceof Error\n\t\t\t\t\t\t\t\t? response.left\n\t\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t\t`Failed to stream ${key}: ${typeof response.left === \"object\" ? JSON.stringify(response.left) : String(response.left)}`,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst stream = yield* readBodyStream(response.right.Body, key);\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.readStream(${key}) => Some(stream)`);\n\t\t\t\t\treturn Option.some(stream);\n\t\t\t\t}),\n\t\t\twriteStream: (key, content) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.writeStream(${key}, stream)`);\n\n\t\t\t\t\tconst multipartUpload = yield* s3\n\t\t\t\t\t\t.createMultipartUpload({ Bucket: bucket, Key: key })\n\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t\t\t`Failed to start upload ${key}: ${typeof error === \"object\" ? JSON.stringify(error) : String(error)}`,\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\tconst uploadIdOption = Option.fromNullable(multipartUpload.UploadId);\n\t\t\t\t\tif (Option.isNone(uploadIdOption)) {\n\t\t\t\t\t\treturn yield* Effect.die(new Error(`Expected UploadId for ${key}`));\n\t\t\t\t\t}\n\n\t\t\t\t\tconst uploadId = uploadIdOption.value;\n\t\t\t\t\tconst uploadParts = Effect.scoped(\n\t\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\t\tconst pull = yield* Stream.toPull(content);\n\t\t\t\t\t\t\tconst completedParts: { ETag: string; PartNumber: number }[] = [];\n\t\t\t\t\t\t\tlet bufferedChunks: Uint8Array[] = [];\n\t\t\t\t\t\t\tlet bufferedLength = 0;\n\t\t\t\t\t\t\tlet partNumber = 1;\n\n\t\t\t\t\t\t\tconst uploadBufferedPart = (force: boolean): Effect.Effect<void> => {\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\tbufferedLength === 0 ||\n\t\t\t\t\t\t\t\t\t(!force && bufferedLength < minimumMultipartPartSize)\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\treturn Effect.void;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst body = combineChunks(bufferedChunks, bufferedLength);\n\t\t\t\t\t\t\t\tbufferedChunks = [];\n\t\t\t\t\t\t\t\tbufferedLength = 0;\n\n\t\t\t\t\t\t\t\treturn s3\n\t\t\t\t\t\t\t\t\t.uploadPart({\n\t\t\t\t\t\t\t\t\t\tBody: body,\n\t\t\t\t\t\t\t\t\t\tBucket: bucket,\n\t\t\t\t\t\t\t\t\t\tContentLength: body.length,\n\t\t\t\t\t\t\t\t\t\tKey: key,\n\t\t\t\t\t\t\t\t\t\tPartNumber: partNumber,\n\t\t\t\t\t\t\t\t\t\tUploadId: uploadId,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t`Failed to upload part ${String(partNumber)} for ${key}: ${typeof error === \"object\" ? JSON.stringify(error) : String(error)}`,\n\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\tEffect.flatMap((result) =>\n\t\t\t\t\t\t\t\t\t\t\tOption.fromNullable(result.ETag).pipe(\n\t\t\t\t\t\t\t\t\t\t\t\tOption.match({\n\t\t\t\t\t\t\t\t\t\t\t\t\tonNone: () =>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tEffect.die(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t`Expected ETag for ${key} part ${partNumber}`,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\tonSome: (etag) =>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tEffect.sync(() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcompletedParts.push({\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tETag: etag,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tPartNumber: partNumber,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tpartNumber += 1;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\twhile (true) {\n\t\t\t\t\t\t\t\tconst nextChunk = yield* Effect.either(pull);\n\n\t\t\t\t\t\t\t\tif (nextChunk._tag === \"Left\") {\n\t\t\t\t\t\t\t\t\treturn yield* uploadBufferedPart(true).pipe(\n\t\t\t\t\t\t\t\t\t\tEffect.as(completedParts),\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tfor (const chunk of Chunk.toReadonlyArray(nextChunk.right)) {\n\t\t\t\t\t\t\t\t\tbufferedChunks.push(chunk);\n\t\t\t\t\t\t\t\t\tbufferedLength += chunk.length;\n\t\t\t\t\t\t\t\t\tif (bufferedLength >= minimumMultipartPartSize) {\n\t\t\t\t\t\t\t\t\t\tyield* uploadBufferedPart(false);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}),\n\t\t\t\t\t).pipe(\n\t\t\t\t\t\tEffect.catchAllCause((cause) =>\n\t\t\t\t\t\t\ts3\n\t\t\t\t\t\t\t\t.abortMultipartUpload({\n\t\t\t\t\t\t\t\t\tBucket: bucket,\n\t\t\t\t\t\t\t\t\tKey: key,\n\t\t\t\t\t\t\t\t\tUploadId: uploadId,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\t\t\tEffect.orDie,\n\t\t\t\t\t\t\t\t\tEffect.catchAll(() => Effect.void),\n\t\t\t\t\t\t\t\t\tEffect.zipRight(Effect.failCause(cause)),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\n\t\t\t\t\tconst completedParts = yield* uploadParts;\n\n\t\t\t\t\tif (completedParts.length === 0) {\n\t\t\t\t\t\tconst emptyResult = yield* s3\n\t\t\t\t\t\t\t.putObject({ Body: new Uint8Array(), Bucket: bucket, Key: key })\n\t\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t\t\t\t`Failed to upload ${key}: ${typeof error === \"object\" ? JSON.stringify(error) : String(error)}`,\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\tconst emptyEtagResult = yield* getEtag(emptyResult, key);\n\t\t\t\t\t\tyield* Effect.logDebug(\n\t\t\t\t\t\t\t`s3KV.writeStream(${key}) => ${emptyEtagResult.etag}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn emptyEtagResult;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst result = yield* s3\n\t\t\t\t\t\t.completeMultipartUpload({\n\t\t\t\t\t\t\tBucket: bucket,\n\t\t\t\t\t\t\tKey: key,\n\t\t\t\t\t\t\tMultipartUpload: { Parts: completedParts },\n\t\t\t\t\t\t\tUploadId: uploadId,\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t\t\t`Failed to upload ${key}: ${typeof error === \"object\" ? JSON.stringify(error) : String(error)}`,\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\n\t\t\t\t\tconst finalResult = yield* getEtag(result, key);\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.writeStream(${key}) => ${finalResult.etag}`);\n\t\t\t\t\treturn finalResult;\n\t\t\t\t}),\n\t\t} satisfies KV;\n\t});"]}
@@ -1,5 +1,5 @@
1
1
  import { Context, Effect } from "effect";
2
2
  import { LocalKV, RemoteKV } from "./storage.js";
3
3
  import type { ConnectionOptions, S3qliteDatabase } from "./types.js";
4
- export declare const initializeContexts: (connectionOptions: ConnectionOptions) => Effect.Effect<Context.Context<LocalKV | RemoteKV>, never, import("effect/Scope").Scope | import("@effect/platform/FileSystem").FileSystem | import("@effect-aws/client-s3").S3Service>;
4
+ export declare const initializeContexts: (connectionOptions: ConnectionOptions) => Effect.Effect<Context.Context<LocalKV | RemoteKV>, import(".").BucketDoesNotExistError | import("effect/Cause").TimeoutException | import("@effect-aws/client-s3").SdkError, import("effect/Scope").Scope | import("@effect/platform/FileSystem").FileSystem | import("@effect-aws/client-s3").S3Service>;
5
5
  export declare const connect: (dbName: string, options: ConnectionOptions) => Effect.Effect<S3qliteDatabase, Error, import("effect/Scope").Scope | LocalKV | RemoteKV>;
@@ -1,6 +1,9 @@
1
+ import type { S3Service } from "@effect-aws/client-s3";
2
+ import type { FileSystem } from "@effect/platform/FileSystem";
1
3
  import { Effect } from "effect";
4
+ import type { Scope } from "effect";
2
5
  import { initializeContexts } from "./connection.js";
3
- import type { ConnectionOptions } from "./types.js";
6
+ import type { ConnectionOptions, S3qliteDatabase } from "./types.js";
4
7
  export * from "./cdc/apply.js";
5
8
  export * from "./cdc/extract.js";
6
9
  export * from "./cdc/types.js";
@@ -9,5 +12,6 @@ export * from "./kv/fileKV.js";
9
12
  export * from "./kv/kv.js";
10
13
  export * from "./kv/memoryKV.js";
11
14
  export * from "./kv/s3KV.js";
15
+ export * from "./types.js";
12
16
  export { initializeContexts as initContexts };
13
- export declare const connect: (dbName: string, connectionOptions: ConnectionOptions) => Effect.Effect<import("./types.js").S3qliteDatabase, Error, import("effect/Scope").Scope | import("@effect/platform/FileSystem").FileSystem | import("@effect-aws/client-s3").S3Service>;
17
+ export declare const connect: (dbName: string, connectionOptions: ConnectionOptions) => Effect.Effect<S3qliteDatabase, Error, Scope.Scope | FileSystem | S3Service>;
@@ -1,4 +1,39 @@
1
- import type { S3Service } from "@effect-aws/client-s3";
2
- import { Effect } from "effect";
3
- import type { KV } from "./kv.js";
4
- export declare const makeS3KV: (bucket: string) => Effect.Effect<KV, never, S3Service>;
1
+ import { Effect, Option, Stream } from "effect";
2
+ import { ConflictError } from "./kv.js";
3
+ declare const BucketDoesNotExistError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
4
+ readonly _tag: "BucketDoesNotExistError";
5
+ } & Readonly<A>;
6
+ export declare class BucketDoesNotExistError extends BucketDoesNotExistError_base<{
7
+ readonly bucket: string;
8
+ readonly message: string;
9
+ }> {
10
+ }
11
+ export declare const makeS3KV: (bucket: string) => Effect.Effect<{
12
+ get: (key: string) => Effect.Effect<Option.None<{
13
+ value: Uint8Array;
14
+ etag: string;
15
+ }> | Option.Some<{
16
+ value: Uint8Array;
17
+ etag: string;
18
+ }>, never, never>;
19
+ getIfChanged: (key: string, etag: string) => Effect.Effect<Option.None<{
20
+ value: Uint8Array;
21
+ etag: string;
22
+ }> | Option.Some<{
23
+ value: Uint8Array;
24
+ etag: string;
25
+ }>, never, never>;
26
+ exists: (key: string) => Effect.Effect<boolean, never, never>;
27
+ set: (key: string, value: Uint8Array<ArrayBufferLike>) => Effect.Effect<{
28
+ etag: string;
29
+ }, never, never>;
30
+ cas: (key: string, value: Uint8Array<ArrayBufferLike>, etag: string) => Effect.Effect<{
31
+ etag: string;
32
+ }, ConflictError, never>;
33
+ delete: (key: string) => Effect.Effect<void, never, never>;
34
+ readStream: (key: string) => Effect.Effect<Option.Option<Stream.Stream<Uint8Array<ArrayBufferLike>, never, never>>, never, never>;
35
+ writeStream: (key: string, content: Stream.Stream<Uint8Array<ArrayBufferLike>, never, never>) => Effect.Effect<{
36
+ etag: string;
37
+ }, never, never>;
38
+ }, BucketDoesNotExistError | import("effect/Cause").TimeoutException | import("@effect-aws/client-s3").SdkError, import("@effect-aws/client-s3").S3Service>;
39
+ export {};
package/esm/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import { S3 } from "@effect-aws/client-s3";
2
2
  import { layer as fileSystemLayer } from "@effect/platform-node/NodeFileSystem";
3
- import { layer as pathLayer } from "@effect/platform-node/NodePath";
4
- import { Effect } from "effect";
3
+ import { Effect, Exit, Scope } from "effect";
5
4
  import { connect as connectEffect } from "./src/index.js";
6
5
  const toPromiseDatabase = (database) => {
7
6
  const pull = database.pull.bind(database);
@@ -17,6 +16,18 @@ const toPromiseDatabase = (database) => {
17
16
  checkpoint: () => Effect.runPromise(checkpoint()),
18
17
  });
19
18
  };
20
- export const connect = async (dbName, { s3, ...connectionOptions }) => Effect.runPromise(Effect.scoped(connectEffect(dbName, connectionOptions).pipe(Effect.provide(fileSystemLayer), Effect.provide(pathLayer), Effect.provide(S3.layer(s3 ?? {})), Effect.map(toPromiseDatabase))));
19
+ export const connect = async (dbName, { s3, ...connectionOptions }) => {
20
+ const scope = await Effect.runPromise(Scope.make());
21
+ try {
22
+ const database = await Effect.runPromise(connectEffect(dbName, connectionOptions).pipe(Effect.provide(fileSystemLayer), Effect.provide(S3.layer(s3 ?? {})), Effect.provideService(Scope.Scope, scope)));
23
+ const wrapped = toPromiseDatabase(database);
24
+ wrapped.close = () => Effect.runPromise(Scope.close(scope, Exit.void));
25
+ return wrapped;
26
+ }
27
+ catch (error) {
28
+ await Effect.runPromise(Scope.close(scope, Exit.void));
29
+ throw error;
30
+ }
31
+ };
21
32
  export * from "./src/index.js";
22
33
  //# sourceMappingURL=index.js.map
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,uBAAuB,CAAC;AAC3C,OAAO,EAAE,KAAK,IAAI,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAChF,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAEpE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,aAAa,CAAC;AAiBvD,MAAM,iBAAiB,GAAG,CAAC,QAAyB,EAA0B,EAAE;IAC/E,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAEtD,OAAO,MAAM,CAAC,MAAM,CAAC,QAAoB,EAAE;QAC1C,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QACrC,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QACrC,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QACrC,IAAI,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzD,UAAU,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;KACjD,CAA2B,CAAC;AAC9B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,EAC3B,MAAc,EACd,EAAE,EAAE,EAAE,GAAG,iBAAiB,EAA4B,EACpB,EAAE,CACpC,MAAM,CAAC,UAAU,CAChB,MAAM,CAAC,MAAM,CACZ,aAAa,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,IAAI,CAC5C,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,EAC/B,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EACzB,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAClC,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAC7B,CACD,CACD,CAAC;AAEH,cAAc,gBAAgB,CAAC","sourcesContent":["import { S3 } from \"@effect-aws/client-s3\";\nimport { layer as fileSystemLayer } from \"@effect/platform-node/NodeFileSystem\";\nimport { layer as pathLayer } from \"@effect/platform-node/NodePath\";\nimport type { Database } from \"@tursodatabase/database\";\nimport { Effect } from \"effect\";\n\nimport { connect as connectEffect } from \"./src/index\";\nimport type { ConnectionOptions, S3qliteDatabase } from \"./src/types\";\n\ntype PromiseMethods = {\n\tpull: () => Promise<void>;\n\tpush: () => Promise<void>;\n\tsync: () => Promise<void>;\n\tfork: (dbName: string) => Promise<void>;\n\tcheckpoint: () => Promise<void>;\n};\n\nexport type PromiseS3qliteDatabase = Database & PromiseMethods;\n\nexport type PromiseConnectionOptions = ConnectionOptions & {\n\ts3?: Parameters<typeof S3.layer>[0];\n};\n\nconst toPromiseDatabase = (database: S3qliteDatabase): PromiseS3qliteDatabase => {\n\tconst pull = database.pull.bind(database);\n\tconst push = database.push.bind(database);\n\tconst sync = database.sync.bind(database);\n\tconst fork = database.fork.bind(database);\n\tconst checkpoint = database.checkpoint.bind(database);\n\n\treturn Object.assign(database as Database, {\n\t\tpull: () => Effect.runPromise(pull()),\n\t\tpush: () => Effect.runPromise(push()),\n\t\tsync: () => Effect.runPromise(sync()),\n\t\tfork: (dbName: string) => Effect.runPromise(fork(dbName)),\n\t\tcheckpoint: () => Effect.runPromise(checkpoint()),\n\t}) as PromiseS3qliteDatabase;\n};\n\nexport const connect = async (\n\tdbName: string,\n\t{ s3, ...connectionOptions }: PromiseConnectionOptions,\n): Promise<PromiseS3qliteDatabase> =>\n\tEffect.runPromise(\n\t\tEffect.scoped(\n\t\t\tconnectEffect(dbName, connectionOptions).pipe(\n\t\t\t\tEffect.provide(fileSystemLayer),\n\t\t\t\tEffect.provide(pathLayer),\n\t\t\t\tEffect.provide(S3.layer(s3 ?? {})),\n\t\t\t\tEffect.map(toPromiseDatabase),\n\t\t\t),\n\t\t),\n\t);\n\nexport * from \"./src/index.js\";"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,uBAAuB,CAAC;AAC3C,OAAO,EAAE,KAAK,IAAI,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAEhF,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAE7C,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,aAAa,CAAC;AAiBvD,MAAM,iBAAiB,GAAG,CAAC,QAAyB,EAA0B,EAAE;IAC/E,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAEtD,OAAO,MAAM,CAAC,MAAM,CAAC,QAAoB,EAAE;QAC1C,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QACrC,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QACrC,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QACrC,IAAI,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzD,UAAU,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;KACjD,CAA2B,CAAC;AAC9B,CAAC,CAAC;AACF,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,EAC3B,MAAc,EACd,EAAE,EAAE,EAAE,GAAG,iBAAiB,EAA4B,EACpB,EAAE;IACpC,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAEpD,IAAI,CAAC;QACJ,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,UAAU,CACvC,aAAa,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,IAAI,CAC5C,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,EAC/B,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAClC,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CACzC,CACD,CAAC;QAEF,MAAM,OAAO,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAC5C,OAAO,CAAC,KAAK,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACvE,OAAO,OAAO,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACvD,MAAM,KAAK,CAAC;IACb,CAAC;AACF,CAAC,CAAC;AAEF,cAAc,gBAAgB,CAAC","sourcesContent":["import { S3 } from \"@effect-aws/client-s3\";\nimport { layer as fileSystemLayer } from \"@effect/platform-node/NodeFileSystem\";\nimport type { Database } from \"@tursodatabase/database\";\nimport { Effect, Exit, Scope } from \"effect\";\n\nimport { connect as connectEffect } from \"./src/index\";\nimport type { ConnectionOptions, S3qliteDatabase } from \"./src/types\";\n\ntype PromiseMethods = {\n\tpull: () => Promise<void>;\n\tpush: () => Promise<void>;\n\tsync: () => Promise<void>;\n\tfork: (dbName: string) => Promise<void>;\n\tcheckpoint: () => Promise<void>;\n};\n\nexport type PromiseS3qliteDatabase = Database & PromiseMethods;\n\nexport type PromiseConnectionOptions = ConnectionOptions & {\n\ts3?: Parameters<typeof S3.layer>[0];\n};\n\nconst toPromiseDatabase = (database: S3qliteDatabase): PromiseS3qliteDatabase => {\n\tconst pull = database.pull.bind(database);\n\tconst push = database.push.bind(database);\n\tconst sync = database.sync.bind(database);\n\tconst fork = database.fork.bind(database);\n\tconst checkpoint = database.checkpoint.bind(database);\n\n\treturn Object.assign(database as Database, {\n\t\tpull: () => Effect.runPromise(pull()),\n\t\tpush: () => Effect.runPromise(push()),\n\t\tsync: () => Effect.runPromise(sync()),\n\t\tfork: (dbName: string) => Effect.runPromise(fork(dbName)),\n\t\tcheckpoint: () => Effect.runPromise(checkpoint()),\n\t}) as PromiseS3qliteDatabase;\n};\nexport const connect = async (\n\tdbName: string,\n\t{ s3, ...connectionOptions }: PromiseConnectionOptions,\n): Promise<PromiseS3qliteDatabase> => {\n\tconst scope = await Effect.runPromise(Scope.make());\n\n\ttry {\n\t\tconst database = await Effect.runPromise(\n\t\t\tconnectEffect(dbName, connectionOptions).pipe(\n\t\t\t\tEffect.provide(fileSystemLayer),\n\t\t\t\tEffect.provide(S3.layer(s3 ?? {})),\n\t\t\t\tEffect.provideService(Scope.Scope, scope),\n\t\t\t),\n\t\t);\n\n\t\tconst wrapped = toPromiseDatabase(database);\n\t\twrapped.close = () => Effect.runPromise(Scope.close(scope, Exit.void));\n\t\treturn wrapped;\n\t} catch (error) {\n\t\tawait Effect.runPromise(Scope.close(scope, Exit.void));\n\t\tthrow error;\n\t}\n};\n\nexport * from \"./src/index.js\";"]}
package/esm/src/index.js CHANGED
@@ -8,6 +8,7 @@ export * from "./kv/fileKV.js";
8
8
  export * from "./kv/kv.js";
9
9
  export * from "./kv/memoryKV.js";
10
10
  export * from "./kv/s3KV.js";
11
+ export * from "./types.js";
11
12
  export { initializeContexts as initContexts };
12
13
  export const connect = (dbName, connectionOptions) => initializeContexts(connectionOptions).pipe(Effect.flatMap((ctx) => connectInternal(dbName, connectionOptions).pipe(Effect.provide(ctx))));
13
14
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAG9E,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAE1B,OAAO,EAAE,kBAAkB,IAAI,YAAY,EAAE,CAAC;AAE9C,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,MAAc,EAAE,iBAAoC,EAAE,EAAE,CAC/E,kBAAkB,CAAC,iBAAiB,CAAC,CAAC,IAAI,CACzC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CACtB,eAAe,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CACpE,CACD,CAAC","sourcesContent":["import { Effect } from \"effect\";\n\nimport { connect as connectInternal, initializeContexts } from \"./connection\";\nimport type { ConnectionOptions } from \"./types\";\n\nexport * from \"./cdc/apply\";\nexport * from \"./cdc/extract\";\nexport * from \"./cdc/types\";\nexport * from \"./fork\";\nexport * from \"./kv/fileKV\";\nexport * from \"./kv/kv\";\nexport * from \"./kv/memoryKV\";\nexport * from \"./kv/s3KV\";\n\nexport { initializeContexts as initContexts };\n\nexport const connect = (dbName: string, connectionOptions: ConnectionOptions) =>\n\tinitializeContexts(connectionOptions).pipe(\n\t\tEffect.flatMap((ctx) =>\n\t\t\tconnectInternal(dbName, connectionOptions).pipe(Effect.provide(ctx)),\n\t\t),\n\t);"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAG9E,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AAExB,OAAO,EAAE,kBAAkB,IAAI,YAAY,EAAE,CAAC;AAE9C,MAAM,CAAC,MAAM,OAAO,GAAG,CACtB,MAAc,EACd,iBAAoC,EAC0C,EAAE,CAChF,kBAAkB,CAAC,iBAAiB,CAAC,CAAC,IAAI,CACzC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CACtB,eAAe,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CACpE,CACD,CAAC","sourcesContent":["import type { S3Service } from \"@effect-aws/client-s3\";\nimport type { FileSystem } from \"@effect/platform/FileSystem\";\nimport { Effect } from \"effect\";\nimport type { Scope } from \"effect\";\n\nimport { connect as connectInternal, initializeContexts } from \"./connection\";\nimport type { ConnectionOptions, S3qliteDatabase } from \"./types\";\n\nexport * from \"./cdc/apply\";\nexport * from \"./cdc/extract\";\nexport * from \"./cdc/types\";\nexport * from \"./fork\";\nexport * from \"./kv/fileKV\";\nexport * from \"./kv/kv\";\nexport * from \"./kv/memoryKV\";\nexport * from \"./kv/s3KV\";\nexport * from \"./types\";\n\nexport { initializeContexts as initContexts };\n\nexport const connect = (\n\tdbName: string,\n\tconnectionOptions: ConnectionOptions,\n): Effect.Effect<S3qliteDatabase, Error, Scope.Scope | FileSystem | S3Service> =>\n\tinitializeContexts(connectionOptions).pipe(\n\t\tEffect.flatMap((ctx) =>\n\t\t\tconnectInternal(dbName, connectionOptions).pipe(Effect.provide(ctx)),\n\t\t),\n\t);\n"]}
@@ -11,6 +11,7 @@ const getEtag = (value) => Effect.promise(async () => {
11
11
  }).pipe(Effect.orDie);
12
12
  export const makeFileKV = (rootDirectory) => Effect.gen(function* () {
13
13
  const fs = yield* FileSystem;
14
+ yield* fs.makeDirectory(rootDirectory, { recursive: true }).pipe(Effect.orDie);
14
15
  const writeBytes = (key, value) => Effect.gen(function* () {
15
16
  const path = `${rootDirectory}/${key}`;
16
17
  const directory = path.split("/").slice(0, -1).join("/");
@@ -1 +1 @@
1
- {"version":3,"file":"fileKV.js","sourceRoot":"","sources":["../../../../src/kv/fileKV.ts"],"names":[],"mappings":"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","sourcesContent":["import { FileSystem } from \"@effect/platform/FileSystem\";\nimport { connect as connectTurso } from \"@tursodatabase/database\";\nimport type { Scope } from \"effect\";\nimport { Effect, Option, Stream } from \"effect\";\nimport { constants } from \"node:fs\";\nimport { copyFile as copyFilePromise } from \"node:fs/promises\";\n\nimport { ConflictError } from \"./kv\";\nimport type { CloneTrait, ConnectDatabaseTrait, KV } from \"./kv\";\n\n// TODO: in the future the etag should be probably cached\nconst getEtag = (value: Uint8Array): Effect.Effect<string> =>\n\tEffect.promise(async () => {\n\t\tconst digest = await crypto.subtle.digest(\"SHA-256\", Uint8Array.from(value).buffer);\n\t\treturn Array.from(new Uint8Array(digest), (byte) =>\n\t\t\tbyte.toString(16).padStart(2, \"0\"),\n\t\t).join(\"\");\n\t}).pipe(Effect.orDie);\n\nexport const makeFileKV = (\n\trootDirectory: string,\n): Effect.Effect<KV & CloneTrait & ConnectDatabaseTrait, never, FileSystem | Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem;\n\n\t\tconst writeBytes = (key: string, value: Uint8Array): Effect.Effect<{ etag: string }> =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\tconst directory = path.split(\"/\").slice(0, -1).join(\"/\");\n\t\t\t\tyield* fs.makeDirectory(directory, { recursive: true }).pipe(Effect.orDie);\n\t\t\t\tconst tempPath = `${path}.${crypto.randomUUID()}.tmp`;\n\t\t\t\tyield* fs.writeFile(tempPath, value).pipe(Effect.orDie);\n\t\t\t\tyield* fs.rename(tempPath, path).pipe(Effect.orDie);\n\t\t\t\treturn { etag: yield* getEtag(value) };\n\t\t\t});\n\n\t\treturn {\n\t\t\tget: (key) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.get(${key})`);\n\n\t\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\t\tif (!(yield* fs.exists(path).pipe(Effect.orDie))) {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.get(${key}) => None`);\n\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t}\n\n\t\t\t\t\tconst value = yield* fs.readFile(path).pipe(Effect.orDie);\n\t\t\t\t\tconst etag = yield* getEtag(value);\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.get(${key}) => Some(${etag})`);\n\t\t\t\t\treturn Option.some({ etag, value });\n\t\t\t\t}),\n\t\t\tgetIfChanged: (key, etag) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.getIfChanged(${key}, ${etag})`);\n\n\t\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\t\tif (!(yield* fs.exists(path).pipe(Effect.orDie))) {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.getIfChanged(${key}) => None`);\n\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t}\n\n\t\t\t\t\tconst value = yield* fs.readFile(path).pipe(Effect.orDie);\n\t\t\t\t\tconst currentEtag = yield* getEtag(value);\n\t\t\t\t\tif (currentEtag === etag) {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.getIfChanged(${key}) => None (not changed)`);\n\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t}\n\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.getIfChanged(${key}) => Some(${currentEtag})`);\n\t\t\t\t\treturn Option.some({ etag: currentEtag, value });\n\t\t\t\t}),\n\t\t\texists: (key) =>\n\t\t\t\tEffect.logDebug(`fileKV.exists(${key})`).pipe(\n\t\t\t\t\tEffect.flatMap(() => fs.exists(`${rootDirectory}/${key}`).pipe(Effect.orDie)),\n\t\t\t\t\tEffect.tap((result) => Effect.logDebug(`fileKV.exists(${key}) => ${result}`)),\n\t\t\t\t),\n\t\t\tset: (key, value) =>\n\t\t\t\tEffect.logDebug(`fileKV.set(${key}, ${value.length} bytes)`).pipe(\n\t\t\t\t\tEffect.flatMap(() => writeBytes(key, value)),\n\t\t\t\t\tEffect.tap((result) => Effect.logDebug(`fileKV.set(${key}) => ${result.etag}`)),\n\t\t\t\t),\n\t\t\tcas: (key, value, etag) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.cas(${key}, ${value.length} bytes, ${etag})`);\n\n\t\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\t\tif (!(yield* fs.exists(path).pipe(Effect.orDie))) {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.cas(${key}) => ConflictError (missing)`);\n\t\t\t\t\t\treturn yield* Effect.fail(new ConflictError({ key }));\n\t\t\t\t\t}\n\n\t\t\t\t\tconst existingValue = yield* fs.readFile(path).pipe(Effect.orDie);\n\t\t\t\t\tif ((yield* getEtag(existingValue)) !== etag) {\n\t\t\t\t\t\tyield* Effect.logDebug(\n\t\t\t\t\t\t\t`fileKV.cas(${key}) => ConflictError (etag mismatch)`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn yield* Effect.fail(new ConflictError({ key }));\n\t\t\t\t\t}\n\n\t\t\t\t\tconst result = yield* writeBytes(key, value);\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.cas(${key}) => ${result.etag}`);\n\t\t\t\t\treturn result;\n\t\t\t\t}),\n\t\t\tdelete: (key) =>\n\t\t\t\tEffect.logDebug(`fileKV.delete(${key})`).pipe(\n\t\t\t\t\tEffect.flatMap(() =>\n\t\t\t\t\t\tfs.remove(`${rootDirectory}/${key}`, { force: true }).pipe(Effect.orDie),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.tap(() => Effect.logDebug(`fileKV.delete(${key}) => void`)),\n\t\t\t\t),\n\t\t\treadStream: (key) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.readStream(${key})`);\n\n\t\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\t\tif (!(yield* fs.exists(path).pipe(Effect.orDie))) {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.readStream(${key}) => None`);\n\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t}\n\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.readStream(${key}) => Some(stream)`);\n\t\t\t\t\treturn Option.some(fs.stream(path).pipe(Stream.orDie));\n\t\t\t\t}),\n\t\t\twriteStream: (key, content) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.writeStream(${key}, stream)`);\n\n\t\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\t\tconst directory = path.split(\"/\").slice(0, -1).join(\"/\");\n\t\t\t\t\tyield* fs.makeDirectory(directory, { recursive: true }).pipe(Effect.orDie);\n\t\t\t\t\tconst tempPath = `${path}.${crypto.randomUUID()}.tmp`;\n\t\t\t\t\tyield* Stream.run(content, fs.sink(tempPath)).pipe(Effect.orDie);\n\t\t\t\t\tyield* fs.rename(tempPath, path).pipe(Effect.orDie);\n\t\t\t\t\tconst value = yield* fs.readFile(path).pipe(Effect.orDie);\n\t\t\t\t\tconst etag = yield* getEtag(value);\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.writeStream(${key}) => ${etag}`);\n\t\t\t\t\treturn { etag };\n\t\t\t\t}),\n\t\t\tclone: (from, to) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.clone(${from}, ${to})`);\n\n\t\t\t\t\tconst fromPath = `${rootDirectory}/${from}`;\n\t\t\t\t\tconst toPath = `${rootDirectory}/${to}`;\n\t\t\t\t\tconst directory = toPath.split(\"/\").slice(0, -1).join(\"/\");\n\t\t\t\t\tyield* fs.makeDirectory(directory, { recursive: true }).pipe(Effect.orDie);\n\t\t\t\t\tconst cloneAttempt = yield* Effect.either(\n\t\t\t\t\t\tEffect.promise(() =>\n\t\t\t\t\t\t\tcopyFilePromise(fromPath, toPath, constants.COPYFILE_FICLONE),\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\n\t\t\t\t\tif (cloneAttempt._tag === \"Right\") {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.clone(${from}, ${to}) => void (copied)`);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst errorOption =\n\t\t\t\t\t\ttypeof cloneAttempt.left === \"object\"\n\t\t\t\t\t\t\t? Option.fromNullable(cloneAttempt.left)\n\t\t\t\t\t\t\t: Option.none();\n\t\t\t\t\tconst currentError = Option.map(\n\t\t\t\t\t\terrorOption,\n\t\t\t\t\t\t(error) => error as { code?: unknown },\n\t\t\t\t\t);\n\n\t\t\t\t\tif (\n\t\t\t\t\t\tOption.isNone(currentError) ||\n\t\t\t\t\t\t!(\"code\" in currentError.value) ||\n\t\t\t\t\t\t![\"ENOTSUP\", \"EINVAL\", \"ENOSYS\", \"EXDEV\", \"EOPNOTSUPP\"].includes(\n\t\t\t\t\t\t\tString(currentError.value.code),\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn yield* Effect.die(cloneAttempt.left);\n\t\t\t\t\t}\n\n\t\t\t\t\tyield* fs.copyFile(fromPath, toPath).pipe(Effect.orDie);\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.clone(${from}, ${to}) => void (copied)`);\n\t\t\t\t}),\n\t\t\tconnect: (key) =>\n\t\t\t\tEffect.logDebug(`fileKV.connect(${key})`).pipe(\n\t\t\t\t\tEffect.flatMap(() =>\n\t\t\t\t\t\tEffect.acquireRelease(\n\t\t\t\t\t\t\tEffect.tryPromise({\n\t\t\t\t\t\t\t\ttry: async () => {\n\t\t\t\t\t\t\t\t\tconst connection = await connectTurso(\n\t\t\t\t\t\t\t\t\t\t`${rootDirectory}/${key}`,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\tawait connection.exec(\n\t\t\t\t\t\t\t\t\t\t\"PRAGMA capture_data_changes_conn('full')\",\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\treturn connection;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tcatch: (e) =>\n\t\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t\t`Failed to connect to database at key ${key}: ${String(e)}`,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(db) => Effect.promise(() => db.close()),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.tap(() => Effect.logDebug(`fileKV.connect(${key}) => database`)),\n\t\t\t\t),\n\t\t};\n\t});"]}
1
+ {"version":3,"file":"fileKV.js","sourceRoot":"","sources":["../../../../src/kv/fileKV.ts"],"names":[],"mappings":"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","sourcesContent":["import { FileSystem } from \"@effect/platform/FileSystem\";\nimport { connect as connectTurso } from \"@tursodatabase/database\";\nimport type { Scope } from \"effect\";\nimport { Effect, Option, Stream } from \"effect\";\nimport { constants } from \"node:fs\";\nimport { copyFile as copyFilePromise } from \"node:fs/promises\";\n\nimport { ConflictError } from \"./kv\";\nimport type { CloneTrait, ConnectDatabaseTrait, KV } from \"./kv\";\n\n// TODO: in the future the etag should be probably cached\nconst getEtag = (value: Uint8Array): Effect.Effect<string> =>\n\tEffect.promise(async () => {\n\t\tconst digest = await crypto.subtle.digest(\"SHA-256\", Uint8Array.from(value).buffer);\n\t\treturn Array.from(new Uint8Array(digest), (byte) =>\n\t\t\tbyte.toString(16).padStart(2, \"0\"),\n\t\t).join(\"\");\n\t}).pipe(Effect.orDie);\n\nexport const makeFileKV = (\n\trootDirectory: string,\n): Effect.Effect<KV & CloneTrait & ConnectDatabaseTrait, never, FileSystem | Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem;\n\t\tyield* fs.makeDirectory(rootDirectory, { recursive: true }).pipe(Effect.orDie);\n\n\t\tconst writeBytes = (key: string, value: Uint8Array): Effect.Effect<{ etag: string }> =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\tconst directory = path.split(\"/\").slice(0, -1).join(\"/\");\n\t\t\t\tyield* fs.makeDirectory(directory, { recursive: true }).pipe(Effect.orDie);\n\t\t\t\tconst tempPath = `${path}.${crypto.randomUUID()}.tmp`;\n\t\t\t\tyield* fs.writeFile(tempPath, value).pipe(Effect.orDie);\n\t\t\t\tyield* fs.rename(tempPath, path).pipe(Effect.orDie);\n\t\t\t\treturn { etag: yield* getEtag(value) };\n\t\t\t});\n\n\t\treturn {\n\t\t\tget: (key) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.get(${key})`);\n\n\t\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\t\tif (!(yield* fs.exists(path).pipe(Effect.orDie))) {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.get(${key}) => None`);\n\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t}\n\n\t\t\t\t\tconst value = yield* fs.readFile(path).pipe(Effect.orDie);\n\t\t\t\t\tconst etag = yield* getEtag(value);\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.get(${key}) => Some(${etag})`);\n\t\t\t\t\treturn Option.some({ etag, value });\n\t\t\t\t}),\n\t\t\tgetIfChanged: (key, etag) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.getIfChanged(${key}, ${etag})`);\n\n\t\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\t\tif (!(yield* fs.exists(path).pipe(Effect.orDie))) {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.getIfChanged(${key}) => None`);\n\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t}\n\n\t\t\t\t\tconst value = yield* fs.readFile(path).pipe(Effect.orDie);\n\t\t\t\t\tconst currentEtag = yield* getEtag(value);\n\t\t\t\t\tif (currentEtag === etag) {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.getIfChanged(${key}) => None (not changed)`);\n\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t}\n\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.getIfChanged(${key}) => Some(${currentEtag})`);\n\t\t\t\t\treturn Option.some({ etag: currentEtag, value });\n\t\t\t\t}),\n\t\t\texists: (key) =>\n\t\t\t\tEffect.logDebug(`fileKV.exists(${key})`).pipe(\n\t\t\t\t\tEffect.flatMap(() => fs.exists(`${rootDirectory}/${key}`).pipe(Effect.orDie)),\n\t\t\t\t\tEffect.tap((result) => Effect.logDebug(`fileKV.exists(${key}) => ${result}`)),\n\t\t\t\t),\n\t\t\tset: (key, value) =>\n\t\t\t\tEffect.logDebug(`fileKV.set(${key}, ${value.length} bytes)`).pipe(\n\t\t\t\t\tEffect.flatMap(() => writeBytes(key, value)),\n\t\t\t\t\tEffect.tap((result) => Effect.logDebug(`fileKV.set(${key}) => ${result.etag}`)),\n\t\t\t\t),\n\t\t\tcas: (key, value, etag) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.cas(${key}, ${value.length} bytes, ${etag})`);\n\n\t\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\t\tif (!(yield* fs.exists(path).pipe(Effect.orDie))) {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.cas(${key}) => ConflictError (missing)`);\n\t\t\t\t\t\treturn yield* Effect.fail(new ConflictError({ key }));\n\t\t\t\t\t}\n\n\t\t\t\t\tconst existingValue = yield* fs.readFile(path).pipe(Effect.orDie);\n\t\t\t\t\tif ((yield* getEtag(existingValue)) !== etag) {\n\t\t\t\t\t\tyield* Effect.logDebug(\n\t\t\t\t\t\t\t`fileKV.cas(${key}) => ConflictError (etag mismatch)`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn yield* Effect.fail(new ConflictError({ key }));\n\t\t\t\t\t}\n\n\t\t\t\t\tconst result = yield* writeBytes(key, value);\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.cas(${key}) => ${result.etag}`);\n\t\t\t\t\treturn result;\n\t\t\t\t}),\n\t\t\tdelete: (key) =>\n\t\t\t\tEffect.logDebug(`fileKV.delete(${key})`).pipe(\n\t\t\t\t\tEffect.flatMap(() =>\n\t\t\t\t\t\tfs.remove(`${rootDirectory}/${key}`, { force: true }).pipe(Effect.orDie),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.tap(() => Effect.logDebug(`fileKV.delete(${key}) => void`)),\n\t\t\t\t),\n\t\t\treadStream: (key) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.readStream(${key})`);\n\n\t\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\t\tif (!(yield* fs.exists(path).pipe(Effect.orDie))) {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.readStream(${key}) => None`);\n\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t}\n\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.readStream(${key}) => Some(stream)`);\n\t\t\t\t\treturn Option.some(fs.stream(path).pipe(Stream.orDie));\n\t\t\t\t}),\n\t\t\twriteStream: (key, content) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.writeStream(${key}, stream)`);\n\n\t\t\t\t\tconst path = `${rootDirectory}/${key}`;\n\t\t\t\t\tconst directory = path.split(\"/\").slice(0, -1).join(\"/\");\n\t\t\t\t\tyield* fs.makeDirectory(directory, { recursive: true }).pipe(Effect.orDie);\n\t\t\t\t\tconst tempPath = `${path}.${crypto.randomUUID()}.tmp`;\n\t\t\t\t\tyield* Stream.run(content, fs.sink(tempPath)).pipe(Effect.orDie);\n\t\t\t\t\tyield* fs.rename(tempPath, path).pipe(Effect.orDie);\n\t\t\t\t\tconst value = yield* fs.readFile(path).pipe(Effect.orDie);\n\t\t\t\t\tconst etag = yield* getEtag(value);\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.writeStream(${key}) => ${etag}`);\n\t\t\t\t\treturn { etag };\n\t\t\t\t}),\n\t\t\tclone: (from, to) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.clone(${from}, ${to})`);\n\n\t\t\t\t\tconst fromPath = `${rootDirectory}/${from}`;\n\t\t\t\t\tconst toPath = `${rootDirectory}/${to}`;\n\t\t\t\t\tconst directory = toPath.split(\"/\").slice(0, -1).join(\"/\");\n\t\t\t\t\tyield* fs.makeDirectory(directory, { recursive: true }).pipe(Effect.orDie);\n\t\t\t\t\tconst cloneAttempt = yield* Effect.either(\n\t\t\t\t\t\tEffect.promise(() =>\n\t\t\t\t\t\t\tcopyFilePromise(fromPath, toPath, constants.COPYFILE_FICLONE),\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\n\t\t\t\t\tif (cloneAttempt._tag === \"Right\") {\n\t\t\t\t\t\tyield* Effect.logDebug(`fileKV.clone(${from}, ${to}) => void (copied)`);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst errorOption =\n\t\t\t\t\t\ttypeof cloneAttempt.left === \"object\"\n\t\t\t\t\t\t\t? Option.fromNullable(cloneAttempt.left)\n\t\t\t\t\t\t\t: Option.none();\n\t\t\t\t\tconst currentError = Option.map(\n\t\t\t\t\t\terrorOption,\n\t\t\t\t\t\t(error) => error as { code?: unknown },\n\t\t\t\t\t);\n\n\t\t\t\t\tif (\n\t\t\t\t\t\tOption.isNone(currentError) ||\n\t\t\t\t\t\t!(\"code\" in currentError.value) ||\n\t\t\t\t\t\t![\"ENOTSUP\", \"EINVAL\", \"ENOSYS\", \"EXDEV\", \"EOPNOTSUPP\"].includes(\n\t\t\t\t\t\t\tString(currentError.value.code),\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn yield* Effect.die(cloneAttempt.left);\n\t\t\t\t\t}\n\n\t\t\t\t\tyield* fs.copyFile(fromPath, toPath).pipe(Effect.orDie);\n\t\t\t\t\tyield* Effect.logDebug(`fileKV.clone(${from}, ${to}) => void (copied)`);\n\t\t\t\t}),\n\t\t\tconnect: (key) =>\n\t\t\t\tEffect.logDebug(`fileKV.connect(${key})`).pipe(\n\t\t\t\t\tEffect.flatMap(() =>\n\t\t\t\t\t\tEffect.acquireRelease(\n\t\t\t\t\t\t\tEffect.tryPromise({\n\t\t\t\t\t\t\t\ttry: async () => {\n\t\t\t\t\t\t\t\t\tconst connection = await connectTurso(\n\t\t\t\t\t\t\t\t\t\t`${rootDirectory}/${key}`,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\tawait connection.exec(\n\t\t\t\t\t\t\t\t\t\t\"PRAGMA capture_data_changes_conn('full')\",\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\treturn connection;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tcatch: (e) =>\n\t\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t\t`Failed to connect to database at key ${key}: ${String(e)}`,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(db) => Effect.promise(() => db.close()),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.tap(() => Effect.logDebug(`fileKV.connect(${key}) => database`)),\n\t\t\t\t),\n\t\t};\n\t});"]}
@@ -1,7 +1,9 @@
1
1
  import { S3 } from "@effect-aws/client-s3";
2
- import { Chunk, Effect, Option, Stream } from "effect";
2
+ import { Chunk, Data, Effect, Option, Stream } from "effect";
3
3
  import { ConflictError } from "./kv.js";
4
- const isMissingObjectError = (error) => Effect.runSync(Effect.sync(() => {
4
+ export class BucketDoesNotExistError extends Data.TaggedError("BucketDoesNotExistError") {
5
+ }
6
+ const isNotModifiedError = (error) => {
5
7
  if (typeof error !== "object") {
6
8
  return false;
7
9
  }
@@ -10,11 +12,19 @@ const isMissingObjectError = (error) => Effect.runSync(Effect.sync(() => {
10
12
  return false;
11
13
  }
12
14
  const currentError = errorOption.value;
13
- return ((typeof currentError.Code === "string" && currentError.Code === "NoSuchKey") ||
14
- (typeof currentError.name === "string" &&
15
- (currentError.name === "NoSuchKey" || currentError.name === "NotFound")));
16
- }));
17
- const isNotModifiedError = (error) => Effect.runSync(Effect.sync(() => {
15
+ if (currentError.Code === "NotModified" || currentError.name === "NotModified") {
16
+ return true;
17
+ }
18
+ if (typeof currentError.$metadata !== "object") {
19
+ return false;
20
+ }
21
+ const metadataOption = Option.fromNullable(currentError.$metadata);
22
+ if (Option.isNone(metadataOption)) {
23
+ return false;
24
+ }
25
+ return metadataOption.value.httpStatusCode === 304;
26
+ };
27
+ const isMissingObjectError = (error) => {
18
28
  if (typeof error !== "object") {
19
29
  return false;
20
30
  }
@@ -23,14 +33,10 @@ const isNotModifiedError = (error) => Effect.runSync(Effect.sync(() => {
23
33
  return false;
24
34
  }
25
35
  const currentError = errorOption.value;
26
- const metadata = typeof currentError.$metadata === "object" &&
27
- Option.isSome(Option.fromNullable(currentError.$metadata))
28
- ? Option.some(currentError.$metadata)
29
- : Option.none();
30
- return ((typeof currentError.Code === "string" && currentError.Code === "NotModified") ||
31
- (typeof currentError.name === "string" && currentError.name === "NotModified") ||
32
- Option.exists(metadata, (currentMetadata) => currentMetadata.httpStatusCode === 304));
33
- }));
36
+ return currentError.name === "NoSuchKey" || currentError.name === "NotFound"
37
+ ? true
38
+ : currentError.Code === "NoSuchKey";
39
+ };
34
40
  const getEtag = (result, key) => Option.fromNullable(result.ETag).pipe(Option.match({
35
41
  onNone: () => Effect.die(new Error(`Expected ETag for ${key}`)),
36
42
  onSome: (etag) => Effect.succeed({ etag }),
@@ -88,6 +94,10 @@ const combineChunks = (chunks, totalLength) => {
88
94
  };
89
95
  export const makeS3KV = (bucket) => Effect.gen(function* () {
90
96
  const s3 = yield* S3;
97
+ yield* s3.headBucket({ Bucket: bucket }).pipe(Effect.catchTag("NotFound", () => Effect.fail(new BucketDoesNotExistError({
98
+ bucket,
99
+ message: `Bucket "${bucket}" does not exist`,
100
+ }))));
91
101
  return {
92
102
  get: (key) => Effect.gen(function* () {
93
103
  yield* Effect.logDebug(`s3KV.get(${key})`);
@@ -99,7 +109,7 @@ export const makeS3KV = (bucket) => Effect.gen(function* () {
99
109
  }
100
110
  return yield* Effect.die(response.left instanceof Error
101
111
  ? response.left
102
- : new Error(`Failed to read ${key}: ${String(response.left)}`));
112
+ : new Error(`Failed to read ${key}: ${typeof response.left === "object" ? JSON.stringify(response.left) : String(response.left)}`));
103
113
  }
104
114
  const { etag } = yield* getEtag(response.right, key);
105
115
  const value = yield* readBodyBytes(response.right.Body, key);
@@ -117,7 +127,7 @@ export const makeS3KV = (bucket) => Effect.gen(function* () {
117
127
  }
118
128
  return yield* Effect.die(response.left instanceof Error
119
129
  ? response.left
120
- : new Error(`Failed to read ${key}: ${String(response.left)}`));
130
+ : new Error(`Failed to read ${key}: ${typeof response.left === "object" ? JSON.stringify(response.left) : String(response.left)}`));
121
131
  }
122
132
  const { etag: currentEtag } = yield* getEtag(response.right, key);
123
133
  const value = yield* readBodyBytes(response.right.Body, key);
@@ -134,14 +144,14 @@ export const makeS3KV = (bucket) => Effect.gen(function* () {
134
144
  }
135
145
  return yield* Effect.die(response.left instanceof Error
136
146
  ? response.left
137
- : new Error(`Failed to stat ${key}: ${String(response.left)}`));
147
+ : new Error(`Failed to stat ${key}: ${typeof response.left === "object" ? JSON.stringify(response.left) : String(response.left)}`));
138
148
  }
139
149
  yield* Effect.logDebug(`s3KV.exists(${key}) => true`);
140
150
  return true;
141
151
  }),
142
152
  set: (key, value) => Effect.logDebug(`s3KV.set(${key}, ${value.length} bytes)`).pipe(Effect.flatMap(() => s3.putObject({ Body: value, Bucket: bucket, Key: key })), Effect.orDieWith((error) => error instanceof Error
143
153
  ? error
144
- : new Error(`Failed to write ${key}: ${String(error)}`)), Effect.flatMap((result) => getEtag(result, key)), Effect.tap((result) => Effect.logDebug(`s3KV.set(${key}) => ${result.etag}`))),
154
+ : new Error(`Failed to write ${key}: ${typeof error === "object" ? JSON.stringify(error) : String(error)}`)), Effect.flatMap((result) => getEtag(result, key)), Effect.tap((result) => Effect.logDebug(`s3KV.set(${key}) => ${result.etag}`))),
145
155
  cas: (key, value, etag) => Effect.logDebug(`s3KV.cas(${key}, ${value.length} bytes, ${etag})`).pipe(Effect.flatMap(() => s3.putObject({ Body: value, Bucket: bucket, IfMatch: etag, Key: key })), Effect.catchAll((error) => {
146
156
  const currentError = typeof error === "object" && Option.isSome(Option.fromNullable(error))
147
157
  ? Option.some(error)
@@ -160,11 +170,11 @@ export const makeS3KV = (bucket) => Effect.gen(function* () {
160
170
  ? Effect.fail(new ConflictError({ key }))
161
171
  : Effect.die(error instanceof Error
162
172
  ? error
163
- : new Error(`Failed to write ${key}: ${String(error)}`));
173
+ : new Error(`Failed to write ${key}: ${typeof error === "object" ? JSON.stringify(error) : String(error)}`));
164
174
  }), Effect.flatMap((result) => getEtag(result, key)), Effect.tap((result) => Effect.logDebug(`s3KV.cas(${key}) => ${result.etag}`))),
165
175
  delete: (key) => Effect.logDebug(`s3KV.delete(${key})`).pipe(Effect.flatMap(() => s3.deleteObject({ Bucket: bucket, Key: key })), Effect.asVoid, Effect.orDieWith((error) => error instanceof Error
166
176
  ? error
167
- : new Error(`Failed to delete ${key}: ${String(error)}`)), Effect.tap(() => Effect.logDebug(`s3KV.delete(${key}) => void`))),
177
+ : new Error(`Failed to delete ${key}: ${typeof error === "object" ? JSON.stringify(error) : String(error)}`)), Effect.tap(() => Effect.logDebug(`s3KV.delete(${key}) => void`))),
168
178
  readStream: (key) => Effect.gen(function* () {
169
179
  yield* Effect.logDebug(`s3KV.readStream(${key})`);
170
180
  const response = yield* Effect.either(s3.getObject({ Bucket: bucket, Key: key }));
@@ -175,7 +185,7 @@ export const makeS3KV = (bucket) => Effect.gen(function* () {
175
185
  }
176
186
  return yield* Effect.die(response.left instanceof Error
177
187
  ? response.left
178
- : new Error(`Failed to stream ${key}: ${String(response.left)}`));
188
+ : new Error(`Failed to stream ${key}: ${typeof response.left === "object" ? JSON.stringify(response.left) : String(response.left)}`));
179
189
  }
180
190
  const stream = yield* readBodyStream(response.right.Body, key);
181
191
  yield* Effect.logDebug(`s3KV.readStream(${key}) => Some(stream)`);
@@ -187,7 +197,7 @@ export const makeS3KV = (bucket) => Effect.gen(function* () {
187
197
  .createMultipartUpload({ Bucket: bucket, Key: key })
188
198
  .pipe(Effect.orDieWith((error) => error instanceof Error
189
199
  ? error
190
- : new Error(`Failed to start upload ${key}: ${String(error)}`)));
200
+ : new Error(`Failed to start upload ${key}: ${typeof error === "object" ? JSON.stringify(error) : String(error)}`)));
191
201
  const uploadIdOption = Option.fromNullable(multipartUpload.UploadId);
192
202
  if (Option.isNone(uploadIdOption)) {
193
203
  return yield* Effect.die(new Error(`Expected UploadId for ${key}`));
@@ -218,7 +228,7 @@ export const makeS3KV = (bucket) => Effect.gen(function* () {
218
228
  })
219
229
  .pipe(Effect.orDieWith((error) => error instanceof Error
220
230
  ? error
221
- : new Error(`Failed to upload ${key} part ${partNumber}: ${String(error)}`)), Effect.flatMap((result) => Option.fromNullable(result.ETag).pipe(Option.match({
231
+ : new Error(`Failed to upload part ${String(partNumber)} for ${key}: ${typeof error === "object" ? JSON.stringify(error) : String(error)}`)), Effect.flatMap((result) => Option.fromNullable(result.ETag).pipe(Option.match({
222
232
  onNone: () => Effect.die(new Error(`Expected ETag for ${key} part ${partNumber}`)),
223
233
  onSome: (etag) => Effect.sync(() => {
224
234
  completedParts.push({
@@ -255,7 +265,7 @@ export const makeS3KV = (bucket) => Effect.gen(function* () {
255
265
  .putObject({ Body: new Uint8Array(), Bucket: bucket, Key: key })
256
266
  .pipe(Effect.orDieWith((error) => error instanceof Error
257
267
  ? error
258
- : new Error(`Failed to upload ${key}: ${String(error)}`)));
268
+ : new Error(`Failed to upload ${key}: ${typeof error === "object" ? JSON.stringify(error) : String(error)}`)));
259
269
  const emptyEtagResult = yield* getEtag(emptyResult, key);
260
270
  yield* Effect.logDebug(`s3KV.writeStream(${key}) => ${emptyEtagResult.etag}`);
261
271
  return emptyEtagResult;
@@ -269,7 +279,7 @@ export const makeS3KV = (bucket) => Effect.gen(function* () {
269
279
  })
270
280
  .pipe(Effect.orDieWith((error) => error instanceof Error
271
281
  ? error
272
- : new Error(`Failed to upload ${key}: ${String(error)}`)));
282
+ : new Error(`Failed to upload ${key}: ${typeof error === "object" ? JSON.stringify(error) : String(error)}`)));
273
283
  const finalResult = yield* getEtag(result, key);
274
284
  yield* Effect.logDebug(`s3KV.writeStream(${key}) => ${finalResult.etag}`);
275
285
  return finalResult;
@@ -1 +1 @@
1
- {"version":3,"file":"s3KV.js","sourceRoot":"","sources":["../../../../src/kv/s3KV.ts"],"names":[],"mappings":"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","sourcesContent":["import { S3 } from \"@effect-aws/client-s3\";\nimport type { S3Service } from \"@effect-aws/client-s3\";\nimport { Chunk, Effect, Option, Stream } from \"effect\";\n\nimport { ConflictError } from \"./kv\";\nimport type { KV } from \"./kv\";\n\nconst isMissingObjectError = (error: unknown): boolean =>\n\tEffect.runSync(\n\t\tEffect.sync(() => {\n\t\t\tif (typeof error !== \"object\") {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst errorOption = Option.fromNullable(error);\n\t\t\tif (Option.isNone(errorOption)) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst currentError = errorOption.value as { Code?: unknown; name?: unknown };\n\t\t\treturn (\n\t\t\t\t(typeof currentError.Code === \"string\" && currentError.Code === \"NoSuchKey\") ||\n\t\t\t\t(typeof currentError.name === \"string\" &&\n\t\t\t\t\t(currentError.name === \"NoSuchKey\" || currentError.name === \"NotFound\"))\n\t\t\t);\n\t\t}),\n\t);\n\nconst isNotModifiedError = (error: unknown): boolean =>\n\tEffect.runSync(\n\t\tEffect.sync(() => {\n\t\t\tif (typeof error !== \"object\") {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst errorOption = Option.fromNullable(error);\n\t\t\tif (Option.isNone(errorOption)) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst currentError = errorOption.value as {\n\t\t\t\tCode?: unknown;\n\t\t\t\tname?: unknown;\n\t\t\t\t$metadata?: unknown;\n\t\t\t};\n\t\t\tconst metadata =\n\t\t\t\ttypeof currentError.$metadata === \"object\" &&\n\t\t\t\tOption.isSome(Option.fromNullable(currentError.$metadata))\n\t\t\t\t\t? Option.some(currentError.$metadata as { httpStatusCode?: number })\n\t\t\t\t\t: Option.none<{ httpStatusCode?: number }>();\n\n\t\t\treturn (\n\t\t\t\t(typeof currentError.Code === \"string\" && currentError.Code === \"NotModified\") ||\n\t\t\t\t(typeof currentError.name === \"string\" && currentError.name === \"NotModified\") ||\n\t\t\t\tOption.exists(metadata, (currentMetadata) => currentMetadata.httpStatusCode === 304)\n\t\t\t);\n\t\t}),\n\t);\n\nconst getEtag = (result: { ETag?: string }, key: string): Effect.Effect<{ etag: string }> =>\n\tOption.fromNullable(result.ETag).pipe(\n\t\tOption.match({\n\t\t\tonNone: () => Effect.die(new Error(`Expected ETag for ${key}`)),\n\t\t\tonSome: (etag) => Effect.succeed({ etag }),\n\t\t}),\n\t);\n\nconst readBodyBytes = (body: unknown, key: string): Effect.Effect<Uint8Array> => {\n\tif (body instanceof Uint8Array) {\n\t\treturn Effect.succeed(body);\n\t}\n\n\tif (typeof body === \"object\") {\n\t\tconst bodyOption = Option.fromNullable(body);\n\t\tif (\n\t\t\tOption.isSome(bodyOption) &&\n\t\t\t\"transformToByteArray\" in bodyOption.value &&\n\t\t\ttypeof bodyOption.value.transformToByteArray === \"function\"\n\t\t) {\n\t\t\tconst currentBody = bodyOption.value as {\n\t\t\t\ttransformToByteArray: () => Promise<Uint8Array>;\n\t\t\t};\n\t\t\treturn Effect.promise(() => currentBody.transformToByteArray()).pipe(Effect.orDie);\n\t\t}\n\t}\n\n\treturn Effect.die(new Error(`Expected readable body for ${key}`));\n};\n\nconst readBodyStream = (body: unknown, key: string): Effect.Effect<Stream.Stream<Uint8Array>> => {\n\tif (body instanceof Uint8Array) {\n\t\treturn Effect.succeed(Stream.fromIterable([body]));\n\t}\n\n\tif (body instanceof ReadableStream) {\n\t\treturn Effect.succeed(\n\t\t\tStream.fromReadableStream<Uint8Array, Error>(\n\t\t\t\t() => body as ReadableStream<Uint8Array>,\n\t\t\t\t() => new Error(`Failed to stream ${key}`),\n\t\t\t).pipe(Stream.orDie),\n\t\t);\n\t}\n\n\tif (typeof body === \"object\") {\n\t\tconst bodyOption = Option.fromNullable(body);\n\t\tif (\n\t\t\tOption.isSome(bodyOption) &&\n\t\t\t\"transformToWebStream\" in bodyOption.value &&\n\t\t\ttypeof bodyOption.value.transformToWebStream === \"function\"\n\t\t) {\n\t\t\tconst currentBody = bodyOption.value as {\n\t\t\t\ttransformToWebStream: () => ReadableStream<Uint8Array>;\n\t\t\t};\n\t\t\treturn Effect.succeed(\n\t\t\t\tStream.fromReadableStream<Uint8Array, Error>(\n\t\t\t\t\t() => currentBody.transformToWebStream(),\n\t\t\t\t\t() => new Error(`Failed to stream ${key}`),\n\t\t\t\t).pipe(Stream.orDie),\n\t\t\t);\n\t\t}\n\t}\n\n\tif (typeof body === \"object\") {\n\t\tconst bodyOption = Option.fromNullable(body);\n\t\tif (\n\t\t\tOption.isSome(bodyOption) &&\n\t\t\t\"transformToByteArray\" in bodyOption.value &&\n\t\t\ttypeof bodyOption.value.transformToByteArray === \"function\"\n\t\t) {\n\t\t\treturn readBodyBytes(bodyOption.value, key).pipe(\n\t\t\t\tEffect.map((bytes) => Stream.fromIterable([bytes])),\n\t\t\t);\n\t\t}\n\t}\n\n\treturn Effect.die(new Error(`Expected streamable body for ${key}`));\n};\n\nconst minimumMultipartPartSize = 5 * 1024 * 1024;\n\nconst combineChunks = (chunks: readonly Uint8Array[], totalLength: number): Uint8Array => {\n\tconst combined = new Uint8Array(totalLength);\n\tlet offset = 0;\n\n\tfor (const chunk of chunks) {\n\t\tcombined.set(chunk, offset);\n\t\toffset += chunk.length;\n\t}\n\n\treturn combined;\n};\n\nexport const makeS3KV = (bucket: string): Effect.Effect<KV, never, S3Service> =>\n\tEffect.gen(function* () {\n\t\tconst s3 = yield* S3;\n\n\t\treturn {\n\t\t\tget: (key) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.get(${key})`);\n\n\t\t\t\t\tconst response = yield* Effect.either(\n\t\t\t\t\t\ts3.getObject({ Bucket: bucket, Key: key }),\n\t\t\t\t\t);\n\t\t\t\t\tif (response._tag === \"Left\") {\n\t\t\t\t\t\tif (isMissingObjectError(response.left)) {\n\t\t\t\t\t\t\tyield* Effect.logDebug(`s3KV.get(${key}) => None`);\n\t\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn yield* Effect.die(\n\t\t\t\t\t\t\tresponse.left instanceof Error\n\t\t\t\t\t\t\t\t? response.left\n\t\t\t\t\t\t\t\t: new Error(`Failed to read ${key}: ${String(response.left)}`),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { etag } = yield* getEtag(response.right, key);\n\t\t\t\t\tconst value = yield* readBodyBytes(response.right.Body, key);\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.get(${key}) => Some(${etag})`);\n\t\t\t\t\treturn Option.some({ etag, value });\n\t\t\t\t}),\n\t\t\tgetIfChanged: (key, etag) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.getIfChanged(${key}, ${etag})`);\n\n\t\t\t\t\tconst response = yield* Effect.either(\n\t\t\t\t\t\ts3.getObject({ Bucket: bucket, IfNoneMatch: etag, Key: key }),\n\t\t\t\t\t);\n\t\t\t\t\tif (response._tag === \"Left\") {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tisMissingObjectError(response.left) ||\n\t\t\t\t\t\t\tisNotModifiedError(response.left)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tyield* Effect.logDebug(`s3KV.getIfChanged(${key}) => None`);\n\t\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn yield* Effect.die(\n\t\t\t\t\t\t\tresponse.left instanceof Error\n\t\t\t\t\t\t\t\t? response.left\n\t\t\t\t\t\t\t\t: new Error(`Failed to read ${key}: ${String(response.left)}`),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { etag: currentEtag } = yield* getEtag(response.right, key);\n\t\t\t\t\tconst value = yield* readBodyBytes(response.right.Body, key);\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.getIfChanged(${key}) => Some(${currentEtag})`);\n\t\t\t\t\treturn Option.some({ etag: currentEtag, value });\n\t\t\t\t}),\n\t\t\texists: (key) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.exists(${key})`);\n\n\t\t\t\t\tconst response = yield* Effect.either(\n\t\t\t\t\t\ts3.headObject({ Bucket: bucket, Key: key }),\n\t\t\t\t\t);\n\t\t\t\t\tif (response._tag === \"Left\") {\n\t\t\t\t\t\tif (isMissingObjectError(response.left)) {\n\t\t\t\t\t\t\tyield* Effect.logDebug(`s3KV.exists(${key}) => false`);\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn yield* Effect.die(\n\t\t\t\t\t\t\tresponse.left instanceof Error\n\t\t\t\t\t\t\t\t? response.left\n\t\t\t\t\t\t\t\t: new Error(`Failed to stat ${key}: ${String(response.left)}`),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.exists(${key}) => true`);\n\t\t\t\t\treturn true;\n\t\t\t\t}),\n\t\t\tset: (key, value) =>\n\t\t\t\tEffect.logDebug(`s3KV.set(${key}, ${value.length} bytes)`).pipe(\n\t\t\t\t\tEffect.flatMap(() => s3.putObject({ Body: value, Bucket: bucket, Key: key })),\n\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t: new Error(`Failed to write ${key}: ${String(error)}`),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.flatMap((result) => getEtag(result, key)),\n\t\t\t\t\tEffect.tap((result) => Effect.logDebug(`s3KV.set(${key}) => ${result.etag}`)),\n\t\t\t\t),\n\t\t\tcas: (key, value, etag) =>\n\t\t\t\tEffect.logDebug(`s3KV.cas(${key}, ${value.length} bytes, ${etag})`).pipe(\n\t\t\t\t\tEffect.flatMap(() =>\n\t\t\t\t\t\ts3.putObject({ Body: value, Bucket: bucket, IfMatch: etag, Key: key }),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.catchAll((error) => {\n\t\t\t\t\t\tconst currentError =\n\t\t\t\t\t\t\ttypeof error === \"object\" && Option.isSome(Option.fromNullable(error))\n\t\t\t\t\t\t\t\t? Option.some(\n\t\t\t\t\t\t\t\t\t\terror as {\n\t\t\t\t\t\t\t\t\t\t\tCode?: unknown;\n\t\t\t\t\t\t\t\t\t\t\tname?: unknown;\n\t\t\t\t\t\t\t\t\t\t\t$metadata?: unknown;\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t: Option.none<{\n\t\t\t\t\t\t\t\t\t\tCode?: unknown;\n\t\t\t\t\t\t\t\t\t\tname?: unknown;\n\t\t\t\t\t\t\t\t\t\t$metadata?: unknown;\n\t\t\t\t\t\t\t\t\t}>();\n\t\t\t\t\t\tconst metadata =\n\t\t\t\t\t\t\tOption.isSome(currentError) &&\n\t\t\t\t\t\t\ttypeof currentError.value.$metadata === \"object\" &&\n\t\t\t\t\t\t\tOption.isSome(Option.fromNullable(currentError.value.$metadata))\n\t\t\t\t\t\t\t\t? Option.some(\n\t\t\t\t\t\t\t\t\t\tcurrentError.value.$metadata as { httpStatusCode?: number },\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t: Option.none<{ httpStatusCode?: number }>();\n\n\t\t\t\t\t\treturn Option.isSome(currentError) &&\n\t\t\t\t\t\t\t((typeof currentError.value.Code === \"string\" &&\n\t\t\t\t\t\t\t\tcurrentError.value.Code === \"PreconditionFailed\") ||\n\t\t\t\t\t\t\t\t(typeof currentError.value.name === \"string\" &&\n\t\t\t\t\t\t\t\t\tcurrentError.value.name === \"PreconditionFailed\")) &&\n\t\t\t\t\t\t\tOption.exists(\n\t\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t\t\t(currentMetadata) => currentMetadata.httpStatusCode === 412,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t? Effect.fail(new ConflictError({ key }))\n\t\t\t\t\t\t\t: Effect.die(\n\t\t\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t\t: new Error(`Failed to write ${key}: ${String(error)}`),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t}),\n\t\t\t\t\tEffect.flatMap((result) => getEtag(result, key)),\n\t\t\t\t\tEffect.tap((result) => Effect.logDebug(`s3KV.cas(${key}) => ${result.etag}`)),\n\t\t\t\t),\n\t\t\tdelete: (key) =>\n\t\t\t\tEffect.logDebug(`s3KV.delete(${key})`).pipe(\n\t\t\t\t\tEffect.flatMap(() => s3.deleteObject({ Bucket: bucket, Key: key })),\n\t\t\t\t\tEffect.asVoid,\n\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t: new Error(`Failed to delete ${key}: ${String(error)}`),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.tap(() => Effect.logDebug(`s3KV.delete(${key}) => void`)),\n\t\t\t\t),\n\t\t\treadStream: (key) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.readStream(${key})`);\n\n\t\t\t\t\tconst response = yield* Effect.either(\n\t\t\t\t\t\ts3.getObject({ Bucket: bucket, Key: key }),\n\t\t\t\t\t);\n\t\t\t\t\tif (response._tag === \"Left\") {\n\t\t\t\t\t\tif (isMissingObjectError(response.left)) {\n\t\t\t\t\t\t\tyield* Effect.logDebug(`s3KV.readStream(${key}) => None`);\n\t\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn yield* Effect.die(\n\t\t\t\t\t\t\tresponse.left instanceof Error\n\t\t\t\t\t\t\t\t? response.left\n\t\t\t\t\t\t\t\t: new Error(`Failed to stream ${key}: ${String(response.left)}`),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst stream = yield* readBodyStream(response.right.Body, key);\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.readStream(${key}) => Some(stream)`);\n\t\t\t\t\treturn Option.some(stream);\n\t\t\t\t}),\n\t\t\twriteStream: (key, content) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.writeStream(${key}, stream)`);\n\n\t\t\t\t\tconst multipartUpload = yield* s3\n\t\t\t\t\t\t.createMultipartUpload({ Bucket: bucket, Key: key })\n\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t: new Error(`Failed to start upload ${key}: ${String(error)}`),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\tconst uploadIdOption = Option.fromNullable(multipartUpload.UploadId);\n\t\t\t\t\tif (Option.isNone(uploadIdOption)) {\n\t\t\t\t\t\treturn yield* Effect.die(new Error(`Expected UploadId for ${key}`));\n\t\t\t\t\t}\n\n\t\t\t\t\tconst uploadId = uploadIdOption.value;\n\t\t\t\t\tconst uploadParts = Effect.scoped(\n\t\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\t\tconst pull = yield* Stream.toPull(content);\n\t\t\t\t\t\t\tconst completedParts: { ETag: string; PartNumber: number }[] = [];\n\t\t\t\t\t\t\tlet bufferedChunks: Uint8Array[] = [];\n\t\t\t\t\t\t\tlet bufferedLength = 0;\n\t\t\t\t\t\t\tlet partNumber = 1;\n\n\t\t\t\t\t\t\tconst uploadBufferedPart = (force: boolean): Effect.Effect<void> => {\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\tbufferedLength === 0 ||\n\t\t\t\t\t\t\t\t\t(!force && bufferedLength < minimumMultipartPartSize)\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\treturn Effect.void;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst body = combineChunks(bufferedChunks, bufferedLength);\n\t\t\t\t\t\t\t\tbufferedChunks = [];\n\t\t\t\t\t\t\t\tbufferedLength = 0;\n\n\t\t\t\t\t\t\t\treturn s3\n\t\t\t\t\t\t\t\t\t.uploadPart({\n\t\t\t\t\t\t\t\t\t\tBody: body,\n\t\t\t\t\t\t\t\t\t\tBucket: bucket,\n\t\t\t\t\t\t\t\t\t\tContentLength: body.length,\n\t\t\t\t\t\t\t\t\t\tKey: key,\n\t\t\t\t\t\t\t\t\t\tPartNumber: partNumber,\n\t\t\t\t\t\t\t\t\t\tUploadId: uploadId,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t`Failed to upload ${key} part ${partNumber}: ${String(error)}`,\n\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\tEffect.flatMap((result) =>\n\t\t\t\t\t\t\t\t\t\t\tOption.fromNullable(result.ETag).pipe(\n\t\t\t\t\t\t\t\t\t\t\t\tOption.match({\n\t\t\t\t\t\t\t\t\t\t\t\t\tonNone: () =>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tEffect.die(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t`Expected ETag for ${key} part ${partNumber}`,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\tonSome: (etag) =>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tEffect.sync(() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcompletedParts.push({\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tETag: etag,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tPartNumber: partNumber,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tpartNumber += 1;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\twhile (true) {\n\t\t\t\t\t\t\t\tconst nextChunk = yield* Effect.either(pull);\n\n\t\t\t\t\t\t\t\tif (nextChunk._tag === \"Left\") {\n\t\t\t\t\t\t\t\t\treturn yield* uploadBufferedPart(true).pipe(\n\t\t\t\t\t\t\t\t\t\tEffect.as(completedParts),\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tfor (const chunk of Chunk.toReadonlyArray(nextChunk.right)) {\n\t\t\t\t\t\t\t\t\tbufferedChunks.push(chunk);\n\t\t\t\t\t\t\t\t\tbufferedLength += chunk.length;\n\t\t\t\t\t\t\t\t\tif (bufferedLength >= minimumMultipartPartSize) {\n\t\t\t\t\t\t\t\t\t\tyield* uploadBufferedPart(false);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}),\n\t\t\t\t\t).pipe(\n\t\t\t\t\t\tEffect.catchAllCause((cause) =>\n\t\t\t\t\t\t\ts3\n\t\t\t\t\t\t\t\t.abortMultipartUpload({\n\t\t\t\t\t\t\t\t\tBucket: bucket,\n\t\t\t\t\t\t\t\t\tKey: key,\n\t\t\t\t\t\t\t\t\tUploadId: uploadId,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\t\t\tEffect.orDie,\n\t\t\t\t\t\t\t\t\tEffect.catchAll(() => Effect.void),\n\t\t\t\t\t\t\t\t\tEffect.zipRight(Effect.failCause(cause)),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\n\t\t\t\t\tconst completedParts = yield* uploadParts;\n\n\t\t\t\t\tif (completedParts.length === 0) {\n\t\t\t\t\t\tconst emptyResult = yield* s3\n\t\t\t\t\t\t\t.putObject({ Body: new Uint8Array(), Bucket: bucket, Key: key })\n\t\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t\t: new Error(`Failed to upload ${key}: ${String(error)}`),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\tconst emptyEtagResult = yield* getEtag(emptyResult, key);\n\t\t\t\t\t\tyield* Effect.logDebug(\n\t\t\t\t\t\t\t`s3KV.writeStream(${key}) => ${emptyEtagResult.etag}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn emptyEtagResult;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst result = yield* s3\n\t\t\t\t\t\t.completeMultipartUpload({\n\t\t\t\t\t\t\tBucket: bucket,\n\t\t\t\t\t\t\tKey: key,\n\t\t\t\t\t\t\tMultipartUpload: { Parts: completedParts },\n\t\t\t\t\t\t\tUploadId: uploadId,\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t: new Error(`Failed to upload ${key}: ${String(error)}`),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\n\t\t\t\t\tconst finalResult = yield* getEtag(result, key);\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.writeStream(${key}) => ${finalResult.etag}`);\n\t\t\t\t\treturn finalResult;\n\t\t\t\t}),\n\t\t} satisfies KV;\n\t});"]}
1
+ {"version":3,"file":"s3KV.js","sourceRoot":"","sources":["../../../../src/kv/s3KV.ts"],"names":[],"mappings":"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","sourcesContent":["import { S3 } from \"@effect-aws/client-s3\";\nimport { Chunk, Data, Effect, Option, Stream } from \"effect\";\n\nimport { ConflictError } from \"./kv\";\nimport type { KV } from \"./kv\";\n\nexport class BucketDoesNotExistError extends Data.TaggedError(\"BucketDoesNotExistError\")<{\n\treadonly bucket: string;\n\treadonly message: string;\n}> {}\n\nconst isNotModifiedError = (error: unknown): boolean => {\n\tif (typeof error !== \"object\") {\n\t\treturn false;\n\t}\n\n\tconst errorOption = Option.fromNullable(error);\n\tif (Option.isNone(errorOption)) {\n\t\treturn false;\n\t}\n\n\tconst currentError = errorOption.value as {\n\t\tCode?: unknown;\n\t\tname?: unknown;\n\t\t$metadata?: unknown;\n\t};\n\n\tif (currentError.Code === \"NotModified\" || currentError.name === \"NotModified\") {\n\t\treturn true;\n\t}\n\n\tif (typeof currentError.$metadata !== \"object\") {\n\t\treturn false;\n\t}\n\n\tconst metadataOption = Option.fromNullable(currentError.$metadata);\n\tif (Option.isNone(metadataOption)) {\n\t\treturn false;\n\t}\n\n\treturn (metadataOption.value as { httpStatusCode?: number }).httpStatusCode === 304;\n};\n\nconst isMissingObjectError = (error: unknown): boolean => {\n\tif (typeof error !== \"object\") {\n\t\treturn false;\n\t}\n\n\tconst errorOption = Option.fromNullable(error);\n\tif (Option.isNone(errorOption)) {\n\t\treturn false;\n\t}\n\n\tconst currentError = errorOption.value as { Code?: unknown; name?: unknown };\n\treturn currentError.name === \"NoSuchKey\" || currentError.name === \"NotFound\"\n\t\t? true\n\t\t: currentError.Code === \"NoSuchKey\";\n};\n\nconst getEtag = (result: { ETag?: string }, key: string): Effect.Effect<{ etag: string }> =>\n\tOption.fromNullable(result.ETag).pipe(\n\t\tOption.match({\n\t\t\tonNone: () => Effect.die(new Error(`Expected ETag for ${key}`)),\n\t\t\tonSome: (etag) => Effect.succeed({ etag }),\n\t\t}),\n\t);\n\nconst readBodyBytes = (body: unknown, key: string): Effect.Effect<Uint8Array> => {\n\tif (body instanceof Uint8Array) {\n\t\treturn Effect.succeed(body);\n\t}\n\n\tif (typeof body === \"object\") {\n\t\tconst bodyOption = Option.fromNullable(body);\n\t\tif (\n\t\t\tOption.isSome(bodyOption) &&\n\t\t\t\"transformToByteArray\" in bodyOption.value &&\n\t\t\ttypeof bodyOption.value.transformToByteArray === \"function\"\n\t\t) {\n\t\t\tconst currentBody = bodyOption.value as {\n\t\t\t\ttransformToByteArray: () => Promise<Uint8Array>;\n\t\t\t};\n\t\t\treturn Effect.promise(() => currentBody.transformToByteArray()).pipe(Effect.orDie);\n\t\t}\n\t}\n\n\treturn Effect.die(new Error(`Expected readable body for ${key}`));\n};\n\nconst readBodyStream = (body: unknown, key: string): Effect.Effect<Stream.Stream<Uint8Array>> => {\n\tif (body instanceof Uint8Array) {\n\t\treturn Effect.succeed(Stream.fromIterable([body]));\n\t}\n\n\tif (body instanceof ReadableStream) {\n\t\treturn Effect.succeed(\n\t\t\tStream.fromReadableStream<Uint8Array, Error>(\n\t\t\t\t() => body as ReadableStream<Uint8Array>,\n\t\t\t\t() => new Error(`Failed to stream ${key}`),\n\t\t\t).pipe(Stream.orDie),\n\t\t);\n\t}\n\n\tif (typeof body === \"object\") {\n\t\tconst bodyOption = Option.fromNullable(body);\n\t\tif (\n\t\t\tOption.isSome(bodyOption) &&\n\t\t\t\"transformToWebStream\" in bodyOption.value &&\n\t\t\ttypeof bodyOption.value.transformToWebStream === \"function\"\n\t\t) {\n\t\t\tconst currentBody = bodyOption.value as {\n\t\t\t\ttransformToWebStream: () => ReadableStream<Uint8Array>;\n\t\t\t};\n\t\t\treturn Effect.succeed(\n\t\t\t\tStream.fromReadableStream<Uint8Array, Error>(\n\t\t\t\t\t() => currentBody.transformToWebStream(),\n\t\t\t\t\t() => new Error(`Failed to stream ${key}`),\n\t\t\t\t).pipe(Stream.orDie),\n\t\t\t);\n\t\t}\n\t}\n\n\tif (typeof body === \"object\") {\n\t\tconst bodyOption = Option.fromNullable(body);\n\t\tif (\n\t\t\tOption.isSome(bodyOption) &&\n\t\t\t\"transformToByteArray\" in bodyOption.value &&\n\t\t\ttypeof bodyOption.value.transformToByteArray === \"function\"\n\t\t) {\n\t\t\treturn readBodyBytes(bodyOption.value, key).pipe(\n\t\t\t\tEffect.map((bytes) => Stream.fromIterable([bytes])),\n\t\t\t);\n\t\t}\n\t}\n\n\treturn Effect.die(new Error(`Expected streamable body for ${key}`));\n};\n\nconst minimumMultipartPartSize = 5 * 1024 * 1024;\n\nconst combineChunks = (chunks: readonly Uint8Array[], totalLength: number): Uint8Array => {\n\tconst combined = new Uint8Array(totalLength);\n\tlet offset = 0;\n\n\tfor (const chunk of chunks) {\n\t\tcombined.set(chunk, offset);\n\t\toffset += chunk.length;\n\t}\n\n\treturn combined;\n};\n\nexport const makeS3KV = (bucket: string) =>\n\tEffect.gen(function* () {\n\t\tconst s3 = yield* S3;\n\n\t\tyield* s3.headBucket({ Bucket: bucket }).pipe(\n\t\t\tEffect.catchTag(\"NotFound\", () =>\n\t\t\t\tEffect.fail(\n\t\t\t\t\tnew BucketDoesNotExistError({\n\t\t\t\t\t\tbucket,\n\t\t\t\t\t\tmessage: `Bucket \"${bucket}\" does not exist`,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\n\t\treturn {\n\t\t\tget: (key) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.get(${key})`);\n\n\t\t\t\t\tconst response = yield* Effect.either(\n\t\t\t\t\t\ts3.getObject({ Bucket: bucket, Key: key }),\n\t\t\t\t\t);\n\t\t\t\t\tif (response._tag === \"Left\") {\n\t\t\t\t\t\tif (isMissingObjectError(response.left)) {\n\t\t\t\t\t\t\tyield* Effect.logDebug(`s3KV.get(${key}) => None`);\n\t\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn yield* Effect.die(\n\t\t\t\t\t\t\tresponse.left instanceof Error\n\t\t\t\t\t\t\t\t? response.left\n\t\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t\t`Failed to read ${key}: ${typeof response.left === \"object\" ? JSON.stringify(response.left) : String(response.left)}`,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { etag } = yield* getEtag(response.right, key);\n\t\t\t\t\tconst value = yield* readBodyBytes(response.right.Body, key);\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.get(${key}) => Some(${etag})`);\n\t\t\t\t\treturn Option.some({ etag, value });\n\t\t\t\t}),\n\t\t\tgetIfChanged: (key, etag) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.getIfChanged(${key}, ${etag})`);\n\n\t\t\t\t\tconst response = yield* Effect.either(\n\t\t\t\t\t\ts3.getObject({ Bucket: bucket, IfNoneMatch: etag, Key: key }),\n\t\t\t\t\t);\n\t\t\t\t\tif (response._tag === \"Left\") {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tisMissingObjectError(response.left) ||\n\t\t\t\t\t\t\tisNotModifiedError(response.left)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tyield* Effect.logDebug(`s3KV.getIfChanged(${key}) => None`);\n\t\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn yield* Effect.die(\n\t\t\t\t\t\t\tresponse.left instanceof Error\n\t\t\t\t\t\t\t\t? response.left\n\t\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t\t`Failed to read ${key}: ${typeof response.left === \"object\" ? JSON.stringify(response.left) : String(response.left)}`,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { etag: currentEtag } = yield* getEtag(response.right, key);\n\t\t\t\t\tconst value = yield* readBodyBytes(response.right.Body, key);\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.getIfChanged(${key}) => Some(${currentEtag})`);\n\t\t\t\t\treturn Option.some({ etag: currentEtag, value });\n\t\t\t\t}),\n\t\t\texists: (key) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.exists(${key})`);\n\n\t\t\t\t\tconst response = yield* Effect.either(\n\t\t\t\t\t\ts3.headObject({ Bucket: bucket, Key: key }),\n\t\t\t\t\t);\n\t\t\t\t\tif (response._tag === \"Left\") {\n\t\t\t\t\t\tif (isMissingObjectError(response.left)) {\n\t\t\t\t\t\t\tyield* Effect.logDebug(`s3KV.exists(${key}) => false`);\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn yield* Effect.die(\n\t\t\t\t\t\t\tresponse.left instanceof Error\n\t\t\t\t\t\t\t\t? response.left\n\t\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t\t`Failed to stat ${key}: ${typeof response.left === \"object\" ? JSON.stringify(response.left) : String(response.left)}`,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.exists(${key}) => true`);\n\t\t\t\t\treturn true;\n\t\t\t\t}),\n\t\t\tset: (key, value) =>\n\t\t\t\tEffect.logDebug(`s3KV.set(${key}, ${value.length} bytes)`).pipe(\n\t\t\t\t\tEffect.flatMap(() => s3.putObject({ Body: value, Bucket: bucket, Key: key })),\n\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t`Failed to write ${key}: ${typeof error === \"object\" ? JSON.stringify(error) : String(error)}`,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.flatMap((result) => getEtag(result, key)),\n\t\t\t\t\tEffect.tap((result) => Effect.logDebug(`s3KV.set(${key}) => ${result.etag}`)),\n\t\t\t\t),\n\t\t\tcas: (key, value, etag) =>\n\t\t\t\tEffect.logDebug(`s3KV.cas(${key}, ${value.length} bytes, ${etag})`).pipe(\n\t\t\t\t\tEffect.flatMap(() =>\n\t\t\t\t\t\ts3.putObject({ Body: value, Bucket: bucket, IfMatch: etag, Key: key }),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.catchAll((error) => {\n\t\t\t\t\t\tconst currentError =\n\t\t\t\t\t\t\ttypeof error === \"object\" && Option.isSome(Option.fromNullable(error))\n\t\t\t\t\t\t\t\t? Option.some(\n\t\t\t\t\t\t\t\t\t\terror as {\n\t\t\t\t\t\t\t\t\t\t\tCode?: unknown;\n\t\t\t\t\t\t\t\t\t\t\tname?: unknown;\n\t\t\t\t\t\t\t\t\t\t\t$metadata?: unknown;\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t: Option.none<{\n\t\t\t\t\t\t\t\t\t\tCode?: unknown;\n\t\t\t\t\t\t\t\t\t\tname?: unknown;\n\t\t\t\t\t\t\t\t\t\t$metadata?: unknown;\n\t\t\t\t\t\t\t\t\t}>();\n\t\t\t\t\t\tconst metadata =\n\t\t\t\t\t\t\tOption.isSome(currentError) &&\n\t\t\t\t\t\t\ttypeof currentError.value.$metadata === \"object\" &&\n\t\t\t\t\t\t\tOption.isSome(Option.fromNullable(currentError.value.$metadata))\n\t\t\t\t\t\t\t\t? Option.some(\n\t\t\t\t\t\t\t\t\t\tcurrentError.value.$metadata as { httpStatusCode?: number },\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t: Option.none<{ httpStatusCode?: number }>();\n\n\t\t\t\t\t\treturn Option.isSome(currentError) &&\n\t\t\t\t\t\t\t((typeof currentError.value.Code === \"string\" &&\n\t\t\t\t\t\t\t\tcurrentError.value.Code === \"PreconditionFailed\") ||\n\t\t\t\t\t\t\t\t(typeof currentError.value.name === \"string\" &&\n\t\t\t\t\t\t\t\t\tcurrentError.value.name === \"PreconditionFailed\")) &&\n\t\t\t\t\t\t\tOption.exists(\n\t\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t\t\t(currentMetadata) => currentMetadata.httpStatusCode === 412,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t? Effect.fail(new ConflictError({ key }))\n\t\t\t\t\t\t\t: Effect.die(\n\t\t\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t\t\t\t`Failed to write ${key}: ${typeof error === \"object\" ? JSON.stringify(error) : String(error)}`,\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t}),\n\t\t\t\t\tEffect.flatMap((result) => getEtag(result, key)),\n\t\t\t\t\tEffect.tap((result) => Effect.logDebug(`s3KV.cas(${key}) => ${result.etag}`)),\n\t\t\t\t),\n\t\t\tdelete: (key) =>\n\t\t\t\tEffect.logDebug(`s3KV.delete(${key})`).pipe(\n\t\t\t\t\tEffect.flatMap(() => s3.deleteObject({ Bucket: bucket, Key: key })),\n\t\t\t\t\tEffect.asVoid,\n\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t`Failed to delete ${key}: ${typeof error === \"object\" ? JSON.stringify(error) : String(error)}`,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.tap(() => Effect.logDebug(`s3KV.delete(${key}) => void`)),\n\t\t\t\t),\n\t\t\treadStream: (key) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.readStream(${key})`);\n\n\t\t\t\t\tconst response = yield* Effect.either(\n\t\t\t\t\t\ts3.getObject({ Bucket: bucket, Key: key }),\n\t\t\t\t\t);\n\t\t\t\t\tif (response._tag === \"Left\") {\n\t\t\t\t\t\tif (isMissingObjectError(response.left)) {\n\t\t\t\t\t\t\tyield* Effect.logDebug(`s3KV.readStream(${key}) => None`);\n\t\t\t\t\t\t\treturn Option.none();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn yield* Effect.die(\n\t\t\t\t\t\t\tresponse.left instanceof Error\n\t\t\t\t\t\t\t\t? response.left\n\t\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t\t`Failed to stream ${key}: ${typeof response.left === \"object\" ? JSON.stringify(response.left) : String(response.left)}`,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst stream = yield* readBodyStream(response.right.Body, key);\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.readStream(${key}) => Some(stream)`);\n\t\t\t\t\treturn Option.some(stream);\n\t\t\t\t}),\n\t\t\twriteStream: (key, content) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.writeStream(${key}, stream)`);\n\n\t\t\t\t\tconst multipartUpload = yield* s3\n\t\t\t\t\t\t.createMultipartUpload({ Bucket: bucket, Key: key })\n\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t\t\t`Failed to start upload ${key}: ${typeof error === \"object\" ? JSON.stringify(error) : String(error)}`,\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\tconst uploadIdOption = Option.fromNullable(multipartUpload.UploadId);\n\t\t\t\t\tif (Option.isNone(uploadIdOption)) {\n\t\t\t\t\t\treturn yield* Effect.die(new Error(`Expected UploadId for ${key}`));\n\t\t\t\t\t}\n\n\t\t\t\t\tconst uploadId = uploadIdOption.value;\n\t\t\t\t\tconst uploadParts = Effect.scoped(\n\t\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\t\tconst pull = yield* Stream.toPull(content);\n\t\t\t\t\t\t\tconst completedParts: { ETag: string; PartNumber: number }[] = [];\n\t\t\t\t\t\t\tlet bufferedChunks: Uint8Array[] = [];\n\t\t\t\t\t\t\tlet bufferedLength = 0;\n\t\t\t\t\t\t\tlet partNumber = 1;\n\n\t\t\t\t\t\t\tconst uploadBufferedPart = (force: boolean): Effect.Effect<void> => {\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\tbufferedLength === 0 ||\n\t\t\t\t\t\t\t\t\t(!force && bufferedLength < minimumMultipartPartSize)\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\treturn Effect.void;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst body = combineChunks(bufferedChunks, bufferedLength);\n\t\t\t\t\t\t\t\tbufferedChunks = [];\n\t\t\t\t\t\t\t\tbufferedLength = 0;\n\n\t\t\t\t\t\t\t\treturn s3\n\t\t\t\t\t\t\t\t\t.uploadPart({\n\t\t\t\t\t\t\t\t\t\tBody: body,\n\t\t\t\t\t\t\t\t\t\tBucket: bucket,\n\t\t\t\t\t\t\t\t\t\tContentLength: body.length,\n\t\t\t\t\t\t\t\t\t\tKey: key,\n\t\t\t\t\t\t\t\t\t\tPartNumber: partNumber,\n\t\t\t\t\t\t\t\t\t\tUploadId: uploadId,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t`Failed to upload part ${String(partNumber)} for ${key}: ${typeof error === \"object\" ? JSON.stringify(error) : String(error)}`,\n\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\tEffect.flatMap((result) =>\n\t\t\t\t\t\t\t\t\t\t\tOption.fromNullable(result.ETag).pipe(\n\t\t\t\t\t\t\t\t\t\t\t\tOption.match({\n\t\t\t\t\t\t\t\t\t\t\t\t\tonNone: () =>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tEffect.die(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t`Expected ETag for ${key} part ${partNumber}`,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\tonSome: (etag) =>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tEffect.sync(() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcompletedParts.push({\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tETag: etag,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tPartNumber: partNumber,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tpartNumber += 1;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\twhile (true) {\n\t\t\t\t\t\t\t\tconst nextChunk = yield* Effect.either(pull);\n\n\t\t\t\t\t\t\t\tif (nextChunk._tag === \"Left\") {\n\t\t\t\t\t\t\t\t\treturn yield* uploadBufferedPart(true).pipe(\n\t\t\t\t\t\t\t\t\t\tEffect.as(completedParts),\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tfor (const chunk of Chunk.toReadonlyArray(nextChunk.right)) {\n\t\t\t\t\t\t\t\t\tbufferedChunks.push(chunk);\n\t\t\t\t\t\t\t\t\tbufferedLength += chunk.length;\n\t\t\t\t\t\t\t\t\tif (bufferedLength >= minimumMultipartPartSize) {\n\t\t\t\t\t\t\t\t\t\tyield* uploadBufferedPart(false);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}),\n\t\t\t\t\t).pipe(\n\t\t\t\t\t\tEffect.catchAllCause((cause) =>\n\t\t\t\t\t\t\ts3\n\t\t\t\t\t\t\t\t.abortMultipartUpload({\n\t\t\t\t\t\t\t\t\tBucket: bucket,\n\t\t\t\t\t\t\t\t\tKey: key,\n\t\t\t\t\t\t\t\t\tUploadId: uploadId,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\t\t\tEffect.orDie,\n\t\t\t\t\t\t\t\t\tEffect.catchAll(() => Effect.void),\n\t\t\t\t\t\t\t\t\tEffect.zipRight(Effect.failCause(cause)),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\n\t\t\t\t\tconst completedParts = yield* uploadParts;\n\n\t\t\t\t\tif (completedParts.length === 0) {\n\t\t\t\t\t\tconst emptyResult = yield* s3\n\t\t\t\t\t\t\t.putObject({ Body: new Uint8Array(), Bucket: bucket, Key: key })\n\t\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t\t\t\t`Failed to upload ${key}: ${typeof error === \"object\" ? JSON.stringify(error) : String(error)}`,\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\tconst emptyEtagResult = yield* getEtag(emptyResult, key);\n\t\t\t\t\t\tyield* Effect.logDebug(\n\t\t\t\t\t\t\t`s3KV.writeStream(${key}) => ${emptyEtagResult.etag}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn emptyEtagResult;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst result = yield* s3\n\t\t\t\t\t\t.completeMultipartUpload({\n\t\t\t\t\t\t\tBucket: bucket,\n\t\t\t\t\t\t\tKey: key,\n\t\t\t\t\t\t\tMultipartUpload: { Parts: completedParts },\n\t\t\t\t\t\t\tUploadId: uploadId,\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\tEffect.orDieWith((error) =>\n\t\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\t\t\t\t`Failed to upload ${key}: ${typeof error === \"object\" ? JSON.stringify(error) : String(error)}`,\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\n\t\t\t\t\tconst finalResult = yield* getEtag(result, key);\n\t\t\t\t\tyield* Effect.logDebug(`s3KV.writeStream(${key}) => ${finalResult.etag}`);\n\t\t\t\t\treturn finalResult;\n\t\t\t\t}),\n\t\t} satisfies KV;\n\t});"]}
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@lika85456/s3qlite",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "dependencies": {
7
7
  "@effect-aws/client-s3": "^1.11.0",
8
- "@effect/platform": "0.96.0",
8
+ "@effect/platform": "^0.96.0",
9
9
  "@effect/platform-bun": "^0.89.0",
10
10
  "@effect/platform-node": "^0.106.0",
11
11
  "@tursodatabase/database": "^0.6.0",