atom.io 0.44.0 → 0.44.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atom.io",
3
- "version": "0.44.0",
3
+ "version": "0.44.2",
4
4
  "description": "Composable and testable reactive data library.",
5
5
  "homepage": "https://atom.io.fyi",
6
6
  "sideEffects": false,
@@ -60,29 +60,30 @@
60
60
  }
61
61
  },
62
62
  "devDependencies": {
63
- "@eslint/core": "0.16.0",
64
- "@storybook/addon-docs": "9.1.13",
65
- "@storybook/addon-onboarding": "9.1.13",
66
- "@storybook/react-vite": "9.1.13",
63
+ "@eslint/core": "0.17.0",
64
+ "@storybook/addon-docs": "10.0.4",
65
+ "@storybook/addon-onboarding": "10.0.4",
66
+ "@storybook/react-vite": "10.0.4",
67
67
  "@testing-library/react": "16.3.0",
68
68
  "@types/bun": "npm:bun-types@1.3.1",
69
69
  "@types/eslint": "9.6.1",
70
70
  "@types/estree": "1.0.8",
71
- "@types/http-proxy": "1.17.16",
71
+ "@types/http-proxy": "1.17.17",
72
72
  "@types/npmlog": "7.0.0",
73
73
  "@types/react": "19.2.2",
74
74
  "@types/tmp": "0.2.6",
75
- "@typescript-eslint/parser": "8.46.2",
76
- "@typescript-eslint/rule-tester": "8.46.2",
77
- "@typescript-eslint/utils": "8.46.2",
78
- "@typescript/native-preview": "7.0.0-dev.20251022.1",
79
- "@vitest/coverage-v8": "4.0.1",
80
- "@vitest/ui": "4.0.1",
75
+ "@typescript-eslint/parser": "8.46.3",
76
+ "@typescript-eslint/rule-tester": "8.46.3",
77
+ "@typescript-eslint/utils": "8.46.3",
78
+ "@typescript/native-preview": "7.0.0-dev.20251105.1",
79
+ "@vitest/coverage-v8": "4.0.7",
80
+ "@vitest/ui": "4.0.7",
81
+ "arktype": "2.1.25",
81
82
  "concurrently": "9.2.1",
82
- "drizzle-kit": "0.31.5",
83
- "drizzle-orm": "0.44.6",
84
- "eslint": "9.38.0",
85
- "happy-dom": "20.0.8",
83
+ "drizzle-kit": "0.31.6",
84
+ "drizzle-orm": "0.44.7",
85
+ "eslint": "9.39.1",
86
+ "happy-dom": "20.0.10",
86
87
  "http-proxy": "1.18.1",
87
88
  "motion": "12.23.24",
88
89
  "npmlog": "7.0.1",
@@ -91,19 +92,18 @@
91
92
  "preact": "10.27.2",
92
93
  "react": "19.2.0",
93
94
  "react-dom": "19.2.0",
94
- "react-router-dom": "7.9.4",
95
- "recoverage": "0.1.11",
95
+ "react-router-dom": "7.9.5",
96
+ "recoverage": "0.1.12",
96
97
  "socket.io": "4.8.1",
97
98
  "socket.io-client": "4.8.1",
98
- "storybook": "9.1.13",
99
+ "storybook": "10.0.4",
99
100
  "tmp": "0.2.5",
100
- "tsdown": "0.15.9",
101
+ "tsdown": "0.16.0",
101
102
  "typescript": "5.9.3",
102
- "vite": "7.1.11",
103
+ "vite": "7.2.0",
103
104
  "vite-tsconfig-paths": "5.1.4",
104
- "vitest": "4.0.1",
105
- "zod": "3.25.76",
106
- "break-check": "0.6.16"
105
+ "vitest": "4.0.7",
106
+ "break-check": "0.6.20"
107
107
  },
108
108
  "main": "./dist/main/index.js",
