@shivaedev/effect-contract 0.4.0 → 0.5.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/src/operation.ts CHANGED
@@ -3,15 +3,15 @@ import type { Bivariant } from "@shivaedev/types/bivariant.ts";
3
3
  import type { Key } from "./keys.ts";
4
4
  import { type MatchingTags, type Reject, type RejectionSpecs, type Rejections, type RejectionUnion, rejectionSet } from "./rejection.ts";
5
5
 
6
- export type PayloadSchema<Payload extends Schema.Top | Schema.Struct.Fields> = Payload extends Schema.Struct.Fields
7
- ? Schema.Struct<Payload>
8
- : Payload;
6
+ export type PayloadSchema<TPayload extends Schema.Top | Schema.Struct.Fields> = TPayload extends Schema.Struct.Fields
7
+ ? Schema.Struct<TPayload>
8
+ : TPayload;
9
9
 
10
10
  type NoRejections = Record<never, never>;
11
11
 
12
12
  export interface OperationShape {
13
13
  readonly error: Schema.Top;
14
- readonly kind: "query" | "command";
14
+ readonly kind: "query" | "command" | "stream";
15
15
  readonly name: string;
16
16
  readonly payload: Schema.Top;
17
17
  readonly Rejection: object;
@@ -25,38 +25,49 @@ export interface QueryShape extends OperationShape {
25
25
  reads: Bivariant<(payload: unknown) => readonly Key[]>;
26
26
  }
27
27
 
28
+ export interface StreamShape extends OperationShape {
29
+ readonly kind: "stream";
30
+ reads: Bivariant<(payload: unknown) => readonly Key[]>;
31
+ }
32
+
28
33
  export interface CommandShape extends OperationShape {
29
34
  invalidates: Bivariant<(payload: unknown, result: unknown) => readonly Key[]>;
30
35
  readonly kind: "command";
31
36
  }
32
37
 
33
- interface Operation<Name extends string, Payload extends Schema.Top, Success extends Schema.Top, Specs extends RejectionSpecs>
38
+ interface Operation<TName extends string, TPayload extends Schema.Top, TSuccess extends Schema.Top, TSpecs extends RejectionSpecs>
34
39
  extends OperationShape {
35
- readonly error: RejectionUnion<Specs>;
36
- readonly name: Name;
37
- readonly payload: Payload;
38
- readonly Rejection: Rejections<Specs>;
39
- readonly reject: Reject<Specs>;
40
- readonly rejections: Specs;
41
- readonly success: Success;
40
+ readonly error: RejectionUnion<TSpecs>;
41
+ readonly name: TName;
42
+ readonly payload: TPayload;
43
+ readonly Rejection: Rejections<TSpecs>;
44
+ readonly reject: Reject<TSpecs>;
45
+ readonly rejections: TSpecs;
46
+ readonly success: TSuccess;
42
47
  }
43
48
 
44
- export interface Query<Name extends string, Payload extends Schema.Top, Success extends Schema.Top, Specs extends RejectionSpecs>
45
- extends Operation<Name, Payload, Success, Specs> {
49
+ export interface Query<TName extends string, TPayload extends Schema.Top, TSuccess extends Schema.Top, TSpecs extends RejectionSpecs>
50
+ extends Operation<TName, TPayload, TSuccess, TSpecs> {
46
51
  readonly kind: "query";
47
- reads: (payload: Payload["Type"]) => readonly Key[];
52
+ reads: (payload: TPayload["Type"]) => readonly Key[];
48
53
  }
49
54
 
50
- export interface Command<Name extends string, Payload extends Schema.Top, Success extends Schema.Top, Specs extends RejectionSpecs>
51
- extends Operation<Name, Payload, Success, Specs> {
52
- invalidates: (payload: Payload["Type"], result: Success["Type"]) => readonly Key[];
55
+ export interface Streaming<TName extends string, TPayload extends Schema.Top, TSuccess extends Schema.Top, TSpecs extends RejectionSpecs>
56
+ extends Operation<TName, TPayload, TSuccess, TSpecs> {
57
+ readonly kind: "stream";
58
+ reads: (payload: TPayload["Type"]) => readonly Key[];
59
+ }
60
+
61
+ export interface Command<TName extends string, TPayload extends Schema.Top, TSuccess extends Schema.Top, TSpecs extends RejectionSpecs>
62
+ extends Operation<TName, TPayload, TSuccess, TSpecs> {
63
+ invalidates: (payload: TPayload["Type"], result: TSuccess["Type"]) => readonly Key[];
53
64
  readonly kind: "command";
54
65
  }
55
66
 
56
- interface Declaration<Payload extends Schema.Top | Schema.Struct.Fields, Success extends Schema.Top, Specs extends RejectionSpecs> {
57
- readonly payload?: Payload;
58
- readonly rejections?: Specs & MatchingTags<Specs>;
59
- readonly success?: Success;
67
+ interface Declaration<TPayload extends Schema.Top | Schema.Struct.Fields, TSuccess extends Schema.Top, TSpecs extends RejectionSpecs> {
68
+ readonly payload?: TPayload;
69
+ readonly rejections?: TSpecs & MatchingTags<TSpecs>;
70
+ readonly success?: TSuccess;
60
71
  }
61
72
 
62
73
  interface Loose {
@@ -65,14 +76,14 @@ interface Loose {
65
76
  readonly success?: Schema.Top;
66
77
  }
67
78
 
68
- const payloadSchema = (payload: Loose["payload"]): Schema.Top => {
79
+ function payloadSchema(payload: Loose["payload"]): Schema.Top {
69
80
  if (payload === undefined) {
70
81
  return Schema.Void;
71
82
  }
72
83
  return Schema.isSchema(payload) ? payload : Schema.Struct(payload);
73
- };
84
+ }
74
85
 
75
- const operation = <Kind extends OperationShape["kind"]>(kind: Kind, name: string, declaration: Loose) => {
86
+ function operation<TKind extends OperationShape["kind"]>(kind: TKind, name: string, declaration: Loose) {
76
87
  const { payload, success, rejections = {} } = declaration;
77
88
  return {
78
89
  kind,
@@ -82,37 +93,53 @@ const operation = <Kind extends OperationShape["kind"]>(kind: Kind, name: string
82
93
  success: success ?? Schema.Void,
83
94
  ...rejectionSet(rejections),
84
95
  };
85
- };
96
+ }
86
97
 
87
98
  export function query<
88
- const Name extends string,
89
- Payload extends Schema.Top | Schema.Struct.Fields = Schema.Void,
90
- Success extends Schema.Top = Schema.Void,
91
- const Specs extends RejectionSpecs = NoRejections,
99
+ const TName extends string,
100
+ TPayload extends Schema.Top | Schema.Struct.Fields = Schema.Void,
101
+ TSuccess extends Schema.Top = Schema.Void,
102
+ const TSpecs extends RejectionSpecs = NoRejections,
92
103
  >(
93
- name: Name,
94
- declaration: Declaration<Payload, Success, Specs> & {
95
- readonly reads: (payload: PayloadSchema<Payload>["Type"]) => readonly Key[];
104
+ name: TName,
105
+ declaration: Declaration<TPayload, TSuccess, TSpecs> & {
106
+ readonly reads: (payload: PayloadSchema<TPayload>["Type"]) => readonly Key[];
96
107
  },
97
- ): NoInfer<Query<Name, PayloadSchema<Payload>, Success, Specs>>;
108
+ ): NoInfer<Query<TName, PayloadSchema<TPayload>, TSuccess, TSpecs>>;
98
109
  export function query(name: string, declaration: Loose & { readonly reads: (payload: unknown) => readonly Key[] }): QueryShape {
99
110
  return { ...operation("query", name, declaration), reads: declaration.reads };
100
111
  }
101
112
 
102
113
  export function command<
103
- const Name extends string,
104
- Payload extends Schema.Top | Schema.Struct.Fields = Schema.Void,
105
- Success extends Schema.Top = Schema.Void,
106
- const Specs extends RejectionSpecs = NoRejections,
114
+ const TName extends string,
115
+ TPayload extends Schema.Top | Schema.Struct.Fields = Schema.Void,
116
+ TSuccess extends Schema.Top = Schema.Void,
117
+ const TSpecs extends RejectionSpecs = NoRejections,
107
118
  >(
108
- name: Name,
109
- declaration: Declaration<Payload, Success, Specs> & {
110
- readonly invalidates: (payload: PayloadSchema<Payload>["Type"], result: Success["Type"]) => readonly Key[];
119
+ name: TName,
120
+ declaration: Declaration<TPayload, TSuccess, TSpecs> & {
121
+ readonly invalidates: (payload: PayloadSchema<TPayload>["Type"], result: TSuccess["Type"]) => readonly Key[];
111
122
  },
112
- ): NoInfer<Command<Name, PayloadSchema<Payload>, Success, Specs>>;
123
+ ): NoInfer<Command<TName, PayloadSchema<TPayload>, TSuccess, TSpecs>>;
113
124
  export function command(
114
125
  name: string,
115
126
  declaration: Loose & { readonly invalidates: (payload: unknown, result: unknown) => readonly Key[] },
116
127
  ): CommandShape {
117
128
  return { ...operation("command", name, declaration), invalidates: declaration.invalidates };
118
129
  }
130
+
131
+ export function stream<
132
+ const TName extends string,
133
+ TPayload extends Schema.Top | Schema.Struct.Fields = Schema.Void,
134
+ TSuccess extends Schema.Top = Schema.Void,
135
+ const TSpecs extends RejectionSpecs = NoRejections,
136
+ >(
137
+ name: TName,
138
+ declaration: Declaration<TPayload, TSuccess, TSpecs> & {
139
+ readonly success: TSuccess;
140
+ readonly reads: (payload: PayloadSchema<TPayload>["Type"]) => readonly Key[];
141
+ },
142
+ ): NoInfer<Streaming<TName, PayloadSchema<TPayload>, TSuccess, TSpecs>>;
143
+ export function stream(name: string, declaration: Loose & { readonly reads: (payload: unknown) => readonly Key[] }): StreamShape {
144
+ return { ...operation("stream", name, declaration), reads: declaration.reads };
145
+ }
package/src/rejection.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import { type Cause, Effect, Schema } from "effect";
2
2
 
3
- export type RejectionValue<Tag extends string, Fields extends Schema.Struct.Fields> = Schema.TaggedStruct<Tag, Fields>["Type"] & Cause.YieldableError;
3
+ export type RejectionValue<TTag extends string, TFields extends Schema.Struct.Fields> = Schema.TaggedStruct<TTag, TFields>["Type"] &
4
+ Cause.YieldableError;
4
5
 
5
- export type RejectionClass<Tag extends string, Fields extends Schema.Struct.Fields> = Schema.Class<
6
- RejectionValue<Tag, Fields>,
7
- Schema.TaggedStruct<Tag, Fields>,
6
+ export type RejectionClass<TTag extends string, TFields extends Schema.Struct.Fields> = Schema.Class<
7
+ RejectionValue<TTag, TFields>,
8
+ Schema.TaggedStruct<TTag, TFields>,
8
9
  Cause.YieldableError
9
10
  >;
10
11
 
@@ -14,42 +15,42 @@ export interface RejectionSpecs {
14
15
  readonly [tag: string]: Schema.Struct.Fields | TaggedRejection;
15
16
  }
16
17
 
17
- export type Rejections<Specs extends RejectionSpecs> = {
18
- readonly [Tag in keyof Specs & string]: Specs[Tag] extends TaggedRejection
19
- ? Specs[Tag]
20
- : Specs[Tag] extends Schema.Struct.Fields
21
- ? RejectionClass<Tag, Specs[Tag]>
18
+ export type Rejections<TSpecs extends RejectionSpecs> = {
19
+ readonly [TTag in keyof TSpecs & string]: TSpecs[TTag] extends TaggedRejection
20
+ ? TSpecs[TTag]
21
+ : TSpecs[TTag] extends Schema.Struct.Fields
22
+ ? RejectionClass<TTag, TSpecs[TTag]>
22
23
  : never;
23
24
  };
24
25
 
25
- export type RejectedBy<Specs extends RejectionSpecs> = {
26
- [Tag in keyof Specs & string]: Rejections<Specs>[Tag]["Type"];
27
- }[keyof Specs & string];
26
+ export type RejectedBy<TSpecs extends RejectionSpecs> = {
27
+ [TTag in keyof TSpecs & string]: Rejections<TSpecs>[TTag]["Type"];
28
+ }[keyof TSpecs & string];
28
29
 
29
- export type Reject<Specs extends RejectionSpecs> = {
30
- readonly [Tag in keyof Specs & string]: Rejections<Specs>[Tag] extends new (
31
- ...args: infer Arguments
32
- ) => infer Value
33
- ? (...args: Arguments) => Effect.Effect<never, Value>
30
+ export type Reject<TSpecs extends RejectionSpecs> = {
31
+ readonly [TTag in keyof TSpecs & string]: Rejections<TSpecs>[TTag] extends new (
32
+ ...args: infer TArguments
33
+ ) => infer TValue
34
+ ? (...args: TArguments) => Effect.Effect<never, TValue>
34
35
  : never;
35
36
  };
36
37
 
37
- export type RejectionUnion<Specs extends RejectionSpecs> = [keyof Specs & string] extends [never]
38
+ export type RejectionUnion<TSpecs extends RejectionSpecs> = [keyof TSpecs & string] extends [never]
38
39
  ? Schema.Never
39
- : Schema.Union<readonly Rejections<Specs>[keyof Specs & string][]>;
40
+ : Schema.Union<readonly Rejections<TSpecs>[keyof TSpecs & string][]>;
40
41
 
41
- export type MatchingTags<Specs extends RejectionSpecs> = {
42
- readonly [Tag in keyof Specs]: Specs[Tag] extends TaggedRejection
43
- ? Specs[Tag]["Type"] extends { readonly _tag: Tag }
44
- ? Specs[Tag]
45
- : `The rejection class under "${Tag & string}" must have that _tag`
46
- : Specs[Tag];
42
+ export type MatchingTags<TSpecs extends RejectionSpecs> = {
43
+ readonly [TTag in keyof TSpecs]: TSpecs[TTag] extends TaggedRejection
44
+ ? TSpecs[TTag]["Type"] extends { readonly _tag: TTag }
45
+ ? TSpecs[TTag]
46
+ : `The rejection class under "${TTag & string}" must have that _tag`
47
+ : TSpecs[TTag];
47
48
  };
48
49
 
49
- export interface RejectionSet<Specs extends RejectionSpecs> {
50
- readonly error: RejectionUnion<Specs>;
51
- readonly Rejection: Rejections<Specs>;
52
- readonly reject: Reject<Specs>;
50
+ export interface RejectionSet<TSpecs extends RejectionSpecs> {
51
+ readonly error: RejectionUnion<TSpecs>;
52
+ readonly Rejection: Rejections<TSpecs>;
53
+ readonly reject: Reject<TSpecs>;
53
54
  }
54
55
 
55
56
  interface LooseRejectionSet {
@@ -58,7 +59,7 @@ interface LooseRejectionSet {
58
59
  readonly reject: { readonly [tag: string]: (...args: readonly unknown[]) => Effect.Effect<never, unknown> };
59
60
  }
60
61
 
61
- export function rejectionSet<const Specs extends RejectionSpecs>(specs: Specs): RejectionSet<Specs>;
62
+ export function rejectionSet<const TSpecs extends RejectionSpecs>(specs: TSpecs): RejectionSet<TSpecs>;
62
63
  export function rejectionSet(specs: RejectionSpecs): LooseRejectionSet {
63
64
  const classes = Object.entries(specs).map(([tag, spec]): readonly [string, TaggedRejection] => [
64
65
  tag,
@@ -73,16 +74,18 @@ export function rejectionSet(specs: RejectionSpecs): LooseRejectionSet {
73
74
  };
74
75
  }
75
76
 
76
- export type FieldRejection<Field extends string> = Readonly<{
77
- field: Schema.Literals<readonly Field[]>;
77
+ export type FieldRejection<TField extends string> = Readonly<{
78
+ field: Schema.Literals<readonly TField[]>;
78
79
  message: Schema.String;
79
80
  }>;
80
81
 
81
- export function fieldRejection<const Fields extends Schema.Struct.Fields>(struct: { readonly fields: Fields }): FieldRejection<keyof Fields & string>;
82
- export function fieldRejection<const Fields extends Schema.Struct.Fields, const Field extends keyof Fields & string>(
83
- struct: { readonly fields: Fields },
84
- fields: readonly Field[],
85
- ): FieldRejection<Field>;
82
+ export function fieldRejection<const TFields extends Schema.Struct.Fields>(struct: {
83
+ readonly fields: TFields;
84
+ }): FieldRejection<keyof TFields & string>;
85
+ export function fieldRejection<const TFields extends Schema.Struct.Fields, const TField extends keyof TFields & string>(
86
+ struct: { readonly fields: TFields },
87
+ fields: readonly TField[],
88
+ ): FieldRejection<TField>;
86
89
  export function fieldRejection(struct: { readonly fields: Schema.Struct.Fields }, fields?: readonly string[]): FieldRejection<string> {
87
90
  return { field: Schema.Literals(fields ?? Object.keys(struct.fields)), message: Schema.String };
88
91
  }
package/src/resume.ts CHANGED
@@ -1,4 +1,4 @@
1
- import * as Atom from "effect/unstable/reactivity/Atom";
1
+ import * as Atom from "effect/reactivity/Atom";
2
2
 
3
3
  export type ResumeSource = (resume: () => void) => () => void;
4
4