atom.io 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +14 -8
  2. package/dist/index.d.ts +117 -62
  3. package/dist/index.js +577 -287
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +574 -285
  6. package/dist/index.mjs.map +1 -1
  7. package/package.json +16 -6
  8. package/react/dist/index.d.ts +12 -17
  9. package/react/dist/index.js +25 -34
  10. package/react/dist/index.js.map +1 -1
  11. package/react/dist/index.mjs +21 -34
  12. package/react/dist/index.mjs.map +1 -1
  13. package/react-devtools/dist/index.css +26 -0
  14. package/react-devtools/dist/index.css.map +1 -0
  15. package/react-devtools/dist/index.d.ts +15 -0
  16. package/react-devtools/dist/index.js +1579 -0
  17. package/react-devtools/dist/index.js.map +1 -0
  18. package/react-devtools/dist/index.mjs +1551 -0
  19. package/react-devtools/dist/index.mjs.map +1 -0
  20. package/react-devtools/package.json +15 -0
  21. package/src/index.ts +14 -8
  22. package/src/internal/atom-internal.ts +10 -5
  23. package/src/internal/families-internal.ts +7 -7
  24. package/src/internal/get.ts +9 -9
  25. package/src/internal/index.ts +2 -1
  26. package/src/internal/meta/attach-meta.ts +17 -0
  27. package/src/internal/meta/index.ts +4 -0
  28. package/src/internal/meta/meta-state.ts +135 -0
  29. package/src/internal/meta/meta-timelines.ts +1 -0
  30. package/src/internal/meta/meta-transactions.ts +1 -0
  31. package/src/internal/operation.ts +14 -3
  32. package/src/internal/selector-internal.ts +37 -15
  33. package/src/internal/store.ts +35 -6
  34. package/src/internal/time-travel-internal.ts +89 -0
  35. package/src/internal/timeline-internal.ts +110 -93
  36. package/src/internal/transaction-internal.ts +14 -5
  37. package/src/{internal/logger.ts → logger.ts} +2 -2
  38. package/src/react/index.ts +28 -46
  39. package/src/react-devtools/AtomIODevtools.tsx +107 -0
  40. package/src/react-devtools/StateEditor.tsx +73 -0
  41. package/src/react-devtools/TokenList.tsx +49 -0
  42. package/src/react-devtools/devtools.scss +130 -0
  43. package/src/react-devtools/index.ts +1 -0
  44. package/src/react-explorer/AtomIOExplorer.tsx +208 -0
  45. package/src/react-explorer/explorer-effects.ts +20 -0
  46. package/src/react-explorer/explorer-states.ts +224 -0
  47. package/src/react-explorer/index.ts +23 -0
  48. package/src/react-explorer/space-states.ts +73 -0
  49. package/src/react-explorer/view-states.ts +43 -0
  50. package/src/selector.ts +11 -11
  51. package/src/subscribe.ts +3 -3
  52. package/src/timeline.ts +3 -12
  53. package/src/transaction.ts +9 -4
  54. package/src/web-effects/index.ts +1 -0
  55. package/src/web-effects/storage.ts +30 -0
@@ -0,0 +1,43 @@
1
+ import type { Location } from "react-router-dom"
2
+
3
+ import { key } from "~/packages/anvl/src/object"
4
+
5
+ import { persistStringSetAtom } from "./explorer-effects"
6
+ import type { AtomToken } from ".."
7
+ import type { AtomFamily } from "../atom"
8
+ import { atom, atomFamily } from "../atom"
9
+ import { lazyLocalStorageEffect } from "../web-effects"
10
+
11
+ export type View = {
12
+ title: string
13
+ location: Omit<Location, `state`>
14
+ }
15
+
16
+ export const makeViewFamily = (key: string): AtomFamily<View, string> =>
17
+ atomFamily<View, string>({
18
+ key: `${key}:view`,
19
+ default: {
20
+ title: ``,
21
+ location: {
22
+ pathname: ``,
23
+ search: ``,
24
+ hash: ``,
25
+ key: ``,
26
+ },
27
+ },
28
+ effects: (subKey) => [lazyLocalStorageEffect(`${key}:${subKey}`)],
29
+ })
30
+
31
+ export const makeViewIndex = (key: string): AtomToken<Set<string>> =>
32
+ atom<Set<string>>({
33
+ key: `${key}:view_index`,
34
+ default: new Set(),
35
+ effects: [persistStringSetAtom(`${key}:view_index`)],
36
+ })
37
+
38
+ export const makeViewFocusedFamily = (key: string): AtomFamily<number, string> =>
39
+ atomFamily<number, string>({
40
+ key: `${key}:view_focused`,
41
+ default: 0,
42
+ effects: (subKey) => [lazyLocalStorageEffect(`${key}:${subKey}`)],
43
+ })
package/src/selector.ts CHANGED
@@ -2,31 +2,31 @@ import type * as Rx from "rxjs"
2
2
 
