ff-effect 0.0.8 → 0.0.10

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.
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,28 +17,57 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/for/drizzle/index.ts
21
31
  var drizzle_exports = {};
22
32
  __export(drizzle_exports, {
33
+ ChannelTypeId: () => ChannelTypeId2,
23
34
  DrizzleError: () => DrizzleError,
24
- TagTypeId: () => TagTypeId,
35
+ EffectTypeId: () => EffectTypeId,
36
+ NodeInspectSymbol: () => NodeInspectSymbol2,
37
+ STMTypeId: () => STMTypeId2,
38
+ SinkTypeId: () => SinkTypeId2,
39
+ StreamTypeId: () => StreamTypeId2,
40
+ TagTypeId: () => TagTypeId2,
41
+ Unify: () => Unify,
25
42
  createDatabase: () => createDatabase
26
43
  });
27
44
  module.exports = __toCommonJS(drizzle_exports);
28
45
  var import_effect = require("effect");
29
- var TagTypeId = import_effect.Context.TagTypeId;
46
+ var Channel = __toESM(require("effect/Channel"), 1);
47
+ var Context = __toESM(require("effect/Context"), 1);
48
+ var Inspectable = __toESM(require("effect/Inspectable"), 1);
49
+ var Sink = __toESM(require("effect/Sink"), 1);
50
+ var STM = __toESM(require("effect/STM"), 1);
51
+ var Stream = __toESM(require("effect/Stream"), 1);
52
+ var EUnify = __toESM(require("effect/Unify"), 1);
53
+ var TagTypeId2 = Context.TagTypeId;
54
+ var ChannelTypeId2 = Channel.ChannelTypeId;
55
+ var EffectTypeId = import_effect.Effect.EffectTypeId;
56
+ var NodeInspectSymbol2 = Inspectable.NodeInspectSymbol;
57
+ var STMTypeId2 = STM.STMTypeId;
58
+ var SinkTypeId2 = Sink.SinkTypeId;
59
+ var StreamTypeId2 = Stream.StreamTypeId;
60
+ var Unify = EUnify;
30
61
  var DrizzleError = class extends import_effect.Data.TaggedError("ff-effect/DrizzleError") {
31
62
  };
32
63
  var WrappedTxError = class extends Error {
33
64
  };