109
109
  "files": [
@@ -21,10 +21,12 @@ import type { ProtoUpdate } from "./operate-on-store"
21
21
  export function dispatchOrDeferStateUpdate<T, E>(
22
22
  target: Store & { operation: OpenOperation<any> },
23
23
  state: WritableState<T, E>,
24
- { oldValue, newValue }: ProtoUpdate<E | T>,
24
+ proto: ProtoUpdate<E | T>,
25
25
  stateIsNewlyCreated: boolean,
26
26
  family?: WritableFamily<T, any, E>,
27
27
  ): void {
28
+ const { oldValue, newValue } = proto
29
+ const hasOldValue = `oldValue` in proto
28
30
  const token = deposit(state)
29
31
  if (stateIsNewlyCreated && family) {
30
32
  state.subject.next({ newValue })
@@ -63,9 +65,16 @@ export function dispatchOrDeferStateUpdate<T, E>(
63
65
  }
64
66
  const { key, subject, type } = state
65
67
 
66
- const update: StateUpdate<T> = {
67
- oldValue: isTransceiver(oldValue) ? oldValue.READONLY_VIEW : oldValue,
68
- newValue: isTransceiver(newValue) ? newValue.READONLY_VIEW : newValue,
68
+ let update: StateUpdate<T>
69
+ if (hasOldValue) {
70
+ update = {
71
+ oldValue: isTransceiver(oldValue) ? oldValue.READONLY_VIEW : oldValue,
72
+ newValue: isTransceiver(newValue) ? newValue.READONLY_VIEW : newValue,
73
+ }
74
+ } else {
75
+ update = {
76
+ newValue: isTransceiver(newValue) ? newValue.READONLY_VIEW : newValue,
77
+ }
69
78
  }
70
79
 
71
80
  if (isRootStore(target)) {
@@ -13,7 +13,7 @@ import { resetAtomOrSelector } from "./reset-atom-or-selector"
13
13
  import { RESET_STATE } from "./reset-in-store"
14
14
  import { setAtomOrSelector } from "./set-atom-or-selector"
15
15
 
16
- export type ProtoUpdate<T> = { oldValue: T; newValue: T }
16
+ export type ProtoUpdate<T> = { oldValue?: T; newValue: T }
17
17
 
18
18
  export const OWN_OP: unique symbol = Symbol(`OWN_OP`)
19
19
  export const JOIN_OP: unique symbol = Symbol(`JOIN_OP`)
@@ -1,23 +1,44 @@
1
- import { writeToCache } from "../caching"
1
+ import { readFromCache, writeToCache } from "../caching"
2
2
  import { readOrComputeValue } from "../get-state/read-or-compute-value"
3
+ import { isFn } from "../is-fn"
3
4
  import type { OpenOperation } from "../operation"
4
5
  import { markDone } from "../operation"
5
6
  import type { Atom } from "../state-types"
6
7
  import type { Store } from "../store"
7
- import { become } from "./become"
8
8
  import { evictDownstreamFromAtom } from "./evict-downstream"
9
9
  import type { ProtoUpdate } from "./operate-on-store"
10
10
 
11
+ const UNSET = Symbol(`UNSET`)
12
+
11
13
  export const setAtom = <T>(
12
14
  target: Store & { operation: OpenOperation<any> },
13
15
  atom: Atom<T, any>,
14
16
  next: NoInfer<T> | ((oldValue: T) => NoInfer<T>),
15
17
  ): ProtoUpdate<T> => {
16
- const oldValue = readOrComputeValue(target, atom, `mut`)
17
- let newValue = become(next, oldValue)
18
+ let oldValue: T | typeof UNSET
19
+ let newValue: T
20
+ if (isFn(next)) {
21
+ const prev = readOrComputeValue(target, atom, `mut`)
22
+ oldValue = prev
23
+ newValue = next(prev)
24
+ } else {
25
+ if (target.valueMap.has(atom.key)) {
26
+ oldValue = readFromCache(target, atom, `mut`)
27
+ } else {
28
+ if (atom.type === `atom` && !isFn(atom.default)) {
29
+ oldValue = atom.default
30
+ } else {
31
+ oldValue = UNSET
32
+ }
33
+ }
34
+ newValue = next
35
+ }
18
36
  target.logger.info(`⭐`, `atom`, atom.key, `setting value`, newValue)
19
37
  newValue = writeToCache(target, atom, newValue)
20
38
  markDone(target, atom.key)
21
39
  evictDownstreamFromAtom(target, atom)
40
+ if (oldValue === UNSET) {
41
+ return { newValue }
42
+ }
22
43
  return { oldValue, newValue }
23
44
  }
@@ -63,6 +63,7 @@ export function useLoadable(
63
63
  fallback = params[2]
64
64
  }
65
65
 
66
+ const hasFallback = fallback !== undefined
66
67
  const isErr = `catch` in state && state.catch.some((E) => value instanceof E)
67
68
 
68
69
  const wrapperRef = useRef<{
@@ -84,7 +85,7 @@ export function useLoadable(
84
85
  if (lastLoaded === `LOADING`) {
85
86
  return `LOADING`
86
87
  }
87
- if (wasErr && fallback) {
88
+ if (wasErr && hasFallback) {
88
89
  wrapper = wrapperRef.current = {
89
90
  loading: true,
90
91
  value: fallback,
@@ -96,7 +97,7 @@ export function useLoadable(
96
97
  } else {
97
98
  lastLoadedRef.current = value
98
99
  if (wrapper.loading === true) {
99
- if (isErr && fallback) {
100
+ if (isErr && hasFallback) {
100
101
  wrapper = wrapperRef.current = {
101
102
  loading: false,
102
103
  value: fallback,
@@ -106,7 +107,7 @@ export function useLoadable(
106
107
  wrapper = wrapperRef.current = { loading: false, value: value }
107
108
  }
108
109
  } else {
109
- if (isErr && fallback) {
110
+ if (isErr && hasFallback) {
110
111
  wrapper.loading = false
111
112
  wrapper.value = fallback
112
113
  wrapper.error = value