@systemfsoftware/effect-atom 0.5.3 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,101 @@
1
+ # @systemfsoftware/effect-atom
2
+
3
+ ## 1.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - The `result` member is removed from the `DehydratedAtomValue` type returned by `dehydrate`.
8
+
9
+ - `DehydratedAtomValue.result` was a `Deferred` that completed when an initially-loading atom reached a real value. It never survived serialization, so it could not work across the process boundary the dehydrated state exists for; reading it after transport failed at runtime.
10
+ - The pending-update behaviour is unchanged: entries created with `encodeInitialAs: 'deferred'` still settle the target registry once `hydrate` applies them and the source atom resolves.
11
+ - Wait for all pending updates by joining the fiber that `hydrate` returns, as before.
12
+ - Code that read `entry.result` directly no longer compiles; drop that access — there is no replacement field.
13
+
14
+ ### Minor Changes
15
+
16
+ - `Registry.make` and `Registry.layerOptions` accept `now` and `scheduleTimer`, so every time-dependent atom can be driven without waiting in real time.
17
+
18
+ - `now?: () => number` supplies the clock.
19
+ - `scheduleTimer?: (f: () => void, delayMillis: number) => () => void` arms a delayed callback and returns its canceller.
20
+
21
+ Both default to the platform's wall clock and timer, so existing callers are unaffected. One substitution now drives all three time-dependent behaviours together: idle-TTL eviction, `Atom.debounce`, and `Atom.swr` staleness. Previously each read the clock and armed timers itself, so testing any of them meant real elapsed time.
22
+
23
+ `Registry` exposes `now` and `scheduleTimer` as members, alongside `scheduler` and `schedulerAsync`.
24
+
25
+ - Atoms built from a runtime keep the last good answer again, and four read paths that lost or overwrote a value are fixed.
26
+
27
+ - A stream-backed atom that emitted values and then completed reported an empty stream and failed with `NoSuchElementError`. It now settles with the value the stream emitted last.
28
+ - A failing refresh, retry or reload no longer clears the value already on screen. The previous success is carried across effect, stream, pull, `subscriptionRef` and `fn` atoms, so `Result.previousSuccess` is populated while waiting and after a failure, as documented.
29
+ - Reading a `subscriptionRef` atom whose runtime layer failed threw `Result.getOrThrow: no value found` instead of reporting the failure. It now reports the layer's failure like every other atom on that runtime.
30
+ - `Atom.kvs` without `mode: 'async'` wrote `defaultValue()` into the store on first read, overwriting a value the store had not finished loading. The fallback is now shown without writing, and the default is stored only once the store reports the key absent.
31
+
32
+ Surface changes:
33
+
34
+ - `AtomContext.self` takes the value type as a parameter: `get.self<MyResult>()` returns `Option<MyResult>` where it previously returned `Option<unknown>`.
35
+ - `AtomRuntime.subscriptionRef` declares `Cause.NoSuchElementError` in its error channel, which its implementation always could produce.
36
+ - The HTTP API client's `mutation` and `query` bound their `Group` and `Endpoint` type parameters to any group and any endpoint. Each is now bound to the group and endpoint its identifier arguments select, so a call that passed one of them explicitly and disagreed with the identifiers no longer compiles.
37
+ - `Result.builder` renders a typed value. `orElse` returns the accumulated value or the fallback, `orNull` and `render` add `null`, and `exhaustive` returns the value alone, where all four previously returned `unknown`. Code that relied on assigning a rendered result anywhere now needs the value's real type.
38
+ - `Atom.mapResult` reports the mapped value with the source atom's error type, where it previously reported a union that included an untyped result. Mapping a mapped atom now gives the second mapper the real value type instead of `unknown`; an annotation written against the old union needs updating.
39
+
40
+ - Harden the v4 fork: Effect-native hydration, zero `as any` casts, browser-mode tests.
41
+
42
+ Breaking changes:
43
+
44
+ - `Hydration.DehydratedAtomValue.resultPromise?: Promise<unknown>` is now `result?: Deferred<unknown>` — the pending-value channel is Effect-native, and `hydrate` returns a `Fiber<void, never>` that completes once every pending result has been applied (join it for deterministic SSR flushes and tests).
45
+ - `Hydration.dehydrate`'s `encodeInitialAs: 'promise'` is now `'deferred'`, `dehydrate` returns `Array<DehydratedAtomValue>` directly, and `Hydration.toValues` is removed.
46
+ - `Registry.setSerializable` now applies to an already-materialized node as well as preloading absent ones.
47
+ - `ScopedAtom.Context` is typed `React.Context<A | undefined>` to match runtime.
48
+ - `useAtom`/`useAtomSet` `mode: 'promise'` and `mode: 'promiseExit'` are gone; the single `mode: 'effect'` returns a lazy `(value) => Effect<A, E>` instead of an eager `Promise`, so callers run the result with `Effect.runPromise`/`yield*` and no raw `Promise` remains on the public surface.
49
+
50
+ Additions:
51
+
52
+ - `Registry.setInitialValue(atom, value)` — typed initial-value seeding (also used by `useAtomInitialValues`).
53
+ - `Result.Schema` now carries a `toArbitrary` hook, so `Schema.toArbitrary` works for property tests; its generated space is the wire-representable subset (no `undefined` defects, which the JSON codec cannot carry).
54
+
55
+ Internal:
56
+
57
+ - Every `as any` / `as unknown as` cast removed from both packages' `src` (Registry, Result, Atom, AtomRef, AtomRpc, AtomHttpApi, Hooks, RegistryContext, ScopedAtom); oxlint `correctness` and `perf` categories now gate as errors.
58
+ - `atom-react` tests run in Vitest browser mode (playwright chromium) with `expect.element` assertions; jest-dom and jsdom are gone. Consumers running these tests need `playwright install chromium`.
59
+ - Fixed a zombie-notification defect: an item removed from an `AtomRef.collection` no longer notifies the collection when mutated.
60
+
61
+ - Port both packages onto the effect v4 release candidate (`effect@4.0.0-rc.108`,
62
+ resolved from the `effect4` catalog). The `src/` is now the v4 reactivity API:
63
+ absorbed packages (`@effect/experimental`, `@effect/platform`, `@effect/rpc`)
64
+ are gone — their modules now live under `effect/unstable/*` and the core `effect`
65
+ barrel — and every removed/renamed v3 symbol is replaced (`Effect.async`→
66
+ `callback`, `Context.Tag`→`Context.Service`, `Runtime<R>`→`Runtime`, `Cause`
67
+ error renames, `Schema.decodeEither`→`decodeExit`, the `Mailbox`/`Subscribable`/
68
+ `GlobalValue`/`FiberId` modules). **Breaking:** the `effect` peer dependency is
69
+ now `4.0.0-rc.x`; consumers must move to effect v4.
70
+
71
+ Breaking changes:
72
+
73
+ - `Registry.isRegistry` is renamed `isAtomRegistry`.
74
+ - The read-context type `Atom.Context` is renamed `Atom.AtomContext`; `defaultMemoMap` and `KvsError` are removed.
75
+ - `Result.toExitAsEffect`, `Result.schemaFromSelf`, `Result.PartialEncoded`, and `Result.Encoded` are removed (use `Result.toExit` + `Effect.exit` and `Result.Schema`).
76
+ - `Atom.make(stream)`/`Atom.fn(stream)` widen the atom's error channel with `Cause.NoSuchElementError`.
77
+ - `Registry.make`/`Registry.layerOptions` and `RegistryProvider` take a changed `scheduleTask` option signature.
78
+ - `@systemfsoftware/effect-atom-react` no longer re-exports the atom package's namespaces (`Atom`, `Registry`, `Result`, `AtomRef`, `AtomHttpApi`, `AtomRpc`, `Hydration`, `ScopedAtom`) from its root — those modules are not browser-safe, and the react entry is browser-tested. Import them from `@systemfsoftware/effect-atom` directly.
79
+ - Runtime type markers `Atom.TypeId`/`WritableTypeId`/`AtomRef.TypeId` moved to `~effect/reactivity/*`; the wire `SerializableTypeId` (`~effect-atom/atom/Atom/Serializable`) is unchanged, so `Hydration` payload keys are stable.
80
+
81
+ - cut over to effect v4 (4.0.0-rc.108): public surface derives from effect types; peers flip effect ^3→^4
82
+
83
+ ### Patch Changes
84
+
85
+ - Array types are spelled one way. `Array<T>` and `ReadonlyArray<T>` in emitted
86
+ declarations become `T[]` and `readonly T[]`, which the type checker cannot tell
87
+ apart: no exported type changes, only how it is written.
88
+
89
+ - A serialised successful result now requires its timestamp to be a finite number.
90
+ It previously accepted `NaN` and `Infinity`, so a corrupted timestamp could decode
91
+ without complaint and reach code that compares it.
92
+
93
+ - New version is published through npm trusted publishing, so it carries a provenance attestation you can verify.
94
+
95
+ - The `atom` packages publish their own author rather than crediting an upstream they are not downstream of, and `stryker-plugins` no longer pulls Node's ambient types into a package that has no runtime dependency on them.
96
+
97
+ - Each of these packages now has a README, so its registry page says what the package is, how
98
+ to install it, and what to import or register — previously the page was blank. The lint
99
+ plugins show the configuration line that enables what they recommend.
100
+
101
+ `@systemfsoftware/stryker-js-mutation-report` also carries its licence text
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@systemfsoftware/effect-atom",
3
3
  "license": "Apache-2.0",
4
- "version": "0.5.3",
4
+ "version": "1.0.0",
5
5
  "author": "Ryan Lee <drdgvhbh@gmail.com>",
6
6
  "repository": {
7
7
  "type": "git",
@@ -57,7 +57,6 @@
57
57
  "files": [
58
58
  "dist"
59
59
  ],
60
- "dependencies": {},
61
60
  "peerDependencies": {
62
61
  "effect": "4.0.0-rc.108"
63
62
  },
@@ -72,10 +71,10 @@
72
71
  "type-fest": "^5.8.0",
73
72
  "typescript": "^7",
74
73
  "vitest": "^4.1.10",
75
- "@systemfsoftware/effect-gherkin-spec": "^0.5.1",
76
- "@systemfsoftware/tsconfig": "^1.3.1",
74
+ "@systemfsoftware/effect-gherkin-spec": "^1.0.0",
75
+ "@systemfsoftware/oxlint-config": "^0.1.0",
77
76
  "@systemfsoftware/vitest-config": "^0.1.0",
78
- "@systemfsoftware/oxlint-config": "^0.1.0"
77
+ "@systemfsoftware/tsconfig": "^1.3.2"
79
78
  },
80
79
  "publishConfig": {
81
80
  "provenance": true