rx-tiny-flux 1.0.39 → 1.0.41

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 (2) hide show
  1. package/CLAUDE.md +40 -0
  2. package/package.json +1 -1
package/CLAUDE.md ADDED
@@ -0,0 +1,40 @@
1
+ # rx-tiny-flux — Maintainer Notes
2
+
3
+ Tiny redux-style store built on RxJS, used by the Tennis Fit Zepp OS mini-program
4
+ (`native/zepp`). We own this library. Source in `src/`, bundled to `dist/` via rollup;
5
+ consumers install the published package, so **a fix here only reaches the watch after a
6
+ rebuild + version bump + reinstall** in the app.
7
+
8
+ ## Effects fail in isolation — but don't rely on it
9
+
10
+ Effects are RxJS streams subscribed in `store.js#registerEffects`. A throw anywhere inside
11
+ an effect (e.g. a serializer invoked from a `tap`) errors the stream. Historically each
12
+ effect was subscribed with **no error handler**, so one throw tore that effect down
13
+ *permanently and silently* for the rest of the session.
14
+
15
+ `registerEffects` now wraps every effect in `catchError((e, caught) => caught)`: it logs the
16
+ failure and re-subscribes the source so the effect keeps reacting to future actions. This is
17
+ a **backstop, not a license to throw** — an effect that throws on every matching action will
18
+ hot-loop re-subscribe. Keep effect bodies defensive; validate before encoding.
19
+
20
+ > Real incident (2026-06-12): the Zepp watch's `appendStrokes` propagation called a binary
21
+ > serializer that threw `Expected non-negative integer` on a `point: -1` (a game-boundary
22
+ > index from the backend). The throw killed the propagation effect on the first game boundary,
23
+ > so strokes uploaded fine through game 1 and then silently stopped for the entire match —
24
+ > while `updateMatch` (JSON-encoded, negative-safe) kept working. The catchError backstop was
25
+ > added in response. See `native/zepp/CLAUDE.md` and `native/zepp/docs/court-logs-2026-06-12-*`.
26
+
27
+ ## `context` — the binding to the ZeppOS instance
28
+
29
+ `action.context` ties an action to its ZeppOS App / Page / SideService instance and carries
30
+ `.call` (cross-context messaging), `.log`, `.debug`, and `._store`. Lifecycle:
31
+
32
+ - **Attached on dispatch when absent** — `zeppos.js` dispatch wraps `action.context ? action : {...action, context: this}`.
33
+ - **Injected into effect *outputs*** — `registerEffects` adds `this._context` to any emitted
34
+ action lacking one, so fresh actions returned from an effect `map` inherit the App context.
35
+ - **Stripped before `messaging.call`** — it holds circular refs and must not be serialized; the
36
+ receiving context re-attaches its own on `onAction`.
37
+
38
+ Because effect outputs are re-contexted automatically, a fresh action from an effect is *not*
39
+ missing its context — verified during the 2026-06-12 investigation (the bug there was the
40
+ serializer throw above, **not** a lost context, despite the symptom looking identical).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rx-tiny-flux",
3
- "version": "1.0.39",
3
+ "version": "1.0.41",
4
4
  "description": "A lightweight, minimalist state management library for pure JavaScript projects, inspired by NgRx and Redux, and built with RxJS.",
5
5
  "author": "Bernardo Baumblatt <baumblatt@gmail.com>",
6
6
  "license": "MIT",