3
3
  import type { Serializable } from "~/packages/anvl/src/json"
4
4
 
5
- import type { ReadonlyValueToken, SelectorToken } from "."
5
+ import type { ReadonlySelectorToken, SelectorToken } from "."
6
6
  import { selectorFamily__INTERNAL, selector__INTERNAL } from "./internal"
7
- import type { ReadonlyTransactors, Transactors } from "./transaction"
7
+ import type { Read, Write } from "./transaction"
8
8
 
9
9
  export type SelectorOptions<T> = {
10
10
  key: string
11
- get: (readonlyTransactors: ReadonlyTransactors) => T
12
- set: (transactors: Transactors, newValue: T) => void
11
+ get: Read<() => T>
12
+ set: Write<(newValue: T) => void>
13
13
  }
14
14
  export type ReadonlySelectorOptions<T> = Omit<SelectorOptions<T>, `set`>
15
15
 
16
- export function selector<T>(options: SelectorOptions<T>): SelectorToken<T>
17
16
  export function selector<T>(
18
17
  options: ReadonlySelectorOptions<T>
19
- ): ReadonlyValueToken<T>
18
+ ): ReadonlySelectorToken<T>
19
+ export function selector<T>(options: SelectorOptions<T>): SelectorToken<T>
20
20
  export function selector<T>(
21
21
  options: ReadonlySelectorOptions<T> | SelectorOptions<T>
22
- ): ReadonlyValueToken<T> | SelectorToken<T> {
22
+ ): ReadonlySelectorToken<T> | SelectorToken<T> {
23
23
  return selector__INTERNAL(options)
24
24
  }
25
25
 
26
26
  export type SelectorFamilyOptions<T, K extends Serializable> = {
27
27
  key: string
28
- get: (key: K) => (readonlyTransactors: ReadonlyTransactors) => T
29
- set: (key: K) => (transactors: Transactors, newValue: T) => void
28
+ get: (key: K) => Read<() => T>
29
+ set: (key: K) => Write<(newValue: T) => void>
30
30
  }
31
31
  export type ReadonlySelectorFamilyOptions<T, K extends Serializable> = Omit<
32
32
  SelectorFamilyOptions<T, K>,
