effect-zero 0.0.0-alpha.0 → 0.1.0

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 realms-labs
3
+ Copyright (c) 2025 sakura-labs
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md ADDED
@@ -0,0 +1,187 @@
1
+ # effect-zero
2
+
3
+ ## Server Setup
4
+
5
+ ```ts
6
+ // server/zero.ts
7
+ import { PostgresJSConnection, ZQLDatabase } from "@rocicorp/zero/pg";
8
+ import { ZeroPushResponse, ZeroPushParams, ZeroPushBody } from "effect-zero/types";
9
+ import * as ZeroServer from "effect-zero/server";
10
+ import * as Schema from "effect/Schema";
11
+ import * as Effect from "effect/Effect";
12
+ import postgres from "postgres";
13
+ import { zeroClient } from '../client/zero'; // optional (see below)
14
+
15
+ // zero schema (define or use something like drizzle-zero)
16
+ import { schema } from "./schema";
17
+
18
+ // setup connection
19
+ const connection = new PostgresJSConnection(postgres(process.env.DATABASE_URL!));
20
+ const database = new ZQLDatabase(connection, schema);
21
+
22
+ // the "server-side" zero instance
23
+ export const zero = ZeroServer.makeServer({
24
+ database,
25
+ // this part is optional, but it allows us to use the client mutators on the server side
26
+ clientTransaction: zeroClient.Transaction,
27
+ });
28
+
29
+ // define mutators (same as client, see below)
30
+ // in practice this can be a centralized file which is imported in both places
31
+ export type MutatorArgs = {
32
+ todo: {
33
+ create: { id: string; title: string };
34
+ toggle: { id: string; done: boolean };
35
+ };
36
+ };
37
+
38
+ // define mutators.
39
+ export const serverMutators = zero.mutators<MutatorArgs>()({
40
+ todo: {
41
+ create: Effect.fn(function* ({ id, title }) {
42
+ // Note, we can run arbitrary logic before/after performing the zero transaction
43
+ // this is a unique feature which is not supported by the default zero push processor implementation
44
+ // shipped with the base `@rocicorp/zero` package
45
+
46
+ // before the transaction
47
+ yield Effect.log("before the transaction");
48
+
49
+ Effect.gen(function* () {
50
+ // during the transaction
51
+ yield Effect.log("during the transaction");
52
+ yield* zero.Transaction.use((tx) => tx.mutate.TodoTable.insert({ id, title, createdAt: Date.now() }));
53
+ yield* zero.Transaction.use((tx) => tx.mutate.TodoTable.update({ id, done: false }));
54
+ // ...
55
+ }).pipe(zero.Transaction.execute);
56
+
57
+ // after the transaction
58
+ yield Effect.log("after the transaction");
59
+ }),
60
+ toggle: Effect.fn(function* ({ id, done }) {
61
+ yield* zero.Transaction.use((tx) => tx.mutate.TodoTable.update({ id, done })).pipe(zero.Transaction.execute);
62
+ }),
63
+ },
64
+ });
65
+
66
+ // handler for push endpoint
67
+ // Note: this is framework-agnostic so that is why Effect.runPromise is used below, however this is of course not needed
68
+ // if your server framework is effect-based (like Effect HTTP module)
69
+
70
+ export async function handleZeroPush(req: Request): Promise<Response> {
71
+ const url = new URL(req.url);
72
+ const urlParams = Schema.decodeSync(ZeroPushParams)({
73
+ schema: url.searchParams.get("schema")!,
74
+ appID: url.searchParams.get("appID")!,
75
+ });
76
+ const payload = Schema.decodeSync(ZeroPushBody)(await req.json());
77
+
78
+ const result = await Effect.runPromise(zero.processPush(serverMutators, urlParams, payload));
79
+ const responseBody = Schema.encodeSync(ZeroPushResponse)(result);
80
+ return new Response(JSON.stringify(responseBody), { status: 200, headers: { "content-type": "application/json" } });
81
+ }
82
+ ```
83
+
84
+ ## Client Setup
85
+
86
+ ```ts
87
+ // client/zero.ts
88
+ import { Zero } from "@rocicorp/zero";
89
+ import * as ZeroClient from "effect-zero/client";
90
+ import * as Effect from "effect/Effect";
91
+ import { schema } from "./schema"; // your schema
92
+
93
+ // as mentioned above, this can be centralized between client and server
94
+ export type MutatorArgs = {
95
+ todo: {
96
+ create: { id: string; title: string };
97
+ toggle: { id: string; done: boolean };
98
+ };
99
+ };
100
+
101
+ // The "client-side" zero instance
102
+ export const zeroClient = ZeroClient.makeClient<typeof schema>();
103
+
104
+ export const clientMutators = zeroClient.mutators<MutatorArgs>()({
105
+ todo: {
106
+ create: Effect.fn(function* ({ id, title }) {
107
+ yield* zeroClient.Transaction.use((tx) => tx.mutate.TodoTable.insert({ id, title, createdAt: Date.now() }));
108
+ }),
109
+ toggle: Effect.fn(function* ({ id, done }) {
110
+ yield* zeroClient.Transaction.use((tx) => tx.mutate.TodoTable.update({ id, done }));
111
+ }),
112
+ },
113
+ });
114
+
115
+ export async function createZero(opts: { userID: string; auth?: string; server: string }) {
116
+ const mutators = await Effect.runPromise(zeroClient.unwrapMutators(clientMutators));
117
+ return new Zero({
118
+ userID: opts.userID,
119
+ auth: opts.auth,
120
+ server: opts.server, // your push/pull endpoint base URL
121
+ schema,
122
+ kvStore: "idb", // or "mem" for in-memory
123
+ mutators,
124
+ });
125
+ }
126
+ ```
127
+
128
+ ## Query Atoms
129
+
130
+ ```ts
131
+ // state/todos.ts
132
+ import { Atom } from "@effect-atom/atom";
133
+ import * as Effect from "effect/Effect";
134
+ import * as Option from "effect/Option";
135
+ import { createZero, zero } from "../client/zero";
136
+
137
+ // build/load the zero instance
138
+ const zeroAtom = Atom.make(
139
+ Effect.fn(function* (get) {
140
+ const zero = yield* Effect.promise(() => createZero({ ... }));
141
+
142
+ //add finalizer
143
+ get.addFinalizer(() => {
144
+ zero.close();
145
+ });
146
+
147
+ return zero;
148
+ }),
149
+ );
150
+
151
+ // example query atom
152
+ export const userAtom = Atom.make(
153
+ Effect.fn(function* (get) {
154
+ const zero = yield* get.result(zeroAtom);
155
+ const userId = yield* get.result(userIdAtom);
156
+ if (Option.isNone(userId)) {
157
+ return Option.none();
158
+ }
159
+ const query = zero.query.UserTable.where("id", "=", userId.value).one();
160
+ return yield* get.result(zeroClient.queryAtom(query)).pipe(Effect.map(Option.fromNullable));
161
+ }),
162
+ );
163
+ ```
164
+
165
+ ## Calling Mutations
166
+
167
+ With the `Zero` instance created using your unwrapped mutators, call them via `zero.mutate`:
168
+
169
+ ```ts
170
+ export const deleteMessageAtom = Atom.fn(
171
+ Effect.fn(function* (messageId: MessageId) {
172
+ const zero = yield* Atom.getResult(zeroAtom);
173
+ yield* Effect.promise(() => zero.mutate.MessageTable.delete({ id: messageId }));
174
+ }),
175
+ );
176
+ ```
177
+
178
+ ## Differences from the original implementation
179
+
180
+ One key difference is that `effect-zero` requires you to manually wrap your DB-related logic in a transaction inside a mutator code, whereas the original implementation automatically wraps the whole mutation in a transaction. This allows you to define some logic outside of transaction (either before or after), but it also creates some edge cases that are not possible in the original implementation, because now the transaction might succeed, but the code outside of it might fail. Below are the edge case rules that `effect-zero` follows during the mutation execution:
181
+
182
+ 1. "One transaction and succeed" -> successful response from the push endpoint (normal flow).
183
+ 2. "One transaction then fail" (code after the transaction produces an error) -> successful response, despite the mutation failing. This is essential to maintain integrity of Zero's internal state: the transaction has already succeeded (and altered the state of the database), thus the result from the push endpoint must coincide. Relatedly, the user must be careful with work performed after the transaction, it is considered "fire and forget".
184
+ 3. "Two or more transactions" -> This is a sub-case of the "One transaction then fail (#2)" scenario; the first transaction will succeed (and thus we must return a successful response from the push endpoint), and the second one will fail. We must be careful of performing multiple transactions in the mutator for this reason.
185
+ 4. "Zero transactions then succeed" -> error response, because all mutations must have a transaction.
186
+ 5. "Zero transactions then fail" -> error response containing the first error encountered.
187
+ 6. "Fail before transaction" -> same as #5.
@@ -0,0 +1,47 @@
1
+ import { Atom } from "@effect-atom/atom";
2
+ import type { HumanReadable, Query, Transaction, Schema as ZeroSchema } from "@rocicorp/zero";
3
+ import * as Cause from "effect/Cause";
4
+ import * as Context from "effect/Context";
5
+ import * as Effect from "effect/Effect";
6
+ import type * as ParseResult from "effect/ParseResult";
7
+ import * as Schema from "effect/Schema";
8
+ import * as Subscribable from "effect/Subscribable";
9
+ import { type AnyMutator, type AnyMutators, type ExtractMutatorsRequirements, MutatorArgsSchemaSym } from "./mutators.js";
10
+ export interface ZeroClientTransaction {
11
+ readonly _tag: unique symbol;
12
+ }
13
+ export declare const makeClient: <S extends ZeroSchema>() => {
14
+ unwrapMutators: <T extends AnyMutators>(mutators: T) => Effect.Effect<{ [A in keyof T]: T[A] extends AnyMutator ? UnwrapMutator<S, T[A]> : { [B in keyof T[A]]: T[A][B] extends AnyMutator ? UnwrapMutator<S, T[A][B]> : never; }; }, never, Exclude<ExtractMutatorsRequirements<T>, ZeroClientTransaction>>;
15
+ querySub: <T extends keyof S["tables"] & string, R>(query: Query<S, T, R>) => Effect.Effect<Subscribable.Subscribable<{
16
+ data: HumanReadable<R>;
17
+ status: "unknown" | "complete" | "error";
18
+ }, never, never>, never, import("effect/Scope").Scope>;
19
+ queryAtom: <T extends keyof S["tables"] & string, R_1>(arg: Query<S, T, R_1>) => Atom.Atom<import("@effect-atom/atom/Result").Result<HumanReadable<R_1>, never>>;
20
+ Transaction: Context.TagClass<ZeroClientTransaction, "effect-zero/ZeroClientTransaction", Transaction<S>> & {
21
+ use: <A>(fn: (transaction: Transaction<S>, options: {
22
+ readonly signal: AbortSignal;
23
+ }) => PromiseLike<A>) => Effect.Effect<A, ZeroClientTransactionError, ZeroClientTransaction>;
24
+ };
25
+ };
26
+ type UnwrapMutator<S extends ZeroSchema, T extends AnyMutator> = Parameters<T> extends [] ? (transaction: Transaction<S>) => Promise<void> : (transaction: Transaction<S>, args: Schema.Schema.Encoded<T[typeof MutatorArgsSchemaSym]>) => Promise<void>;
27
+ export type UnwrapMutators<S extends ZeroSchema, T extends AnyMutators> = {
28
+ [A in keyof T]: T[A] extends AnyMutator ? UnwrapMutator<S, T[A]> : {
29
+ [B in keyof T[A]]: T[A][B] extends AnyMutator ? UnwrapMutator<S, T[A][B]> : never;
30
+ };
31
+ } & {};
32
+ declare const ZeroClientTransactionError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Cause.YieldableError & {
33
+ readonly _tag: "ZeroClientTransactionError";
34
+ } & Readonly<A>;
35
+ export declare class ZeroClientTransactionError extends ZeroClientTransactionError_base<{
36
+ cause: Cause.Cause<unknown>;
37
+ }> {
38
+ }
39
+ declare const ZeroClientArgsParseError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Cause.YieldableError & {
40
+ readonly _tag: "ZeroClientArgsParseError";
41
+ } & Readonly<A>;
42
+ export declare class ZeroClientArgsParseError extends ZeroClientArgsParseError_base<{
43
+ cause: Cause.Cause<ParseResult.ParseError>;
44
+ }> {
45
+ }
46
+ export {};
47
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,KAAK,EAAE,aAAa,EAAE,KAAK,EAAqB,WAAW,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjH,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAE1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,OAAO,KAAK,KAAK,WAAW,MAAM,oBAAoB,CAAC;AAIvD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,YAAY,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EACL,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,2BAA2B,EAChC,oBAAoB,EACrB,MAAM,eAAe,CAAC;AAOvB,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,OAAO,MAAM,CAAC;CAC9B;AAED,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,UAAU;qBAcD,CAAC,SAAS,WAAW,mCAuEhE,CAAC,oEAEK,CAAC;eAlD8B,CAAC,SAAS,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,MAAM,EAAE,CAAC;;;;gBA+B9C,CAAC,SAAS,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,MAAM;;cAhEtD,CAAC,MAAM,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE;YAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;SAAE,KAAK,WAAW,CAAC,CAAC,CAAC;;CA0E/G,CAAC;AAEF,KAAK,aAAa,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,UAAU,IAAI,UAAU,CAAC,CAAC,CAAC,SAAS,EAAE,GACrF,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAC9C,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,oBAAoB,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEhH,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,WAAW,IAAI;KACvE,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,GACnC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GACtB;SAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,GAAG,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK;KAAE;CAC1F,GAAG,EAAE,CAAC;;;;AAEP,qBAAa,0BAA2B,SAAQ,gCAA+C;IAC7F,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;CAC7B,CAAC;CAAG;;;;AAEL,qBAAa,wBAAyB,SAAQ,8BAA6C;IACzF,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;CAC5C,CAAC;CAAG"}
package/dist/client.js ADDED
@@ -0,0 +1,61 @@
1
+ import { Atom } from "@effect-atom/atom";
2
+ import * as Cause from "effect/Cause";
3
+ import * as Context from "effect/Context";
4
+ import * as Data from "effect/Data";
5
+ import * as Effect from "effect/Effect";
6
+ import * as Exit from "effect/Exit";
7
+ import * as Match from "effect/Match";
8
+ import * as Predicate from "effect/Predicate";
9
+ import * as Rec from "effect/Record";
10
+ import * as Runtime from "effect/Runtime";
11
+ import * as Schema from "effect/Schema";
12
+ import * as Stream from "effect/Stream";
13
+ import * as Subscribable from "effect/Subscribable";
14
+ import * as SubscriptionRef from "effect/SubscriptionRef";
15
+ import { MutatorArgsSchemaSym, } from "./mutators.js";
16
+ import { deepClone, getDefaultSnapshot, getSnapshot } from "./snapshot.js";
17
+ import { prefixId } from "./utils.js";
18
+ export const makeClient = () => {
19
+ // TODO: Maybe prefix this / suffix this with a tag passed in to `make`?
20
+ const ZeroClientTransaction = Context.Tag(prefixId("ZeroClientTransaction"))();
21
+ const use = (fn) => Effect.flatMap(ZeroClientTransaction, (transaction) => Effect.promise((signal) => fn(transaction, { signal }))).pipe(Effect.tapErrorCause((cause) => Effect.logError(cause)), Effect.sandbox, Effect.annotateLogs({ module: prefixId("ZeroClient.Transaction"), method: "use" }), Effect.mapError((cause) => new ZeroClientTransactionError({ cause })));
22
+ const unwrapMutators = Effect.fn(function* (mutators) {
23
+ const runtime = yield* Effect.runtime();
24
+ function unwrapMutator(mutator) {
25
+ return async (tx, args) => {
26
+ const exit = await Schema.decode(mutator[MutatorArgsSchemaSym])(args).pipe(Effect.catchTag("ParseError", (e) => new ZeroClientArgsParseError({ cause: Cause.fail(e) })), Effect.flatMap(mutator), Effect.provideService(ZeroClientTransaction, tx), Runtime.runPromiseExit(runtime));
27
+ return Exit.getOrElse(exit, (c) => {
28
+ // Extract underlying error bypassing FiberFailure
29
+ throw Cause.squash(c);
30
+ });
31
+ };
32
+ }
33
+ return Rec.map(mutators, (v) => Match.value(v).pipe(Match.when(Predicate.isFunction, unwrapMutator), Match.orElse(Rec.map(unwrapMutator))));
34
+ });
35
+ const querySub = Effect.fn(function* (query) {
36
+ const view = yield* Effect.acquireRelease(Effect.sync(() => query.materialize()), (view) => Effect.sync(() => view.destroy()));
37
+ const subscriptionRef = yield* SubscriptionRef.make(getDefaultSnapshot(query.format.singular));
38
+ yield* Stream.asyncEffect((emit) => Effect.sync(() => view.addListener((...args) => emit.single(args)))).pipe(Stream.mapEffect(([data, resultType]) => Effect.sync(() => {
39
+ // logic here borrowed from: https://github.com/rocicorp/mono/blob/288b00ec94f5a9ae6e988513423af25c281dbb2a/packages/zero-react/src/use-query.tsx#L295
40
+ const cloned = data === undefined ? data : deepClone(data);
41
+ return getSnapshot(query.format.singular, cloned, resultType);
42
+ })), Stream.runForEach((snapshot) => SubscriptionRef.set(subscriptionRef, snapshot)), Effect.forkScoped);
43
+ return subscriptionRef.pipe(Subscribable.map(([data, { type: status }]) => ({
44
+ data,
45
+ status,
46
+ })));
47
+ });
48
+ /** Create an Atom for the query */
49
+ const queryAtom = Atom.family((query) => Atom.subscribable(querySub(query)).pipe(Atom.mapResult((res) => res.data)));
50
+ return {
51
+ unwrapMutators,
52
+ querySub,
53
+ queryAtom,
54
+ Transaction: Object.assign(ZeroClientTransaction, { use }),
55
+ };
56
+ };
57
+ export class ZeroClientTransactionError extends Data.TaggedError("ZeroClientTransactionError") {
58
+ }
59
+ export class ZeroClientArgsParseError extends Data.TaggedError("ZeroClientArgsParseError") {
60
+ }
61
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAGzC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,IAAI,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,IAAI,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,OAAO,KAAK,SAAS,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,GAAG,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,YAAY,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,eAAe,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAIL,oBAAoB,GACrB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAStC,MAAM,CAAC,MAAM,UAAU,GAAG,GAAyB,EAAE;IACnD,wEAAwE;IACxE,MAAM,qBAAqB,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAAC,EAAyC,CAAC;IAEtH,MAAM,GAAG,GAAG,CAAI,EAA8F,EAAE,EAAE,CAChH,MAAM,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC,WAAW,EAAE,EAAE,CACpD,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,CACxD,CAAC,IAAI,CACJ,MAAM,CAAC,aAAa,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EACvD,MAAM,CAAC,OAAO,EACd,MAAM,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,wBAAwB,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAClF,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,0BAA0B,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CACtE,CAAC;IAEJ,MAAM,cAAc,GAAG,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAyB,QAAW;QAC5E,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,EAAkE,CAAC;QAExG,SAAS,aAAa,CAAI,OAAsD;YAC9E,OAAO,KAAK,EAAE,EAAkB,EAAE,IAAa,EAAE,EAAE;gBACjD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACxE,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,wBAAwB,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAC5F,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EACvB,MAAM,CAAC,cAAc,CAAC,qBAAqB,EAAE,EAAE,CAAC,EAChD,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,CAChC,CAAC;gBACF,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE;oBAChC,kDAAkD;oBAClD,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;gBACxB,CAAC,CAAC,CAAC;YACL,CAAC,CAAC;QACJ,CAAC;QAED,OAAO,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAC7B,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,aAAa,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CACnF,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAA2C,KAAqB;QAClG,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,cAAc,CACvC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,EACtC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAC5C,CAAC;QAEF,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,eAAe,CAAC,IAAI,CAAiB,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAE/G,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAA0D,CAAC,IAAI,EAAE,EAAE,CAC1F,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CACpE,CAAC,IAAI,CACJ,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,EAAE,CACtC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;YACf,sJAAsJ;YACtJ,MAAM,MAAM,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAE,SAAS,CAAC,IAAyB,CAAsB,CAAC;YACtG,OAAO,WAAW,CAAI,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QACnE,CAAC,CAAC,CACH,EACD,MAAM,CAAC,UAAU,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC,EAC/E,MAAM,CAAC,UAAU,CAClB,CAAC;QAEF,OAAO,eAAe,CAAC,IAAI,CACzB,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YAC9C,IAAI;YACJ,MAAM;SACP,CAAC,CAAC,CACJ,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,mCAAmC;IACnC,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,CAA0C,KAAqB,EAAE,EAAE,CAC/F,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAC3E,CAAC;IAEF,OAAO;QACL,cAAc;QACd,QAAQ;QACR,SAAS;QACT,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,qBAAqB,EAAE,EAAE,GAAG,EAAE,CAAC;KAC3D,CAAC;AACJ,CAAC,CAAC;AAYF,MAAM,OAAO,0BAA2B,SAAQ,IAAI,CAAC,WAAW,CAAC,4BAA4B,CAE3F;CAAG;AAEL,MAAM,OAAO,wBAAyB,SAAQ,IAAI,CAAC,WAAW,CAAC,0BAA0B,CAEvF;CAAG"}
@@ -0,0 +1,35 @@
1
+ import type * as Effect from "effect/Effect";
2
+ import * as Schema from "effect/Schema";
3
+ export type AnyMutatorDef<R = any, TArgs extends any[] = any[]> = (...args: TArgs) => Effect.Effect<any, any, R>;
4
+ export type AnyMutatorDefs<R = any> = {
5
+ [K: string]: AnyMutatorDef<R> | {
6
+ [K: string]: AnyMutatorDef<R>;
7
+ };
8
+ };
9
+ export type AnyMutatorSchemaArgs = Schema.Schema<any, any, never>;
10
+ export type AnyMutatorSchema = Record<string, AnyMutatorSchemaArgs | Record<string, AnyMutatorSchemaArgs>>;
11
+ export type MutatorDefs<TSchema extends AnyMutatorSchema> = {
12
+ [K in keyof TSchema]: TSchema[K] extends AnyMutatorSchemaArgs ? AnyMutatorDef<unknown, [Schema.Schema.Type<TSchema[K]>]> : TSchema[K] extends infer TSchema extends Record<string, AnyMutatorSchemaArgs> ? {
13
+ [K in keyof TSchema]: AnyMutatorDef<unknown, [Schema.Schema.Type<TSchema[K]>]>;
14
+ } : never;
15
+ };
16
+ export declare const MutatorArgsSchemaSym: unique symbol;
17
+ export type Mutator<TFunc extends AnyMutatorDef = AnyMutatorDef, TSchema extends AnyMutatorSchemaArgs = AnyMutatorSchemaArgs> = TFunc & {
18
+ [MutatorArgsSchemaSym]: TSchema;
19
+ };
20
+ export type Mutators<TSchema extends AnyMutatorSchema, TDefs extends AnyMutatorDefs> = {
21
+ [K in keyof TDefs & keyof TSchema]: TDefs[K] extends AnyMutatorDef ? TSchema[K] extends AnyMutatorSchemaArgs ? Mutator<TDefs[K], TSchema[K]> : never : TSchema[K] extends infer TSchema extends Record<string, AnyMutatorSchemaArgs> ? TDefs[K] extends infer TDefs extends Record<string, AnyMutatorDef> ? {
22
+ [K in keyof TDefs & keyof TSchema]: Mutator<TDefs[K], TSchema[K]>;
23
+ } : never : never;
24
+ } & {};
25
+ export type AnyMutator<R = any, E = any> = Mutator<(...args: any[]) => Effect.Effect<any, E, R>>;
26
+ export type AnyMutators<R = any> = Record<string, AnyMutator<R> | Record<string, AnyMutator<R>>>;
27
+ export type ExtractMutatorsRequirements<T extends AnyMutators> = T extends AnyMutators<infer R> ? R : never;
28
+ export declare class MutatorSchema<T extends AnyMutatorSchema> {
29
+ schema: T;
30
+ private constructor();
31
+ static make<T extends AnyMutatorSchema>(schema: T): MutatorSchema<T>;
32
+ private makeMutator;
33
+ makeMutators<TDefs extends MutatorDefs<T>>(mutators: TDefs): Mutators<T, TDefs>;
34
+ }
35
+ //# sourceMappingURL=mutators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutators.d.ts","sourceRoot":"","sources":["../src/mutators.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import * as Match from "effect/Match";
2
+ import * as Option from "effect/Option";
3
+ import * as Predicate from "effect/Predicate";
4
+ import * as Rec from "effect/Record";
5
+ import * as Schema from "effect/Schema";
6
+ import { prefixId } from "./utils.js";
7
+ export const MutatorArgsSchemaSym = Symbol.for(prefixId("MutatorArgsSchema"));
8
+ export class MutatorSchema {
9
+ schema;
10
+ constructor(schema) {
11
+ this.schema = schema;
12
+ }
13
+ static make(schema) {
14
+ return new MutatorSchema(schema);
15
+ }
16
+ // Associates mutator with its args schema
17
+ makeMutator(argsSchema, fn) {
18
+ return Object.assign(fn, { [MutatorArgsSchemaSym]: argsSchema });
19
+ }
20
+ makeMutators(mutators) {
21
+ return Rec.map(mutators, (v, name) => {
22
+ return Match.value([v, this.schema[name]]).pipe(Match.when([Predicate.isFunction, Schema.isSchema], ([mutator, schema]) => this.makeMutator(schema, mutator)), Match.when([Predicate.isRecord, Predicate.isRecord], ([mutator, schema]) => Rec.map(mutator, (mutator, name) => this.makeMutator(Option.getOrThrow(Rec.get(schema, name)), mutator))), Match.orElseAbsurd);
23
+ });
24
+ }
25
+ }
26
+ //# sourceMappingURL=mutators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutators.js","sourceRoot":"","sources":["../src/mutators.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,SAAS,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,GAAG,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAsBtC,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC,CAAC;AA6B9E,MAAM,OAAO,aAAa;IACG;IAA3B,YAA2B,MAAS;QAAT,WAAM,GAAN,MAAM,CAAG;IAAG,CAAC;IAExC,MAAM,CAAC,IAAI,CAA6B,MAAS;QAC/C,OAAO,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAED,0CAA0C;IAClC,WAAW,CAAC,UAAgC,EAAE,EAAiB;QACrE,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,oBAAoB,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;IACnE,CAAC;IAGD,YAAY,CAAC,QAAwB;QACnC,OAAO,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE;YACnC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAC7C,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAC7G,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EAAE,CACzE,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CACzG,EACD,KAAK,CAAC,YAAY,CACnB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,188 @@
1
+ import type { Database, TransactionProviderHooks, TransactionProviderInput } from "@rocicorp/zero/pg";
2
+ import * as Cause from "effect/Cause";
3
+ import * as Context from "effect/Context";
4
+ import * as Effect from "effect/Effect";
5
+ import * as SynchronizedRef from "effect/SynchronizedRef";
6
+ import { type AnyMutators, type ExtractMutatorsRequirements } from "./mutators.js";
7
+ export interface ZeroServerTransactionContext {
8
+ readonly _tag: unique symbol;
9
+ }
10
+ export declare const makeServer: <T, I = never>(options: {
11
+ database: Database<T>;
12
+ clientTransaction?: Context.Tag<I, T>;
13
+ }) => {
14
+ Transaction: Context.TagClass<ZeroServerTransactionContext, "effect-zero/ZeroServerTransactionContext", {
15
+ transaction: T;
16
+ transactionHooks: TransactionProviderHooks;
17
+ }> & {
18
+ execute: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect.AsEffect<Effect.Effect<A, ZeroDatabaseError | UpdateClientMutationIDError | MultipleTransactionsError | OutOfOrderMutationError | MutationAlreadyProcessedError | E, ZeroTransactionInput | ZeroServerMutationContext | Exclude<Exclude<R, ZeroServerTransactionContext>, I>>>;
19
+ use: <A>(fn: (transaction: T, options: {
20
+ readonly signal: AbortSignal;
21
+ }) => PromiseLike<A>) => Effect.Effect<A, unknown, ZeroServerTransactionContext>;
22
+ };
23
+ processPush: <T_1 extends AnyMutators>(mutators: T_1, params: {
24
+ readonly schema: string;
25
+ readonly appID: string;
26
+ }, request: {
27
+ readonly timestamp: number;
28
+ readonly clientGroupID: string;
29
+ readonly mutations: readonly ({
30
+ readonly name: "_zero_crud";
31
+ readonly type: "crud";
32
+ readonly id: number;
33
+ readonly clientID: string;
34
+ readonly args: readonly [{
35
+ readonly ops: readonly ({
36
+ readonly value: {
37
+ readonly [x: string]: unknown;
38
+ };
39
+ readonly primaryKey: readonly string[];
40
+ readonly op: "insert";
41
+ readonly tableName: string;
42
+ } | {
43
+ readonly value: {
44
+ readonly [x: string]: unknown;
45
+ };
46
+ readonly primaryKey: readonly string[];
47
+ readonly op: "upsert";
48
+ readonly tableName: string;
49
+ } | {
50
+ readonly value: {
51
+ readonly [x: string]: unknown;
52
+ };
53
+ readonly primaryKey: readonly string[];
54
+ readonly op: "update";
55
+ readonly tableName: string;
56
+ } | {
57
+ readonly value: {
58
+ readonly [x: string]: string | number | boolean;
59
+ };
60
+ readonly primaryKey: readonly string[];
61
+ readonly op: "delete";
62
+ readonly tableName: string;
63
+ })[];
64
+ }];
65
+ readonly timestamp: number;
66
+ } | {
67
+ readonly name: string;
68
+ readonly type: "custom";
69
+ readonly id: number;
70
+ readonly clientID: string;
71
+ readonly args: readonly unknown[];
72
+ readonly timestamp: number;
73
+ })[];
74
+ readonly pushVersion: number;
75
+ readonly schemaVersion?: number | undefined;
76
+ readonly requestID: string;
77
+ }) => Effect.Effect<{
78
+ error: "unsupportedPushVersion";
79
+ mutations?: undefined;
80
+ } | {
81
+ mutations: {
82
+ readonly id: {
83
+ readonly id: number;
84
+ readonly clientID: string;
85
+ };
86
+ readonly result: {
87
+ readonly error: "app";
88
+ readonly details?: unknown;
89
+ } | {
90
+ readonly error: "oooMutation" | "alreadyProcessed";
91
+ readonly details?: unknown;
92
+ } | {
93
+ readonly data?: unknown;
94
+ };
95
+ }[];
96
+ error?: undefined;
97
+ }, CustomMutationExpectedError, Exclude<Exclude<ExtractMutatorsRequirements<T_1>, ZeroServerMutationContext>, ZeroTransactionInput>>;
98
+ };
99
+ declare const ZeroTransactionInput_base: Context.TagClass<ZeroTransactionInput, "effect-zero/ZeroTransactionInput", TransactionProviderInput>;
100
+ declare class ZeroTransactionInput extends ZeroTransactionInput_base {
101
+ }
102
+ declare const ZeroServerMutationContext_base: Effect.Service.Class<ZeroServerMutationContext, "effect-zero/ZeroServerMutationContext", {
103
+ readonly effect: Effect.Effect<{
104
+ wasTransactionExecuted: SynchronizedRef.SynchronizedRef<boolean>;
105
+ }, never, never>;
106
+ }>;
107
+ declare class ZeroServerMutationContext extends ZeroServerMutationContext_base {
108
+ static wasTransactionExecuted: Effect.Effect<boolean, never, ZeroServerMutationContext>;
109
+ static guard: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E | MultipleTransactionsError, ZeroServerMutationContext | R>;
110
+ }
111
+ declare const ZeroDatabaseError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Cause.YieldableError & {
112
+ readonly _tag: "ZeroDatabaseError";
113
+ } & Readonly<A>;
114
+ declare class ZeroDatabaseError extends ZeroDatabaseError_base<{
115
+ cause: Cause.Cause<unknown>;
116
+ }> {
117
+ }
118
+ declare const UpdateClientMutationIDError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Cause.YieldableError & {
119
+ readonly _tag: "UpdateClientMutationIDError";
120
+ } & Readonly<A>;
121
+ declare class UpdateClientMutationIDError extends UpdateClientMutationIDError_base<{
122
+ readonly cause: Cause.Cause<unknown>;
123
+ }> {
124
+ }
125
+ declare const CustomMutationExpectedError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Cause.YieldableError & {
126
+ readonly _tag: "CustomMutationExpectedError";
127
+ } & Readonly<A>;
128
+ declare class CustomMutationExpectedError extends CustomMutationExpectedError_base<object> {
129
+ }
130
+ declare const MultipleTransactionsError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Cause.YieldableError & {
131
+ readonly _tag: "MultipleTransactionsError";
132
+ } & Readonly<A>;
133
+ export declare class MultipleTransactionsError extends MultipleTransactionsError_base {
134
+ message: string;
135
+ }
136
+ declare const NoTransactionError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Cause.YieldableError & {
137
+ readonly _tag: "NoTransactionError";
138
+ } & Readonly<A>;
139
+ export declare class NoTransactionError extends NoTransactionError_base {
140
+ message: string;
141
+ }
142
+ declare const OutOfOrderMutationErrorTypeId: unique symbol;
143
+ declare const OutOfOrderMutationError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Cause.YieldableError & {
144
+ readonly _tag: "OutOfOrderMutationError";
145
+ } & Readonly<A>;
146
+ export declare class OutOfOrderMutationError extends OutOfOrderMutationError_base<{
147
+ readonly clientID: string;
148
+ readonly receivedMutationID: number;
149
+ readonly lastMutationID: number | bigint;
150
+ }> {
151
+ readonly [OutOfOrderMutationErrorTypeId]: symbol;
152
+ get message(): string;
153
+ static is(e: unknown): e is OutOfOrderMutationError;
154
+ }
155
+ declare const MutationAlreadyProcessedErrorTypeId: unique symbol;
156
+ declare const MutationAlreadyProcessedError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Cause.YieldableError & {
157
+ readonly _tag: "MutationAlreadyProcessedError";
158
+ } & Readonly<A>;
159
+ export declare class MutationAlreadyProcessedError extends MutationAlreadyProcessedError_base<{
160
+ readonly clientID: string;
161
+ readonly received: number;
162
+ readonly actual: number | bigint;
163
+ }> {
164
+ readonly [MutationAlreadyProcessedErrorTypeId]: symbol;
165
+ get message(): string;
166
+ static is(e: unknown): e is MutationAlreadyProcessedError;
167
+ }
168
+ declare const ZeroTransactionUserErrorTypeId: unique symbol;
169
+ declare const ZeroTransactionUserError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Cause.YieldableError & {
170
+ readonly _tag: "ZeroTransactionUserError";
171
+ } & Readonly<A>;
172
+ export declare class ZeroTransactionUserError extends ZeroTransactionUserError_base {
173
+ readonly [ZeroTransactionUserErrorTypeId]: symbol;
174
+ static is(e: unknown): e is ZeroTransactionUserError;
175
+ }
176
+ declare const ZeroMutationUserErrorTypeId: unique symbol;
177
+ declare const ZeroMutationUserError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Cause.YieldableError & {
178
+ readonly _tag: "ZeroMutationUserError";
179
+ } & Readonly<A>;
180
+ export declare class ZeroMutationUserError extends ZeroMutationUserError_base<{
181
+ cause: Cause.Cause<unknown>;
182
+ }> {
183
+ readonly [ZeroMutationUserErrorTypeId]: symbol;
184
+ static is(e: unknown): e is ZeroMutationUserError;
185
+ get message(): string;
186
+ }
187
+ export {};
188
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}