34
- function createDatabase(tagId, createClient) {
35
- class Drizzle extends import_effect.Context.Tag(tagId)() {
36
- }
37
- const txTag = `${tagId}.tx`;
38
- class DrizzleTx extends import_effect.Context.Tag(txTag)() {
39
- }
65
+ var defaultPrefix = "@ff-effect/Drizzle";
66
+ function createDatabase(createClient, opts) {
67
+ const tagId = opts?.tagId ?? defaultPrefix;
68
+ const Drizzle = Context.Tag(tagId)();
69
+ const drizzleTxTagId = `${tagId}.tx`;
70
+ const DrizzleTx = Context.Tag(drizzleTxTagId)();
40
71
  const db = (fn) => import_effect.Effect.gen(function* () {
41
72
  const client = yield* Drizzle;
42
73
  return yield* import_effect.Effect.tryPromise({
@@ -76,14 +107,23 @@ function createDatabase(tagId, createClient) {
76
107
  return {
77
108
  db,
78
109
  tx,
110
+ Drizzle,
111
+ DrizzleTx,
79
112
  withTransaction,
80
113
  layer: import_effect.Layer.effect(Drizzle, createClient)
81
114
  };
82
115
  }
83
116
  // Annotate the CommonJS export names for ESM import in node:
84
117
  0 && (module.exports = {
118
+ ChannelTypeId,
85
119
  DrizzleError,
120
+ EffectTypeId,
121
+ NodeInspectSymbol,
122
+ STMTypeId,
123
+ SinkTypeId,
124
+ StreamTypeId,
86
125
  TagTypeId,
126
+ Unify,
87
127
  createDatabase
88
128
  });
89
129
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/for/drizzle/index.ts"],"sourcesContent":["import { Context, Data, Effect, FiberSet, Layer } from 'effect';\n\n// TypeScript issue where the return type of createDatabase\n// contains internal Effect types (TagTypeId) that aren't exported\n// from this module,\n// so TypeScript can't \"name\" them in the declaration file.\nexport const TagTypeId = Context.TagTypeId;\n\nexport class DrizzleError extends Data.TaggedError('ff-effect/DrizzleError')<{\n\tmessage: string;\n\tcause?: unknown;\n}> {}\n\ntype AnyDrizzleClient = {\n\ttransaction: (fn: (tx: any) => Promise<any>) => Promise<any>;\n};\n\ntype TxClient<TClient extends AnyDrizzleClient> = Parameters<\n\tParameters<TClient['transaction']>[0]\n>[0];\n\nclass WrappedTxError extends Error {}\n\nexport function createDatabase<\n\tTAG extends string,\n\tTClient extends AnyDrizzleClient,\n\tE,\n\tR,\n>(tagId: TAG, createClient: Effect.Effect<TClient, E, R>) {\n\ttype Client = TClient | TxClient<TClient>;\n\ttype Tx = TxClient<TClient>;\n\n\tclass Drizzle extends Context.Tag(tagId)<Drizzle, Client>() {}\n\tconst txTag = `${tagId}.tx` as const;\n\tclass DrizzleTx extends Context.Tag(txTag)<DrizzleTx, Tx>() {}\n\n\tconst db = <T>(fn: (client: Client) => Promise<T>) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst client = yield* Drizzle;\n\t\t\treturn yield* Effect.tryPromise({\n\t\t\t\ttry: () => fn(client),\n\t\t\t\tcatch: (cause) =>\n\t\t\t\t\tnew DrizzleError({ message: 'Database operation failed', cause }),\n\t\t\t});\n\t\t});\n\n\t/** Requires being inside withTransaction - enforces transaction at compile time */\n\tconst tx = <T>(fn: (client: Tx) => Promise<T>) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst client = yield* DrizzleTx;\n\t\t\treturn yield* Effect.tryPromise({\n\t\t\t\ttry: () => fn(client),\n\t\t\t\tcatch: (cause) =>\n\t\t\t\t\tnew DrizzleError({ message: 'Database operation failed', cause }),\n\t\t\t});\n\t\t});\n\n\tconst withTransaction = <A, E, R>(effect: Effect.Effect<A, E, R>) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst client = yield* Drizzle;\n\t\t\tconst runFork =\n\t\t\t\tyield* FiberSet.makeRuntimePromise<Exclude<R, DrizzleTx>>();\n\n\t\t\treturn yield* Effect.tryPromise<A, E | DrizzleError>({\n\t\t\t\ttry: () =>\n\t\t\t\t\t(client as TClient).transaction((txClient) =>\n\t\t\t\t\t\trunFork(\n\t\t\t\t\t\t\teffect.pipe(\n\t\t\t\t\t\t\t\tEffect.provideService(Drizzle, txClient as Client),\n\t\t\t\t\t\t\t\tEffect.provideService(DrizzleTx, txClient as Tx),\n\t\t\t\t\t\t\t\tEffect.mapError((e) => new WrappedTxError('', { cause: e })),\n\t\t\t\t\t\t\t) as Effect.Effect<A, WrappedTxError, Exclude<R, DrizzleTx>>,\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\tcatch: (error) => {\n\t\t\t\t\tif (error instanceof WrappedTxError) return error.cause as E;\n\t\t\t\t\treturn new DrizzleError({\n\t\t\t\t\t\tmessage: 'Transaction failed',\n\t\t\t\t\t\tcause: error,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t});\n\t\t}).pipe(Effect.scoped);\n\n\treturn {\n\t\tdb,\n\t\ttx,\n\t\twithTransaction,\n\t\tlayer: Layer.effect(Drizzle, createClient),\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAuD;AAMhD,IAAM,YAAY,sBAAQ;AAE1B,IAAM,eAAN,cAA2B,mBAAK,YAAY,wBAAwB,EAGxE;AAAC;AAUJ,IAAM,iBAAN,cAA6B,MAAM;AAAC;AAE7B,SAAS,eAKd,OAAY,cAA4C;AAAA,EAIzD,MAAM,gBAAgB,sBAAQ,IAAI,KAAK,EAAmB,EAAE;AAAA,EAAC;AAC7D,QAAM,QAAQ,GAAG,KAAK;AAAA,EACtB,MAAM,kBAAkB,sBAAQ,IAAI,KAAK,EAAiB,EAAE;AAAA,EAAC;AAE7D,QAAM,KAAK,CAAI,OACd,qBAAO,IAAI,aAAa;AACvB,UAAM,SAAS,OAAO;AACtB,WAAO,OAAO,qBAAO,WAAW;AAAA,MAC/B,KAAK,MAAM,GAAG,MAAM;AAAA,MACpB,OAAO,CAAC,UACP,IAAI,aAAa,EAAE,SAAS,6BAA6B,MAAM,CAAC;AAAA,IAClE,CAAC;AAAA,EACF,CAAC;AAGF,QAAM,KAAK,CAAI,OACd,qBAAO,IAAI,aAAa;AACvB,UAAM,SAAS,OAAO;AACtB,WAAO,OAAO,qBAAO,WAAW;AAAA,MAC/B,KAAK,MAAM,GAAG,MAAM;AAAA,MACpB,OAAO,CAAC,UACP,IAAI,aAAa,EAAE,SAAS,6BAA6B,MAAM,CAAC;AAAA,IAClE,CAAC;AAAA,EACF,CAAC;AAEF,QAAM,kBAAkB,CAAU,WACjC,qBAAO,IAAI,aAAa;AACvB,UAAM,SAAS,OAAO;AACtB,UAAM,UACL,OAAO,uBAAS,mBAA0C;AAE3D,WAAO,OAAO,qBAAO,WAAgC;AAAA,MACpD,KAAK,MACH,OAAmB;AAAA,QAAY,CAAC,aAChC;AAAA,UACC,OAAO;AAAA,YACN,qBAAO,eAAe,SAAS,QAAkB;AAAA,YACjD,qBAAO,eAAe,WAAW,QAAc;AAAA,YAC/C,qBAAO,SAAS,CAAC,MAAM,IAAI,eAAe,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AAAA,UAC5D;AAAA,QACD;AAAA,MACD;AAAA,MACD,OAAO,CAAC,UAAU;AACjB,YAAI,iBAAiB,eAAgB,QAAO,MAAM;AAClD,eAAO,IAAI,aAAa;AAAA,UACvB,SAAS;AAAA,UACT,OAAO;AAAA,QACR,CAAC;AAAA,MACF;AAAA,IACD,CAAC;AAAA,EACF,CAAC,EAAE,KAAK,qBAAO,MAAM;AAEtB,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,oBAAM,OAAO,SAAS,YAAY;AAAA,EAC1C;AACD;","names":[]}
1
+ {"version":3,"sources":["../../../src/for/drizzle/index.ts"],"sourcesContent":["import { Data, Effect, FiberSet, Layer } from 'effect';\nimport * as Channel from 'effect/Channel';\nimport * as Context from 'effect/Context';\nimport * as Inspectable from 'effect/Inspectable';\nimport * as Sink from 'effect/Sink';\nimport * as STM from 'effect/STM';\nimport * as Stream from 'effect/Stream';\nimport * as EUnify from 'effect/Unify';\n\n// TypeScript issue where the return type of createDatabase\n// contains internal Effect types (TagTypeId) that aren't exported\n// from this module,\n// so TypeScript can't \"name\" them in the declaration file.\nexport const TagTypeId = Context.TagTypeId;\nexport const ChannelTypeId = Channel.ChannelTypeId;\nexport const EffectTypeId = Effect.EffectTypeId;\nexport const NodeInspectSymbol = Inspectable.NodeInspectSymbol;\nexport const STMTypeId = STM.STMTypeId;\nexport const SinkTypeId = Sink.SinkTypeId;\nexport const StreamTypeId = Stream.StreamTypeId;\nexport const Unify = EUnify;\n\nexport class DrizzleError extends Data.TaggedError('ff-effect/DrizzleError')<{\n\tmessage: string;\n\tcause?: unknown;\n}> {}\n\ntype AnyDrizzleClient = {\n\ttransaction: (fn: (tx: any) => Promise<any>) => Promise<any>;\n};\n\ntype TxClient<TClient extends AnyDrizzleClient> = Parameters<\n\tParameters<TClient['transaction']>[0]\n>[0];\n\nclass WrappedTxError extends Error {}\n\nconst defaultPrefix = '@ff-effect/Drizzle' as const;\n\nexport function createDatabase<\n\tTClient extends AnyDrizzleClient,\n\tE,\n\tR,\n\tT extends string = typeof defaultPrefix,\n>(createClient: Effect.Effect<TClient, E, R>, opts?: { tagId?: T }) {\n\ttype Client = TClient | TxClient<TClient>;\n\ttype Tx = TxClient<TClient>;\n\n\tconst tagId = (opts?.tagId ?? defaultPrefix) as T;\n\n\ttype Drizzle = typeof tagId;\n\tconst Drizzle = Context.Tag(tagId)<Drizzle, Client>();\n\n\tconst drizzleTxTagId = `${tagId}.tx` as const;\n\ttype DrizzleTx = typeof drizzleTxTagId;\n\tconst DrizzleTx = Context.Tag(drizzleTxTagId)<DrizzleTx, Tx>();\n\n\tconst db = <T>(fn: (client: Client) => Promise<T>) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst client = yield* Drizzle;\n\t\t\treturn yield* Effect.tryPromise({\n\t\t\t\ttry: () => fn(client),\n\t\t\t\tcatch: (cause) =>\n\t\t\t\t\tnew DrizzleError({ message: 'Database operation failed', cause }),\n\t\t\t});\n\t\t});\n\n\t/** Requires being inside withTransaction - enforces transaction at compile time */\n\tconst tx = <T>(fn: (client: Tx) => Promise<T>) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst client = yield* DrizzleTx;\n\t\t\treturn yield* Effect.tryPromise({\n\t\t\t\ttry: () => fn(client),\n\t\t\t\tcatch: (cause) =>\n\t\t\t\t\tnew DrizzleError({ message: 'Database operation failed', cause }),\n\t\t\t});\n\t\t});\n\n\tconst withTransaction = <A, E, R>(effect: Effect.Effect<A, E, R>) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst client = yield* Drizzle;\n\t\t\tconst runFork =\n\t\t\t\tyield* FiberSet.makeRuntimePromise<Exclude<R, DrizzleTx>>();\n\n\t\t\treturn yield* Effect.tryPromise<A, E | DrizzleError>({\n\t\t\t\ttry: () =>\n\t\t\t\t\t(client as TClient).transaction((txClient) =>\n\t\t\t\t\t\trunFork(\n\t\t\t\t\t\t\teffect.pipe(\n\t\t\t\t\t\t\t\tEffect.provideService(Drizzle, txClient as Client),\n\t\t\t\t\t\t\t\tEffect.provideService(DrizzleTx, txClient as Tx),\n\t\t\t\t\t\t\t\tEffect.mapError((e) => new WrappedTxError('', { cause: e })),\n\t\t\t\t\t\t\t) as Effect.Effect<A, WrappedTxError, Exclude<R, DrizzleTx>>,\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\tcatch: (error) => {\n\t\t\t\t\tif (error instanceof WrappedTxError) return error.cause as E;\n\t\t\t\t\treturn new DrizzleError({\n\t\t\t\t\t\tmessage: 'Transaction failed',\n\t\t\t\t\t\tcause: error,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t});\n\t\t}).pipe(Effect.scoped);\n\n\treturn {\n\t\tdb,\n\t\ttx,\n\t\tDrizzle,\n\t\tDrizzleTx,\n\t\twithTransaction,\n\t\tlayer: Layer.effect(Drizzle, createClient),\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA,uBAAAA;AAAA,EAAA;AAAA;AAAA,2BAAAC;AAAA,EAAA,iBAAAC;AAAA,EAAA,kBAAAC;AAAA,EAAA,oBAAAC;AAAA,EAAA,iBAAAC;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,oBAA8C;AAC9C,cAAyB;AACzB,cAAyB;AACzB,kBAA6B;AAC7B,WAAsB;AACtB,UAAqB;AACrB,aAAwB;AACxB,aAAwB;AAMjB,IAAMA,aAAoB;AAC1B,IAAML,iBAAwB;AAC9B,IAAM,eAAe,qBAAO;AAC5B,IAAMC,qBAAgC;AACtC,IAAMC,aAAgB;AACtB,IAAMC,cAAkB;AACxB,IAAMC,gBAAsB;AAC5B,IAAM,QAAQ;AAEd,IAAM,eAAN,cAA2B,mBAAK,YAAY,wBAAwB,EAGxE;AAAC;AAUJ,IAAM,iBAAN,cAA6B,MAAM;AAAC;AAEpC,IAAM,gBAAgB;AAEf,SAAS,eAKd,cAA4C,MAAsB;AAInE,QAAM,QAAS,MAAM,SAAS;AAG9B,QAAM,UAAkB,YAAI,KAAK,EAAmB;AAEpD,QAAM,iBAAiB,GAAG,KAAK;AAE/B,QAAM,YAAoB,YAAI,cAAc,EAAiB;AAE7D,QAAM,KAAK,CAAI,OACd,qBAAO,IAAI,aAAa;AACvB,UAAM,SAAS,OAAO;AACtB,WAAO,OAAO,qBAAO,WAAW;AAAA,MAC/B,KAAK,MAAM,GAAG,MAAM;AAAA,MACpB,OAAO,CAAC,UACP,IAAI,aAAa,EAAE,SAAS,6BAA6B,MAAM,CAAC;AAAA,IAClE,CAAC;AAAA,EACF,CAAC;AAGF,QAAM,KAAK,CAAI,OACd,qBAAO,IAAI,aAAa;AACvB,UAAM,SAAS,OAAO;AACtB,WAAO,OAAO,qBAAO,WAAW;AAAA,MAC/B,KAAK,MAAM,GAAG,MAAM;AAAA,MACpB,OAAO,CAAC,UACP,IAAI,aAAa,EAAE,SAAS,6BAA6B,MAAM,CAAC;AAAA,IAClE,CAAC;AAAA,EACF,CAAC;AAEF,QAAM,kBAAkB,CAAU,WACjC,qBAAO,IAAI,aAAa;AACvB,UAAM,SAAS,OAAO;AACtB,UAAM,UACL,OAAO,uBAAS,mBAA0C;AAE3D,WAAO,OAAO,qBAAO,WAAgC;AAAA,MACpD,KAAK,MACH,OAAmB;AAAA,QAAY,CAAC,aAChC;AAAA,UACC,OAAO;AAAA,YACN,qBAAO,eAAe,SAAS,QAAkB;AAAA,YACjD,qBAAO,eAAe,WAAW,QAAc;AAAA,YAC/C,qBAAO,SAAS,CAAC,MAAM,IAAI,eAAe,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AAAA,UAC5D;AAAA,QACD;AAAA,MACD;AAAA,MACD,OAAO,CAAC,UAAU;AACjB,YAAI,iBAAiB,eAAgB,QAAO,MAAM;AAClD,eAAO,IAAI,aAAa;AAAA,UACvB,SAAS;AAAA,UACT,OAAO;AAAA,QACR,CAAC;AAAA,MACF;AAAA,IACD,CAAC;AAAA,EACF,CAAC,EAAE,KAAK,qBAAO,MAAM;AAEtB,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,oBAAM,OAAO,SAAS,YAAY;AAAA,EAC1C;AACD;","names":["ChannelTypeId","NodeInspectSymbol","STMTypeId","SinkTypeId","StreamTypeId","TagTypeId"]}
@@ -1,9 +1,18 @@
1
1
  import * as effect_Scope from 'effect/Scope';
2
2
  import * as effect_Cause from 'effect/Cause';
3
3
  import * as effect_Types from 'effect/Types';
4
- import { Effect, Context, Layer } from 'effect';
4
+ import { Effect, Layer } from 'effect';
5
+ import * as Context from 'effect/Context';
6
+ import * as EUnify from 'effect/Unify';
5
7
 
6
8
  declare const TagTypeId: symbol;
9
+ declare const ChannelTypeId: symbol;
10
+ declare const EffectTypeId: symbol;
11
+ declare const NodeInspectSymbol: symbol;
12
+ declare const STMTypeId: symbol;
13
+ declare const SinkTypeId: symbol;
14
+ declare const StreamTypeId: symbol;
15
+ declare const Unify: typeof EUnify;
7
16
  declare const DrizzleError_base: new <A extends Record<string, any> = {}>(args: effect_Types.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => effect_Cause.YieldableError & {
8
17
  readonly _tag: "ff-effect/DrizzleError";
9
18
  } & Readonly<A>;
@@ -16,31 +25,16 @@ type AnyDrizzleClient = {
16
25
  transaction: (fn: (tx: any) => Promise<any>) => Promise<any>;
17
26
  };
18
27
  type TxClient<TClient extends AnyDrizzleClient> = Parameters<Parameters<TClient['transaction']>[0]>[0];
19
- declare function createDatabase<TAG extends string, TClient extends AnyDrizzleClient, E, R>(tagId: TAG, createClient: Effect.Effect<TClient, E, R>): {
20
- db: <T>(fn: (client: TClient | TxClient<TClient>) => Promise<T>) => Effect.Effect<T, DrizzleError, {
21
- readonly Id: TAG;
22
- readonly Type: TClient | TxClient<TClient>;
23
- readonly [TagTypeId]: Context.TagTypeId;
24
- }>;
25
- tx: <T>(fn: (client: TxClient<TClient>) => Promise<T>) => Effect.Effect<T, DrizzleError, {
26
- readonly Id: `${TAG}.tx`;
27
- readonly Type: TxClient<TClient>;
28
- readonly [TagTypeId]: Context.TagTypeId;
29
- }>;
30
- withTransaction: <A, E_1, R_1>(effect: Effect.Effect<A, E_1, R_1>) => Effect.Effect<A, DrizzleError | E_1, {
31
- readonly Id: TAG;
32
- readonly Type: TClient | TxClient<TClient>;
33
- readonly [TagTypeId]: Context.TagTypeId;
34
- } | Exclude<Exclude<R_1, {
35
- readonly Id: `${TAG}.tx`;
36
- readonly Type: TxClient<TClient>;
37
- readonly [TagTypeId]: Context.TagTypeId;
38
- }>, effect_Scope.Scope>>;
39
- layer: Layer.Layer<{
40
- readonly Id: TAG;
41
- readonly Type: TClient | TxClient<TClient>;
42
- readonly [TagTypeId]: Context.TagTypeId;
43
- }, E, R>;
28
+ declare const defaultPrefix: "@ff-effect/Drizzle";
29
+ declare function createDatabase<TClient extends AnyDrizzleClient, E, R, T extends string = typeof defaultPrefix>(createClient: Effect.Effect<TClient, E, R>, opts?: {
30
+ tagId?: T;
31
+ }): {
32
+ db: <T_1>(fn: (client: TClient | TxClient<TClient>) => Promise<T_1>) => Effect.Effect<T_1, DrizzleError, T>;
33
+ tx: <T_1>(fn: (client: TxClient<TClient>) => Promise<T_1>) => Effect.Effect<T_1, DrizzleError, `${T}.tx`>;
34
+ Drizzle: Context.TagClass<T, T, TClient | TxClient<TClient>>;
35
+ DrizzleTx: Context.TagClass<`${T}.tx`, `${T}.tx`, TxClient<TClient>>;
36
+ withTransaction: <A, E_1, R_1>(effect: Effect.Effect<A, E_1, R_1>) => Effect.Effect<A, DrizzleError | E_1, Exclude<T, effect_Scope.Scope> | Exclude<Exclude<R_1, `${T}.tx`>, effect_Scope.Scope>>;
37
+ layer: Layer.Layer<T, E, R>;
44
38
  };
45
39
 
46
- export { DrizzleError, TagTypeId, createDatabase };
40
+ export { ChannelTypeId, DrizzleError, EffectTypeId, NodeInspectSymbol, STMTypeId, SinkTypeId, StreamTypeId, TagTypeId, Unify, createDatabase };
@@ -1,9 +1,18 @@
1
1
  import * as effect_Scope from 'effect/Scope';
2
2
  import * as effect_Cause from 'effect/Cause';
3
3
  import * as effect_Types from 'effect/Types';
4
- import { Effect, Context, Layer } from 'effect';
4
+ import { Effect, Layer } from 'effect';
5
+ import * as Context from 'effect/Context';
6
+ import * as EUnify from 'effect/Unify';
5
7
 
6
8
  declare const TagTypeId: symbol;
9
+ declare const ChannelTypeId: symbol;
10
+ declare const EffectTypeId: symbol;
11
+ declare const NodeInspectSymbol: symbol;
12
+ declare const STMTypeId: symbol;
13
+ declare const SinkTypeId: symbol;
14
+ declare const StreamTypeId: symbol;
15
+ declare const Unify: typeof EUnify;
7
16
  declare const DrizzleError_base: new <A extends Record<string, any> = {}>(args: effect_Types.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => effect_Cause.YieldableError & {
8
17
  readonly _tag: "ff-effect/DrizzleError";
9
18
  } & Readonly<A>;
@@ -16,31 +25,16 @@ type AnyDrizzleClient = {
16
25
  transaction: (fn: (tx: any) => Promise<any>) => Promise<any>;
17
26
  };
18
27
  type TxClient<TClient extends AnyDrizzleClient> = Parameters<Parameters<TClient['transaction']>[0]>[0];
19
- declare function createDatabase<TAG extends string, TClient extends AnyDrizzleClient, E, R>(tagId: TAG, createClient: Effect.Effect<TClient, E, R>): {
20
- db: <T>(fn: (client: TClient | TxClient<TClient>) => Promise<T>) => Effect.Effect<T, DrizzleError, {
21
- readonly Id: TAG;
22
- readonly Type: TClient | TxClient<TClient>;
23
- readonly [TagTypeId]: Context.TagTypeId;
24
- }>;
25
- tx: <T>(fn: (client: TxClient<TClient>) => Promise<T>) => Effect.Effect<T, DrizzleError, {
26
- readonly Id: `${TAG}.tx`;
27
- readonly Type: TxClient<TClient>;
28
- readonly [TagTypeId]: Context.TagTypeId;
29
- }>;
30
- withTransaction: <A, E_1, R_1>(effect: Effect.Effect<A, E_1, R_1>) => Effect.Effect<A, DrizzleError | E_1, {
31
- readonly Id: TAG;
32
- readonly Type: TClient | TxClient<TClient>;
33
- readonly [TagTypeId]: Context.TagTypeId;
34
- } | Exclude<Exclude<R_1, {
35
- readonly Id: `${TAG}.tx`;
36
- readonly Type: TxClient<TClient>;
37
- readonly [TagTypeId]: Context.TagTypeId;
38
- }>, effect_Scope.Scope>>;
39
- layer: Layer.Layer<{
40
- readonly Id: TAG;
41
- readonly Type: TClient | TxClient<TClient>;
42
- readonly [TagTypeId]: Context.TagTypeId;
43
- }, E, R>;
28
+ declare const defaultPrefix: "@ff-effect/Drizzle";
29
+ declare function createDatabase<TClient extends AnyDrizzleClient, E, R, T extends string = typeof defaultPrefix>(createClient: Effect.Effect<TClient, E, R>, opts?: {
30
+ tagId?: T;
31
+ }): {
32
+ db: <T_1>(fn: (client: TClient | TxClient<TClient>) => Promise<T_1>) => Effect.Effect<T_1, DrizzleError, T>;
33
+ tx: <T_1>(fn: (client: TxClient<TClient>) => Promise<T_1>) => Effect.Effect<T_1, DrizzleError, `${T}.tx`>;
34
+ Drizzle: Context.TagClass<T, T, TClient | TxClient<TClient>>;
35
+ DrizzleTx: Context.TagClass<`${T}.tx`, `${T}.tx`, TxClient<TClient>>;
36
+ withTransaction: <A, E_1, R_1>(effect: Effect.Effect<A, E_1, R_1>) => Effect.Effect<A, DrizzleError | E_1, Exclude<T, effect_Scope.Scope> | Exclude<Exclude<R_1, `${T}.tx`>, effect_Scope.Scope>>;
37
+ layer: Layer.Layer<T, E, R>;
44
38
  };
45
39
 
46
- export { DrizzleError, TagTypeId, createDatabase };
40
+ export { ChannelTypeId, DrizzleError, EffectTypeId, NodeInspectSymbol, STMTypeId, SinkTypeId, StreamTypeId, TagTypeId, Unify, createDatabase };
@@ -1,16 +1,30 @@
1
1
  // src/for/drizzle/index.ts
2
- import { Context, Data, Effect, FiberSet, Layer } from "effect";
3
- var TagTypeId = Context.TagTypeId;
2
+ import { Data, Effect, FiberSet, Layer } from "effect";
3
+ import * as Channel from "effect/Channel";
4
+ import * as Context from "effect/Context";
5
+ import * as Inspectable from "effect/Inspectable";
6
+ import * as Sink from "effect/Sink";
7
+ import * as STM from "effect/STM";
8
+ import * as Stream from "effect/Stream";
9
+ import * as EUnify from "effect/Unify";
10
+ var TagTypeId2 = Context.TagTypeId;
11
+ var ChannelTypeId2 = Channel.ChannelTypeId;
12
+ var EffectTypeId = Effect.EffectTypeId;
13
+ var NodeInspectSymbol2 = Inspectable.NodeInspectSymbol;
14
+ var STMTypeId2 = STM.STMTypeId;
15
+ var SinkTypeId2 = Sink.SinkTypeId;
16
+ var StreamTypeId2 = Stream.StreamTypeId;
17
+ var Unify = EUnify;
4
18
  var DrizzleError = class extends Data.TaggedError("ff-effect/DrizzleError") {
5
19
  };
6
20
  var WrappedTxError = class extends Error {
7
21
  };
8
- function createDatabase(tagId, createClient) {
9
- class Drizzle extends Context.Tag(tagId)() {
10
- }
11
- const txTag = `${tagId}.tx`;
12
- class DrizzleTx extends Context.Tag(txTag)() {
13
- }
22
+ var defaultPrefix = "@ff-effect/Drizzle";
23
+ function createDatabase(createClient, opts) {
24
+ const tagId = opts?.tagId ?? defaultPrefix;
25
+ const Drizzle = Context.Tag(tagId)();
26
+ const drizzleTxTagId = `${tagId}.tx`;
27
+ const DrizzleTx = Context.Tag(drizzleTxTagId)();
14
28
  const db = (fn) => Effect.gen(function* () {
15
29
  const client = yield* Drizzle;
16
30
  return yield* Effect.tryPromise({
@@ -50,13 +64,22 @@ function createDatabase(tagId, createClient) {
50
64
  return {
51
65
  db,
52
66
  tx,
67
+ Drizzle,
68
+ DrizzleTx,
53
69
  withTransaction,
54
70
  layer: Layer.effect(Drizzle, createClient)
55
71
  };
56
72
  }
57
73
  export {
74
+ ChannelTypeId2 as ChannelTypeId,
58
75
  DrizzleError,
59
- TagTypeId,
76
+ EffectTypeId,
77
+ NodeInspectSymbol2 as NodeInspectSymbol,
78
+ STMTypeId2 as STMTypeId,
79
+ SinkTypeId2 as SinkTypeId,
80
+ StreamTypeId2 as StreamTypeId,
81
+ TagTypeId2 as TagTypeId,
82
+ Unify,
60
83
  createDatabase
61
84
  };
62
85
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/for/drizzle/index.ts"],"sourcesContent":["import { Context, Data, Effect, FiberSet, Layer } from 'effect';\n\n// TypeScript issue where the return type of createDatabase\n// contains internal Effect types (TagTypeId) that aren't exported\n// from this module,\n// so TypeScript can't \"name\" them in the declaration file.\nexport const TagTypeId = Context.TagTypeId;\n\nexport class DrizzleError extends Data.TaggedError('ff-effect/DrizzleError')<{\n\tmessage: string;\n\tcause?: unknown;\n}> {}\n\ntype AnyDrizzleClient = {\n\ttransaction: (fn: (tx: any) => Promise<any>) => Promise<any>;\n};\n\ntype TxClient<TClient extends AnyDrizzleClient> = Parameters<\n\tParameters<TClient['transaction']>[0]\n>[0];\n\nclass WrappedTxError extends Error {}\n\nexport function createDatabase<\n\tTAG extends string,\n\tTClient extends AnyDrizzleClient,\n\tE,\n\tR,\n>(tagId: TAG, createClient: Effect.Effect<TClient, E, R>) {\n\ttype Client = TClient | TxClient<TClient>;\n\ttype Tx = TxClient<TClient>;\n\n\tclass Drizzle extends Context.Tag(tagId)<Drizzle, Client>() {}\n\tconst txTag = `${tagId}.tx` as const;\n\tclass DrizzleTx extends Context.Tag(txTag)<DrizzleTx, Tx>() {}\n\n\tconst db = <T>(fn: (client: Client) => Promise<T>) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst client = yield* Drizzle;\n\t\t\treturn yield* Effect.tryPromise({\n\t\t\t\ttry: () => fn(client),\n\t\t\t\tcatch: (cause) =>\n\t\t\t\t\tnew DrizzleError({ message: 'Database operation failed', cause }),\n\t\t\t});\n\t\t});\n\n\t/** Requires being inside withTransaction - enforces transaction at compile time */\n\tconst tx = <T>(fn: (client: Tx) => Promise<T>) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst client = yield* DrizzleTx;\n\t\t\treturn yield* Effect.tryPromise({\n\t\t\t\ttry: () => fn(client),\n\t\t\t\tcatch: (cause) =>\n\t\t\t\t\tnew DrizzleError({ message: 'Database operation failed', cause }),\n\t\t\t});\n\t\t});\n\n\tconst withTransaction = <A, E, R>(effect: Effect.Effect<A, E, R>) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst client = yield* Drizzle;\n\t\t\tconst runFork =\n\t\t\t\tyield* FiberSet.makeRuntimePromise<Exclude<R, DrizzleTx>>();\n\n\t\t\treturn yield* Effect.tryPromise<A, E | DrizzleError>({\n\t\t\t\ttry: () =>\n\t\t\t\t\t(client as TClient).transaction((txClient) =>\n\t\t\t\t\t\trunFork(\n\t\t\t\t\t\t\teffect.pipe(\n\t\t\t\t\t\t\t\tEffect.provideService(Drizzle, txClient as Client),\n\t\t\t\t\t\t\t\tEffect.provideService(DrizzleTx, txClient as Tx),\n\t\t\t\t\t\t\t\tEffect.mapError((e) => new WrappedTxError('', { cause: e })),\n\t\t\t\t\t\t\t) as Effect.Effect<A, WrappedTxError, Exclude<R, DrizzleTx>>,\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\tcatch: (error) => {\n\t\t\t\t\tif (error instanceof WrappedTxError) return error.cause as E;\n\t\t\t\t\treturn new DrizzleError({\n\t\t\t\t\t\tmessage: 'Transaction failed',\n\t\t\t\t\t\tcause: error,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t});\n\t\t}).pipe(Effect.scoped);\n\n\treturn {\n\t\tdb,\n\t\ttx,\n\t\twithTransaction,\n\t\tlayer: Layer.effect(Drizzle, createClient),\n\t};\n}\n"],"mappings":";AAAA,SAAS,SAAS,MAAM,QAAQ,UAAU,aAAa;AAMhD,IAAM,YAAY,QAAQ;AAE1B,IAAM,eAAN,cAA2B,KAAK,YAAY,wBAAwB,EAGxE;AAAC;AAUJ,IAAM,iBAAN,cAA6B,MAAM;AAAC;AAE7B,SAAS,eAKd,OAAY,cAA4C;AAAA,EAIzD,MAAM,gBAAgB,QAAQ,IAAI,KAAK,EAAmB,EAAE;AAAA,EAAC;AAC7D,QAAM,QAAQ,GAAG,KAAK;AAAA,EACtB,MAAM,kBAAkB,QAAQ,IAAI,KAAK,EAAiB,EAAE;AAAA,EAAC;AAE7D,QAAM,KAAK,CAAI,OACd,OAAO,IAAI,aAAa;AACvB,UAAM,SAAS,OAAO;AACtB,WAAO,OAAO,OAAO,WAAW;AAAA,MAC/B,KAAK,MAAM,GAAG,MAAM;AAAA,MACpB,OAAO,CAAC,UACP,IAAI,aAAa,EAAE,SAAS,6BAA6B,MAAM,CAAC;AAAA,IAClE,CAAC;AAAA,EACF,CAAC;AAGF,QAAM,KAAK,CAAI,OACd,OAAO,IAAI,aAAa;AACvB,UAAM,SAAS,OAAO;AACtB,WAAO,OAAO,OAAO,WAAW;AAAA,MAC/B,KAAK,MAAM,GAAG,MAAM;AAAA,MACpB,OAAO,CAAC,UACP,IAAI,aAAa,EAAE,SAAS,6BAA6B,MAAM,CAAC;AAAA,IAClE,CAAC;AAAA,EACF,CAAC;AAEF,QAAM,kBAAkB,CAAU,WACjC,OAAO,IAAI,aAAa;AACvB,UAAM,SAAS,OAAO;AACtB,UAAM,UACL,OAAO,SAAS,mBAA0C;AAE3D,WAAO,OAAO,OAAO,WAAgC;AAAA,MACpD,KAAK,MACH,OAAmB;AAAA,QAAY,CAAC,aAChC;AAAA,UACC,OAAO;AAAA,YACN,OAAO,eAAe,SAAS,QAAkB;AAAA,YACjD,OAAO,eAAe,WAAW,QAAc;AAAA,YAC/C,OAAO,SAAS,CAAC,MAAM,IAAI,eAAe,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AAAA,UAC5D;AAAA,QACD;AAAA,MACD;AAAA,MACD,OAAO,CAAC,UAAU;AACjB,YAAI,iBAAiB,eAAgB,QAAO,MAAM;AAClD,eAAO,IAAI,aAAa;AAAA,UACvB,SAAS;AAAA,UACT,OAAO;AAAA,QACR,CAAC;AAAA,MACF;AAAA,IACD,CAAC;AAAA,EACF,CAAC,EAAE,KAAK,OAAO,MAAM;AAEtB,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,MAAM,OAAO,SAAS,YAAY;AAAA,EAC1C;AACD;","names":[]}
1
+ {"version":3,"sources":["../../../src/for/drizzle/index.ts"],"sourcesContent":["import { Data, Effect, FiberSet, Layer } from 'effect';\nimport * as Channel from 'effect/Channel';\nimport * as Context from 'effect/Context';\nimport * as Inspectable from 'effect/Inspectable';\nimport * as Sink from 'effect/Sink';\nimport * as STM from 'effect/STM';\nimport * as Stream from 'effect/Stream';\nimport * as EUnify from 'effect/Unify';\n\n// TypeScript issue where the return type of createDatabase\n// contains internal Effect types (TagTypeId) that aren't exported\n// from this module,\n// so TypeScript can't \"name\" them in the declaration file.\nexport const TagTypeId = Context.TagTypeId;\nexport const ChannelTypeId = Channel.ChannelTypeId;\nexport const EffectTypeId = Effect.EffectTypeId;\nexport const NodeInspectSymbol = Inspectable.NodeInspectSymbol;\nexport const STMTypeId = STM.STMTypeId;\nexport const SinkTypeId = Sink.SinkTypeId;\nexport const StreamTypeId = Stream.StreamTypeId;\nexport const Unify = EUnify;\n\nexport class DrizzleError extends Data.TaggedError('ff-effect/DrizzleError')<{\n\tmessage: string;\n\tcause?: unknown;\n}> {}\n\ntype AnyDrizzleClient = {\n\ttransaction: (fn: (tx: any) => Promise<any>) => Promise<any>;\n};\n\ntype TxClient<TClient extends AnyDrizzleClient> = Parameters<\n\tParameters<TClient['transaction']>[0]\n>[0];\n\nclass WrappedTxError extends Error {}\n\nconst defaultPrefix = '@ff-effect/Drizzle' as const;\n\nexport function createDatabase<\n\tTClient extends AnyDrizzleClient,\n\tE,\n\tR,\n\tT extends string = typeof defaultPrefix,\n>(createClient: Effect.Effect<TClient, E, R>, opts?: { tagId?: T }) {\n\ttype Client = TClient | TxClient<TClient>;\n\ttype Tx = TxClient<TClient>;\n\n\tconst tagId = (opts?.tagId ?? defaultPrefix) as T;\n\n\ttype Drizzle = typeof tagId;\n\tconst Drizzle = Context.Tag(tagId)<Drizzle, Client>();\n\n\tconst drizzleTxTagId = `${tagId}.tx` as const;\n\ttype DrizzleTx = typeof drizzleTxTagId;\n\tconst DrizzleTx = Context.Tag(drizzleTxTagId)<DrizzleTx, Tx>();\n\n\tconst db = <T>(fn: (client: Client) => Promise<T>) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst client = yield* Drizzle;\n\t\t\treturn yield* Effect.tryPromise({\n\t\t\t\ttry: () => fn(client),\n\t\t\t\tcatch: (cause) =>\n\t\t\t\t\tnew DrizzleError({ message: 'Database operation failed', cause }),\n\t\t\t});\n\t\t});\n\n\t/** Requires being inside withTransaction - enforces transaction at compile time */\n\tconst tx = <T>(fn: (client: Tx) => Promise<T>) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst client = yield* DrizzleTx;\n\t\t\treturn yield* Effect.tryPromise({\n\t\t\t\ttry: () => fn(client),\n\t\t\t\tcatch: (cause) =>\n\t\t\t\t\tnew DrizzleError({ message: 'Database operation failed', cause }),\n\t\t\t});\n\t\t});\n\n\tconst withTransaction = <A, E, R>(effect: Effect.Effect<A, E, R>) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst client = yield* Drizzle;\n\t\t\tconst runFork =\n\t\t\t\tyield* FiberSet.makeRuntimePromise<Exclude<R, DrizzleTx>>();\n\n\t\t\treturn yield* Effect.tryPromise<A, E | DrizzleError>({\n\t\t\t\ttry: () =>\n\t\t\t\t\t(client as TClient).transaction((txClient) =>\n\t\t\t\t\t\trunFork(\n\t\t\t\t\t\t\teffect.pipe(\n\t\t\t\t\t\t\t\tEffect.provideService(Drizzle, txClient as Client),\n\t\t\t\t\t\t\t\tEffect.provideService(DrizzleTx, txClient as Tx),\n\t\t\t\t\t\t\t\tEffect.mapError((e) => new WrappedTxError('', { cause: e })),\n\t\t\t\t\t\t\t) as Effect.Effect<A, WrappedTxError, Exclude<R, DrizzleTx>>,\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\tcatch: (error) => {\n\t\t\t\t\tif (error instanceof WrappedTxError) return error.cause as E;\n\t\t\t\t\treturn new DrizzleError({\n\t\t\t\t\t\tmessage: 'Transaction failed',\n\t\t\t\t\t\tcause: error,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t});\n\t\t}).pipe(Effect.scoped);\n\n\treturn {\n\t\tdb,\n\t\ttx,\n\t\tDrizzle,\n\t\tDrizzleTx,\n\t\twithTransaction,\n\t\tlayer: Layer.effect(Drizzle, createClient),\n\t};\n}\n"],"mappings":";AAAA,SAAS,MAAM,QAAQ,UAAU,aAAa;AAC9C,YAAY,aAAa;AACzB,YAAY,aAAa;AACzB,YAAY,iBAAiB;AAC7B,YAAY,UAAU;AACtB,YAAY,SAAS;AACrB,YAAY,YAAY;AACxB,YAAY,YAAY;AAMjB,IAAMA,aAAoB;AAC1B,IAAMC,iBAAwB;AAC9B,IAAM,eAAe,OAAO;AAC5B,IAAMC,qBAAgC;AACtC,IAAMC,aAAgB;AACtB,IAAMC,cAAkB;AACxB,IAAMC,gBAAsB;AAC5B,IAAM,QAAQ;AAEd,IAAM,eAAN,cAA2B,KAAK,YAAY,wBAAwB,EAGxE;AAAC;AAUJ,IAAM,iBAAN,cAA6B,MAAM;AAAC;AAEpC,IAAM,gBAAgB;AAEf,SAAS,eAKd,cAA4C,MAAsB;AAInE,QAAM,QAAS,MAAM,SAAS;AAG9B,QAAM,UAAkB,YAAI,KAAK,EAAmB;AAEpD,QAAM,iBAAiB,GAAG,KAAK;AAE/B,QAAM,YAAoB,YAAI,cAAc,EAAiB;AAE7D,QAAM,KAAK,CAAI,OACd,OAAO,IAAI,aAAa;AACvB,UAAM,SAAS,OAAO;AACtB,WAAO,OAAO,OAAO,WAAW;AAAA,MAC/B,KAAK,MAAM,GAAG,MAAM;AAAA,MACpB,OAAO,CAAC,UACP,IAAI,aAAa,EAAE,SAAS,6BAA6B,MAAM,CAAC;AAAA,IAClE,CAAC;AAAA,EACF,CAAC;AAGF,QAAM,KAAK,CAAI,OACd,OAAO,IAAI,aAAa;AACvB,UAAM,SAAS,OAAO;AACtB,WAAO,OAAO,OAAO,WAAW;AAAA,MAC/B,KAAK,MAAM,GAAG,MAAM;AAAA,MACpB,OAAO,CAAC,UACP,IAAI,aAAa,EAAE,SAAS,6BAA6B,MAAM,CAAC;AAAA,IAClE,CAAC;AAAA,EACF,CAAC;AAEF,QAAM,kBAAkB,CAAU,WACjC,OAAO,IAAI,aAAa;AACvB,UAAM,SAAS,OAAO;AACtB,UAAM,UACL,OAAO,SAAS,mBAA0C;AAE3D,WAAO,OAAO,OAAO,WAAgC;AAAA,MACpD,KAAK,MACH,OAAmB;AAAA,QAAY,CAAC,aAChC;AAAA,UACC,OAAO;AAAA,YACN,OAAO,eAAe,SAAS,QAAkB;AAAA,YACjD,OAAO,eAAe,WAAW,QAAc;AAAA,YAC/C,OAAO,SAAS,CAAC,MAAM,IAAI,eAAe,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AAAA,UAC5D;AAAA,QACD;AAAA,MACD;AAAA,MACD,OAAO,CAAC,UAAU;AACjB,YAAI,iBAAiB,eAAgB,QAAO,MAAM;AAClD,eAAO,IAAI,aAAa;AAAA,UACvB,SAAS;AAAA,UACT,OAAO;AAAA,QACR,CAAC;AAAA,MACF;AAAA,IACD,CAAC;AAAA,EACF,CAAC,EAAE,KAAK,OAAO,MAAM;AAEtB,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,MAAM,OAAO,SAAS,YAAY;AAAA,EAC1C;AACD;","names":["TagTypeId","ChannelTypeId","NodeInspectSymbol","STMTypeId","SinkTypeId","StreamTypeId"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ff-effect",
3
- "version": "0.0.8",
3
+ "version": "0.0.10",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -28,6 +28,7 @@
28
28
  "@effect/platform-bun": "^0.87.1",
29
29
  "@effect/platform-node": "^0.104.1",
30
30
  "@effect/vitest": "^0.27.0",
31
+ "@electric-sql/pglite": "^0.3.15",
31
32
  "@libsql/client": "^0.17.0",
32
33
  "@orpc/contract": "^1.11.3",
33
34
  "@orpc/server": "^1.11.3",
@@ -1,54 +1,52 @@
1
- import { randomUUID } from 'node:crypto';
2
- import { FileSystem, Path } from '@effect/platform';
3
1
  import * as BunContext from '@effect/platform-bun/BunContext';
4
2
  import { describe, expect, layer } from '@effect/vitest';
5
- import { createClient } from '@libsql/client';
6
- import { sql } from 'drizzle-orm';
7
- import { drizzle } from 'drizzle-orm/libsql';
8
- import { sqliteTable, text } from 'drizzle-orm/sqlite-core';
9
- import { Effect } from 'effect';
3
+ import { PGlite } from '@electric-sql/pglite';
4
+ import { pgTable, text } from 'drizzle-orm/pg-core';
5
+ import { drizzle } from 'drizzle-orm/pglite';
6
+ import { Effect, Layer } from 'effect';
10
7
  import { expectTypeOf } from 'vitest';
11
8
  import { createDatabase, DrizzleError } from './index.js';
12
9
 
13
- const users = sqliteTable('users', {
10
+ const users = pgTable('users', {
14
11
  id: text('id').primaryKey(),
15
12
  name: text('name').notNull(),
16
13
  });
17
14
 
18
15
  const schema = { users };
19
16
 
20
- const createTestDb = Effect.gen(function* () {
21
- const fs = yield* FileSystem.FileSystem;
22
- const path = yield* Path.Path;
23
-
24
- const tmpDir = yield* fs.makeTempDirectoryScoped();
25
- const dbPath = path.join(tmpDir, `test-${randomUUID()}.db`);
26
-
27
- const client = createClient({ url: `file:${dbPath}` });
28
- return drizzle(client, { schema });
29
- });
30
-
31
- const setupTable = (testDb: ReturnType<typeof drizzle>) =>
32
- Effect.gen(function* () {
33
- yield* Effect.promise(() => testDb.run(sql`DROP TABLE IF EXISTS users`));
34
- yield* Effect.promise(() =>
35
- testDb.run(
36
- sql`CREATE TABLE users (id TEXT PRIMARY KEY, name TEXT NOT NULL)`,
37
- ),
38
- );
39
- });
40
-
41
- layer(BunContext.layer)((it) => {
17
+ export class TestDb extends Effect.Service<TestDb>()('TestDb', {
18
+ accessors: true,
19
+ scoped: Effect.gen(function* () {
20
+ const db = new PGlite();
21
+ yield* Effect.promise(async () => {
22
+ await db.query('DROP TABLE IF EXISTS users');
23
+ await db.query(
24
+ 'CREATE TABLE users (id TEXT PRIMARY KEY, name TEXT NOT NULL)',
25
+ );
26
+ });
27
+
28
+ const dump = yield* Effect.promise(() => db.dumpDataDir());
29
+
30
+ return {
31
+ get: () =>
32
+ Effect.gen(function* () {
33
+ const db = new PGlite('memory://', { loadDataDir: dump });
34
+ return drizzle(db, { schema });
35
+ }),
36
+ };
37
+ }),
38
+ }) {}
39
+
40
+ layer(Layer.mergeAll(BunContext.layer, TestDb.Default))((it) => {
42
41
  describe('db', () => {
43
42
  it.scoped('wraps promises and returns correct data', () =>
44
43
  Effect.gen(function* () {
45
- const testDb = yield* createTestDb;
46
- yield* setupTable(testDb);
44
+ const testDb = yield* TestDb.get();
47
45
  yield* Effect.promise(() =>
48
46
  testDb.insert(users).values({ id: '1', name: 'Alice' }),
49
47
  );
50
48
 
51
- const database = createDatabase('test/db', Effect.succeed(testDb));
49
+ const database = createDatabase(Effect.succeed(testDb));
52
50
 
53
51
  const result = yield* database
54
52
  .db((d) => d.select().from(users))
@@ -60,12 +58,9 @@ layer(BunContext.layer)((it) => {
60
58
 
61
59
  it.scoped('surfaces errors as DrizzleError', () =>
62
60
  Effect.gen(function* () {
63
- const testDb = yield* createTestDb;
61
+ const testDb = yield* TestDb.get();
64
62
 
65
- const database = createDatabase(
66
- 'test/db-error',
67
- Effect.succeed(testDb),
68
- );
63
+ const database = createDatabase(Effect.succeed(testDb));
69
64
 
70
65
  const result = yield* database
71
66
  .db(() => Promise.reject(new Error('DB failure')))
@@ -82,10 +77,9 @@ layer(BunContext.layer)((it) => {
82
77
  describe('withTransaction', () => {
83
78
  it.scoped('provides transaction context to nested db calls', () =>
84
79
  Effect.gen(function* () {
85
- const testDb = yield* createTestDb;
86
- yield* setupTable(testDb);
80
+ const testDb = yield* TestDb.get();
87
81
 
88
- const database = createDatabase('test/db-tx', Effect.succeed(testDb));
82
+ const database = createDatabase(Effect.succeed(testDb));
89
83
 
90
84
  yield* Effect.gen(function* () {
91
85
  const ok = 'ok' as const;
@@ -114,13 +108,9 @@ layer(BunContext.layer)((it) => {
114
108
 
115
109
  it.scoped('rolls back on error', () =>
116
110
  Effect.gen(function* () {
117
- const testDb = yield* createTestDb;
118
- yield* setupTable(testDb);
111
+ const testDb = yield* TestDb.get();
119
112
 
120
- const database = createDatabase(
121
- 'test/db-rollback',
122
- Effect.succeed(testDb),
123
- );
113
+ const database = createDatabase(Effect.succeed(testDb));
124
114
 
125
115
  const result = yield* Effect.gen(function* () {
126
116
  const txResult = yield* database
@@ -147,4 +137,73 @@ layer(BunContext.layer)((it) => {
147
137
  }),
148
138
  );
149
139
  });
140
+
141
+ describe('multiple database', () => {
142
+ it.scoped(
143
+ 'allows creating multiple database instances with different tagIds',
144
+ () =>
145
+ Effect.gen(function* () {
146
+ const testDb = yield* TestDb;
147
+ const database1 = createDatabase(testDb.get());
148
+
149
+ const database2Identifier = 'custom-db' as const;
150
+ const database2 = createDatabase(testDb.get(), {
151
+ tagId: database2Identifier,
152
+ });
153
+
154
+ const firstDbEffect = Effect.gen(function* () {
155
+ yield* database1.db((d) =>
156
+ d.insert(users).values({ id: '1', name: 'Eve' }),
157
+ );
158
+ });
159
+ expectTypeOf(firstDbEffect).toEqualTypeOf<
160
+ Effect.Effect<
161
+ void,
162
+ DrizzleError,
163
+ typeof database1.Drizzle.Identifier
164
+ >
165
+ >();
166
+
167
+ const secondDbEffect = Effect.gen(function* () {
168
+ yield* database2.db((d) =>
169
+ d.insert(users).values({ id: '2', name: 'Frank' }),
170
+ );
171
+ });
172
+ expectTypeOf(secondDbEffect).toEqualTypeOf<
173
+ Effect.Effect<void, DrizzleError, typeof database2Identifier>
174
+ >();
175
+
176
+ const main = Effect.gen(function* () {
177
+ yield* firstDbEffect;
178
+ yield* secondDbEffect;
179
+
180
+ yield* database1
181
+ .db((d) => d.select().from(users))
182
+ .pipe(
183
+ Effect.flatMap((result) =>
184
+ Effect.sync(() => {
185
+ expect(result).toEqual([{ id: '1', name: 'Eve' }]);
186
+ }),
187
+ ),
188
+ );
189
+
190
+ yield* database2
191
+ .db((d) => d.select().from(users))
192
+ .pipe(
193
+ Effect.flatMap((result) =>
194
+ Effect.sync(() => {
195
+ expect(result).toEqual([{ id: '2', name: 'Frank' }]);
196
+ }),
197
+ ),
198
+ );
199
+ }).pipe(
200
+ Effect.provide(database1.layer),
201
+ Effect.provide(database2.layer),
202
+ );
203
+
204
+ yield* main;
205
+ expectTypeOf(main).toEqualTypeOf<Effect.Effect<void, DrizzleError>>();
206
+ }),
207
+ );
208
+ });
150
209
  });
@@ -1,10 +1,24 @@
1
- import { Context, Data, Effect, FiberSet, Layer } from 'effect';
1
+ import { Data, Effect, FiberSet, Layer } from 'effect';
2
+ import * as Channel from 'effect/Channel';
3
+ import * as Context from 'effect/Context';
4
+ import * as Inspectable from 'effect/Inspectable';
5
+ import * as Sink from 'effect/Sink';
6
+ import * as STM from 'effect/STM';
7
+ import * as Stream from 'effect/Stream';
8
+ import * as EUnify from 'effect/Unify';
2
9
 
3
10
  // TypeScript issue where the return type of createDatabase
4
11
  // contains internal Effect types (TagTypeId) that aren't exported
5
12
  // from this module,
6
13
  // so TypeScript can't "name" them in the declaration file.
7
14
  export const TagTypeId = Context.TagTypeId;
15
+ export const ChannelTypeId = Channel.ChannelTypeId;
16
+ export const EffectTypeId = Effect.EffectTypeId;
17
+ export const NodeInspectSymbol = Inspectable.NodeInspectSymbol;
18
+ export const STMTypeId = STM.STMTypeId;
19
+ export const SinkTypeId = Sink.SinkTypeId;
20
+ export const StreamTypeId = Stream.StreamTypeId;
21
+ export const Unify = EUnify;
8
22
 
9
23
  export class DrizzleError extends Data.TaggedError('ff-effect/DrizzleError')<{
10
24
  message: string;
@@ -21,18 +35,25 @@ type TxClient<TClient extends AnyDrizzleClient> = Parameters<
21
35
 
22
36
  class WrappedTxError extends Error {}
23
37
 
38
+ const defaultPrefix = '@ff-effect/Drizzle' as const;
39
+
24
40
  export function createDatabase<
25
- TAG extends string,
26
41
  TClient extends AnyDrizzleClient,
27
42
  E,
28
43
  R,
29
- >(tagId: TAG, createClient: Effect.Effect<TClient, E, R>) {
44
+ T extends string = typeof defaultPrefix,
45
+ >(createClient: Effect.Effect<TClient, E, R>, opts?: { tagId?: T }) {
30
46
  type Client = TClient | TxClient<TClient>;
31
47
  type Tx = TxClient<TClient>;
32
48
 
33
- class Drizzle extends Context.Tag(tagId)<Drizzle, Client>() {}
34
- const txTag = `${tagId}.tx` as const;
35
- class DrizzleTx extends Context.Tag(txTag)<DrizzleTx, Tx>() {}
49
+ const tagId = (opts?.tagId ?? defaultPrefix) as T;
50
+
51
+ type Drizzle = typeof tagId;
52
+ const Drizzle = Context.Tag(tagId)<Drizzle, Client>();
53
+
54
+ const drizzleTxTagId = `${tagId}.tx` as const;
55
+ type DrizzleTx = typeof drizzleTxTagId;
56
+ const DrizzleTx = Context.Tag(drizzleTxTagId)<DrizzleTx, Tx>();
36
57
 
37
58
  const db = <T>(fn: (client: Client) => Promise<T>) =>
38
59
  Effect.gen(function* () {
@@ -85,6 +106,8 @@ export function createDatabase<
85
106
  return {
86
107
  db,
87
108
  tx,
109
+ Drizzle,
110
+ DrizzleTx,
88
111
  withTransaction,
89
112
  layer: Layer.effect(Drizzle, createClient),
90
113
  };