@@ -43,10 +43,10 @@ export type SelectorFamily<T, K extends Serializable = Serializable> = ((
43
43
 
44
44
  export type ReadonlySelectorFamily<T, K extends Serializable = Serializable> = ((
45
45
  key: K
46
- ) => ReadonlyValueToken<T>) & {
46
+ ) => ReadonlySelectorToken<T>) & {
47
47
  key: string
48
48
  type: `readonly_selector_family`
49
- subject: Rx.Subject<ReadonlyValueToken<T>>
49
+ subject: Rx.Subject<ReadonlySelectorToken<T>>
50
50
  }
51
51
 
52
52
  export function selectorFamily<T, K extends Serializable>(
package/src/subscribe.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ReadonlyValueToken, StateToken, TransactionToken, ƒn } from "."
1
+ import type { ReadonlySelectorToken, StateToken, TransactionToken, ƒn } from "."
2
2
  import type { Store, TransactionUpdate } from "./internal"
3
3
  import { IMPLICIT, subscribeToRootAtoms, withdraw } from "./internal"
4
4
 
@@ -6,7 +6,7 @@ export type StateUpdate<T> = { newValue: T; oldValue: T }
6
6
  export type UpdateHandler<T> = (update: StateUpdate<T>) => void
7
7
 
8
8
  export const subscribe = <T>(
9
- token: ReadonlyValueToken<T> | StateToken<T>,
9
+ token: ReadonlySelectorToken<T> | StateToken<T>,
10
10
  handleUpdate: UpdateHandler<T>,
11
11
  store: Store = IMPLICIT.STORE
12
12
  ): (() => void) => {
@@ -14,7 +14,7 @@ export const subscribe = <T>(
14
14
  const subscription = state.subject.subscribe(handleUpdate)
15
15
  store.config.logger?.info(`👀 subscribe to "${state.key}"`)
16
16
  const dependencySubscriptions =
17
- `get` in state ? subscribeToRootAtoms(state, store) : null
17
+ state.type !== `atom` ? subscribeToRootAtoms(state, store) : null
18
18
 
19
19
  const unsubscribe =
20
20
  dependencySubscriptions === null
package/src/timeline.ts CHANGED
@@ -1,15 +1,6 @@
1
- import HAMT from "hamt_plus"
2
- import type * as Rx from "rxjs"
3
-
4
- import type { AtomFamily, AtomToken, ƒn } from "."
5
- import { setState } from "."
6
- import type { Store, KeyedStateUpdate, TransactionUpdate } from "./internal"
7
- import { target, IMPLICIT, withdraw } from "./internal"
8
- import {
9
- redo__INTERNAL,
10
- timeline__INTERNAL,
11
- undo__INTERNAL,
12
- } from "./internal/timeline-internal"
1
+ import type { AtomFamily, AtomToken } from "."
2
+ import { IMPLICIT } from "./internal"
3
+ import { redo__INTERNAL, timeline__INTERNAL, undo__INTERNAL } from "./internal/"
13
4
 
14
5
  export type TimelineToken = {
15
6
  key: string
@@ -1,25 +1,30 @@
1
1
  import type * as Rx from "rxjs"
2
2
 
3
- import type { ReadonlyValueToken, StateToken, TransactionToken } from "."
3
+ import type { ReadonlySelectorToken, StateToken, TransactionToken } from "."
4
4
  import type { Store, TransactionUpdate } from "./internal"
5
5
  import { IMPLICIT, transaction__INTERNAL, withdraw } from "./internal"
6
6
 
7
7
  export type ƒn = (...parameters: any[]) => any
8
8
 
9
9
  export type Transactors = {
10
- get: <S>(state: ReadonlyValueToken<S> | StateToken<S>) => S
10
+ get: <S>(state: ReadonlySelectorToken<S> | StateToken<S>) => S
11
11
  set: <S>(state: StateToken<S>, newValue: S | ((oldValue: S) => S)) => void
12
12
  }
13
13
  export type ReadonlyTransactors = Pick<Transactors, `get`>
14
14
 
15
- export type Action<ƒ extends ƒn> = (
15
+ export type Read<ƒ extends ƒn> = (
16
+ transactors: ReadonlyTransactors,
17
+ ...parameters: Parameters<ƒ>
18
+ ) => ReturnType<ƒ>
19
+
20
+ export type Write<ƒ extends ƒn> = (
16
21
  transactors: Transactors,
17
22
  ...parameters: Parameters<ƒ>
18
23
  ) => ReturnType<ƒ>
19
24
 
20
25
  export type TransactionOptions<ƒ extends ƒn> = {
21
26
  key: string
22
- do: Action<ƒ>
27
+ do: Write<ƒ>
23
28
  }
24
29
 
25
30
  export type Transaction<ƒ extends ƒn> = {
@@ -0,0 +1 @@
1
+ export * from "./storage"
@@ -0,0 +1,30 @@
1
+ import type { Json } from "~/packages/anvl/src/json"
2
+
3
+ import type { AtomEffect } from "../index"
4
+
5
+ export type StringInterface<T> = {
6
+ stringify: (t: T) => string
7
+ parse: (s: string) => T
8
+ }
9
+
10
+ export const persistAtom =
11
+ <T>(storage: Storage) =>
12
+ ({ stringify, parse }: StringInterface<T>) =>
13
+ (key: string): AtomEffect<T> =>
14
+ ({ setSelf, onSet }) => {
15
+ const savedValue = storage.getItem(key)
16
+
17
+ if (savedValue != null) setSelf(parse(savedValue))
18
+
19
+ onSet(({ newValue }) => {
20
+ if (newValue == null) {
21
+ storage.removeItem(key)
22
+ return
23
+ }
24
+ storage.setItem(key, stringify(newValue))
25
+ })
26
+ }
27
+
28
+ export const lazyLocalStorageEffect: <J extends Json>(
29
+ key: string
30
+ ) => AtomEffect<J> = persistAtom(localStorage)(JSON)