@shivaedev/effect-react 0.4.1 → 0.5.1
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 +13 -0
- package/README.md +22 -44
- package/dist/client/create.d.ts +2 -2
- package/dist/client/create.d.ts.map +1 -1
- package/dist/client/create.js +1 -1
- package/dist/client/create.js.map +1 -1
- package/dist/client/editor.d.ts +2 -2
- package/dist/client/editor.d.ts.map +1 -1
- package/dist/client/editor.js +1 -1
- package/dist/client/editor.js.map +1 -1
- package/dist/client/sessionBoundary.d.ts.map +1 -1
- package/dist/client/sessionBoundary.js +3 -1
- package/dist/client/sessionBoundary.js.map +1 -1
- package/dist/{field-rejection.d.ts → fieldRejection.d.ts} +1 -1
- package/dist/fieldRejection.d.ts.map +1 -0
- package/dist/{field-rejection.js → fieldRejection.js} +1 -1
- package/dist/fieldRejection.js.map +1 -0
- package/dist/internal/sessionRecheck.d.ts +4 -0
- package/dist/internal/sessionRecheck.d.ts.map +1 -0
- package/dist/internal/sessionRecheck.js +14 -0
- package/dist/internal/sessionRecheck.js.map +1 -0
- package/dist/loadQuery.d.ts.map +1 -1
- package/dist/loadQuery.js +2 -0
- package/dist/loadQuery.js.map +1 -1
- package/dist/{resume-signal.d.ts → resumeSignal.d.ts} +1 -1
- package/dist/resumeSignal.d.ts.map +1 -0
- package/dist/{resume-signal.js → resumeSignal.js} +1 -1
- package/dist/resumeSignal.js.map +1 -0
- package/dist/submission.d.ts +1 -1
- package/dist/submission.d.ts.map +1 -1
- package/dist/submission.js +1 -1
- package/dist/submission.js.map +1 -1
- package/package.json +20 -107
- package/src/client/create.ts +2 -2
- package/src/client/editor.ts +2 -2
- package/src/client/sessionBoundary.ts +3 -1
- package/src/internal/sessionRecheck.ts +17 -0
- package/src/loadQuery.ts +2 -0
- package/src/submission.ts +1 -1
- package/dist/field-rejection.d.ts.map +0 -1
- package/dist/field-rejection.js.map +0 -1
- package/dist/resume-signal.d.ts.map +0 -1
- package/dist/resume-signal.js.map +0 -1
- package/docs/north-star.md +0 -45
- package/docs/roadmap.md +0 -29
- /package/src/{field-rejection.ts → fieldRejection.ts} +0 -0
- /package/src/{resume-signal.ts → resumeSignal.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.1 - 2026-10-18
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Route loaders and `loadQuery` recheck the owning `SessionBoundary` session once when a query fails with `Unauthorized`, so sign-in redirects can see an ended session.
|
|
8
|
+
|
|
9
|
+
## 0.5.0 - 2026-10-18
|
|
10
|
+
|
|
11
|
+
### Breaking
|
|
12
|
+
|
|
13
|
+
- Modules are named in camelCase: `field-rejection.ts` becomes `fieldRejection.ts`, and `resume-signal.ts` becomes `resumeSignal.ts`.
|
|
14
|
+
- Every module's import path is now its path under `src/`. `router.ts` becomes `loadQuery.ts`; `create.ts`, `editor.ts` and `testing.ts` move under `client/`; `result-state.ts`, `save-state.ts` and `session-boundary.ts` become `client/resultState.ts`, `client/saveState.ts` and `client/sessionBoundary.ts`.
|
|
15
|
+
|
|
3
16
|
## 0.4.1 - 2026-10-17
|
|
4
17
|
|
|
5
18
|
### Fixed
|
package/README.md
CHANGED
|
@@ -47,7 +47,7 @@ export function App() {
|
|
|
47
47
|
`Orders` is the application's feature component. For authenticated screens, use `SessionBoundary` at the authenticated root instead:
|
|
48
48
|
|
|
49
49
|
```tsx
|
|
50
|
-
import { SessionBoundary } from "@shivaedev/effect-react/
|
|
50
|
+
import { SessionBoundary } from "@shivaedev/effect-react/client/sessionBoundary.ts";
|
|
51
51
|
import { makeOrderClient, OrderScreens } from "./orders.tsx";
|
|
52
52
|
|
|
53
53
|
interface Session {
|
|
@@ -76,7 +76,7 @@ export function App({ session, recheck }: {
|
|
|
76
76
|
|
|
77
77
|
`makeOrderClient` and `OrderScreens` belong to the application. A changed generation creates a new client and registry, remounts the screens and disposes the outgoing registry. `undefined` renders `signedOut`. Updating the session object with the same generation keeps the existing client: `connect` does not receive a rotated token until the identity changes. Include the credential generation when the client captures its token, as above.
|
|
78
78
|
|
|
79
|
-
A query that fails with a tagged `Unauthorized` asks `recheck` to run and keeps its retained data. The auth owner can retry the same session or remove it; the hook does not sign the user out. The boundary also handles React StrictMode's effect replay and preserves component state across hiding and revealing an `<Activity>` subtree, supplying a live registry when revealed.
|
|
79
|
+
A query that fails with a tagged `Unauthorized` asks `recheck` to run and keeps its retained data. An action does the same once per failed result, retaining its last successful `data` and the typed failure in `cause`; rerendering that result does not repeat the recheck. The auth owner can retry the same session or remove it; the hook does not sign the user out. The boundary also handles React StrictMode's effect replay and preserves component state across hiding and revealing an `<Activity>` subtree, supplying a live registry when revealed.
|
|
80
80
|
|
|
81
81
|
### 2. Once per feature: native queries and actions
|
|
82
82
|
|
|
@@ -84,7 +84,7 @@ The hooks accept native atoms directly. This complete component module shows que
|
|
|
84
84
|
|
|
85
85
|
```tsx
|
|
86
86
|
import { RegistryProvider } from "@effect/atom-react";
|
|
87
|
-
import { useAction, useQuery } from "@shivaedev/effect-react/
|
|
87
|
+
import { useAction, useQuery } from "@shivaedev/effect-react/client/resultState.ts";
|
|
88
88
|
import { Effect, Option } from "effect";
|
|
89
89
|
import * as Atom from "effect/reactivity/Atom";
|
|
90
90
|
|
|
@@ -121,6 +121,8 @@ export function App() {
|
|
|
121
121
|
}
|
|
122
122
|
```
|
|
123
123
|
|
|
124
|
+
For both queries and actions, a successful `undefined` is `Option.some(undefined)` in `data`, with `pending` and `refreshing` false. A defect or interruption is available as `Option.some(cause)` in `cause`; `isUnauthorized` returns false for those causes and they do not request a session recheck, even when the defect has an `Unauthorized` tag.
|
|
125
|
+
|
|
124
126
|
The example's action returns a value; it does not persist the report or invalidate its query. In an application, use the native RPC query and mutation atoms instead:
|
|
125
127
|
|
|
126
128
|
```ts
|
|
@@ -135,13 +137,13 @@ create.dispatch({
|
|
|
135
137
|
});
|
|
136
138
|
```
|
|
137
139
|
|
|
138
|
-
`NotesClient` is an application's `AtomRpc.Service` with `ListNotes` and `CreateNote` RPCs. The native mutation's reactivity keys refresh the matching query after success.
|
|
140
|
+
`NotesClient` is an application's `AtomRpc.Service` with `ListNotes` and `CreateNote` RPCs. The native mutation's reactivity keys refresh the matching query after success.
|
|
139
141
|
|
|
140
142
|
An action's `dispatch(input)` returns `void`. Read the atom's latest result from `data`, `cause` or `result`. With the default `Atom.fn` action, a later dispatch interrupts the earlier work and the shared state reports the later result. Disable duplicate submissions or give independent work distinct native action atoms. When one caller needs its own success or failure, run the actual RPC Effect through its runtime, as the editor's `save` does; shared atom state cannot identify one invocation's completion.
|
|
141
143
|
|
|
142
144
|
### Route loaders with TanStack Router
|
|
143
145
|
|
|
144
|
-
TanStack Router owns routes, navigation, loader data and error components. `@shivaedev/effect-react/
|
|
146
|
+
TanStack Router owns routes, navigation, loader data and error components. `@shivaedev/effect-react/loadQuery.ts` supplies `loadQuery(registry, atom, loaderContext)` to read a contract query atom in the same registry as React. The atom runs through its native RPC runtime; the loader does not create another runtime or query cache.
|
|
145
147
|
|
|
146
148
|
This example assumes an application-owned `api.get.query({ id })` returning `{ id, title }`, with a declared `NoteMissing` rejection:
|
|
147
149
|
|
|
@@ -151,7 +153,7 @@ import { createRootRouteWithContext, createRoute, createRouter, Outlet, RouterPr
|
|
|
151
153
|
import type { ErrorComponentProps } from "@tanstack/react-router";
|
|
152
154
|
import { Predicate } from "effect";
|
|
153
155
|
import * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
154
|
-
import { loadQuery } from "@shivaedev/effect-react/
|
|
156
|
+
import { loadQuery } from "@shivaedev/effect-react/loadQuery.ts";
|
|
155
157
|
import { api } from "./notes-client.ts";
|
|
156
158
|
|
|
157
159
|
const registry = AtomRegistry.make();
|
|
@@ -193,7 +195,7 @@ export function App() {
|
|
|
193
195
|
}
|
|
194
196
|
```
|
|
195
197
|
|
|
196
|
-
`defaultPendingMs: Infinity` keeps the current route's data visible during navigation; the shell reads TanStack's `isLoading` to display pending state. The new route commits when its loader settles. This is TanStack's pending policy, separate from `useQuery`'s retained display. The
|
|
198
|
+
`defaultPendingMs: Infinity` keeps the current route's data visible during navigation; the shell reads TanStack's `isLoading` to display pending state. The new route commits when its loader settles. This is TanStack's pending policy, separate from `useQuery`'s retained display. The loader and the component share one query execution.
|
|
197
199
|
|
|
198
200
|
`loadQuery` waits through a native query refresh instead of returning its retained success. Typed failures are thrown directly, so the route can inspect `_tag` rather than an Effect fiber wrapper. Defects remain failed Promises. TanStack's loader `abortController` cancels the waiting subscription and rejects with `name: "AbortError"`; other readers of the same query can still complete. The application owns the registry's lifetime and disposes it when its client or session ends. Use the same registry for router context and `RegistryContext.Provider`.
|
|
199
201
|
|
|
@@ -208,9 +210,9 @@ pnpm add @tanstack/react-router
|
|
|
208
210
|
The next module assumes `./invoice-lines-client.ts` exports a contract-bound `api` with `get`, `save` and `create`, and its native `InvoiceLinesClient`. `get` returns `{ id, name, quantity }`; both commands return the saved row. The [contract guide](https://github.com/ShivaeDev/platform/blob/main/packages/effect-contract/README.md) describes that binding.
|
|
209
211
|
|
|
210
212
|
```tsx
|
|
211
|
-
import { useCreate } from "@shivaedev/effect-react/create.ts";
|
|
212
|
-
import { useEditor } from "@shivaedev/effect-react/editor.ts";
|
|
213
|
-
import { useField } from "@shivaedev/effect-form/react.ts";
|
|
213
|
+
import { useCreate } from "@shivaedev/effect-react/client/create.ts";
|
|
214
|
+
import { useEditor } from "@shivaedev/effect-react/client/editor.ts";
|
|
215
|
+
import { useField } from "@shivaedev/effect-form/client/react.ts";
|
|
214
216
|
import type { Form } from "@shivaedev/effect-form/shape.ts";
|
|
215
217
|
import { Option, Schema } from "effect";
|
|
216
218
|
import { api, InvoiceLinesClient } from "./invoice-lines-client.ts";
|
|
@@ -318,7 +320,7 @@ Here `save` has a tagged `SubtitleRejected` failure referring to the server's `s
|
|
|
318
320
|
Keep the signal and query identities stable:
|
|
319
321
|
|
|
320
322
|
```ts
|
|
321
|
-
import { resumeSignal } from "@shivaedev/effect-react/
|
|
323
|
+
import { resumeSignal } from "@shivaedev/effect-react/resumeSignal.ts";
|
|
322
324
|
import { Effect } from "effect";
|
|
323
325
|
import * as Atom from "effect/reactivity/Atom";
|
|
324
326
|
|
|
@@ -354,30 +356,17 @@ const query = Atom.swr(atom, {
|
|
|
354
356
|
|
|
355
357
|
`useQuery(atom, options?)` adds `refresh(): void`; `useAction` adds `dispatch(input): void`. `QueryOptions.keepPreviousData` defaults to `false` and controls retention across query atom changes. Same-identity refresh retention is always enabled. `result` and `cause` describe the current native query even when `data` displays a previous atom's success. Success, input and typed failure types are inferred from the supplied atom.
|
|
356
358
|
|
|
357
|
-
|
|
358
|
-
| --- | --- |
|
|
359
|
-
| `result-state.ts` | `useQuery`, `useAction`, `isUnauthorized`; `ResultState`, `QueryOptions`, `QueryState`, `ActionState`. |
|
|
360
|
-
| `session-boundary.ts` | `SessionBoundary`, `useSessionRecheck`; `SessionBoundaryProps`. |
|
|
361
|
-
| `editor.ts` | `useEditor`; `Editor`, `EditorConfig`. |
|
|
362
|
-
| `create.ts` | `useCreate`; `Create`, `CreateConfig`. |
|
|
363
|
-
| `resume-signal.ts` | `resumeSignal`; `ResumeSource`, `ResumeWindow`, `ResumeOptions`. |
|
|
364
|
-
| `router.ts` | `loadQuery`. |
|
|
365
|
-
| `save-state.ts` | `useSaveState`; `SaveState`. |
|
|
366
|
-
| `field-rejection.ts` | `fieldRejectionOf`, `rejecting`; `FieldRejection`, `RejectField`, `FieldRejectionMapping`, `AtomServices`. |
|
|
367
|
-
| `testing.ts` | `render`, `eventually`, `expectNoReactWarnings`; `Rendered`. |
|
|
368
|
-
| `submission.ts` | `submission`; `Submission`, `SubmissionConfig`. |
|
|
369
|
-
|
|
370
|
-
Import the defining `.ts` module, such as `@shivaedev/effect-react/editor.ts`. There is no root import. `SessionBoundaryProps` supplies `session`, `identify`, `connect`, `recheck`, a client-to-children function and optional `signedOut`; `useSessionRecheck()` reads that boundary's callback.
|
|
359
|
+
Import the defining `.ts` module, such as `@shivaedev/effect-react/client/editor.ts`. There is no root import. `useSessionRecheck()` from `client/sessionBoundary.ts` reads the boundary's `recheck` callback.
|
|
371
360
|
|
|
372
|
-
|
|
361
|
+
Prefer `useEditor` and `useCreate` when binding a form to a command. The lower-level modules expose the same composition pieces: `submission` from `submission.ts` makes a form and its submission snapshot reader, `rejecting` from `fieldRejection.ts` maps save failures through a submitter, and `useSaveState` from `client/saveState.ts` observes submission and invokes a success callback.
|
|
373
362
|
|
|
374
363
|
### Render tests in happy-dom
|
|
375
364
|
|
|
376
|
-
Use `@shivaedev/effect-react/testing.ts` with Vitest's `happy-dom` environment. Install effect-contract for the example's query and command declarations, and the testing peers and environment in your app's dev dependencies:
|
|
365
|
+
Use `@shivaedev/effect-react/client/testing.ts` with Vitest's `happy-dom` environment. Install effect-contract for the example's query and command declarations, and the testing peers and environment in your app's dev dependencies:
|
|
377
366
|
|
|
378
367
|
```sh
|
|
379
368
|
pnpm add @shivaedev/effect-contract
|
|
380
|
-
pnpm add -D vitest happy-dom react-dom@19.
|
|
369
|
+
pnpm add -D vitest happy-dom react-dom@19.3.0 @types/react-dom
|
|
381
370
|
```
|
|
382
371
|
|
|
383
372
|
Configure Vitest with `test: { environment: "happy-dom" }`, or select that environment for your DOM test project. This complete `notes.dom.test.tsx` renders a component that runs a declared query and command against native RPC test handlers:
|
|
@@ -392,8 +381,8 @@ import { bind } from "@shivaedev/effect-contract/bind.ts";
|
|
|
392
381
|
import { contract } from "@shivaedev/effect-contract/contract.ts";
|
|
393
382
|
import { collection } from "@shivaedev/effect-contract/keys.ts";
|
|
394
383
|
import { command, query } from "@shivaedev/effect-contract/operation.ts";
|
|
395
|
-
import { useAction, useQuery } from "@shivaedev/effect-react/
|
|
396
|
-
import { eventually, expectNoReactWarnings, render } from "@shivaedev/effect-react/testing.ts";
|
|
384
|
+
import { useAction, useQuery } from "@shivaedev/effect-react/client/resultState.ts";
|
|
385
|
+
import { eventually, expectNoReactWarnings, render } from "@shivaedev/effect-react/client/testing.ts";
|
|
397
386
|
|
|
398
387
|
Object.assign(globalThis, { "IS_REACT_ACT_ENVIRONMENT": true });
|
|
399
388
|
expectNoReactWarnings();
|
|
@@ -456,16 +445,12 @@ it("renders a query and refetches it after a command through a test RPC layer",
|
|
|
456
445
|
|
|
457
446
|
`render(node)` returns the attached `container`, its fresh native `registry`, `render(nextNode)` to update the same root and registry, and `unmount()` to release the root, registry and container. Always unmount in `finally`. Keep component interactions inside React's `act`. `eventually(assert)` retries the assertion for up to three seconds, allowing pending responses to settle inside `act` between attempts; it throws the last assertion failure on timeout. `expectNoReactWarnings()` registers a Vitest hook that fails a test if it logged to `console.error`.
|
|
458
447
|
|
|
459
|
-
The RPC layer stays application-owned: replace these in-memory handlers with the service Layer your component needs.
|
|
460
|
-
|
|
461
|
-
### Testing a feature through its stack
|
|
462
|
-
|
|
463
|
-
The [order feature’s application-owned kit](https://github.com/ShivaeDev/platform/tree/main/packages/effect-react/src/test-support/order-example) uses `test-story` above `effect-test` to compose real PostgreSQL, HTTP RPC and the actual React components. Its screen traits mount fresh native atom registries and scoped roots; its verbs dispatch DOM events and wait for rendered output. The [stories](https://github.com/ShivaeDev/platform/blob/main/packages/effect-react/src/orderStory.dom.spec.tsx) verify list refresh through `useAction` and rejected-input retention and retry through `useEditor`, with persistence read from a separate PostgreSQL pool. These tests require `PLATFORM_EFFECT_SQL_TEST_DATABASE_URL`; DOM and loopback HTTP establish no physical browser, SSR or mobile behavior.
|
|
448
|
+
The RPC layer stays application-owned: replace these in-memory handlers with the service Layer your component needs.
|
|
464
449
|
|
|
465
450
|
### Install, setup and limits
|
|
466
451
|
|
|
467
452
|
```sh
|
|
468
|
-
pnpm add @shivaedev/effect-react @effect/atom-react@4.0.4 effect@4.0.4 react@19.
|
|
453
|
+
pnpm add @shivaedev/effect-react @effect/atom-react@4.0.4 effect@4.0.4 react@19.3.0
|
|
469
454
|
```
|
|
470
455
|
|
|
471
456
|
For editor, create or lower-level form modules, also install the optional form peer:
|
|
@@ -474,14 +459,7 @@ For editor, create or lower-level form modules, also install the optional form p
|
|
|
474
459
|
pnpm add @shivaedev/effect-form
|
|
475
460
|
```
|
|
476
461
|
|
|
477
|
-
Query, action, session and resume modules do not require effect-form. The package
|
|
462
|
+
Query, action, session and resume modules do not require effect-form. The package needs Node 24 or newer.
|
|
478
463
|
|
|
479
464
|
- Query identity, TTL, invalidation and action concurrency remain native atom policies. Put the registry at the lifetime boundary those policies need.
|
|
480
|
-
- Action state describes the atom's latest result. A `dispatch` is not a Promise or a separate result handle.
|
|
481
|
-
- A session generation is application-defined. Credentials captured by `connect` require a changed generation when they rotate.
|
|
482
465
|
- The package has no SSR registry/hydration adapter, offline write queue or optimistic reconciliation policy.
|
|
483
|
-
- DOM tests and an injected resume source do not prove real-browser or mobile lifecycle behavior. The real HTTP order fixture proves its local composition, not a deployed host's auth, cancellation or rendering policy.
|
|
484
|
-
|
|
485
|
-
The full design is in [the north star](https://github.com/ShivaeDev/platform/blob/main/packages/effect-react/docs/north-star.md). Implementation status and unresolved choices are in [the roadmap](https://github.com/ShivaeDev/platform/blob/main/packages/effect-react/docs/roadmap.md).
|
|
486
|
-
|
|
487
|
-
The [reference PostgreSQL feature](https://github.com/ShivaeDev/platform/blob/main/docs/framework/composed-example.md) uses the same leased database infrastructure and a scoped story verb for its real server and rendered clients. It is a test fixture, not a copyable app; an app template is still needed. Its stories verify commit visibility, live refresh of a second editor, retained local edits and rollback without publication.
|
package/dist/client/create.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type Effect, Option, type Schema } from "effect";
|
|
2
2
|
import type * as Atom from "effect/reactivity/Atom";
|
|
3
|
-
import { type BrowserDraftConfig } from "@shivaedev/effect-form/react.ts";
|
|
3
|
+
import { type BrowserDraftConfig } from "@shivaedev/effect-form/client/react.ts";
|
|
4
4
|
import type { Decoded, Encoded, FieldFailure, Fields, Form, Services } from "@shivaedev/effect-form/shape.ts";
|
|
5
|
-
import type { AtomServices, FieldRejectionMapping } from "#
|
|
5
|
+
import type { AtomServices, FieldRejectionMapping } from "#fieldRejection.ts";
|
|
6
6
|
import { type SaveState } from "./saveState.ts";
|
|
7
7
|
export type CreateConfig<TFields extends Fields, TCreated, TSaveError, R, TRuntimeError> = {
|
|
8
8
|
readonly persistedDraft?: BrowserDraftConfig | undefined;
|
|
@@ -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,wBAAwB,CAAC;AAEpD,OAAO,EAAE,KAAK,kBAAkB,EAAqB,MAAM,
|
|
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,wCAAwC,CAAC;AACpG,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,oBAAoB,CAAC;AAE9E,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,6 +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
|
+
import { usePersistedDraft } from "@shivaedev/effect-form/client/react.ts";
|
|
4
4
|
import { submission } from "#submission.ts";
|
|
5
5
|
import { useSaveState } from "./saveState.js";
|
|
6
6
|
function editedSince(current, submitted) {
|
|
@@ -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;AAC9C,OAAO,EAA2B,iBAAiB,EAAE,MAAM,
|
|
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,wCAAwC,CAAC;AAGpG,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,9 +1,9 @@
|
|
|
1
1
|
import { type Effect, type Schema } from "effect";
|
|
2
2
|
import type * as AsyncResult from "effect/reactivity/AsyncResult";
|
|
3
3
|
import type * as Atom from "effect/reactivity/Atom";
|
|
4
|
-
import { type BrowserDraftConfig } from "@shivaedev/effect-form/react.ts";
|
|
4
|
+
import { type BrowserDraftConfig } from "@shivaedev/effect-form/client/react.ts";
|
|
5
5
|
import type { Decoded, Encoded, FieldFailure, Fields, Form, Services } from "@shivaedev/effect-form/shape.ts";
|
|
6
|
-
import type { AtomServices, FieldRejectionMapping } from "#
|
|
6
|
+
import type { AtomServices, FieldRejectionMapping } from "#fieldRejection.ts";
|
|
7
7
|
import { type QueryState } from "./resultState.ts";
|
|
8
8
|
import { type SaveState } from "./saveState.ts";
|
|
9
9
|
export type EditorConfig<TFields extends Fields, TRow, TQueryError, TSaveError, R, TRuntimeError> = {
|
|
@@ -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,+BAA+B,CAAC;AAClE,OAAO,KAAK,KAAK,IAAI,MAAM,wBAAwB,CAAC;AAEpD,OAAO,EAAE,KAAK,kBAAkB,EAAqB,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,wCAAwC,CAAC;AACpG,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,oBAAoB,CAAC;AAE9E,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,6 +1,6 @@
|
|
|
1
1
|
import { Option } from "effect";
|
|
2
2
|
import { useCallback, useEffect, useState } from "react";
|
|
3
|
-
import { usePersistedDraft } from "@shivaedev/effect-form/react.ts";
|
|
3
|
+
import { usePersistedDraft } from "@shivaedev/effect-form/client/react.ts";
|
|
4
4
|
import { submission } from "#submission.ts";
|
|
5
5
|
import { useQuery } from "./resultState.js";
|
|
6
6
|
import { useSaveState } from "./saveState.js";
|
|
@@ -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;AACzD,OAAO,EAA2B,iBAAiB,EAAE,MAAM,
|
|
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,wCAAwC,CAAC;AAGpG,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 +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;AAIhH,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;AAuDD,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,7 +1,8 @@
|
|
|
1
1
|
import { RegistryContext } from "@effect/atom-react";
|
|
2
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";
|
|
4
|
+
import { DraftSessionContext } from "@shivaedev/effect-form/client/react.ts";
|
|
5
|
+
import { registerSessionRecheck } from "#internal/sessionRecheck.ts";
|
|
5
6
|
import { useDraftOwner } from "./useDraftOwner.js";
|
|
6
7
|
const RecheckContext = createContext(() => undefined);
|
|
7
8
|
export function useSessionRecheck() {
|
|
@@ -30,6 +31,7 @@ function hidden(client) {
|
|
|
30
31
|
}
|
|
31
32
|
function Generation({ session, connect, recheck, children }) {
|
|
32
33
|
const [owned, own] = useState(() => owning(connect(session)));
|
|
34
|
+
useEffect(() => registerSessionRecheck(owned.registry, recheck), [owned, recheck]);
|
|
33
35
|
useEffect(() => {
|
|
34
36
|
owned.mounted += 1;
|
|
35
37
|
return () => {
|
|
@@ -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,gCAAgC,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,QAAQ,EAAkB,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAChH,OAAO,EAAE,mBAAmB,EAAE,MAAM,
|
|
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,gCAAgC,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,QAAQ,EAAkB,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAChH,OAAO,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAC;AAC7E,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AASnD,MAAM,cAAc,GAAG,aAAa,CAAa,GAAS,EAAE,CAAC,SAAS,CAAC,CAAC;AACxE,MAAM,UAAU,iBAAiB;IAChC,OAAO,UAAU,CAAC,cAAc,CAAC,CAAC;AACnC,CAAC;AAMD,SAAS,MAAM,CAAU,MAAe;IACvC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC;AAC9D,CAAC;AACD,uHAAuH;AACvH,SAAS,MAAM,CAAU,MAAe;IACvC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7B,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,CAAC,QAAQ,CAAC,WAAW,GAAG,GAAG,EAAE;QACjC,IAAI,OAAO,IAAI,KAAK,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;YAClC,OAAO;QACR,CAAC;QACD,OAAO,GAAG,IAAI,CAAC;QACf,UAAU,CAAC,GAAG,EAAE;YACf,OAAO,GAAG,KAAK,CAAC;YAChB,IAAI,KAAK,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;gBACzB,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;YACxB,CAAC;QACF,CAAC,EAAE,CAAC,CAAC,CAAC;IACP,CAAC,CAAC;IACF,OAAO,KAAK,CAAC;AACd,CAAC;AAOD,SAAS,UAAU,CAAoB,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAsC;IACjH,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9D,SAAS,CAAC,GAAG,EAAE,CAAC,sBAAsB,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;IACnF,SAAS,CAAC,GAAG,EAAE;QACd,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;QACnB,OAAO,GAAG,EAAE;YACX,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;YACnB,cAAc,CAAC,GAAG,EAAE;gBACnB,IAAI,KAAK,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;oBACvB,OAAO;gBACR,CAAC;gBACD,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACzB,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YACxE,CAAC,CAAC,CAAC;QACJ,CAAC,CAAC;IACH,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IACZ,OAAO,aAAa,CACnB,cAAc,CAAC,QAAQ,EACvB,EAAE,KAAK,EAAE,OAAO,EAAE,EAClB,aAAa,CAAC,eAAe,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAC1F,CAAC;AACH,CAAC;AACD,MAAM,UAAU,eAAe,CAAoB,EAClD,OAAO,EACP,QAAQ,EACR,OAAO,EACP,OAAO,EACP,SAAS,EACT,QAAQ,GACiC;IACzC,MAAM,EAAE,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACjE,MAAM,OAAO,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC;IAClC,OAAO,OAAO,KAAK,SAAS;QAC3B,CAAC,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,CAAC;QAC1C,CAAC,CAAC,aAAa,CACb,mBAAmB,CAAC,QAAQ,EAC5B,EAAE,KAAK,EAAE,OAAO,EAAE,EAClB,aAAa,CAAC,UAA6B,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAC9F,CAAC;AACL,CAAC"}
|
|
@@ -20,4 +20,4 @@ export type FieldRejectionMapping<F extends Fields, E> = {
|
|
|
20
20
|
export declare const fieldRejectionOf: <F extends Fields>(schema: Schema.Struct<F>) => (error: unknown) => FieldRejection<Name<F>> | undefined;
|
|
21
21
|
export declare const rejecting: <F extends Fields, V, A, E, R>(schema: Schema.Struct<F>, save: (values: V) => Effect.Effect<A, E, R>, reject: RejectField<F, E> | undefined) => (values: V, submitter: Submitter<Name<F>>) => Effect.Effect<A, E | FieldFailure, R>;
|
|
22
22
|
export {};
|
|
23
|
-
//# sourceMappingURL=
|
|
23
|
+
//# sourceMappingURL=fieldRejection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fieldRejection.d.ts","sourceRoot":"","sources":["../src/fieldRejection.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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fieldRejection.js","sourceRoot":"","sources":["../src/fieldRejection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,SAAS,EAA2B,MAAM,QAAQ,CAAC;AAwBpE,MAAM,CAAC,MAAM,gBAAgB,GAC5B,CAAmB,MAAwB,EAAE,EAAE,CAC/C,CAAC,KAAc,EAAuC,EAAE;IACvD,SAAS,MAAM,CAAC,IAAa;QAC5B,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;QACjI,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IACvC,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAClH,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,SAAS,GAAG,CACxB,MAAwB,EACxB,IAA2C,EAC3C,MAAqC,EACpC,EAAE;IACH,MAAM,SAAS,GAAG,MAAM,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACrD,OAAO,CAAC,MAAS,EAAE,SAA6B,EAAyC,EAAE,CAC1F,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAA0C,EAAE;QAC5E,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QAC/B,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9F,CAAC,CAAC,CAAC;AACL,CAAC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
2
|
+
export declare function registerSessionRecheck(registry: AtomRegistry.AtomRegistry, recheck: () => void): () => void;
|
|
3
|
+
export declare function recheckUnauthorized(registry: AtomRegistry.AtomRegistry, error: unknown): Promise<void>;
|
|
4
|
+
//# sourceMappingURL=sessionRecheck.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionRecheck.d.ts","sourceRoot":"","sources":["../../src/internal/sessionRecheck.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,YAAY,MAAM,gCAAgC,CAAC;AAIpE,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,YAAY,CAAC,YAAY,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAK3G;AAED,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,YAAY,CAAC,YAAY,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAI5G"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Predicate } from "effect";
|
|
2
|
+
const rechecks = new WeakMap();
|
|
3
|
+
export function registerSessionRecheck(registry, recheck) {
|
|
4
|
+
rechecks.set(registry, recheck);
|
|
5
|
+
return () => {
|
|
6
|
+
rechecks.delete(registry);
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export async function recheckUnauthorized(registry, error) {
|
|
10
|
+
if (Predicate.isTagged(error, "Unauthorized")) {
|
|
11
|
+
await rechecks.get(registry)?.();
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=sessionRecheck.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionRecheck.js","sourceRoot":"","sources":["../../src/internal/sessionRecheck.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAGnC,MAAM,QAAQ,GAAG,IAAI,OAAO,EAAyC,CAAC;AAEtE,MAAM,UAAU,sBAAsB,CAAC,QAAmC,EAAE,OAAmB;IAC9F,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,GAAG,EAAE;QACX,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC3B,CAAC,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,QAAmC,EAAE,KAAc;IAC5F,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC,EAAE,CAAC;QAC/C,MAAM,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;IAClC,CAAC;AACF,CAAC"}
|
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,+BAA+B,CAAC;AAClE,OAAO,KAAK,KAAK,IAAI,MAAM,wBAAwB,CAAC;AACpD,OAAO,KAAK,YAAY,MAAM,gCAAgC,CAAC;
|
|
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;AAG/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,CAiBZ"}
|
package/dist/loadQuery.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
import * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
3
|
+
import { recheckUnauthorized } from "#internal/sessionRecheck.ts";
|
|
3
4
|
export async function loadQuery(registry, atom, { abortController }) {
|
|
4
5
|
const { signal } = abortController;
|
|
5
6
|
try {
|
|
6
7
|
const result = await Effect.runPromise(Effect.result(AtomRegistry.getResult(registry, atom, { suspendOnWaiting: true })), { signal });
|
|
7
8
|
if (result._tag === "Failure") {
|
|
9
|
+
await recheckUnauthorized(registry, result.failure);
|
|
8
10
|
throw result.failure;
|
|
9
11
|
}
|
|
10
12
|
return result.success;
|
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,gCAAgC,CAAC;
|
|
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;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAElE,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,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;YACpD,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"}
|
|
@@ -3,4 +3,4 @@ export type ResumeSource = ContractSource;
|
|
|
3
3
|
export type ResumeWindow = ContractWindow;
|
|
4
4
|
export type ResumeOptions = ContractOptions;
|
|
5
5
|
export declare function resumeSignal(options: ResumeOptions): import("effect/reactivity/Atom").Atom<number>;
|
|
6
|
-
//# sourceMappingURL=
|
|
6
|
+
//# sourceMappingURL=resumeSignal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resumeSignal.d.ts","sourceRoot":"","sources":["../src/resumeSignal.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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resumeSignal.js","sourceRoot":"","sources":["../src/resumeSignal.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,YAAY,IAAI,oBAAoB,GACpC,MAAM,sCAAsC,CAAC;AAK9C,MAAM,UAAU,YAAY,CAAC,OAAsB;IAClD,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC;AACtC,CAAC"}
|
package/dist/submission.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { Effect, Schema } from "effect";
|
|
|
2
2
|
import type * as Atom from "effect/reactivity/Atom";
|
|
3
3
|
import type { PersistedDraftConfig } from "@shivaedev/effect-form/persistence.ts";
|
|
4
4
|
import type { Decoded, Encoded, FieldFailure, Fields, Form, Services } from "@shivaedev/effect-form/shape.ts";
|
|
5
|
-
import { type AtomServices, type RejectField } from "./
|
|
5
|
+
import { type AtomServices, type RejectField } from "./fieldRejection.ts";
|
|
6
6
|
export interface SubmissionConfig<F extends Fields, A, E, R, ER> {
|
|
7
7
|
readonly fields: Schema.Struct<F>;
|
|
8
8
|
readonly initialValues: Encoded<F>;
|
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,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,
|
|
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,qBAAqB,CAAC;AAErF,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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { make } from "@shivaedev/effect-form/form.ts";
|
|
2
|
-
import { rejecting } from "./
|
|
2
|
+
import { rejecting } from "./fieldRejection.js";
|
|
3
3
|
export const submission = (config) => {
|
|
4
4
|
const { fields, initialValues, runtime } = config;
|
|
5
5
|
const save = rejecting(fields, config.save, config.rejectField);
|
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;AAGtD,OAAO,EAAuC,SAAS,EAAE,MAAM,
|
|
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,qBAAqB,CAAC;AAgBrF,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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shivaedev/effect-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
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": {
|
|
@@ -20,105 +20,19 @@
|
|
|
20
20
|
"source": "./src/*.ts",
|
|
21
21
|
"types": "./dist/*.d.ts",
|
|
22
22
|
"default": "./dist/*.js"
|
|
23
|
-
},
|
|
24
|
-
"#create.ts": {
|
|
25
|
-
"source": "./src/client/create.ts",
|
|
26
|
-
"types": "./dist/client/create.d.ts",
|
|
27
|
-
"default": "./dist/client/create.js"
|
|
28
|
-
},
|
|
29
|
-
"#editor.ts": {
|
|
30
|
-
"source": "./src/client/editor.ts",
|
|
31
|
-
"types": "./dist/client/editor.d.ts",
|
|
32
|
-
"default": "./dist/client/editor.js"
|
|
33
|
-
},
|
|
34
|
-
"#result-state.ts": {
|
|
35
|
-
"source": "./src/client/resultState.ts",
|
|
36
|
-
"types": "./dist/client/resultState.d.ts",
|
|
37
|
-
"default": "./dist/client/resultState.js"
|
|
38
|
-
},
|
|
39
|
-
"#save-state.ts": {
|
|
40
|
-
"source": "./src/client/saveState.ts",
|
|
41
|
-
"types": "./dist/client/saveState.d.ts",
|
|
42
|
-
"default": "./dist/client/saveState.js"
|
|
43
|
-
},
|
|
44
|
-
"#session-boundary.ts": {
|
|
45
|
-
"source": "./src/client/sessionBoundary.ts",
|
|
46
|
-
"types": "./dist/client/sessionBoundary.d.ts",
|
|
47
|
-
"default": "./dist/client/sessionBoundary.js"
|
|
48
|
-
},
|
|
49
|
-
"#testing.ts": {
|
|
50
|
-
"source": "./src/client/testing.ts",
|
|
51
|
-
"types": "./dist/client/testing.d.ts",
|
|
52
|
-
"default": "./dist/client/testing.js"
|
|
53
23
|
}
|
|
54
24
|
},
|
|
55
25
|
"exports": {
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
"types": "./dist
|
|
59
|
-
"
|
|
60
|
-
"import": "./dist/loadQuery.js",
|
|
61
|
-
"default": "./dist/loadQuery.js"
|
|
62
|
-
},
|
|
63
|
-
"./loadQuery.ts": null,
|
|
64
|
-
"./create.ts": {
|
|
65
|
-
"types": "./dist/client/create.d.ts",
|
|
66
|
-
"source": "./src/client/create.ts",
|
|
67
|
-
"import": "./dist/client/create.js",
|
|
68
|
-
"default": "./dist/client/create.js"
|
|
69
|
-
},
|
|
70
|
-
"./editor.ts": {
|
|
71
|
-
"types": "./dist/client/editor.d.ts",
|
|
72
|
-
"source": "./src/client/editor.ts",
|
|
73
|
-
"import": "./dist/client/editor.js",
|
|
74
|
-
"default": "./dist/client/editor.js"
|
|
75
|
-
},
|
|
76
|
-
"./field-rejection.ts": {
|
|
77
|
-
"types": "./dist/field-rejection.d.ts",
|
|
78
|
-
"source": "./src/field-rejection.ts",
|
|
79
|
-
"import": "./dist/field-rejection.js",
|
|
80
|
-
"default": "./dist/field-rejection.js"
|
|
81
|
-
},
|
|
82
|
-
"./result-state.ts": {
|
|
83
|
-
"types": "./dist/client/resultState.d.ts",
|
|
84
|
-
"source": "./src/client/resultState.ts",
|
|
85
|
-
"import": "./dist/client/resultState.js",
|
|
86
|
-
"default": "./dist/client/resultState.js"
|
|
87
|
-
},
|
|
88
|
-
"./resume-signal.ts": {
|
|
89
|
-
"types": "./dist/resume-signal.d.ts",
|
|
90
|
-
"source": "./src/resume-signal.ts",
|
|
91
|
-
"import": "./dist/resume-signal.js",
|
|
92
|
-
"default": "./dist/resume-signal.js"
|
|
93
|
-
},
|
|
94
|
-
"./save-state.ts": {
|
|
95
|
-
"types": "./dist/client/saveState.d.ts",
|
|
96
|
-
"source": "./src/client/saveState.ts",
|
|
97
|
-
"import": "./dist/client/saveState.js",
|
|
98
|
-
"default": "./dist/client/saveState.js"
|
|
99
|
-
},
|
|
100
|
-
"./session-boundary.ts": {
|
|
101
|
-
"types": "./dist/client/sessionBoundary.d.ts",
|
|
102
|
-
"source": "./src/client/sessionBoundary.ts",
|
|
103
|
-
"import": "./dist/client/sessionBoundary.js",
|
|
104
|
-
"default": "./dist/client/sessionBoundary.js"
|
|
105
|
-
},
|
|
106
|
-
"./submission.ts": {
|
|
107
|
-
"types": "./dist/submission.d.ts",
|
|
108
|
-
"source": "./src/submission.ts",
|
|
109
|
-
"import": "./dist/submission.js",
|
|
110
|
-
"default": "./dist/submission.js"
|
|
26
|
+
"./*.ts": {
|
|
27
|
+
"source": "./src/*.ts",
|
|
28
|
+
"types": "./dist/*.d.ts",
|
|
29
|
+
"default": "./dist/*.js"
|
|
111
30
|
},
|
|
112
|
-
"./
|
|
113
|
-
|
|
114
|
-
"source": "./src/client/testing.ts",
|
|
115
|
-
"import": "./dist/client/testing.js",
|
|
116
|
-
"default": "./dist/client/testing.js"
|
|
117
|
-
}
|
|
31
|
+
"./internal/*": null,
|
|
32
|
+
"./package.json": "./package.json"
|
|
118
33
|
},
|
|
119
34
|
"files": [
|
|
120
35
|
"dist",
|
|
121
|
-
"docs",
|
|
122
36
|
"src",
|
|
123
37
|
"!src/**/*.test.ts",
|
|
124
38
|
"!src/**/*.test.tsx",
|
|
@@ -130,36 +44,35 @@
|
|
|
130
44
|
],
|
|
131
45
|
"dependencies": {
|
|
132
46
|
"@shivaedev/effect-contract": "0.5.1",
|
|
133
|
-
"@shivaedev/effect-form": "0.
|
|
47
|
+
"@shivaedev/effect-form": "0.5.0"
|
|
134
48
|
},
|
|
135
49
|
"devDependencies": {
|
|
136
50
|
"@effect/atom-react": "4.0.4",
|
|
137
51
|
"@effect/platform-node": "4.0.4",
|
|
138
52
|
"@effect/sql-pg": "4.0.4",
|
|
139
53
|
"@effect/sql-sqlite-node": "4.0.4",
|
|
140
|
-
"@shivaedev/effect-pg-boss": "0.
|
|
141
|
-
"@shivaedev/effect-service": "0.
|
|
142
|
-
"@shivaedev/effect-sql": "0.5.
|
|
143
|
-
"@shivaedev/effect-test": "0.
|
|
144
|
-
"@shivaedev/local-postgres": "0.
|
|
145
|
-
"@shivaedev/platform": "0.
|
|
146
|
-
"@shivaedev/quality": "0.
|
|
147
|
-
"@shivaedev/test-story": "0.
|
|
148
|
-
"@tanstack/react-router": "1.170.
|
|
149
|
-
"@types/node": "24.19.
|
|
54
|
+
"@shivaedev/effect-pg-boss": "0.9.0",
|
|
55
|
+
"@shivaedev/effect-service": "0.4.0",
|
|
56
|
+
"@shivaedev/effect-sql": "0.5.2",
|
|
57
|
+
"@shivaedev/effect-test": "0.6.0",
|
|
58
|
+
"@shivaedev/local-postgres": "0.4.0",
|
|
59
|
+
"@shivaedev/platform": "0.16.1",
|
|
60
|
+
"@shivaedev/quality": "0.26.0",
|
|
61
|
+
"@shivaedev/test-story": "0.8.0",
|
|
62
|
+
"@tanstack/react-router": "1.170.42",
|
|
63
|
+
"@types/node": "24.19.2",
|
|
150
64
|
"@types/react": "19.3.0",
|
|
151
65
|
"@types/react-dom": "19.3.0",
|
|
152
|
-
"@typescript/native": "npm:typescript@7.0.2",
|
|
153
66
|
"effect": "4.0.4",
|
|
154
67
|
"happy-dom": "20.14.6",
|
|
155
68
|
"react": "19.3.0",
|
|
156
69
|
"react-dom": "19.3.0",
|
|
157
|
-
"typescript": "
|
|
70
|
+
"typescript": "7.0.2",
|
|
158
71
|
"vitest": "5.0.3"
|
|
159
72
|
},
|
|
160
73
|
"peerDependencies": {
|
|
161
74
|
"@effect/atom-react": "4.0.4",
|
|
162
|
-
"@tanstack/react-router": "1.170.
|
|
75
|
+
"@tanstack/react-router": "1.170.42",
|
|
163
76
|
"effect": "4.0.4",
|
|
164
77
|
"react": "19.3.0",
|
|
165
78
|
"react-dom": "19.3.0",
|
package/src/client/create.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { type Effect, Equal, Option, type Schema } from "effect";
|
|
2
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
|
+
import { type BrowserDraftConfig, usePersistedDraft } from "@shivaedev/effect-form/client/react.ts";
|
|
5
5
|
import type { Decoded, Encoded, FieldFailure, Fields, Form, Services } from "@shivaedev/effect-form/shape.ts";
|
|
6
|
-
import type { AtomServices, FieldRejectionMapping } from "#
|
|
6
|
+
import type { AtomServices, FieldRejectionMapping } from "#fieldRejection.ts";
|
|
7
7
|
import { submission } from "#submission.ts";
|
|
8
8
|
import { type SaveState, useSaveState } from "./saveState.ts";
|
|
9
9
|
export type CreateConfig<TFields extends Fields, TCreated, TSaveError, R, TRuntimeError> = {
|
package/src/client/editor.ts
CHANGED
|
@@ -2,9 +2,9 @@ import { type Effect, Option, type Schema } from "effect";
|
|
|
2
2
|
import type * as AsyncResult from "effect/reactivity/AsyncResult";
|
|
3
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
|
+
import { type BrowserDraftConfig, usePersistedDraft } from "@shivaedev/effect-form/client/react.ts";
|
|
6
6
|
import type { Decoded, Encoded, FieldFailure, Fields, Form, Services } from "@shivaedev/effect-form/shape.ts";
|
|
7
|
-
import type { AtomServices, FieldRejectionMapping } from "#
|
|
7
|
+
import type { AtomServices, FieldRejectionMapping } from "#fieldRejection.ts";
|
|
8
8
|
import { submission } from "#submission.ts";
|
|
9
9
|
import { type QueryState, useQuery } from "./resultState.ts";
|
|
10
10
|
import { type SaveState, useSaveState } from "./saveState.ts";
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { RegistryContext } from "@effect/atom-react";
|
|
2
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";
|
|
4
|
+
import { DraftSessionContext } from "@shivaedev/effect-form/client/react.ts";
|
|
5
|
+
import { registerSessionRecheck } from "#internal/sessionRecheck.ts";
|
|
5
6
|
import { useDraftOwner } from "./useDraftOwner.ts";
|
|
6
7
|
export interface SessionBoundaryProps<TSession, TClient> {
|
|
7
8
|
readonly children: (client: TClient) => ReactNode;
|
|
@@ -49,6 +50,7 @@ interface GenerationProps<TSession, TClient> {
|
|
|
49
50
|
}
|
|
50
51
|
function Generation<TSession, TClient>({ session, connect, recheck, children }: GenerationProps<TSession, TClient>): ReactNode {
|
|
51
52
|
const [owned, own] = useState(() => owning(connect(session)));
|
|
53
|
+
useEffect(() => registerSessionRecheck(owned.registry, recheck), [owned, recheck]);
|
|
52
54
|
useEffect(() => {
|
|
53
55
|
owned.mounted += 1;
|
|
54
56
|
return () => {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Predicate } from "effect";
|
|
2
|
+
import type * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
3
|
+
|
|
4
|
+
const rechecks = new WeakMap<AtomRegistry.AtomRegistry, () => void>();
|
|
5
|
+
|
|
6
|
+
export function registerSessionRecheck(registry: AtomRegistry.AtomRegistry, recheck: () => void): () => void {
|
|
7
|
+
rechecks.set(registry, recheck);
|
|
8
|
+
return () => {
|
|
9
|
+
rechecks.delete(registry);
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export async function recheckUnauthorized(registry: AtomRegistry.AtomRegistry, error: unknown): Promise<void> {
|
|
14
|
+
if (Predicate.isTagged(error, "Unauthorized")) {
|
|
15
|
+
await rechecks.get(registry)?.();
|
|
16
|
+
}
|
|
17
|
+
}
|
package/src/loadQuery.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { Effect } from "effect";
|
|
|
3
3
|
import type * as AsyncResult from "effect/reactivity/AsyncResult";
|
|
4
4
|
import type * as Atom from "effect/reactivity/Atom";
|
|
5
5
|
import * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
6
|
+
import { recheckUnauthorized } from "#internal/sessionRecheck.ts";
|
|
6
7
|
|
|
7
8
|
export async function loadQuery<A, E>(
|
|
8
9
|
registry: AtomRegistry.AtomRegistry,
|
|
@@ -13,6 +14,7 @@ export async function loadQuery<A, E>(
|
|
|
13
14
|
try {
|
|
14
15
|
const result = await Effect.runPromise(Effect.result(AtomRegistry.getResult(registry, atom, { suspendOnWaiting: true })), { signal });
|
|
15
16
|
if (result._tag === "Failure") {
|
|
17
|
+
await recheckUnauthorized(registry, result.failure);
|
|
16
18
|
throw result.failure;
|
|
17
19
|
}
|
|
18
20
|
return result.success;
|
package/src/submission.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type * as Atom from "effect/reactivity/Atom";
|
|
|
3
3
|
import { make } from "@shivaedev/effect-form/form.ts";
|
|
4
4
|
import type { PersistedDraftConfig } from "@shivaedev/effect-form/persistence.ts";
|
|
5
5
|
import type { Decoded, Encoded, FieldFailure, Fields, Form, Services } from "@shivaedev/effect-form/shape.ts";
|
|
6
|
-
import { type AtomServices, type RejectField, rejecting } from "./
|
|
6
|
+
import { type AtomServices, type RejectField, rejecting } from "./fieldRejection.ts";
|
|
7
7
|
|
|
8
8
|
export interface SubmissionConfig<F extends Fields, A, E, R, ER> {
|
|
9
9
|
readonly fields: Schema.Struct<F>;
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"field-rejection.js","sourceRoot":"","sources":["../src/field-rejection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,SAAS,EAA2B,MAAM,QAAQ,CAAC;AAwBpE,MAAM,CAAC,MAAM,gBAAgB,GAC5B,CAAmB,MAAwB,EAAE,EAAE,CAC/C,CAAC,KAAc,EAAuC,EAAE;IACvD,SAAS,MAAM,CAAC,IAAa;QAC5B,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;QACjI,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IACvC,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAClH,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,SAAS,GAAG,CACxB,MAAwB,EACxB,IAA2C,EAC3C,MAAqC,EACpC,EAAE;IACH,MAAM,SAAS,GAAG,MAAM,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACrD,OAAO,CAAC,MAAS,EAAE,SAA6B,EAAyC,EAAE,CAC1F,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAA0C,EAAE;QAC5E,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QAC/B,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9F,CAAC,CAAC,CAAC;AACL,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resume-signal.js","sourceRoot":"","sources":["../src/resume-signal.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,YAAY,IAAI,oBAAoB,GACpC,MAAM,sCAAsC,CAAC;AAK9C,MAAM,UAAU,YAAY,CAAC,OAAsB;IAClD,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC;AACtC,CAAC"}
|
package/docs/north-star.md
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# North star
|
|
2
|
-
|
|
3
|
-
## The problem
|
|
4
|
-
|
|
5
|
-
Native Effect atoms already know how to run, refresh and share an asynchronous result. A React application still needs to decide what to display while they work, what to keep when a request fails and which lifetime owns their registry. Repeating those decisions in every screen makes them drift. One screen blanks during a refresh, another loses a draft when a response arrives, and a third keeps the previous session's state after the user changes.
|
|
6
|
-
|
|
7
|
-
Editing combines two kinds of state. A server row can change independently, while the user types encoded input values that a schema must decode before saving. The latest server response is not necessarily the user's latest intent. Whole-form replacement makes a simple screen overwrite newer edits; leaving the form alone makes untouched fields stale. A create form adds another race: clearing the successful entry must not clear what the user has already begun typing for the next one.
|
|
8
|
-
|
|
9
|
-
## The ideal
|
|
10
|
-
|
|
11
|
-
React components read state in the words they render: data, failure, pending and refreshing. An editor says which query supplies its row, which fields describe its inputs and which Effect saves the decoded values. A session root says which identity owns those screens. Each definition stays small because the package supplies repeated coordination, while native Effect and effect-form remain the owners of the underlying work.
|
|
12
|
-
|
|
13
|
-
Good client state has these properties:
|
|
14
|
-
|
|
15
|
-
- Useful data can stay on screen during refresh and after a refresh failure. Showing retained data does not hide the failed result.
|
|
16
|
-
- Query identity changes reset displayed data by default. Applications can opt into `keepPreviousData` for payload transitions; displayed data still clears when the registry owner changes.
|
|
17
|
-
- A draft belongs to one query identity and one session generation. Changing either must not transfer edits into a different record or person's screen.
|
|
18
|
-
- A refresh, a normalized save result and a create reset respect edits made after the operation began. Untouched fields can adopt new server values without replacing newer input.
|
|
19
|
-
- Failure types reach the component. A field rejection names its field; another failure remains available for application-owned wording.
|
|
20
|
-
- An action reports the native atom's current state honestly. An imperative caller that needs one invocation's outcome runs an Effect with that lifetime instead of guessing from a shared latest-result atom.
|
|
21
|
-
- A registry has an owner. Session replacement and unmount release the old generation, including work created around React's StrictMode and Activity lifecycles.
|
|
22
|
-
|
|
23
|
-
## Boundaries
|
|
24
|
-
|
|
25
|
-
The root repository's one path for client state is this package. It should add React coordination where applications repeat it, without taking a neighbouring package's job:
|
|
26
|
-
|
|
27
|
-
- Native atoms own execution, identity, cache retention, invalidation and action scheduling.
|
|
28
|
-
- effect-contract owns query and command declarations, declared rejections and native client bindings. Its shared resume source also works without React.
|
|
29
|
-
- effect-form owns encoded fields, schema decoding, validation, submission and draft merge rules. The editor and create hooks arrange those pieces around rows and command results.
|
|
30
|
-
- The platform request modules and the application's auth integration verify identity. The session boundary owns a client-side generation; its `recheck` callback asks the auth owner for a verdict.
|
|
31
|
-
- The application owns transport, loading/error wording, credential rotation policy and the point where a runtime runs a particular Effect.
|
|
32
|
-
|
|
33
|
-
## Trade-offs
|
|
34
|
-
|
|
35
|
-
1. **Native ownership before convenience.** A second query cache or parallel form model would make easy call sites look simpler while giving the application two places to understand identity and cleanup. Thin bindings keep the native state visible.
|
|
36
|
-
2. **Identity isolation before draft continuity.** A draft is valuable only within the record and session that created it. Switching identities starts fresh even if retaining a previous draft would save typing.
|
|
37
|
-
3. **Newer intent before replacing the whole form.** A response updates what it can without erasing fields the user edited meanwhile. A user who wants the server's latest values can explicitly revert.
|
|
38
|
-
4. **Truthful shared state before per-call ergonomics.** One atom's result cannot describe several concurrent invocations independently. The action hook preserves its native semantics rather than implying a Promise belongs to one dispatch.
|
|
39
|
-
5. **Observable evidence before brevity.** A helper earns its place by removing repeated application code and having tests for the races and lifetimes it claims to handle. A DOM fixture proves that fixture, not another runtime or deployment.
|
|
40
|
-
|
|
41
|
-
## What it leaves out
|
|
42
|
-
|
|
43
|
-
The package does not define another RPC contract language, replace native atom scheduling or decide an application's auth policy. It does not supply a general form language, an optimistic reconciliation strategy or an offline write queue. Server rendering and mobile host integration need their own architecture and evidence; a resume callback alone cannot establish them.
|
|
44
|
-
|
|
45
|
-
Use [README.md](../README.md) for examples and [roadmap.md](./roadmap.md) for what is implemented and which choices remain with the maintainer.
|
package/docs/roadmap.md
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
# Roadmap
|
|
2
|
-
|
|
3
|
-
This roadmap owns the package's hooks, form coordination and session-registry implementation. The [framework roadmap](https://github.com/ShivaeDev/platform/blob/main/docs/framework/roadmap.md) owns composed feature fixtures, adoption and host/deployment validation. A local hook test is evidence for its own runtime and scenario.
|
|
4
|
-
|
|
5
|
-
## Built
|
|
6
|
-
|
|
7
|
-
- [x] Opt-in `keepPreviousData` retains the last successful query value across payload changes, pending requests and failures; the default resets it. Registry replacement clears retained data, superseded responses do not replace the latest result, and disabling retention drops an inherited value. [Rendered query evidence](https://github.com/ShivaeDev/platform/blob/main/packages/effect-react/src/queryPayload.dom.spec.ts).
|
|
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
|
-
- [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
|
-
- [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).
|
|
12
|
-
- [x] Session cleanup across StrictMode effect replay and Activity hiding, reveal and hidden unmount, with credential rotation tested against the chosen identity key.
|
|
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.
|
|
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.
|
|
15
|
-
- [x] Tagged field-rejection mapping, a typed custom mapper and compile-time requirements for rejection field types that exceed the form's names; other save failures remain separately available.
|
|
16
|
-
- [x] A resume module using effect-contract's shared implementation, with visible browser events, an injected native source, listener disposal and native stale-while-revalidate policy covered by tests.
|
|
17
|
-
- [x] TanStack Router query loaders sharing the native registry, with tagged RPC failures, refresh waiting and abort handling. Render tests cover shared query execution, the route error component and previous data during navigation.
|
|
18
|
-
|
|
19
|
-
## Next
|
|
20
|
-
|
|
21
|
-
- [ ] Add direct rendered regressions for Unauthorized action failures invoking the session callback.
|
|
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.
|
|
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.
|
|
24
|
-
|
|
25
|
-
## Open questions
|
|
26
|
-
|
|
27
|
-
- Do consumers need an independently scoped action helper, or are distinct native atoms and actual Effects enough for imperative per-invocation outcomes? Keep native shared-action semantics unless a demonstrated use case requires more.
|
|
28
|
-
- What per-request registry and hydration wiring does the TanStack Router host need for SSR? Client render fixtures do not establish SSR isolation.
|
|
29
|
-
- Which hook configuration values should be allowed to change without replacing the form? A rule for changing schemas, runtimes, save functions or initial values needs consumer evidence and explicit lifetime tests.
|
|
File without changes
|
|
File without changes
|