@shivaedev/effect-react 0.2.1 → 0.2.2

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.
Files changed (63) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +452 -55
  3. package/dist/client/create.d.ts +17 -0
  4. package/dist/client/create.d.ts.map +1 -0
  5. package/dist/{create.js → client/create.js} +9 -9
  6. package/dist/client/create.js.map +1 -0
  7. package/dist/client/editor.d.ts +20 -0
  8. package/dist/client/editor.d.ts.map +1 -0
  9. package/dist/{editor.js → client/editor.js} +5 -5
  10. package/dist/client/editor.js.map +1 -0
  11. package/dist/client/resultState.d.ts +23 -0
  12. package/dist/client/resultState.d.ts.map +1 -0
  13. package/dist/client/resultState.js +48 -0
  14. package/dist/client/resultState.js.map +1 -0
  15. package/dist/{save-state.d.ts → client/saveState.d.ts} +2 -2
  16. package/dist/client/saveState.d.ts.map +1 -0
  17. package/dist/{save-state.js → client/saveState.js} +5 -5
  18. package/dist/client/saveState.js.map +1 -0
  19. package/dist/client/sessionBoundary.d.ts +12 -0
  20. package/dist/client/sessionBoundary.d.ts.map +1 -0
  21. package/dist/{session-boundary.js → client/sessionBoundary.js} +18 -12
  22. package/dist/client/sessionBoundary.js.map +1 -0
  23. package/dist/client/testing.d.ts +12 -0
  24. package/dist/client/testing.d.ts.map +1 -0
  25. package/dist/client/testing.js +66 -0
  26. package/dist/client/testing.js.map +1 -0
  27. package/dist/field-rejection.d.ts.map +1 -1
  28. package/dist/field-rejection.js +3 -1
  29. package/dist/field-rejection.js.map +1 -1
  30. package/dist/loadQuery.d.ts +6 -0
  31. package/dist/loadQuery.d.ts.map +1 -0
  32. package/dist/loadQuery.js +21 -0
  33. package/dist/loadQuery.js.map +1 -0
  34. package/dist/submission.d.ts.map +1 -1
  35. package/docs/north-star.md +45 -0
  36. package/docs/roadmap.md +28 -0
  37. package/package.json +122 -16
  38. package/src/client/create.ts +41 -0
  39. package/src/client/editor.ts +56 -0
  40. package/src/client/resultState.ts +73 -0
  41. package/src/{save-state.ts → client/saveState.ts} +11 -10
  42. package/src/{session-boundary.ts → client/sessionBoundary.ts} +28 -32
  43. package/src/client/testing.ts +68 -0
  44. package/src/field-rejection.ts +3 -1
  45. package/src/loadQuery.ts +27 -0
  46. package/dist/create.d.ts +0 -17
  47. package/dist/create.d.ts.map +0 -1
  48. package/dist/create.js.map +0 -1
  49. package/dist/editor.d.ts +0 -20
  50. package/dist/editor.d.ts.map +0 -1
  51. package/dist/editor.js.map +0 -1
  52. package/dist/result-state.d.ts +0 -20
  53. package/dist/result-state.d.ts.map +0 -1
  54. package/dist/result-state.js +0 -36
  55. package/dist/result-state.js.map +0 -1
  56. package/dist/save-state.d.ts.map +0 -1
  57. package/dist/save-state.js.map +0 -1
  58. package/dist/session-boundary.d.ts +0 -12
  59. package/dist/session-boundary.d.ts.map +0 -1
  60. package/dist/session-boundary.js.map +0 -1
  61. package/src/create.ts +0 -43
  62. package/src/editor.ts +0 -58
  63. package/src/result-state.ts +0 -58
