@shivaedev/form 0.8.0 → 0.9.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/CHANGELOG.md +10 -0
- package/README.md +5 -16
- package/dist/form.d.ts +1 -1
- package/dist/form.d.ts.map +1 -1
- package/dist/form.js +8 -3
- package/dist/form.js.map +1 -1
- package/dist/shape.d.ts +5 -2
- package/dist/shape.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/form.ts +25 -4
- package/src/shape.ts +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.9.0 - 2026-10-30
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Forms without application service requirements can omit `runtime` and use an empty atom runtime. Handlers, advisory checks and schema decoding that require application services still need a matching runtime.
|
|
8
|
+
|
|
9
|
+
### Breaking
|
|
10
|
+
|
|
11
|
+
- `Config` is a conditional type so service requirements determine whether `runtime` is required. Extend generic configurations with an intersection type instead of an interface that extends `Config`.
|
|
12
|
+
|
|
3
13
|
## 0.8.0 - 2026-10-30
|
|
4
14
|
|
|
5
15
|
### Fixed
|
package/README.md
CHANGED
|
@@ -10,7 +10,6 @@ An input gives you a string; your service needs a number. Meanwhile, fresh serve
|
|
|
10
10
|
const order = form(Schema.Struct({ name: Schema.String, quantity: Schema.NumberFromString }), {
|
|
11
11
|
initialValues: { name: "Paper", quantity: "300" },
|
|
12
12
|
onSubmit: Effect.succeed,
|
|
13
|
-
runtime,
|
|
14
13
|
});
|
|
15
14
|
|
|
16
15
|
order.change("name", "Copy paper");
|
|
@@ -29,21 +28,19 @@ The **baseline** is the encoded value against which the form recognizes edits. I
|
|
|
29
28
|
|
|
30
29
|
Keep one form instance for one editing session. Use a new instance for a different entity or user session. Query acquisition, entity identity, normalized saved rows and create-reset orchestration can be composed with [`useEditor` and `useCreate`](https://github.com/ShivaeDev/platform/blob/main/packages/react/README.md) from `@shivaedev/react`.
|
|
31
30
|
|
|
32
|
-
### Once per application: supply
|
|
31
|
+
### Once per application: supply services and a registry
|
|
33
32
|
|
|
34
|
-
`form`
|
|
33
|
+
`form` uses an empty atom runtime when the handler, field checks and schema decoding need no application services. To use application services, pass `runtime: Atom.runtime(layer)` with a Layer that provides them. Missing service dependencies fail to compile. The native `Scope`, `AtomRegistry` and `Reactivity` services are available without a supplied runtime.
|
|
35
34
|
|
|
36
35
|
Use an `AtomRegistry` to mount and read atoms and write the submit atom. Own its lifetime at the application boundary. In React, provide that registry through `RegistryContext` from `@effect/atom-react`.
|
|
37
36
|
|
|
38
37
|
### Once per feature: define fields and submission
|
|
39
38
|
|
|
40
39
|
```ts
|
|
41
|
-
import { Effect,
|
|
42
|
-
import * as Atom from "effect/reactivity/Atom";
|
|
40
|
+
import { Effect, Schema } from "effect";
|
|
43
41
|
import * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
44
42
|
import { form } from "@shivaedev/form/form.ts";
|
|
45
43
|
|
|
46
|
-
const runtime = Atom.runtime(Layer.empty);
|
|
47
44
|
const fields = Schema.Struct({
|
|
48
45
|
name: Schema.NonEmptyString,
|
|
49
46
|
quantity: Schema.NumberFromString,
|
|
@@ -52,7 +49,6 @@ const fields = Schema.Struct({
|
|
|
52
49
|
const order = form(fields, {
|
|
53
50
|
initialValues: { name: "Paper", quantity: "300" },
|
|
54
51
|
onSubmit: (values, submitter) => (values.name === "reserved" ? submitter.fail("name", "Choose another name") : Effect.succeed(values)),
|
|
55
|
-
runtime,
|
|
56
52
|
});
|
|
57
53
|
|
|
58
54
|
const registry = AtomRegistry.make();
|
|
@@ -77,15 +73,13 @@ The handler has three arguments: decoded values, the submitter, and the submitte
|
|
|
77
73
|
|
|
78
74
|
```tsx
|
|
79
75
|
import { RegistryContext } from "@effect/atom-react";
|
|
80
|
-
import { Effect,
|
|
81
|
-
import * as Atom from "effect/reactivity/Atom";
|
|
76
|
+
import { Effect, Schema } from "effect";
|
|
82
77
|
import * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
83
78
|
import { useState } from "react";
|
|
84
79
|
import { createRoot } from "react-dom/client";
|
|
85
80
|
import { form } from "@shivaedev/form/form.ts";
|
|
86
81
|
import { useDirty, useField, useSubmit } from "@shivaedev/form/client/react.ts";
|
|
87
82
|
|
|
88
|
-
const runtime = Atom.runtime(Layer.empty);
|
|
89
83
|
const fields = Schema.Struct({ name: Schema.NonEmptyString, quantity: Schema.NumberFromString });
|
|
90
84
|
|
|
91
85
|
function OrderEditor() {
|
|
@@ -93,7 +87,6 @@ function OrderEditor() {
|
|
|
93
87
|
form(fields, {
|
|
94
88
|
initialValues: { name: "Paper", quantity: "300" },
|
|
95
89
|
onSubmit: Effect.succeed,
|
|
96
|
-
runtime,
|
|
97
90
|
}),
|
|
98
91
|
);
|
|
99
92
|
const name = useField(order, "name");
|
|
@@ -174,7 +167,6 @@ const order = form(fields, {
|
|
|
174
167
|
initialValues: { name: "Paper", quantity: "300" },
|
|
175
168
|
onSubmit: Effect.succeed,
|
|
176
169
|
persistedDraft: { key: "order:123", now, storage: () => window.localStorage },
|
|
177
|
-
runtime,
|
|
178
170
|
});
|
|
179
171
|
```
|
|
180
172
|
|
|
@@ -191,7 +183,6 @@ function OrderEditor({ now }: { readonly now: () => number }) {
|
|
|
191
183
|
initialValues: { name: "Paper", quantity: "300" },
|
|
192
184
|
onSubmit: Effect.succeed,
|
|
193
185
|
persistedDraft,
|
|
194
|
-
runtime,
|
|
195
186
|
}),
|
|
196
187
|
);
|
|
197
188
|
return <OrderFields form={order} />;
|
|
@@ -220,7 +211,6 @@ const profile = form(Schema.Struct({ name: Schema.String }), {
|
|
|
220
211
|
debounce: "300 millis",
|
|
221
212
|
initialValues: { name: "" },
|
|
222
213
|
onSubmit: Effect.succeed,
|
|
223
|
-
runtime,
|
|
224
214
|
});
|
|
225
215
|
```
|
|
226
216
|
|
|
@@ -241,7 +231,6 @@ const answers = form(
|
|
|
241
231
|
arrayKeys: { answers: (answer) => answer.id },
|
|
242
232
|
initialValues: { answers: [{ id: "question", text: "Yes" }] },
|
|
243
233
|
onSubmit: (_values, submitter) => submitter.fail(["answers", 0, "text"], "This answer is closed"),
|
|
244
|
-
runtime,
|
|
245
234
|
},
|
|
246
235
|
);
|
|
247
236
|
```
|
|
@@ -283,7 +272,7 @@ Import the module that defines a name; there is no root entry.
|
|
|
283
272
|
| Option | Type or role |
|
|
284
273
|
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
285
274
|
| `initialValues` | `Encoded<F>` |
|
|
286
|
-
| `runtime` |
|
|
275
|
+
| `runtime` | Optional when no application services are needed; otherwise an atom runtime for handler/check and schema decoding services |
|
|
287
276
|
| `onSubmit` | `(values, submitter, submitted) => Effect<A, E, R>`; the three arguments are decoded values, field failure helper and encoded snapshot |
|
|
288
277
|
| `checks` | Optional functions keyed by field, from encoded input to an Effect of `string \| undefined` |
|
|
289
278
|
| `arrayKeys` | Optional `ArrayKeys<F>` selectors keyed by top-level array field, from encoded element to stable `PropertyKey`; retains nested feedback across reordering |
|
package/dist/form.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
2
|
import { type Config, type Fields, type Form } from "./shape.ts";
|
|
3
|
-
export declare function form<TFields extends Fields, TValue, TError, TServices, TRuntimeError>(schema: Schema.Struct<TFields>, config: Config<TFields, TValue, TError, TServices, TRuntimeError>): Form<TFields, TValue, TError, TRuntimeError>;
|
|
3
|
+
export declare function form<TFields extends Fields, TValue, TError, TServices = never, TRuntimeError = never>(schema: Schema.Struct<TFields>, config: Config<TFields, TValue, TError, TServices, TRuntimeError>): Form<TFields, TValue, TError, TRuntimeError>;
|
|
4
4
|
//# sourceMappingURL=form.d.ts.map
|
package/dist/form.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../src/form.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../src/form.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,MAAM,EAAkC,MAAM,QAAQ,CAAC;AAS9F,OAAO,EACN,KAAK,MAAM,EAIX,KAAK,MAAM,EACX,KAAK,IAAI,EAKT,MAAM,YAAY,CAAC;AAapB,wBAAgB,IAAI,CAAC,OAAO,SAAS,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,KAAK,EAAE,aAAa,GAAG,KAAK,EACpG,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAC9B,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,CAAC,GAC/D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,CA8G9C"}
|
package/dist/form.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Effect, Equal, Result, Schema, SchemaParser } from "effect";
|
|
1
|
+
import { Effect, Equal, Layer, Result, Schema, SchemaParser } from "effect";
|
|
2
2
|
import * as AsyncResult from "effect/reactivity/AsyncResult";
|
|
3
3
|
import * as Atom from "effect/reactivity/Atom";
|
|
4
4
|
import { draft } from "./draft.js";
|
|
@@ -6,11 +6,16 @@ import { literalChoices, messageAt, messagesByField, schemaFeedback } from "./me
|
|
|
6
6
|
import { pathMessageAt } from "./paths.js";
|
|
7
7
|
import { persistence } from "./persistence.js";
|
|
8
8
|
import { fromRef, propertyRef } from "./refs.js";
|
|
9
|
-
import { FieldFailure, Invalid } from "./shape.js";
|
|
9
|
+
import { FieldFailure, Invalid, } from "./shape.js";
|
|
10
10
|
import { statusOf } from "./statusOf.js";
|
|
11
11
|
import { trackRejections } from "./trackRejections.js";
|
|
12
|
+
const emptyRuntime = Atom.runtime(Layer.empty);
|
|
13
|
+
function configuredRuntime(config) {
|
|
14
|
+
return config.runtime ?? emptyRuntime;
|
|
15
|
+
}
|
|
12
16
|
export function form(schema, config) {
|
|
13
|
-
const { initialValues, onSubmit
|
|
17
|
+
const { initialValues, onSubmit } = config;
|
|
18
|
+
const runtime = configuredRuntime(config);
|
|
14
19
|
const debounce = config.debounce ?? "300 millis";
|
|
15
20
|
const checks = new Map(Object.entries(config.checks ?? {}));
|
|
16
21
|
const decode = SchemaParser.decodeUnknownEffect(schema, { errors: "all" });
|
package/dist/form.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form.js","sourceRoot":"","sources":["../src/form.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAoB,YAAY,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"form.js","sourceRoot":"","sources":["../src/form.ts"],"names":[],"mappings":"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"}
|
package/dist/shape.d.ts
CHANGED
|
@@ -36,15 +36,18 @@ export interface Submitter<TName extends string> {
|
|
|
36
36
|
export type Checks<TFields extends Fields, R> = {
|
|
37
37
|
readonly [TKey in Name<TFields>]?: (value: Encoded<TFields>[TKey]) => Effect.Effect<string | undefined, never, R>;
|
|
38
38
|
};
|
|
39
|
-
export
|
|
39
|
+
export type Config<TFields extends Fields, A, E, R, TRuntimeError> = {
|
|
40
40
|
readonly arrayKeys?: ArrayKeys<TFields>;
|
|
41
41
|
readonly checks?: Checks<TFields, R>;
|
|
42
42
|
readonly debounce?: Duration.Input;
|
|
43
43
|
readonly initialValues: Encoded<TFields>;
|
|
44
44
|
readonly onSubmit: (values: Decoded<TFields>, submitter: Submitter<Name<TFields>>, submitted: Encoded<TFields>) => Effect.Effect<A, E, R | Scope.Scope | AtomRegistry | Reactivity>;
|
|
45
45
|
readonly persistedDraft?: PersistedDraftConfig | undefined;
|
|
46
|
+
} & ([Exclude<Services<TFields, R>, Scope.Scope | AtomRegistry | Reactivity>] extends [never] ? {
|
|
47
|
+
readonly runtime?: Atom.AtomRuntime<Services<TFields, R>, TRuntimeError>;
|
|
48
|
+
} : {
|
|
46
49
|
readonly runtime: Atom.AtomRuntime<Services<TFields, R>, TRuntimeError>;
|
|
47
|
-
}
|
|
50
|
+
});
|
|
48
51
|
export interface Form<TFields extends Fields, A, E, TRuntimeError> {
|
|
49
52
|
readonly blur: (name: Name<TFields>) => void;
|
|
50
53
|
readonly change: <TKey extends Name<TFields>>(name: TKey, value: Encoded<TFields>[TKey]) => void;
|
package/dist/shape.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shape.d.ts","sourceRoot":"","sources":["../src/shape.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,KAAK,MAAM,EAAE,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAC;AACnF,OAAO,KAAK,KAAK,IAAI,MAAM,wBAAwB,CAAC;AACpD,OAAO,KAAK,KAAK,OAAO,MAAM,2BAA2B,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;AAE1C,MAAM,MAAM,OAAO,CAAC,OAAO,SAAS,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAE7E,MAAM,MAAM,OAAO,CAAC,OAAO,SAAS,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAE1E,MAAM,MAAM,IAAI,CAAC,OAAO,SAAS,MAAM,IAAI,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC;AAE3E,MAAM,MAAM,IAAI,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,IAAI,SAAS,CAAC,KAAK,EAAE,GAAG,WAAW,EAAE,CAAC,CAAC;AAErF,MAAM,MAAM,SAAS,CAAC,OAAO,SAAS,MAAM,IAAI;IAC/C,QAAQ,EAAE,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,SAAS,CAAC,MAAM,QAAQ,CAAC,EAAE,GACvG,CAAC,OAAO,EAAE,QAAQ,KAAK,WAAW,GAClC,KAAK;CACR,CAAC;AAEF,MAAM,MAAM,QAAQ,CAAC,OAAO,SAAS,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;;;;AAE9F,qBAAa,YAAa,SAAQ,kBAAiC;IAClE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC;CACzB,CAAC;CAAG;;;;AAEL,qBAAa,OAAQ,SAAQ,aAA4B;IACxD,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;CACjC,CAAC;CAAG;AAEL,MAAM,WAAW,SAAS,CAAC,KAAK,SAAS,MAAM;IAC9C,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;CAClG;AAED,MAAM,MAAM,MAAM,CAAC,OAAO,SAAS,MAAM,EAAE,CAAC,IAAI;IAC/C,QAAQ,EAAE,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;CACjH,CAAC;AAEF,MAAM,
|
|
1
|
+
{"version":3,"file":"shape.d.ts","sourceRoot":"","sources":["../src/shape.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shivaedev/form",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Schema-derived Effect atom forms with optional React hooks",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"effect"
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@effect/atom-react": "4.0.6",
|
|
47
47
|
"@effect/vitest": "4.0.6",
|
|
48
|
-
"@shivaedev/quality": "0.
|
|
49
|
-
"@shivaedev/test": "0.
|
|
50
|
-
"@shivaedev/test-story": "0.
|
|
48
|
+
"@shivaedev/quality": "0.48.0",
|
|
49
|
+
"@shivaedev/test": "0.12.0",
|
|
50
|
+
"@shivaedev/test-story": "0.26.2",
|
|
51
51
|
"@types/node": "24.19.2",
|
|
52
52
|
"@types/react": "19.3.0",
|
|
53
53
|
"effect": "4.0.6",
|
package/src/form.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Effect, Equal, Result, Schema, type SchemaIssue, SchemaParser } from "effect";
|
|
1
|
+
import { Effect, Equal, Layer, Result, Schema, type SchemaIssue, SchemaParser } from "effect";
|
|
2
2
|
import * as AsyncResult from "effect/reactivity/AsyncResult";
|
|
3
3
|
import * as Atom from "effect/reactivity/Atom";
|
|
4
4
|
import type * as AtomRef from "effect/reactivity/AtomRef";
|
|
@@ -7,15 +7,36 @@ import { literalChoices, messageAt, messagesByField, schemaFeedback } from "./me
|
|
|
7
7
|
import { pathMessageAt } from "./paths.ts";
|
|
8
8
|
import { persistence } from "./persistence.ts";
|
|
9
9
|
import { fromRef, propertyRef } from "./refs.ts";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
type Config,
|
|
12
|
+
type Decoded,
|
|
13
|
+
type Encoded,
|
|
14
|
+
FieldFailure,
|
|
15
|
+
type Fields,
|
|
16
|
+
type Form,
|
|
17
|
+
Invalid,
|
|
18
|
+
type Name,
|
|
19
|
+
type Services,
|
|
20
|
+
type Submitter,
|
|
21
|
+
} from "./shape.ts";
|
|
11
22
|
import { statusOf } from "./statusOf.ts";
|
|
12
23
|
import { trackRejections } from "./trackRejections.ts";
|
|
13
24
|
|
|
14
|
-
|
|
25
|
+
const emptyRuntime = Atom.runtime(Layer.empty);
|
|
26
|
+
|
|
27
|
+
function configuredRuntime<TFields extends Fields, A, E, R, TRuntimeError>(
|
|
28
|
+
config: Config<TFields, A, E, R, TRuntimeError>,
|
|
29
|
+
): Atom.AtomRuntime<Services<TFields, R>, TRuntimeError>;
|
|
30
|
+
function configuredRuntime(config: { readonly runtime?: Atom.AtomRuntime<never, unknown> }): Atom.AtomRuntime<never, unknown> {
|
|
31
|
+
return config.runtime ?? emptyRuntime;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function form<TFields extends Fields, TValue, TError, TServices = never, TRuntimeError = never>(
|
|
15
35
|
schema: Schema.Struct<TFields>,
|
|
16
36
|
config: Config<TFields, TValue, TError, TServices, TRuntimeError>,
|
|
17
37
|
): Form<TFields, TValue, TError, TRuntimeError> {
|
|
18
|
-
const { initialValues, onSubmit
|
|
38
|
+
const { initialValues, onSubmit } = config;
|
|
39
|
+
const runtime = configuredRuntime(config);
|
|
19
40
|
const debounce = config.debounce ?? "300 millis";
|
|
20
41
|
const checks: ReadonlyMap<string, (value: Encoded<TFields>[Name<TFields>]) => Effect.Effect<string | undefined, never, TServices>> = new Map(
|
|
21
42
|
Object.entries(config.checks ?? {}),
|
package/src/shape.ts
CHANGED
|
@@ -42,7 +42,7 @@ export type Checks<TFields extends Fields, R> = {
|
|
|
42
42
|
readonly [TKey in Name<TFields>]?: (value: Encoded<TFields>[TKey]) => Effect.Effect<string | undefined, never, R>;
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
-
export
|
|
45
|
+
export type Config<TFields extends Fields, A, E, R, TRuntimeError> = {
|
|
46
46
|
readonly arrayKeys?: ArrayKeys<TFields>;
|
|
47
47
|
readonly checks?: Checks<TFields, R>;
|
|
48
48
|
readonly debounce?: Duration.Input;
|
|
@@ -53,8 +53,9 @@ export interface Config<TFields extends Fields, A, E, R, TRuntimeError> {
|
|
|
53
53
|
submitted: Encoded<TFields>,
|
|
54
54
|
) => Effect.Effect<A, E, R | Scope.Scope | AtomRegistry | Reactivity>;
|
|
55
55
|
readonly persistedDraft?: PersistedDraftConfig | undefined;
|
|
56
|
-
|
|
57
|
-
}
|
|
56
|
+
} & ([Exclude<Services<TFields, R>, Scope.Scope | AtomRegistry | Reactivity>] extends [never]
|
|
57
|
+
? { readonly runtime?: Atom.AtomRuntime<Services<TFields, R>, TRuntimeError> }
|
|
58
|
+
: { readonly runtime: Atom.AtomRuntime<Services<TFields, R>, TRuntimeError> });
|
|
58
59
|
|
|
59
60
|
export interface Form<TFields extends Fields, A, E, TRuntimeError> {
|
|
60
61
|
readonly blur: (name: Name<TFields>) => void;
|