@shivaedev/effect-react 0.2.2 → 0.4.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 +20 -0
- package/README.md +9 -7
- package/dist/client/create.d.ts +3 -1
- package/dist/client/create.d.ts.map +1 -1
- package/dist/client/create.js +3 -1
- package/dist/client/create.js.map +1 -1
- package/dist/client/editor.d.ts +4 -2
- package/dist/client/editor.d.ts.map +1 -1
- package/dist/client/editor.js +3 -0
- package/dist/client/editor.js.map +1 -1
- package/dist/client/resultState.d.ts +2 -2
- package/dist/client/resultState.d.ts.map +1 -1
- package/dist/client/resultState.js +1 -1
- package/dist/client/resultState.js.map +1 -1
- package/dist/client/saveState.js +2 -2
- package/dist/client/saveState.js.map +1 -1
- package/dist/client/sessionBoundary.d.ts.map +1 -1
- package/dist/client/sessionBoundary.js +6 -2
- package/dist/client/sessionBoundary.js.map +1 -1
- package/dist/client/testing.d.ts +1 -1
- package/dist/client/testing.d.ts.map +1 -1
- package/dist/client/testing.js +1 -1
- package/dist/client/testing.js.map +1 -1
- package/dist/client/useDraftOwner.d.ts +3 -0
- package/dist/client/useDraftOwner.d.ts.map +1 -0
- package/dist/client/useDraftOwner.js +36 -0
- package/dist/client/useDraftOwner.js.map +1 -0
- package/dist/field-rejection.d.ts +2 -2
- package/dist/field-rejection.d.ts.map +1 -1
- package/dist/loadQuery.d.ts +3 -3
- package/dist/loadQuery.d.ts.map +1 -1
- package/dist/loadQuery.js +1 -1
- package/dist/loadQuery.js.map +1 -1
- package/dist/resume-signal.d.ts +1 -1
- package/dist/resume-signal.d.ts.map +1 -1
- package/dist/submission.d.ts +3 -1
- package/dist/submission.d.ts.map +1 -1
- package/dist/submission.js +1 -0
- package/dist/submission.js.map +1 -1
- package/docs/roadmap.md +2 -1
- package/package.json +25 -29
- package/src/client/create.ts +5 -2
- package/src/client/editor.ts +6 -2
- package/src/client/resultState.ts +3 -3
- package/src/client/saveState.ts +2 -2
- package/src/client/sessionBoundary.ts +10 -2
- package/src/client/testing.ts +1 -1
- package/src/client/useDraftOwner.ts +42 -0
- package/src/field-rejection.ts +2 -2
- package/src/loadQuery.ts +3 -3
- package/src/submission.ts +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.4.0 - 2026-10-13
|
|
4
|
+
|
|
5
|
+
### Breaking
|
|
6
|
+
|
|
7
|
+
- Requires stable Effect 4.0.4 in place of 4.0.0-rc.112. Effect 4.0.4 moves the former `effect/unstable/*` modules to `effect/*` and renames constructors such as `Config.string` to `Config.String`. Install `@effect/atom-react` 4.0.4 alongside it, and Vitest 5 for the test helpers.
|
|
8
|
+
|
|
9
|
+
## 0.3.0 - 2026-10-13
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `useEditor` and `useCreate` accept opt-in `persistedDraft` settings with application keys, storage and bounds. They inherit `SessionBoundary` ownership, which drops tracked drafts when the session changes or ends, including drafts from unmounted screens.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Include `@shivaedev/effect-form` as a workspace dependency for shared draft ownership at the session boundary.
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- Reconcile `SessionBoundary` draft ownership when a session replacement commits. A suspended, canceled transition preserves the visible session's draft and future persistence; committed replacements also clear old drafts while Activity is hidden.
|
|
22
|
+
|
|
3
23
|
## 0.2.2 - 2026-10-12
|
|
4
24
|
|
|
5
25
|
### Added
|
package/README.md
CHANGED
|
@@ -30,6 +30,8 @@ An **editor** joins a query atom, an effect-form field schema and a save Effect.
|
|
|
30
30
|
|
|
31
31
|
A **session generation** is the string returned by `identify(session)`. `SessionBoundary` owns its client, registry and React subtree. Your auth owner supplies the session and decides when to replace or end it. Cache policy, RPC declarations and transport stay with native Effect and the application; this package supplies their React state and lifecycle boundary.
|
|
32
32
|
|
|
33
|
+
`useEditor` and `useCreate` opt into persisted input with `persistedDraft: { key }`. Choose a stable key for the record or create request, independent of its server revision. The adapters use effect-form's browser storage and inherit ownership from `SessionBoundary`: reload and query refresh preserve edits, successful submission clears accepted input, and a committed session replacement drops tracked drafts. A suspended replacement that is canceled keeps the visible session's draft and future writes. Later edits made during a save remain persisted. Optional `storage`, `maxBytes` and `maxAgeMs` customize the provider and bounds; defaults are `localStorage`, 256 KiB of UTF-8 JSON and seven days. See [effect-form's persisted input API](https://github.com/ShivaeDev/platform/tree/main/packages/effect-form#persist-input-across-reloads) for direct form hooks and limits.
|
|
34
|
+
|
|
33
35
|
### 1. Once per application: own the registry
|
|
34
36
|
|
|
35
37
|
For a screen without a session boundary, wrap it in the native provider:
|
|
@@ -84,7 +86,7 @@ The hooks accept native atoms directly. This complete component module shows que
|
|
|
84
86
|
import { RegistryProvider } from "@effect/atom-react";
|
|
85
87
|
import { useAction, useQuery } from "@shivaedev/effect-react/result-state.ts";
|
|
86
88
|
import { Effect, Option } from "effect";
|
|
87
|
-
import * as Atom from "effect/
|
|
89
|
+
import * as Atom from "effect/reactivity/Atom";
|
|
88
90
|
|
|
89
91
|
const report = Atom.make(Effect.succeed({ id: 1, title: "Quarterly report" }));
|
|
90
92
|
const rename = Atom.fn<string>()((title) =>
|
|
@@ -148,7 +150,7 @@ import { RegistryContext } from "@effect/atom-react";
|
|
|
148
150
|
import { createRootRouteWithContext, createRoute, createRouter, Outlet, RouterProvider, useRouterState } from "@tanstack/react-router";
|
|
149
151
|
import type { ErrorComponentProps } from "@tanstack/react-router";
|
|
150
152
|
import { Predicate } from "effect";
|
|
151
|
-
import * as AtomRegistry from "effect/
|
|
153
|
+
import * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
152
154
|
import { loadQuery } from "@shivaedev/effect-react/router.ts";
|
|
153
155
|
import { api } from "./notes-client.ts";
|
|
154
156
|
|
|
@@ -318,7 +320,7 @@ Keep the signal and query identities stable:
|
|
|
318
320
|
```ts
|
|
319
321
|
import { resumeSignal } from "@shivaedev/effect-react/resume-signal.ts";
|
|
320
322
|
import { Effect } from "effect";
|
|
321
|
-
import * as Atom from "effect/
|
|
323
|
+
import * as Atom from "effect/reactivity/Atom";
|
|
322
324
|
|
|
323
325
|
const resume = resumeSignal({ window });
|
|
324
326
|
const query = Atom.makeRefreshOnSignal(resume)(Atom.make(Effect.succeed("ready")));
|
|
@@ -382,8 +384,8 @@ Configure Vitest with `test: { environment: "happy-dom" }`, or select that envir
|
|
|
382
384
|
|
|
383
385
|
```tsx
|
|
384
386
|
import { Effect, Option, Ref, Schema } from "effect";
|
|
385
|
-
import * as AtomRpc from "effect/
|
|
386
|
-
import { RpcTest } from "effect/
|
|
387
|
+
import * as AtomRpc from "effect/reactivity/AtomRpc";
|
|
388
|
+
import { RpcTest } from "effect/rpc";
|
|
387
389
|
import { act, createElement } from "react";
|
|
388
390
|
import { expect, it } from "vitest";
|
|
389
391
|
import { bind } from "@shivaedev/effect-contract/bind.ts";
|
|
@@ -463,7 +465,7 @@ The [order feature’s application-owned kit](https://github.com/ShivaeDev/platf
|
|
|
463
465
|
### Install, setup and limits
|
|
464
466
|
|
|
465
467
|
```sh
|
|
466
|
-
pnpm add @shivaedev/effect-react @effect/atom-react@4.0.
|
|
468
|
+
pnpm add @shivaedev/effect-react @effect/atom-react@4.0.4 effect@4.0.4 react@19.2.8
|
|
467
469
|
```
|
|
468
470
|
|
|
469
471
|
For editor, create or lower-level form modules, also install the optional form peer:
|
|
@@ -472,7 +474,7 @@ For editor, create or lower-level form modules, also install the optional form p
|
|
|
472
474
|
pnpm add @shivaedev/effect-form
|
|
473
475
|
```
|
|
474
476
|
|
|
475
|
-
Query, action, session and resume modules do not require effect-form. The package declares Node 24 or newer and peers on Effect, atom-react and React; this repository checks Effect and atom-react `4.0.
|
|
477
|
+
Query, action, session and resume modules do not require effect-form. The package declares Node 24 or newer and peers on Effect, atom-react and React; this repository checks Effect and atom-react `4.0.4` with React `19.2.8`.
|
|
476
478
|
|
|
477
479
|
- Query identity, TTL, invalidation and action concurrency remain native atom policies. Put the registry at the lifetime boundary those policies need.
|
|
478
480
|
- Action state describes the atom's latest result. A `dispatch` is not a Promise or a separate result handle.
|
package/dist/client/create.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { type Effect, Option, type Schema } from "effect";
|
|
2
|
-
import type * as Atom from "effect/
|
|
2
|
+
import type * as Atom from "effect/reactivity/Atom";
|
|
3
|
+
import { type BrowserDraftConfig } from "@shivaedev/effect-form/react.ts";
|
|
3
4
|
import type { Decoded, Encoded, FieldFailure, Fields, Form, Services } from "@shivaedev/effect-form/shape.ts";
|
|
4
5
|
import type { AtomServices, FieldRejectionMapping } from "#field-rejection.ts";
|
|
5
6
|
import { type SaveState } from "./saveState.ts";
|
|
6
7
|
export type CreateConfig<TFields extends Fields, TCreated, TSaveError, R, TRuntimeError> = {
|
|
8
|
+
readonly persistedDraft?: BrowserDraftConfig | undefined;
|
|
7
9
|
readonly fields: Schema.Struct<TFields>;
|
|
8
10
|
readonly initialValues: Encoded<TFields>;
|
|
9
11
|
readonly create: (values: Decoded<TFields>) => Effect.Effect<TCreated, TSaveError, AtomServices<R>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/client/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAS,MAAM,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AACjE,OAAO,KAAK,KAAK,IAAI,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/client/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAS,MAAM,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AACjE,OAAO,KAAK,KAAK,IAAI,MAAM,wBAAwB,CAAC;AAEpD,OAAO,EAAE,KAAK,kBAAkB,EAAqB,MAAM,iCAAiC,CAAC;AAC7F,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAC9G,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAE/E,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,gBAAgB,CAAC;AAC9D,MAAM,MAAM,YAAY,CAAC,OAAO,SAAS,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,IAAI;IAC1F,QAAQ,CAAC,cAAc,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACzD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACxC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IACpG,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;CACxE,GAAG,qBAAqB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAC/C,MAAM,WAAW,MAAM,CAAC,OAAO,SAAS,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,aAAa,CAAE,SAAQ,SAAS,CAAC,UAAU,GAAG,aAAa,CAAC;IACjI,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC1C,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,GAAG,YAAY,EAAE,aAAa,CAAC,CAAC;CACjF;AAKD,wBAAgB,SAAS,CAAC,OAAO,SAAS,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EACvF,MAAM,EAAE,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,CAAC,GACnE,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,aAAa,CAAC,CAkBtD"}
|
package/dist/client/create.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Equal, Option } from "effect";
|
|
2
2
|
import { useCallback, useState } from "react";
|
|
3
|
+
import { usePersistedDraft } from "@shivaedev/effect-form/react.ts";
|
|
3
4
|
import { submission } from "#submission.ts";
|
|
4
5
|
import { useSaveState } from "./saveState.js";
|
|
5
6
|
function editedSince(current, submitted) {
|
|
@@ -7,9 +8,10 @@ function editedSince(current, submitted) {
|
|
|
7
8
|
return Object.fromEntries(Object.entries(current).filter(([name, value]) => !Equal.equals(value, before.get(name))));
|
|
8
9
|
}
|
|
9
10
|
export function useCreate(config) {
|
|
11
|
+
const persistedDraft = usePersistedDraft(config.persistedDraft);
|
|
10
12
|
const [{ initialValues: baseline, fresh }] = useState(() => {
|
|
11
13
|
const { fields, initialValues, runtime, create, rejectField } = config;
|
|
12
|
-
return { fresh: () => submission({ fields, initialValues, rejectField, runtime, save: create }), initialValues };
|
|
14
|
+
return { fresh: () => submission({ fields, initialValues, persistedDraft, rejectField, runtime, save: create }), initialValues };
|
|
13
15
|
});
|
|
14
16
|
const [current, replace] = useState(fresh);
|
|
15
17
|
const [created, record] = useState(Option.none());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/client/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,EAAE,MAAM,EAAe,MAAM,QAAQ,CAAC;AAEjE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/client/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,EAAE,MAAM,EAAe,MAAM,QAAQ,CAAC;AAEjE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC9C,OAAO,EAA2B,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAG7F,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAkB,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAY9D,SAAS,WAAW,CAAoB,OAAW,EAAE,SAAyB;IAC7E,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,CAAC,CAAC;IAC7D,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACtH,CAAC;AACD,MAAM,UAAU,SAAS,CACxB,MAAqE;IAErE,MAAM,cAAc,GAAG,iBAAiB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAChE,MAAM,CAAC,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE;QAC1D,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC;QACvE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC;IAClI,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC3C,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,QAAQ,CAA0B,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3E,MAAM,OAAO,GAAG,WAAW,CAC1B,CAAC,KAAe,EAAE,EAAE;QACnB,MAAM,IAAI,GAAG,KAAK,EAAE,CAAC;QACrB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,QAAQ,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;QACtG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,CAAC;IACf,CAAC,EACD,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,CAC1B,CAAC;IACF,OAAO,EAAE,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;AAChF,CAAC"}
|
package/dist/client/editor.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { type Effect, type Schema } from "effect";
|
|
2
|
-
import type * as AsyncResult from "effect/
|
|
3
|
-
import type * as Atom from "effect/
|
|
2
|
+
import type * as AsyncResult from "effect/reactivity/AsyncResult";
|
|
3
|
+
import type * as Atom from "effect/reactivity/Atom";
|
|
4
|
+
import { type BrowserDraftConfig } from "@shivaedev/effect-form/react.ts";
|
|
4
5
|
import type { Decoded, Encoded, FieldFailure, Fields, Form, Services } from "@shivaedev/effect-form/shape.ts";
|
|
5
6
|
import type { AtomServices, FieldRejectionMapping } from "#field-rejection.ts";
|
|
6
7
|
import { type QueryState } from "./resultState.ts";
|
|
7
8
|
import { type SaveState } from "./saveState.ts";
|
|
8
9
|
export type EditorConfig<TFields extends Fields, TRow, TQueryError, TSaveError, R, TRuntimeError> = {
|
|
10
|
+
readonly persistedDraft?: BrowserDraftConfig | undefined;
|
|
9
11
|
readonly query: Atom.Atom<AsyncResult.AsyncResult<TRow, TQueryError>>;
|
|
10
12
|
readonly fields: Schema.Struct<TFields>;
|
|
11
13
|
readonly values: (row: TRow) => Encoded<TFields>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/client/editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAU,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,KAAK,KAAK,WAAW,MAAM,
|
|
1
|
+
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/client/editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAU,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,KAAK,KAAK,WAAW,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,KAAK,IAAI,MAAM,wBAAwB,CAAC;AAEpD,OAAO,EAAE,KAAK,kBAAkB,EAAqB,MAAM,iCAAiC,CAAC;AAC7F,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAC9G,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAE/E,OAAO,EAAE,KAAK,UAAU,EAAY,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,gBAAgB,CAAC;AAC9D,MAAM,MAAM,YAAY,CAAC,OAAO,SAAS,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,IAAI;IACnG,QAAQ,CAAC,cAAc,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACzD,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;IACtE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACxC,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACjD,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9F,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;CACxE,GAAG,qBAAqB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAC/C,MAAM,WAAW,MAAM,CAAC,OAAO,SAAS,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,CAAE,SAAQ,SAAS,CAAC,UAAU,GAAG,aAAa,CAAC;IAC1I,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,UAAU,GAAG,YAAY,EAAE,aAAa,CAAC,GAAG,SAAS,CAAC;IACzF,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;CAC9C;AAMD,wBAAgB,SAAS,CAAC,OAAO,SAAS,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAChG,MAAM,EAAE,YAAY,CAAC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,CAAC,GAC5E,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,CAAC,CA8B/D"}
|
package/dist/client/editor.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { Option } from "effect";
|
|
2
2
|
import { useCallback, useEffect, useState } from "react";
|
|
3
|
+
import { usePersistedDraft } from "@shivaedev/effect-form/react.ts";
|
|
3
4
|
import { submission } from "#submission.ts";
|
|
4
5
|
import { useQuery } from "./resultState.js";
|
|
5
6
|
import { useSaveState } from "./saveState.js";
|
|
6
7
|
export function useEditor(config) {
|
|
8
|
+
const persistedDraft = usePersistedDraft(config.persistedDraft);
|
|
7
9
|
const query = useQuery(config.query);
|
|
8
10
|
const row = Option.getOrUndefined(query.data);
|
|
9
11
|
const [held, hold] = useState(undefined);
|
|
@@ -13,6 +15,7 @@ export function useEditor(config) {
|
|
|
13
15
|
form: submission({
|
|
14
16
|
fields: config.fields,
|
|
15
17
|
initialValues: config.values(row),
|
|
18
|
+
persistedDraft,
|
|
16
19
|
rejectField: config.rejectField,
|
|
17
20
|
runtime: config.runtime,
|
|
18
21
|
save: config.save,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.js","sourceRoot":"","sources":["../../src/client/editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,MAAM,EAAe,MAAM,QAAQ,CAAC;AAG1D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"editor.js","sourceRoot":"","sources":["../../src/client/editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,MAAM,EAAe,MAAM,QAAQ,CAAC;AAG1D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAA2B,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAG7F,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAmB,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAkB,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAkB9D,MAAM,UAAU,SAAS,CACxB,MAA8E;IAE9E,MAAM,cAAc,GAAG,iBAAiB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAChE,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,QAAQ,CAA6D,SAAS,CAAC,CAAC;IACrG,IAAI,OAAO,GAAG,IAAI,EAAE,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9D,IAAI,OAAO,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QAChD,OAAO,GAAG;YACT,IAAI,EAAE,UAAU,CAAC;gBAChB,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;gBACjC,cAAc;gBACd,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,IAAI,EAAE,MAAM,CAAC,IAAI;aACjB,CAAC,CAAC,IAAI;YACP,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,MAAM,EAAE,MAAM,CAAC,MAAM;SACrB,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,CAAC;IACf,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,CAAC;IAC3B,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,CAAC;IAC/B,SAAS,CAAC,GAAG,EAAE;QACd,IAAI,IAAI,IAAI,MAAM,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACzC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3B,CAAC;IACF,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IACxB,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,KAAW,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IACzH,OAAO,EAAE,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACxD,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Cause, Option } from "effect";
|
|
2
|
-
import * as AsyncResult from "effect/
|
|
3
|
-
import type * as Atom from "effect/
|
|
2
|
+
import * as AsyncResult from "effect/reactivity/AsyncResult";
|
|
3
|
+
import type * as Atom from "effect/reactivity/Atom";
|
|
4
4
|
export interface ResultState<A, E> {
|
|
5
5
|
readonly cause: Option.Option<Cause.Cause<E>>;
|
|
6
6
|
readonly data: Option.Option<A>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resultState.d.ts","sourceRoot":"","sources":["../../src/client/resultState.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAa,MAAM,QAAQ,CAAC;AAClD,OAAO,KAAK,WAAW,MAAM,
|
|
1
|
+
{"version":3,"file":"resultState.d.ts","sourceRoot":"","sources":["../../src/client/resultState.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAa,MAAM,QAAQ,CAAC;AAClD,OAAO,KAAK,WAAW,MAAM,+BAA+B,CAAC;AAC7D,OAAO,KAAK,KAAK,IAAI,MAAM,wBAAwB,CAAC;AAIpD,MAAM,WAAW,WAAW,CAAC,CAAC,EAAE,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAC/C;AAUD,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,CAEhE;AASD,MAAM,WAAW,UAAU,CAAC,CAAC,EAAE,CAAC,CAAE,SAAQ,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1D,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;CAC7B;AACD,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CACpC;AASD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,GAAE,YAAiB,GAAG,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAe3H;AACD,MAAM,WAAW,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAE,SAAQ,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC;IACnE,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAIxG"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RegistryContext, useAtomRefresh, useAtomSet, useAtomValue } from "@effect/atom-react";
|
|
2
2
|
import { Cause, Option, Predicate } from "effect";
|
|
3
|
-
import * as AsyncResult from "effect/
|
|
3
|
+
import * as AsyncResult from "effect/reactivity/AsyncResult";
|
|
4
4
|
import { useContext, useEffect, useState } from "react";
|
|
5
5
|
import { useSessionRecheck } from "./sessionBoundary.js";
|
|
6
6
|
function state(result, data = AsyncResult.value(result)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resultState.js","sourceRoot":"","sources":["../../src/client/resultState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC/F,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,KAAK,WAAW,MAAM,
|
|
1
|
+
{"version":3,"file":"resultState.js","sourceRoot":"","sources":["../../src/client/resultState.ts"],"names":[],"mappings":"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"}
|
package/dist/client/saveState.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RegistryContext, useAtomValue } from "@effect/atom-react";
|
|
2
2
|
import { Option } from "effect";
|
|
3
|
-
import * as AsyncResult from "effect/
|
|
4
|
-
import * as Atom from "effect/
|
|
3
|
+
import * as AsyncResult from "effect/reactivity/AsyncResult";
|
|
4
|
+
import * as Atom from "effect/reactivity/Atom";
|
|
5
5
|
import { useCallback, useContext, useEffect } from "react";
|
|
6
6
|
import { FieldFailure, Invalid } from "@shivaedev/effect-form/shape.ts";
|
|
7
7
|
import { isUnauthorized } from "./resultState.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"saveState.js","sourceRoot":"","sources":["../../src/client/saveState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,WAAW,MAAM,
|
|
1
|
+
{"version":3,"file":"saveState.js","sourceRoot":"","sources":["../../src/client/saveState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,WAAW,MAAM,+BAA+B,CAAC;AAC7D,OAAO,KAAK,IAAI,MAAM,wBAAwB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC3D,OAAO,EAAE,YAAY,EAA0B,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAChG,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;AAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAQ/B,MAAM,UAAU,YAAY,CAC3B,IAAmE,EACnE,OAA4B;IAE5B,MAAM,QAAQ,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,MAAM,MAAM,GAA2E,YAAY,CAAC,IAAI,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC;IAC1H,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,KAAK,IAAI,KAAK,CAAC,CAAC;IACjD,SAAS,CAAC,GAAG,EAAE;QACd,IAAI,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACnE,OAAO,EAAE,CAAC;QACX,CAAC;IACF,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;IACtB,SAAS,CACR,GAAG,EAAE,CACJ,IAAI;WACD,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YAC3C,IAAI,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;QACF,CAAC,CAAC,EACH,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CACzB,CAAC;IACF,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE;QAC7B,IAAI,IAAI,KAAK,SAAS,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;YAC7D,OAAO;QACR,CAAC;QACD,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACtC,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;IACrB,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAC5B,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,EACzB,CAAC,KAAK,EAA8B,EAAE,CAAC,CAAC,CAAC,KAAK,YAAY,YAAY,IAAI,KAAK,YAAY,OAAO,CAAC,CACnG,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;AACjE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessionBoundary.d.ts","sourceRoot":"","sources":["../../src/client/sessionBoundary.ts"],"names":[],"mappings":"AAEA,OAAO,EAA0C,KAAK,SAAS,EAAmC,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"sessionBoundary.d.ts","sourceRoot":"","sources":["../../src/client/sessionBoundary.ts"],"names":[],"mappings":"AAEA,OAAO,EAA0C,KAAK,SAAS,EAAmC,MAAM,OAAO,CAAC;AAGhH,MAAM,WAAW,oBAAoB,CAAC,QAAQ,EAAE,OAAO;IACtD,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,SAAS,CAAC;IAClD,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,OAAO,CAAC;IACjD,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,MAAM,CAAC;IACjD,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;CAC/B;AAED,wBAAgB,iBAAiB,IAAI,MAAM,IAAI,CAE9C;AAsDD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,EAClD,OAAO,EACP,QAAQ,EACR,OAAO,EACP,OAAO,EACP,SAAS,EACT,QAAQ,GACR,EAAE,oBAAoB,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,SAAS,CAUrD"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { RegistryContext } from "@effect/atom-react";
|
|
2
|
-
import * as AtomRegistry from "effect/
|
|
2
|
+
import * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
3
3
|
import { createContext, createElement, Fragment, useContext, useEffect, useState } from "react";
|
|
4
|
+
import { DraftSessionContext } from "@shivaedev/effect-form/react.ts";
|
|
5
|
+
import { useDraftOwner } from "./useDraftOwner.js";
|
|
4
6
|
const RecheckContext = createContext(() => undefined);
|
|
5
7
|
export function useSessionRecheck() {
|
|
6
8
|
return useContext(RecheckContext);
|
|
@@ -44,8 +46,10 @@ function Generation({ session, connect, recheck, children }) {
|
|
|
44
46
|
return createElement(RecheckContext.Provider, { value: recheck }, createElement(RegistryContext.Provider, { value: owned.registry }, children(owned.client)));
|
|
45
47
|
}
|
|
46
48
|
export function SessionBoundary({ session, identify, connect, recheck, signedOut, children, }) {
|
|
49
|
+
const id = session === undefined ? undefined : identify(session);
|
|
50
|
+
const current = useDraftOwner(id);
|
|
47
51
|
return session === undefined
|
|
48
52
|
? createElement(Fragment, null, signedOut)
|
|
49
|
-
: createElement(Generation, { children, connect, key:
|
|
53
|
+
: createElement(DraftSessionContext.Provider, { value: current }, createElement(Generation, { children, connect, key: id, recheck, session }));
|
|
50
54
|
}
|
|
51
55
|
//# sourceMappingURL=sessionBoundary.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessionBoundary.js","sourceRoot":"","sources":["../../src/client/sessionBoundary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,YAAY,MAAM,
|
|
1
|
+
{"version":3,"file":"sessionBoundary.js","sourceRoot":"","sources":["../../src/client/sessionBoundary.ts"],"names":[],"mappings":"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"}
|
package/dist/client/testing.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as AtomRegistry from "effect/
|
|
1
|
+
import * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
2
2
|
import { type ReactNode } from "react";
|
|
3
3
|
export declare function expectNoReactWarnings(): void;
|
|
4
4
|
export declare function eventually(assert: () => void): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/client/testing.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,YAAY,MAAM,
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/client/testing.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,YAAY,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG3D,wBAAgB,qBAAqB,SASpC;AACD,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,IAAI,iBAgBlD;AACD,MAAM,WAAW,QAAQ;IACxB,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC,YAAY,CAAC;IAC7C,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AACD,wBAAsB,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,CA4B/D"}
|
package/dist/client/testing.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RegistryContext } from "@effect/atom-react";
|
|
2
2
|
import { Clock, Effect } from "effect";
|
|
3
|
-
import * as AtomRegistry from "effect/
|
|
3
|
+
import * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
4
4
|
import { act, createElement } from "react";
|
|
5
5
|
import { createRoot } from "react-dom/client";
|
|
6
6
|
import { beforeEach, expect, vi } from "vitest";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../../src/client/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,YAAY,MAAM,
|
|
1
|
+
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../../src/client/testing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDraftOwner.d.ts","sourceRoot":"","sources":["../../src/client/useDraftOwner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,YAAY,EAAgB,MAAM,wCAAwC,CAAC;AAuBzF,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,YAAY,GAAG,SAAS,CAiB9E"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { useInsertionEffect, useRef, useState } from "react";
|
|
2
|
+
import { draftSession } from "@shivaedev/effect-form/draftSession.ts";
|
|
3
|
+
function owner(id, active) {
|
|
4
|
+
const session = draftSession(id);
|
|
5
|
+
let committed = active;
|
|
6
|
+
return {
|
|
7
|
+
activate: () => {
|
|
8
|
+
committed = true;
|
|
9
|
+
},
|
|
10
|
+
session: {
|
|
11
|
+
...session,
|
|
12
|
+
get active() {
|
|
13
|
+
return committed && session.active;
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export function useDraftOwner(id) {
|
|
19
|
+
const [held, hold] = useState(() => (id === undefined ? undefined : owner(id, true)));
|
|
20
|
+
const committedRef = useRef(held);
|
|
21
|
+
let current = held;
|
|
22
|
+
if (current?.session.id !== id) {
|
|
23
|
+
current = id === undefined ? undefined : owner(id, committedRef.current === undefined);
|
|
24
|
+
hold(current);
|
|
25
|
+
}
|
|
26
|
+
// Insertion effects also run for Activity commits while layout and passive effects are disconnected.
|
|
27
|
+
useInsertionEffect(() => {
|
|
28
|
+
if (committedRef.current !== current) {
|
|
29
|
+
committedRef.current?.session.drop();
|
|
30
|
+
current?.activate();
|
|
31
|
+
committedRef.current = current;
|
|
32
|
+
}
|
|
33
|
+
}, [current]);
|
|
34
|
+
return current?.session;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=useDraftOwner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDraftOwner.js","sourceRoot":"","sources":["../../src/client/useDraftOwner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC7D,OAAO,EAAqB,YAAY,EAAE,MAAM,wCAAwC,CAAC;AAOzF,SAAS,KAAK,CAAC,EAAU,EAAE,MAAe;IACzC,MAAM,OAAO,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;IACjC,IAAI,SAAS,GAAG,MAAM,CAAC;IACvB,OAAO;QACN,QAAQ,EAAE,GAAG,EAAE;YACd,SAAS,GAAG,IAAI,CAAC;QAClB,CAAC;QACD,OAAO,EAAE;YACR,GAAG,OAAO;YACV,IAAI,MAAM;gBACT,OAAO,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;YACpC,CAAC;SACD;KACD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,EAAsB;IACnD,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IACtF,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,IAAI,OAAO,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QAChC,OAAO,GAAG,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,YAAY,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC;QACvF,IAAI,CAAC,OAAO,CAAC,CAAC;IACf,CAAC;IACD,qGAAqG;IACrG,kBAAkB,CAAC,GAAG,EAAE;QACvB,IAAI,YAAY,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;YACtC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;YACrC,OAAO,EAAE,QAAQ,EAAE,CAAC;YACpB,YAAY,CAAC,OAAO,GAAG,OAAO,CAAC;QAChC,CAAC;IACF,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACd,OAAO,OAAO,EAAE,OAAO,CAAC;AACzB,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Effect, type Schema, type Scope } from "effect";
|
|
2
|
-
import type { AtomRegistry } from "effect/
|
|
3
|
-
import type { Reactivity } from "effect/
|
|
2
|
+
import type { AtomRegistry } from "effect/reactivity/AtomRegistry";
|
|
3
|
+
import type { Reactivity } from "effect/reactivity/Reactivity";
|
|
4
4
|
import type { FieldFailure, Fields, Name, Submitter } from "@shivaedev/effect-form/shape.ts";
|
|
5
5
|
export interface FieldRejection<N extends string> {
|
|
6
6
|
readonly field: N;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field-rejection.d.ts","sourceRoot":"","sources":["../src/field-rejection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAa,KAAK,MAAM,EAAE,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"field-rejection.d.ts","sourceRoot":"","sources":["../src/field-rejection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAa,KAAK,MAAM,EAAE,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAE7F,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,MAAM;IAC/C,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAClB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,GAAG,YAAY,GAAG,UAAU,CAAC;AAE1E,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;AAEjG,KAAK,SAAS,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAChG,OAAO,SAAS,MAAM,CAAC,GACtB,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,GACxC,KAAK,GACN,KAAK,CAAC;AAET,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,IAAI;IAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;CAAE,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GACvI,OAAO,GACP;IAAE,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;CAAE,CAAC,CAAC;AAEhD,eAAO,MAAM,gBAAgB,GAC3B,CAAC,SAAS,MAAM,UAAU,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,aACnC,OAAO,KAAG,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,SAS3C,CAAC;AAEH,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,UAC7C,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,QAClB,CAAC,MAAM,EAAE,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,UACnC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,cAGrB,CAAC,aAAa,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,YAAY,EAAE,CAAC,CAKvF,CAAC"}
|
package/dist/loadQuery.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { LoaderFnContext } from "@tanstack/react-router";
|
|
2
|
-
import type * as AsyncResult from "effect/
|
|
3
|
-
import type * as Atom from "effect/
|
|
4
|
-
import * as AtomRegistry from "effect/
|
|
2
|
+
import type * as AsyncResult from "effect/reactivity/AsyncResult";
|
|
3
|
+
import type * as Atom from "effect/reactivity/Atom";
|
|
4
|
+
import * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
5
5
|
export declare function loadQuery<A, E>(registry: AtomRegistry.AtomRegistry, atom: Atom.Atom<AsyncResult.AsyncResult<A, E>>, { abortController }: Pick<LoaderFnContext, "abortController">): Promise<A>;
|
|
6
6
|
//# sourceMappingURL=loadQuery.d.ts.map
|
package/dist/loadQuery.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loadQuery.d.ts","sourceRoot":"","sources":["../src/loadQuery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,OAAO,KAAK,KAAK,WAAW,MAAM,
|
|
1
|
+
{"version":3,"file":"loadQuery.d.ts","sourceRoot":"","sources":["../src/loadQuery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,OAAO,KAAK,KAAK,WAAW,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,KAAK,IAAI,MAAM,wBAAwB,CAAC;AACpD,OAAO,KAAK,YAAY,MAAM,gCAAgC,CAAC;AAE/D,wBAAsB,SAAS,CAAC,CAAC,EAAE,CAAC,EACnC,QAAQ,EAAE,YAAY,CAAC,YAAY,EACnC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAC9C,EAAE,eAAe,EAAE,EAAE,IAAI,CAAC,eAAe,EAAE,iBAAiB,CAAC,GAC3D,OAAO,CAAC,CAAC,CAAC,CAgBZ"}
|
package/dist/loadQuery.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
|
-
import * as AtomRegistry from "effect/
|
|
2
|
+
import * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
3
3
|
export async function loadQuery(registry, atom, { abortController }) {
|
|
4
4
|
const { signal } = abortController;
|
|
5
5
|
try {
|
package/dist/loadQuery.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loadQuery.js","sourceRoot":"","sources":["../src/loadQuery.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,OAAO,KAAK,YAAY,MAAM,
|
|
1
|
+
{"version":3,"file":"loadQuery.js","sourceRoot":"","sources":["../src/loadQuery.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,OAAO,KAAK,YAAY,MAAM,gCAAgC,CAAC;AAE/D,MAAM,CAAC,KAAK,UAAU,SAAS,CAC9B,QAAmC,EACnC,IAA8C,EAC9C,EAAE,eAAe,EAA4C;IAE7D,MAAM,EAAE,MAAM,EAAE,GAAG,eAAe,CAAC;IACnC,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACtI,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC/B,MAAM,MAAM,CAAC,OAAO,CAAC;QACtB,CAAC;QACD,OAAO,MAAM,CAAC,OAAO,CAAC;IACvB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,wBAAwB,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;YACvE,QAAQ,CAAC,IAAI,GAAG,YAAY,CAAC;YAC7B,MAAM,QAAQ,CAAC;QAChB,CAAC;QACD,MAAM,KAAK,CAAC;IACb,CAAC;AACF,CAAC"}
|
package/dist/resume-signal.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ import { type ResumeOptions as ContractOptions, type ResumeSource as ContractSou
|
|
|
2
2
|
export type ResumeSource = ContractSource;
|
|
3
3
|
export type ResumeWindow = ContractWindow;
|
|
4
4
|
export type ResumeOptions = ContractOptions;
|
|
5
|
-
export declare function resumeSignal(options: ResumeOptions): import("effect/
|
|
5
|
+
export declare function resumeSignal(options: ResumeOptions): import("effect/reactivity/Atom").Atom<number>;
|
|
6
6
|
//# sourceMappingURL=resume-signal.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resume-signal.d.ts","sourceRoot":"","sources":["../src/resume-signal.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,aAAa,IAAI,eAAe,EACrC,KAAK,YAAY,IAAI,cAAc,EACnC,KAAK,YAAY,IAAI,cAAc,EAEnC,MAAM,sCAAsC,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG,cAAc,CAAC;AAC1C,MAAM,MAAM,YAAY,GAAG,cAAc,CAAC;AAC1C,MAAM,MAAM,aAAa,GAAG,eAAe,CAAC;AAC5C,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"resume-signal.d.ts","sourceRoot":"","sources":["../src/resume-signal.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,aAAa,IAAI,eAAe,EACrC,KAAK,YAAY,IAAI,cAAc,EACnC,KAAK,YAAY,IAAI,cAAc,EAEnC,MAAM,sCAAsC,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG,cAAc,CAAC;AAC1C,MAAM,MAAM,YAAY,GAAG,cAAc,CAAC;AAC1C,MAAM,MAAM,aAAa,GAAG,eAAe,CAAC;AAC5C,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,iDAElD"}
|
package/dist/submission.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { Effect, Schema } from "effect";
|
|
2
|
-
import type * as Atom from "effect/
|
|
2
|
+
import type * as Atom from "effect/reactivity/Atom";
|
|
3
|
+
import type { PersistedDraftConfig } from "@shivaedev/effect-form/persistence.ts";
|
|
3
4
|
import type { Decoded, Encoded, FieldFailure, Fields, Form, Services } from "@shivaedev/effect-form/shape.ts";
|
|
4
5
|
import { type AtomServices, type RejectField } from "./field-rejection.ts";
|
|
5
6
|
export interface SubmissionConfig<F extends Fields, A, E, R, ER> {
|
|
6
7
|
readonly fields: Schema.Struct<F>;
|
|
7
8
|
readonly initialValues: Encoded<F>;
|
|
9
|
+
readonly persistedDraft?: PersistedDraftConfig | undefined;
|
|
8
10
|
readonly rejectField: RejectField<F, E> | undefined;
|
|
9
11
|
readonly runtime: Atom.AtomRuntime<Services<F, R>, ER>;
|
|
10
12
|
readonly save: (values: Decoded<F>) => Effect.Effect<A, E, AtomServices<R>>;
|
package/dist/submission.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submission.d.ts","sourceRoot":"","sources":["../src/submission.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,KAAK,KAAK,IAAI,MAAM,
|
|
1
|
+
{"version":3,"file":"submission.d.ts","sourceRoot":"","sources":["../src/submission.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,KAAK,KAAK,IAAI,MAAM,wBAAwB,CAAC;AAEpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAC9G,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAa,MAAM,sBAAsB,CAAC;AAEtF,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE;IAC9D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAClC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACnC,QAAQ,CAAC,cAAc,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;IAC3D,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC;IACpD,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACvD,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;CAC5E;AAED,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE;IACrD,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,YAAY,EAAE,EAAE,CAAC,CAAC;IAChD,QAAQ,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;CACjD;AAED,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,UAAU,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAG,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAc1H,CAAC"}
|
package/dist/submission.js
CHANGED
package/dist/submission.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submission.js","sourceRoot":"","sources":["../src/submission.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"submission.js","sourceRoot":"","sources":["../src/submission.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAC;AAGtD,OAAO,EAAuC,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAgBtF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAgC,MAAwC,EAA2B,EAAE;IAC9H,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAClD,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;IAChE,IAAI,SAAiC,CAAC;IACtC,MAAM,IAAI,GAAqC,IAAI,CAAC,MAAM,EAAE;QAC3D,aAAa;QACb,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE;YACzC,SAAS,GAAG,QAAQ,CAAC;YACrB,OAAO,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAChC,CAAC;QACD,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,OAAO;KACP,CAAC,CAAC;IACH,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC;AAC7C,CAAC,CAAC"}
|
package/docs/roadmap.md
CHANGED
|
@@ -8,6 +8,7 @@ This roadmap owns the package's hooks, form coordination and session-registry im
|
|
|
8
8
|
- [x] Public `testing.ts` render helpers supply an isolated native registry per mount, retain it on rerender, and dispose native resources and remove the container on idempotent unmount. [DOM evidence](https://github.com/ShivaeDev/platform/blob/main/packages/effect-react/src/client/testing.dom.test.tsx) also exercises query refetch after a command through a test RPC Layer; it does not establish browser networking.
|
|
9
9
|
- [x] Native query and action hooks with inferred input/success/failure types, retained data, pending/refresh state and explicit refresh/dispatch methods. DOM tests cover query identity changes, shared query execution and latest-dispatch interruption; compiler fixtures cover types.
|
|
10
10
|
- [x] A session generation owning its client, registry and subtree, with replacement/sign-out cleanup, query Unauthorized rechecking and retained screens until the auth owner changes the session.
|
|
11
|
+
- [x] Unauthorized saves in `useCreate` and `useEditor` invoke the session callback exactly once and retain the draft and typed failure, including after rerendering and further edits. [Rendered save evidence](https://github.com/ShivaeDev/platform/blob/main/packages/effect-react/src/client/saveState.dom.test.tsx).
|
|
11
12
|
- [x] Session cleanup across StrictMode effect replay and Activity hiding, reveal and hidden unmount, with credential rotation tested against the chosen identity key.
|
|
12
13
|
- [x] `useEditor` composing query, fields and save Effect, with initial loading, per-query forms, per-field refresh/saved-result merges, normalized results and in-flight edits covered by rendered tests.
|
|
13
14
|
- [x] `useCreate` starting a fresh form after success while retaining fields edited during schema decoding or the request; submissions through the form API settle the hooks too.
|
|
@@ -17,7 +18,7 @@ This roadmap owns the package's hooks, form coordination and session-registry im
|
|
|
17
18
|
|
|
18
19
|
## Next
|
|
19
20
|
|
|
20
|
-
- [ ] Add direct rendered regressions for Unauthorized action
|
|
21
|
+
- [ ] Add direct rendered regressions for Unauthorized action failures invoking the session callback.
|
|
21
22
|
- [ ] Add explicit result-state regressions for a successful `undefined` value and causes containing defects or interruption before making stronger README guarantees about those cases.
|
|
22
23
|
- [ ] Verify changing hook configuration during one form lifetime before documenting any supported reconfiguration policy. Creation currently captures its initial configuration, and an editor holds submission functions per query identity.
|
|
23
24
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shivaedev/effect-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "React query, action, editor and session hooks for native Effect atoms",
|
|
5
5
|
"homepage": "https://github.com/ShivaeDev/platform/tree/main/packages/effect-react#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -129,47 +129,43 @@
|
|
|
129
129
|
"README.md"
|
|
130
130
|
],
|
|
131
131
|
"dependencies": {
|
|
132
|
-
"@shivaedev/effect-contract": "0.
|
|
132
|
+
"@shivaedev/effect-contract": "0.5.0",
|
|
133
|
+
"@shivaedev/effect-form": "0.4.0"
|
|
133
134
|
},
|
|
134
135
|
"devDependencies": {
|
|
135
|
-
"@effect/atom-react": "4.0.
|
|
136
|
-
"@effect/platform-node": "4.0.
|
|
137
|
-
"@effect/sql-pg": "4.0.
|
|
138
|
-
"@effect/sql-sqlite-node": "4.0.
|
|
139
|
-
"@shivaedev/effect-
|
|
140
|
-
"@shivaedev/effect-
|
|
141
|
-
"@shivaedev/effect-
|
|
142
|
-
"@shivaedev/effect-
|
|
143
|
-
"@shivaedev/effect-test": "0.3.2",
|
|
136
|
+
"@effect/atom-react": "4.0.4",
|
|
137
|
+
"@effect/platform-node": "4.0.4",
|
|
138
|
+
"@effect/sql-pg": "4.0.4",
|
|
139
|
+
"@effect/sql-sqlite-node": "4.0.4",
|
|
140
|
+
"@shivaedev/effect-pg-boss": "0.5.0",
|
|
141
|
+
"@shivaedev/effect-service": "0.3.0",
|
|
142
|
+
"@shivaedev/effect-sql": "0.3.0",
|
|
143
|
+
"@shivaedev/effect-test": "0.4.0",
|
|
144
144
|
"@shivaedev/local-postgres": "0.2.0",
|
|
145
|
-
"@shivaedev/platform": "0.
|
|
146
|
-
"@shivaedev/quality": "0.
|
|
147
|
-
"@shivaedev/test-story": "0.
|
|
145
|
+
"@shivaedev/platform": "0.7.0",
|
|
146
|
+
"@shivaedev/quality": "0.20.0",
|
|
147
|
+
"@shivaedev/test-story": "0.2.0",
|
|
148
148
|
"@tanstack/react-router": "1.170.41",
|
|
149
149
|
"@types/node": "24.19.1",
|
|
150
|
-
"@types/react": "19.
|
|
151
|
-
"@types/react-dom": "19.
|
|
150
|
+
"@types/react": "19.3.0",
|
|
151
|
+
"@types/react-dom": "19.3.0",
|
|
152
152
|
"@typescript/native": "npm:typescript@7.0.2",
|
|
153
|
-
"effect": "4.0.
|
|
153
|
+
"effect": "4.0.4",
|
|
154
154
|
"happy-dom": "20.14.5",
|
|
155
|
-
"react": "19.
|
|
156
|
-
"react-dom": "19.
|
|
155
|
+
"react": "19.3.0",
|
|
156
|
+
"react-dom": "19.3.0",
|
|
157
157
|
"typescript": "npm:@typescript/typescript6@6.0.2",
|
|
158
|
-
"vitest": "
|
|
158
|
+
"vitest": "5.0.3"
|
|
159
159
|
},
|
|
160
160
|
"peerDependencies": {
|
|
161
|
-
"@effect/atom-react": "4.0.
|
|
162
|
-
"@shivaedev/effect-form": "0.2.1",
|
|
161
|
+
"@effect/atom-react": "4.0.4",
|
|
163
162
|
"@tanstack/react-router": "1.170.41",
|
|
164
|
-
"effect": "4.0.
|
|
165
|
-
"react": "19.
|
|
166
|
-
"react-dom": "19.
|
|
167
|
-
"vitest": "
|
|
163
|
+
"effect": "4.0.4",
|
|
164
|
+
"react": "19.3.0",
|
|
165
|
+
"react-dom": "19.3.0",
|
|
166
|
+
"vitest": "5.0.3"
|
|
168
167
|
},
|
|
169
168
|
"peerDependenciesMeta": {
|
|
170
|
-
"@shivaedev/effect-form": {
|
|
171
|
-
"optional": true
|
|
172
|
-
},
|
|
173
169
|
"@tanstack/react-router": {
|
|
174
170
|
"optional": true
|
|
175
171
|
},
|
package/src/client/create.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { type Effect, Equal, Option, type Schema } from "effect";
|
|
2
|
-
import type * as Atom from "effect/
|
|
2
|
+
import type * as Atom from "effect/reactivity/Atom";
|
|
3
3
|
import { useCallback, useState } from "react";
|
|
4
|
+
import { type BrowserDraftConfig, usePersistedDraft } from "@shivaedev/effect-form/react.ts";
|
|
4
5
|
import type { Decoded, Encoded, FieldFailure, Fields, Form, Services } from "@shivaedev/effect-form/shape.ts";
|
|
5
6
|
import type { AtomServices, FieldRejectionMapping } from "#field-rejection.ts";
|
|
6
7
|
import { submission } from "#submission.ts";
|
|
7
8
|
import { type SaveState, useSaveState } from "./saveState.ts";
|
|
8
9
|
export type CreateConfig<TFields extends Fields, TCreated, TSaveError, R, TRuntimeError> = {
|
|
10
|
+
readonly persistedDraft?: BrowserDraftConfig | undefined;
|
|
9
11
|
readonly fields: Schema.Struct<TFields>;
|
|
10
12
|
readonly initialValues: Encoded<TFields>;
|
|
11
13
|
readonly create: (values: Decoded<TFields>) => Effect.Effect<TCreated, TSaveError, AtomServices<R>>;
|
|
@@ -22,9 +24,10 @@ function editedSince<TV extends object>(current: TV, submitted: TV | undefined):
|
|
|
22
24
|
export function useCreate<TFields extends Fields, TCreated, TSaveError, R, TRuntimeError>(
|
|
23
25
|
config: CreateConfig<TFields, TCreated, TSaveError, R, TRuntimeError>,
|
|
24
26
|
): Create<TFields, TCreated, TSaveError, TRuntimeError> {
|
|
27
|
+
const persistedDraft = usePersistedDraft(config.persistedDraft);
|
|
25
28
|
const [{ initialValues: baseline, fresh }] = useState(() => {
|
|
26
29
|
const { fields, initialValues, runtime, create, rejectField } = config;
|
|
27
|
-
return { fresh: () => submission({ fields, initialValues, rejectField, runtime, save: create }), initialValues };
|
|
30
|
+
return { fresh: () => submission({ fields, initialValues, persistedDraft, rejectField, runtime, save: create }), initialValues };
|
|
28
31
|
});
|
|
29
32
|
const [current, replace] = useState(fresh);
|
|
30
33
|
const [created, record] = useState<Option.Option<TCreated>>(Option.none());
|
package/src/client/editor.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { type Effect, Option, type Schema } from "effect";
|
|
2
|
-
import type * as AsyncResult from "effect/
|
|
3
|
-
import type * as Atom from "effect/
|
|
2
|
+
import type * as AsyncResult from "effect/reactivity/AsyncResult";
|
|
3
|
+
import type * as Atom from "effect/reactivity/Atom";
|
|
4
4
|
import { useCallback, useEffect, useState } from "react";
|
|
5
|
+
import { type BrowserDraftConfig, usePersistedDraft } from "@shivaedev/effect-form/react.ts";
|
|
5
6
|
import type { Decoded, Encoded, FieldFailure, Fields, Form, Services } from "@shivaedev/effect-form/shape.ts";
|
|
6
7
|
import type { AtomServices, FieldRejectionMapping } from "#field-rejection.ts";
|
|
7
8
|
import { submission } from "#submission.ts";
|
|
8
9
|
import { type QueryState, useQuery } from "./resultState.ts";
|
|
9
10
|
import { type SaveState, useSaveState } from "./saveState.ts";
|
|
10
11
|
export type EditorConfig<TFields extends Fields, TRow, TQueryError, TSaveError, R, TRuntimeError> = {
|
|
12
|
+
readonly persistedDraft?: BrowserDraftConfig | undefined;
|
|
11
13
|
readonly query: Atom.Atom<AsyncResult.AsyncResult<TRow, TQueryError>>;
|
|
12
14
|
readonly fields: Schema.Struct<TFields>;
|
|
13
15
|
readonly values: (row: TRow) => Encoded<TFields>;
|
|
@@ -26,6 +28,7 @@ interface Held<TFields extends Fields, TRow, TSaveError, TRuntimeError> {
|
|
|
26
28
|
export function useEditor<TFields extends Fields, TRow, TQueryError, TSaveError, R, TRuntimeError>(
|
|
27
29
|
config: EditorConfig<TFields, TRow, TQueryError, TSaveError, R, TRuntimeError>,
|
|
28
30
|
): Editor<TFields, TRow, TQueryError, TSaveError, TRuntimeError> {
|
|
31
|
+
const persistedDraft = usePersistedDraft(config.persistedDraft);
|
|
29
32
|
const query = useQuery(config.query);
|
|
30
33
|
const row = Option.getOrUndefined(query.data);
|
|
31
34
|
const [held, hold] = useState<Held<TFields, TRow, TSaveError, TRuntimeError> | undefined>(undefined);
|
|
@@ -35,6 +38,7 @@ export function useEditor<TFields extends Fields, TRow, TQueryError, TSaveError,
|
|
|
35
38
|
form: submission({
|
|
36
39
|
fields: config.fields,
|
|
37
40
|
initialValues: config.values(row),
|
|
41
|
+
persistedDraft,
|
|
38
42
|
rejectField: config.rejectField,
|
|
39
43
|
runtime: config.runtime,
|
|
40
44
|
save: config.save,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { RegistryContext, useAtomRefresh, useAtomSet, useAtomValue } from "@effect/atom-react";
|
|
2
2
|
import { Cause, Option, Predicate } from "effect";
|
|
3
|
-
import * as AsyncResult from "effect/
|
|
4
|
-
import type * as Atom from "effect/
|
|
5
|
-
import type * as AtomRegistry from "effect/
|
|
3
|
+
import * as AsyncResult from "effect/reactivity/AsyncResult";
|
|
4
|
+
import type * as Atom from "effect/reactivity/Atom";
|
|
5
|
+
import type * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
6
6
|
import { useContext, useEffect, useState } from "react";
|
|
7
7
|
import { useSessionRecheck } from "./sessionBoundary.ts";
|
|
8
8
|
export interface ResultState<A, E> {
|
package/src/client/saveState.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RegistryContext, useAtomValue } from "@effect/atom-react";
|
|
2
2
|
import { Option } from "effect";
|
|
3
|
-
import * as AsyncResult from "effect/
|
|
4
|
-
import * as Atom from "effect/
|
|
3
|
+
import * as AsyncResult from "effect/reactivity/AsyncResult";
|
|
4
|
+
import * as Atom from "effect/reactivity/Atom";
|
|
5
5
|
import { useCallback, useContext, useEffect } from "react";
|
|
6
6
|
import { FieldFailure, type Fields, type Form, Invalid } from "@shivaedev/effect-form/shape.ts";
|
|
7
7
|
import { isUnauthorized } from "./resultState.ts";
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { RegistryContext } from "@effect/atom-react";
|
|
2
|
-
import * as AtomRegistry from "effect/
|
|
2
|
+
import * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
3
3
|
import { createContext, createElement, Fragment, type ReactNode, useContext, useEffect, useState } from "react";
|
|
4
|
+
import { DraftSessionContext } from "@shivaedev/effect-form/react.ts";
|
|
5
|
+
import { useDraftOwner } from "./useDraftOwner.ts";
|
|
4
6
|
export interface SessionBoundaryProps<TSession, TClient> {
|
|
5
7
|
readonly children: (client: TClient) => ReactNode;
|
|
6
8
|
readonly connect: (session: TSession) => TClient;
|
|
@@ -74,7 +76,13 @@ export function SessionBoundary<TSession, TClient>({
|
|
|
74
76
|
signedOut,
|
|
75
77
|
children,
|
|
76
78
|
}: SessionBoundaryProps<TSession, TClient>): ReactNode {
|
|
79
|
+
const id = session === undefined ? undefined : identify(session);
|
|
80
|
+
const current = useDraftOwner(id);
|
|
77
81
|
return session === undefined
|
|
78
82
|
? createElement(Fragment, null, signedOut)
|
|
79
|
-
: createElement(
|
|
83
|
+
: createElement(
|
|
84
|
+
DraftSessionContext.Provider,
|
|
85
|
+
{ value: current },
|
|
86
|
+
createElement(Generation<TSession, TClient>, { children, connect, key: id, recheck, session }),
|
|
87
|
+
);
|
|
80
88
|
}
|
package/src/client/testing.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RegistryContext } from "@effect/atom-react";
|
|
2
2
|
import { Clock, Effect } from "effect";
|
|
3
|
-
import * as AtomRegistry from "effect/
|
|
3
|
+
import * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
4
4
|
import { act, createElement, type ReactNode } from "react";
|
|
5
5
|
import { createRoot } from "react-dom/client";
|
|
6
6
|
import { beforeEach, expect, vi } from "vitest";
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { useInsertionEffect, useRef, useState } from "react";
|
|
2
|
+
import { type DraftSession, draftSession } from "@shivaedev/effect-form/draftSession.ts";
|
|
3
|
+
|
|
4
|
+
interface DraftOwner {
|
|
5
|
+
readonly activate: () => void;
|
|
6
|
+
readonly session: DraftSession;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function owner(id: string, active: boolean): DraftOwner {
|
|
10
|
+
const session = draftSession(id);
|
|
11
|
+
let committed = active;
|
|
12
|
+
return {
|
|
13
|
+
activate: () => {
|
|
14
|
+
committed = true;
|
|
15
|
+
},
|
|
16
|
+
session: {
|
|
17
|
+
...session,
|
|
18
|
+
get active() {
|
|
19
|
+
return committed && session.active;
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function useDraftOwner(id: string | undefined): DraftSession | undefined {
|
|
26
|
+
const [held, hold] = useState(() => (id === undefined ? undefined : owner(id, true)));
|
|
27
|
+
const committedRef = useRef(held);
|
|
28
|
+
let current = held;
|
|
29
|
+
if (current?.session.id !== id) {
|
|
30
|
+
current = id === undefined ? undefined : owner(id, committedRef.current === undefined);
|
|
31
|
+
hold(current);
|
|
32
|
+
}
|
|
33
|
+
// Insertion effects also run for Activity commits while layout and passive effects are disconnected.
|
|
34
|
+
useInsertionEffect(() => {
|
|
35
|
+
if (committedRef.current !== current) {
|
|
36
|
+
committedRef.current?.session.drop();
|
|
37
|
+
current?.activate();
|
|
38
|
+
committedRef.current = current;
|
|
39
|
+
}
|
|
40
|
+
}, [current]);
|
|
41
|
+
return current?.session;
|
|
42
|
+
}
|
package/src/field-rejection.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Effect, Predicate, type Schema, type Scope } from "effect";
|
|
2
|
-
import type { AtomRegistry } from "effect/
|
|
3
|
-
import type { Reactivity } from "effect/
|
|
2
|
+
import type { AtomRegistry } from "effect/reactivity/AtomRegistry";
|
|
3
|
+
import type { Reactivity } from "effect/reactivity/Reactivity";
|
|
4
4
|
import type { FieldFailure, Fields, Name, Submitter } from "@shivaedev/effect-form/shape.ts";
|
|
5
5
|
|
|
6
6
|
export interface FieldRejection<N extends string> {
|
package/src/loadQuery.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { LoaderFnContext } from "@tanstack/react-router";
|
|
2
2
|
import { Effect } from "effect";
|
|
3
|
-
import type * as AsyncResult from "effect/
|
|
4
|
-
import type * as Atom from "effect/
|
|
5
|
-
import * as AtomRegistry from "effect/
|
|
3
|
+
import type * as AsyncResult from "effect/reactivity/AsyncResult";
|
|
4
|
+
import type * as Atom from "effect/reactivity/Atom";
|
|
5
|
+
import * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
6
6
|
|
|
7
7
|
export async function loadQuery<A, E>(
|
|
8
8
|
registry: AtomRegistry.AtomRegistry,
|
package/src/submission.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import type { Effect, Schema } from "effect";
|
|
2
|
-
import type * as Atom from "effect/
|
|
2
|
+
import type * as Atom from "effect/reactivity/Atom";
|
|
3
3
|
import { make } from "@shivaedev/effect-form/form.ts";
|
|
4
|
+
import type { PersistedDraftConfig } from "@shivaedev/effect-form/persistence.ts";
|
|
4
5
|
import type { Decoded, Encoded, FieldFailure, Fields, Form, Services } from "@shivaedev/effect-form/shape.ts";
|
|
5
6
|
import { type AtomServices, type RejectField, rejecting } from "./field-rejection.ts";
|
|
6
7
|
|
|
7
8
|
export interface SubmissionConfig<F extends Fields, A, E, R, ER> {
|
|
8
9
|
readonly fields: Schema.Struct<F>;
|
|
9
10
|
readonly initialValues: Encoded<F>;
|
|
11
|
+
readonly persistedDraft?: PersistedDraftConfig | undefined;
|
|
10
12
|
readonly rejectField: RejectField<F, E> | undefined;
|
|
11
13
|
readonly runtime: Atom.AtomRuntime<Services<F, R>, ER>;
|
|
12
14
|
readonly save: (values: Decoded<F>) => Effect.Effect<A, E, AtomServices<R>>;
|
|
@@ -27,6 +29,7 @@ export const submission = <F extends Fields, A, E, R, ER>(config: SubmissionConf
|
|
|
27
29
|
submitted = snapshot;
|
|
28
30
|
return save(values, submitter);
|
|
29
31
|
},
|
|
32
|
+
persistedDraft: config.persistedDraft,
|
|
30
33
|
runtime,
|
|
31
34
|
});
|
|
32
35
|
return { form, submitted: () => submitted };
|