package/dist/editor.d.ts DELETED
@@ -1,20 +0,0 @@
1
- import { type Effect, type Schema } from "effect";
2
- import type * as AsyncResult from "effect/unstable/reactivity/AsyncResult";
3
- import type * as Atom from "effect/unstable/reactivity/Atom";
4
- import type { Decoded, Encoded, FieldFailure, Fields, Form, Services } from "@shivaedev/effect-form/shape.ts";
5
- import type { AtomServices, FieldRejectionMapping } from "./field-rejection.ts";
6
- import { type QueryState } from "./result-state.ts";
7
- import { type SaveState } from "./save-state.ts";
8
- export type EditorConfig<F extends Fields, Row, QE, SE, R, ER> = {
9
- readonly query: Atom.Atom<AsyncResult.AsyncResult<Row, QE>>;
10
- readonly fields: Schema.Struct<F>;
11
- readonly values: (row: Row) => Encoded<F>;
12
- readonly save: (values: Decoded<F>) => Effect.Effect<Row, SE, AtomServices<R>>;
13
- readonly runtime: Atom.AtomRuntime<Services<F, R>, ER>;
14
- } & FieldRejectionMapping<F, SE>;
15
- export interface Editor<F extends Fields, Row, QE, SE, ER> extends SaveState<SE | ER> {
16
- readonly form: Form<F, Row, SE | FieldFailure, ER> | undefined;
17
- readonly query: QueryState<Row, QE>;
18
- }
19
- export declare const useEditor: <F extends Fields, Row, QE, SE, R, ER>(config: EditorConfig<F, Row, QE, SE, R, ER>) => Editor<F, Row, QE, SE, ER>;
20
- //# sourceMappingURL=editor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../src/editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAU,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,KAAK,KAAK,WAAW,MAAM,wCAAwC,CAAC;AAC3E,OAAO,KAAK,KAAK,IAAI,MAAM,iCAAiC,CAAC;AAE7D,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,sBAAsB,CAAC;AAChF,OAAO,EAAE,KAAK,UAAU,EAAY,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,iBAAiB,CAAC;AAG/D,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI;IAChE,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1C,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/E,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;CACvD,GAAG,qBAAqB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAEjC,MAAM,WAAW,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAE,SAAQ,SAAS,CAAC,EAAE,GAAG,EAAE,CAAC;IACpF,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,YAAY,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC;IAC/D,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;CACpC;AAQD,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,QAAQ,YAAY,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,KAAG,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CA4BtI,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"editor.js","sourceRoot":"","sources":["../src/editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,MAAM,EAAe,MAAM,QAAQ,CAAC;AAG1D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAGzD,OAAO,EAAmB,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAkB,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAqB7C,MAAM,CAAC,MAAM,SAAS,GAAG,CAAuC,MAA2C,EAA8B,EAAE;IAC1I,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,CAAmC,SAAS,CAAC,CAAC;IAC3E,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,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,KAAU,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;IACxH,OAAO,EAAE,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACxD,CAAC,CAAC"}
@@ -1,20 +0,0 @@
1
- import { Cause, Option } from "effect";
2
- import * as AsyncResult from "effect/unstable/reactivity/AsyncResult";
3
- import type * as Atom from "effect/unstable/reactivity/Atom";
4
- export interface ResultState<A, E> {
5
- readonly cause: Option.Option<Cause.Cause<E>>;
6
- readonly data: Option.Option<A>;
7
- readonly pending: boolean;
8
- readonly refreshing: boolean;
9
- readonly result: AsyncResult.AsyncResult<A, E>;
10
- }
11
- export declare const isUnauthorized: <E>(cause: Cause.Cause<E>) => boolean;
12
- export interface QueryState<A, E> extends ResultState<A, E> {
13
- readonly refresh: () => void;
14
- }
15
- export declare const useQuery: <A, E>(atom: Atom.Atom<AsyncResult.AsyncResult<A, E>>) => QueryState<A, E>;
16
- export interface ActionState<Input, A, E> extends ResultState<A, E> {
17
- readonly dispatch: (input: Input) => void;
18
- }
19
- export declare const useAction: <Input, A, E>(atom: Atom.AtomResultFn<Input, A, E>) => ActionState<Input, A, E>;
20
- //# sourceMappingURL=result-state.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"result-state.d.ts","sourceRoot":"","sources":["../src/result-state.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAa,MAAM,QAAQ,CAAC;AAClD,OAAO,KAAK,WAAW,MAAM,wCAAwC,CAAC;AACtE,OAAO,KAAK,KAAK,IAAI,MAAM,iCAAiC,CAAC;AAI7D,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;AAaD,eAAO,MAAM,cAAc,GAAI,CAAC,EAAE,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAG,OACwE,CAAC;AAWnI,MAAM,WAAW,UAAU,CAAC,CAAC,EAAE,CAAC,CAAE,SAAQ,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1D,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,eAAO,MAAM,QAAQ,GAAI,CAAC,EAAE,CAAC,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAG,UAAU,CAAC,CAAC,EAAE,CAAC,CAI9F,CAAC;AAEF,MAAM,WAAW,WAAW,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAE,SAAQ,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC;IAClE,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC1C;AAGD,eAAO,MAAM,SAAS,GAAI,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,KAAG,WAAW,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAIpG,CAAC"}
@@ -1,36 +0,0 @@
1
- import { useAtomRefresh, useAtomSet, useAtomValue } from "@effect/atom-react";
2
- import { Cause, Option, Predicate } from "effect";
3
- import * as AsyncResult from "effect/unstable/reactivity/AsyncResult";
4
- import { useEffect } from "react";
5
- import { useSessionRecheck } from "./session-boundary.js";
6
- const state = (result) => {
7
- const data = AsyncResult.value(result);
8
- return {
9
- cause: AsyncResult.cause(result),
10
- data,
11
- pending: result.waiting,
12
- refreshing: result.waiting && Option.isSome(data),
13
- result,
14
- };
15
- };
16
- export const isUnauthorized = (cause) => Option.match(Cause.findErrorOption(cause), { onNone: () => false, onSome: (error) => Predicate.isTagged(error, "Unauthorized") });
17
- const useRecheckOnUnauthorized = (result) => {
18
- const recheck = useSessionRecheck();
19
- useEffect(() => {
20
- if (AsyncResult.isFailure(result) && isUnauthorized(result.cause)) {
21
- recheck();
22
- }
23
- }, [recheck, result]);
24
- };
25
- export const useQuery = (atom) => {
26
- const result = useAtomValue(atom);
27
- useRecheckOnUnauthorized(result);
28
- return { ...state(result), refresh: useAtomRefresh(atom) };
29
- };
30
- // The atom's state is shared by every dispatch, so it never claims to be one invocation's completion result.
31
- export const useAction = (atom) => {
32
- const result = useAtomValue(atom);
33
- useRecheckOnUnauthorized(result);
34
- return { ...state(result), dispatch: useAtomSet(atom) };
35
- };
36
- //# sourceMappingURL=result-state.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"result-state.js","sourceRoot":"","sources":["../src/result-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,KAAK,WAAW,MAAM,wCAAwC,CAAC;AAEtE,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAU1D,MAAM,KAAK,GAAG,CAAO,MAAqC,EAAqB,EAAE;IAChF,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACvC,OAAO;QACN,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC;QAChC,IAAI;QACJ,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,UAAU,EAAE,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;QACjD,MAAM;KACN,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAI,KAAqB,EAAW,EAAE,CACnE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC;AAEnI,MAAM,wBAAwB,GAAG,CAAO,MAAqC,EAAQ,EAAE;IACtF,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,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;AACvB,CAAC,CAAC;AAMF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAO,IAA8C,EAAoB,EAAE;IAClG,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAClC,wBAAwB,CAAC,MAAM,CAAC,CAAC;IACjC,OAAO,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;AAC5D,CAAC,CAAC;AAMF,6GAA6G;AAC7G,MAAM,CAAC,MAAM,SAAS,GAAG,CAAc,IAAoC,EAA4B,EAAE;IACxG,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAClC,wBAAwB,CAAC,MAAM,CAAC,CAAC;IACjC,OAAO,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;AACzD,CAAC,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"save-state.d.ts","sourceRoot":"","sources":["../src/save-state.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIhC,OAAO,EAAE,YAAY,EAAE,KAAK,MAAM,EAAE,KAAK,IAAI,EAAW,MAAM,iCAAiC,CAAC;AAOhG,MAAM,WAAW,SAAS,CAAC,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CACzB;AAED,eAAO,MAAM,YAAY,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EACtD,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,YAAY,EAAE,EAAE,CAAC,GAAG,SAAS,EAClD,SAAS,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,KAC1B,SAAS,CAAC,CAAC,GAAG,EAAE,CA6BlB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"save-state.js","sourceRoot":"","sources":["../src/save-state.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,wCAAwC,CAAC;AACtE,OAAO,KAAK,IAAI,MAAM,iCAAiC,CAAC;AACxD,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,mBAAmB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;AAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAU/B,MAAM,CAAC,MAAM,YAAY,GAAG,CAC3B,IAAkD,EAClD,OAA4B,EACR,EAAE;IACtB,MAAM,QAAQ,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,MAAM,MAAM,GAAgE,YAAY,CAAC,IAAI,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC;IAC/G,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,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAmB,EAAE,CAAC,CAAC,CAAC,KAAK,YAAY,YAAY,IAAI,KAAK,YAAY,OAAO,CAAC,CAAC,CAAC;IACnJ,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;AACjE,CAAC,CAAC"}
@@ -1,12 +0,0 @@
1
- import { type ReactNode } from "react";
2
- export interface SessionBoundaryProps<S, Client> {
3
- readonly children: (client: Client) => ReactNode;
4
- readonly connect: (session: S) => Client;
5
- readonly identify: (session: S) => string;
6
- readonly recheck: () => void;
7
- readonly session: S | undefined;
8
- readonly signedOut?: ReactNode;
9
- }
10
- export declare const useSessionRecheck: () => (() => void);
11
- export declare const SessionBoundary: <S, Client>({ session, identify, connect, recheck, signedOut, children, }: SessionBoundaryProps<S, Client>) => ReactNode;
12
- //# sourceMappingURL=session-boundary.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"session-boundary.d.ts","sourceRoot":"","sources":["../src/session-boundary.ts"],"names":[],"mappings":"AAEA,OAAO,EAA0C,KAAK,SAAS,EAAmC,MAAM,OAAO,CAAC;AAEhH,MAAM,WAAW,oBAAoB,CAAC,CAAC,EAAE,MAAM;IAC9C,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,SAAS,CAAC;IACjD,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,MAAM,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,MAAM,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,SAAS,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;CAC/B;AAID,eAAO,MAAM,iBAAiB,QAAO,CAAC,MAAM,IAAI,CAAwB,CAAC;AA0DzE,eAAO,MAAM,eAAe,GAAI,CAAC,EAAE,MAAM,EAAE,+DAOxC,oBAAoB,CAAC,CAAC,EAAE,MAAM,CAAC,KAAG,SAGoE,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"session-boundary.js","sourceRoot":"","sources":["../src/session-boundary.ts"],"names":[],"mappings":"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"}
package/src/create.ts DELETED
@@ -1,43 +0,0 @@
1
- import { type Effect, Equal, Option, type Schema } from "effect";
2
- import type * as Atom from "effect/unstable/reactivity/Atom";
3
- import { useCallback, useState } from "react";
4
- import type { Decoded, Encoded, FieldFailure, Fields, Form, Services } from "@shivaedev/effect-form/shape.ts";
5
- import type { AtomServices, FieldRejectionMapping } from "./field-rejection.ts";
6
- import { type SaveState, useSaveState } from "./save-state.ts";
7
- import { submission } from "./submission.ts";
8
-
9
- export type CreateConfig<F extends Fields, Created, SE, R, ER> = {
10
- readonly fields: Schema.Struct<F>;
11
- readonly initialValues: Encoded<F>;
12
- readonly create: (values: Decoded<F>) => Effect.Effect<Created, SE, AtomServices<R>>;
13
- readonly runtime: Atom.AtomRuntime<Services<F, R>, ER>;
14
- } & FieldRejectionMapping<F, SE>;
15
-
16
- export interface Create<F extends Fields, Created, SE, ER> extends SaveState<SE | ER> {
17
- readonly created: Option.Option<Created>;
18
- readonly form: Form<F, Created, SE | FieldFailure, ER>;
19
- }
20
-
21
- const editedSince = <V extends object>(current: V, submitted: V | undefined): Readonly<Record<string, unknown>> => {
22
- const before = new Map(Object.entries(submitted ?? current));
23
- return Object.fromEntries(Object.entries(current).filter(([name, value]) => !Equal.equals(value, before.get(name))));
24
- };
25
-
26
- export const useCreate = <F extends Fields, Created, SE, R, ER>(config: CreateConfig<F, Created, SE, R, ER>): Create<F, Created, SE, ER> => {
27
- const [{ initialValues, fresh }] = useState(() => {
28
- const { fields, initialValues, runtime, create, rejectField } = config;
29
- return { fresh: () => submission({ fields, initialValues, rejectField, runtime, save: create }), initialValues };
30
- });
31
- const [current, replace] = useState(fresh);
32
- const [created, record] = useState<Option.Option<Created>>(Option.none());
33
- const settled = useCallback(
34
- (value: Created) => {
35
- const next = fresh();
36
- next.form.values.set({ ...initialValues, ...editedSince(current.form.values.value, current.submitted()) });
37
- record(Option.some(value));
38
- replace(next);
39
- },
40
- [current, fresh, initialValues],
41
- );
42
- return { ...useSaveState(current.form, settled), created, form: current.form };
43
- };
package/src/editor.ts DELETED
@@ -1,58 +0,0 @@
1
- import { type Effect, Option, type Schema } from "effect";
2
- import type * as AsyncResult from "effect/unstable/reactivity/AsyncResult";
3
- import type * as Atom from "effect/unstable/reactivity/Atom";
4
- import { useCallback, useEffect, useState } from "react";
5
- import type { Decoded, Encoded, FieldFailure, Fields, Form, Services } from "@shivaedev/effect-form/shape.ts";
6
- import type { AtomServices, FieldRejectionMapping } from "./field-rejection.ts";
7
- import { type QueryState, useQuery } from "./result-state.ts";
8
- import { type SaveState, useSaveState } from "./save-state.ts";
9
- import { submission } from "./submission.ts";
10
-
11
- export type EditorConfig<F extends Fields, Row, QE, SE, R, ER> = {
12
- readonly query: Atom.Atom<AsyncResult.AsyncResult<Row, QE>>;
13
- readonly fields: Schema.Struct<F>;
14
- readonly values: (row: Row) => Encoded<F>;
15
- readonly save: (values: Decoded<F>) => Effect.Effect<Row, SE, AtomServices<R>>;
16
- readonly runtime: Atom.AtomRuntime<Services<F, R>, ER>;
17
- } & FieldRejectionMapping<F, SE>;
18
-
19
- export interface Editor<F extends Fields, Row, QE, SE, ER> extends SaveState<SE | ER> {
20
- readonly form: Form<F, Row, SE | FieldFailure, ER> | undefined;
21
- readonly query: QueryState<Row, QE>;
22
- }
23
-
24
- interface Held<F extends Fields, Row, SE, ER> {
25
- readonly form: Form<F, Row, SE | FieldFailure, ER>;
26
- readonly query: Atom.Atom<unknown>;
27
- readonly values: (row: Row) => Encoded<F>;
28
- }
29
-
30
- export const useEditor = <F extends Fields, Row, QE, SE, R, ER>(config: EditorConfig<F, Row, QE, SE, R, ER>): Editor<F, Row, QE, SE, ER> => {
31
- const query = useQuery(config.query);
32
- const row = Option.getOrUndefined(query.data);
33
- const [held, hold] = useState<Held<F, Row, SE, ER> | undefined>(undefined);
34
- let current = held?.query === config.query ? held : undefined;
35
- if (current === undefined && row !== undefined) {
36
- current = {
37
- form: submission({
38
- fields: config.fields,
39
- initialValues: config.values(row),
40
- rejectField: config.rejectField,
41
- runtime: config.runtime,
42
- save: config.save,
43
- }).form,
44
- query: config.query,
45
- values: config.values,
46
- };
47
- hold(current);
48
- }
49
- const form = current?.form;
50
- const values = current?.values;
51
- useEffect(() => {
52
- if (form && values && row !== undefined) {
53
- form.receive(values(row));
54
- }
55
- }, [form, values, row]);
56
- const settled = useCallback((saved: Row) => (form && values ? form.receive(values(saved)) : undefined), [form, values]);
57
- return { ...useSaveState(form, settled), form, query };
58
- };
@@ -1,58 +0,0 @@
1
- import { useAtomRefresh, useAtomSet, useAtomValue } from "@effect/atom-react";
2
- import { Cause, Option, Predicate } from "effect";
3
- import * as AsyncResult from "effect/unstable/reactivity/AsyncResult";
4
- import type * as Atom from "effect/unstable/reactivity/Atom";
5
- import { useEffect } from "react";
6
- import { useSessionRecheck } from "./session-boundary.ts";
7
-
8
- export interface ResultState<A, E> {
9
- readonly cause: Option.Option<Cause.Cause<E>>;
10
- readonly data: Option.Option<A>;
11
- readonly pending: boolean;
12
- readonly refreshing: boolean;
13
- readonly result: AsyncResult.AsyncResult<A, E>;
14
- }
15
-
16
- const state = <A, E>(result: AsyncResult.AsyncResult<A, E>): ResultState<A, E> => {
17
- const data = AsyncResult.value(result);
18
- return {
19
- cause: AsyncResult.cause(result),
20
- data,
21
- pending: result.waiting,
22
- refreshing: result.waiting && Option.isSome(data),
23
- result,
24
- };
25
- };
26
-
27
- export const isUnauthorized = <E>(cause: Cause.Cause<E>): boolean =>
28
- Option.match(Cause.findErrorOption(cause), { onNone: () => false, onSome: (error) => Predicate.isTagged(error, "Unauthorized") });
29
-
30
- const useRecheckOnUnauthorized = <A, E>(result: AsyncResult.AsyncResult<A, E>): void => {
31
- const recheck = useSessionRecheck();
32
- useEffect(() => {
33
- if (AsyncResult.isFailure(result) && isUnauthorized(result.cause)) {
34
- recheck();
35
- }
36
- }, [recheck, result]);
37
- };
38
-
39
- export interface QueryState<A, E> extends ResultState<A, E> {
40
- readonly refresh: () => void;
41
- }
42
-
43
- export const useQuery = <A, E>(atom: Atom.Atom<AsyncResult.AsyncResult<A, E>>): QueryState<A, E> => {
44
- const result = useAtomValue(atom);
45
- useRecheckOnUnauthorized(result);
46
- return { ...state(result), refresh: useAtomRefresh(atom) };
47
- };
48
-
49
- export interface ActionState<Input, A, E> extends ResultState<A, E> {
50
- readonly dispatch: (input: Input) => void;
51
- }
52
-
53
- // The atom's state is shared by every dispatch, so it never claims to be one invocation's completion result.
54
- export const useAction = <Input, A, E>(atom: Atom.AtomResultFn<Input, A, E>): ActionState<Input, A, E> => {
55
- const result = useAtomValue(atom);
56
- useRecheckOnUnauthorized(result);
57
- return { ...state(result), dispatch: useAtomSet(atom) };
58
- };