@pumped-fn/lite 2.0.0 → 2.1.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/CHANGELOG.md +49 -0
- package/PATTERNS.md +12 -11
- package/README.md +8 -1
- package/dist/index.cjs +224 -99
- package/dist/index.d.cts +46 -9
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +46 -9
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +224 -99
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,54 @@
|
|
|
1
1
|
# @pumped-fn/lite
|
|
2
2
|
|
|
3
|
+
## 2.1.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 8ed17e7: - Fix watch and invalidation edge cases in `@pumped-fn/lite` by aligning `select()` with `Object.is`, snapshotting select listeners during notification, making watch option typing match the runtime contract, and surfacing invalidation-chain failures from `flush()` instead of leaking them as background rejections.
|
|
8
|
+
- Fix `@pumped-fn/lite-react` hook refresh behavior by keeping stale values visible during re-resolution, recomputing `useSelect` snapshots when selector or equality semantics change, tracking pending promises per controller, and suppressing non-Suspense `unhandledRejection` leaks on failed refreshes.
|
|
9
|
+
|
|
10
|
+
## 2.1.1
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- 2ce41fc: Fix 16 bugs found via adversarial triage + 5 rounds of Codex review:
|
|
15
|
+
|
|
16
|
+
**Correctness**
|
|
17
|
+
|
|
18
|
+
- `preset(atom, undefined)` now works — uses `has()` check instead of `!== undefined`
|
|
19
|
+
- `seekHas()` traverses parent chain via interface dispatch, not `instanceof`
|
|
20
|
+
- Error-path `pendingSet` only reschedules value-type sets — `fn(undefined)` no longer produces garbage
|
|
21
|
+
- `doInvalidateSequential` swallows resolve errors when pending operations exist
|
|
22
|
+
- Resource cycle detection moved to per-execution-chain WeakMap — fixes false errors with `ctx.exec()`
|
|
23
|
+
- Resource inflight check runs before circular check — sibling `ctx.exec()` no longer false-positives
|
|
24
|
+
|
|
25
|
+
**Reactive system**
|
|
26
|
+
|
|
27
|
+
- `set()`/`update()` pendingSet path skips cleanups — watch deps preserved since factory doesn't re-run
|
|
28
|
+
- Unconditional `invalidationChain.delete()` in pendingSet fast-path — prevents self-loops
|
|
29
|
+
- Copy-on-iterate on all 4 listener iteration sites — unsub during notification no longer drops siblings
|
|
30
|
+
|
|
31
|
+
**Lifecycle**
|
|
32
|
+
|
|
33
|
+
- `dispose()` awaits `chainPromise` before setting `disposed` — drains pending invalidation chain
|
|
34
|
+
- `resolve()`, `controller()`, `createContext()` throw after dispose
|
|
35
|
+
- `release()` cleans up dependents + schedules GC on freed deps
|
|
36
|
+
|
|
37
|
+
**SelectHandle**
|
|
38
|
+
|
|
39
|
+
- Eager subscription in constructor — tracks changes without active subscribers
|
|
40
|
+
- `dispose()` method for explicit teardown
|
|
41
|
+
- Re-subscribe refreshes cached value after auto-cleanup
|
|
42
|
+
- Added `seekHas()` to `ContextData` interface, `dispose()` to `SelectHandle` interface
|
|
43
|
+
|
|
44
|
+
## 2.1.0
|
|
45
|
+
|
|
46
|
+
### Minor Changes
|
|
47
|
+
|
|
48
|
+
- a87362f: Add `controller({ resolve: true, watch: true, eq? })` for automatic reactive invalidation.
|
|
49
|
+
|
|
50
|
+
When `watch: true` is set, the parent atom re-runs automatically whenever the dep resolves to a new value (equality-gated via `Object.is` or a custom `eq` function). Replaces manual `ctx.cleanup(ctx.scope.on('resolved', dep, () => ctx.invalidate()))` wiring. Watch listeners are auto-cleaned on re-resolve, release, and dispose.
|
|
51
|
+
|
|
3
52
|
## 2.0.0
|
|
4
53
|
|
|
5
54
|
### Major Changes
|
package/PATTERNS.md
CHANGED
|
@@ -218,22 +218,23 @@ sequenceDiagram
|
|
|
218
218
|
|
|
219
219
|
### Controller as Dependency
|
|
220
220
|
|
|
221
|
-
Receive reactive handle instead of resolved value in atom
|
|
221
|
+
Receive a reactive handle instead of the resolved value in atom deps. Use `resolve: true` to pre-resolve before the factory runs. Add `watch: true` (atom deps only) to auto-invalidate the parent when the dep value changes — replaces manual `ctx.cleanup(ctx.scope.on('resolved', dep, () => ctx.invalidate()))`.
|
|
222
222
|
|
|
223
223
|
```mermaid
|
|
224
224
|
sequenceDiagram
|
|
225
225
|
participant Scope
|
|
226
|
-
participant
|
|
226
|
+
participant Parent as derivedAtom
|
|
227
|
+
participant Dep as configAtom
|
|
227
228
|
participant Ctrl as Controller
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
Note over
|
|
229
|
+
|
|
230
|
+
Scope->>Parent: resolve(derivedAtom)
|
|
231
|
+
Note over Parent: deps: { cfg: controller(configAtom, { resolve: true, watch: true, eq? }) }
|
|
232
|
+
Parent->>Scope: resolve configAtom first
|
|
233
|
+
Scope-->>Ctrl: ctrl (resolved)
|
|
234
|
+
Parent->>Parent: factory(_, { cfg: ctrl })
|
|
235
|
+
Note over Scope: on dep 'resolved': compare prev/next via eq ?? Object.is
|
|
236
|
+
Scope->>Parent: scheduleInvalidation if changed
|
|
237
|
+
Note over Parent: watch listener auto-cleaned on re-resolve / release / dispose
|
|
237
238
|
```
|
|
238
239
|
|
|
239
240
|
### Inline Function Execution
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @pumped-fn/lite
|
|
2
2
|
|
|
3
|
-
    
|
|
4
4
|
|
|
5
5
|
**Scoped Ambient State** for TypeScript — a scope-local atom graph with explicit dependencies and opt-in reactivity.
|
|
6
6
|
|
|
@@ -151,6 +151,13 @@ sequenceDiagram
|
|
|
151
151
|
|
|
152
152
|
App->>Scope: select(atom, selector, { eq })
|
|
153
153
|
Scope-->>App: handle { get, subscribe }
|
|
154
|
+
|
|
155
|
+
Note over App,Ctrl: Dependency reactivity — atom deps only
|
|
156
|
+
Note right of Scope: watch:true replaces manual ctx.cleanup(ctx.scope.on('resolved', dep, () => ctx.invalidate()))
|
|
157
|
+
App->>Scope: resolve(derivedAtom)
|
|
158
|
+
Note right of Scope: deps: { src: controller(srcAtom, { resolve: true, watch: true, eq? }) }
|
|
159
|
+
Scope->>Scope: on dep 'resolved': eq(prev, next) → scheduleInvalidation if changed
|
|
160
|
+
Note right of Scope: watch listener auto-cleaned on re-resolve / release / dispose
|
|
154
161
|
end
|
|
155
162
|
|
|
156
163
|
%% ── Cleanup & Teardown ──
|