@push.rocks/smartstate 2.0.31 → 2.1.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/dist_ts/00_commitinfo_data.js +3 -3
- package/dist_ts/index.d.ts +2 -0
- package/dist_ts/index.js +3 -1
- package/dist_ts/smartstate.classes.computed.d.ts +7 -0
- package/dist_ts/smartstate.classes.computed.js +10 -0
- package/dist_ts/smartstate.classes.smartstate.d.ts +19 -10
- package/dist_ts/smartstate.classes.smartstate.js +44 -17
- package/dist_ts/smartstate.classes.statepart.d.ts +26 -9
- package/dist_ts/smartstate.classes.statepart.js +120 -24
- package/dist_ts/smartstate.contextprovider.d.ts +16 -0
- package/dist_ts/smartstate.contextprovider.js +44 -0
- package/npmextra.json +8 -2
- package/package.json +9 -4
- package/readme.hints.md +47 -30
- package/readme.md +218 -213
- package/ts/00_commitinfo_data.ts +2 -2
- package/ts/index.ts +2 -0
- package/ts/smartstate.classes.computed.ts +16 -0
- package/ts/smartstate.classes.smartstate.ts +51 -17
- package/ts/smartstate.classes.statepart.ts +140 -23
- package/ts/smartstate.contextprovider.ts +61 -0
package/npmextra.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"githost": "code.foss.global",
|
|
17
17
|
"gitscope": "push.rocks",
|
|
18
18
|
"gitrepo": "smartstate",
|
|
19
|
-
"description": "A
|
|
19
|
+
"description": "A TypeScript-first reactive state management library with middleware, computed state, batching, persistence, and Web Component Context Protocol support.",
|
|
20
20
|
"npmPackagename": "@push.rocks/smartstate",
|
|
21
21
|
"license": "MIT",
|
|
22
22
|
"keywords": [
|
|
@@ -29,7 +29,13 @@
|
|
|
29
29
|
"state selection",
|
|
30
30
|
"state notification",
|
|
31
31
|
"asynchronous state",
|
|
32
|
-
"cumulative notification"
|
|
32
|
+
"cumulative notification",
|
|
33
|
+
"middleware",
|
|
34
|
+
"computed state",
|
|
35
|
+
"batch updates",
|
|
36
|
+
"context protocol",
|
|
37
|
+
"web components",
|
|
38
|
+
"AbortSignal"
|
|
33
39
|
]
|
|
34
40
|
},
|
|
35
41
|
"release": {
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@push.rocks/smartstate",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"private": false,
|
|
5
|
-
"description": "A
|
|
5
|
+
"description": "A TypeScript-first reactive state management library with middleware, computed state, batching, persistence, and Web Component Context Protocol support.",
|
|
6
6
|
"main": "dist_ts/index.js",
|
|
7
7
|
"typings": "dist_ts/index.d.ts",
|
|
8
8
|
"type": "module",
|
|
@@ -22,7 +22,6 @@
|
|
|
22
22
|
"@types/node": "^25.3.2"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@push.rocks/lik": "^6.2.2",
|
|
26
25
|
"@push.rocks/smarthash": "^3.2.6",
|
|
27
26
|
"@push.rocks/smartjson": "^6.0.0",
|
|
28
27
|
"@push.rocks/smartpromise": "^4.2.3",
|
|
@@ -54,7 +53,13 @@
|
|
|
54
53
|
"state selection",
|
|
55
54
|
"state notification",
|
|
56
55
|
"asynchronous state",
|
|
57
|
-
"cumulative notification"
|
|
56
|
+
"cumulative notification",
|
|
57
|
+
"middleware",
|
|
58
|
+
"computed state",
|
|
59
|
+
"batch updates",
|
|
60
|
+
"context protocol",
|
|
61
|
+
"web components",
|
|
62
|
+
"AbortSignal"
|
|
58
63
|
],
|
|
59
64
|
"homepage": "https://code.foss.global/push.rocks/smartstate",
|
|
60
65
|
"repository": {
|
package/readme.hints.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Smartstate Implementation Notes
|
|
2
2
|
|
|
3
|
-
## Current API (as of v2.0.
|
|
3
|
+
## Current API (as of v2.0.31)
|
|
4
4
|
|
|
5
5
|
### State Part Initialization
|
|
6
6
|
- State parts can be created with different init modes: 'soft' (default), 'mandatory', 'force', 'persistent'
|
|
@@ -8,53 +8,70 @@
|
|
|
8
8
|
- 'mandatory' - requires state part to not exist, fails if it does
|
|
9
9
|
- 'force' - always creates new state part, overwriting any existing
|
|
10
10
|
- 'persistent' - like 'soft' but with WebStore persistence (IndexedDB)
|
|
11
|
-
- Persistent mode automatically calls init() internally
|
|
11
|
+
- Persistent mode automatically calls init() internally
|
|
12
12
|
- State merge order fixed: initial state takes precedence over stored state
|
|
13
13
|
|
|
14
14
|
### Actions
|
|
15
15
|
- Actions are created with `createAction()` method
|
|
16
|
-
- Two ways to dispatch
|
|
17
|
-
|
|
18
|
-
2. `await statePart.dispatchAction(stateAction, payload)` - returns Promise<TStatePayload>
|
|
19
|
-
- Both methods return the same Promise, providing flexibility in usage
|
|
16
|
+
- Two ways to dispatch: `stateAction.trigger(payload)` or `statePart.dispatchAction(stateAction, payload)`
|
|
17
|
+
- Both return Promise<TStatePayload>
|
|
20
18
|
|
|
21
19
|
### State Management Methods
|
|
22
|
-
- `select()` - returns Observable
|
|
23
|
-
- `waitUntilPresent()` - waits for
|
|
20
|
+
- `select(fn?, { signal? })` - returns Observable, memoized by selector fn ref, supports AbortSignal
|
|
21
|
+
- `waitUntilPresent(fn?, number | { timeoutMs?, signal? })` - waits for state condition, backward compat with number arg
|
|
24
22
|
- `stateSetup()` - async state initialization with cumulative defer
|
|
25
23
|
- `notifyChangeCumulative()` - defers notification to end of call stack
|
|
26
24
|
- `getState()` - returns current state or undefined
|
|
27
|
-
- `setState()` -
|
|
25
|
+
- `setState()` - runs middleware, validates, persists, notifies
|
|
26
|
+
- `addMiddleware(fn)` - intercepts setState, returns removal function
|
|
27
|
+
|
|
28
|
+
### Middleware
|
|
29
|
+
- Type: `(newState, oldState) => newState | Promise<newState>`
|
|
30
|
+
- Runs sequentially in insertion order before validation/persistence
|
|
31
|
+
- Throw to reject state changes (atomic — state unchanged on error)
|
|
32
|
+
- Does NOT run during initial createStatePart() hydration
|
|
33
|
+
|
|
34
|
+
### Selector Memoization
|
|
35
|
+
- Uses WeakMap<Function, Observable> for fn-keyed cache
|
|
36
|
+
- `defaultSelectObservable` for no-arg select()
|
|
37
|
+
- Wrapped in `shareReplay({ bufferSize: 1, refCount: true })`
|
|
38
|
+
- NOT cached when AbortSignal is provided
|
|
39
|
+
|
|
40
|
+
### Batch Updates
|
|
41
|
+
- `smartstate.batch(async () => {...})` — defers notifications until batch completes
|
|
42
|
+
- Supports nesting — only flushes at outermost level
|
|
43
|
+
- StatePart has `smartstateRef` set by `createStatePart()` for batch awareness
|
|
44
|
+
- State parts created via `new StatePart()` directly work without batching
|
|
45
|
+
|
|
46
|
+
### Computed State
|
|
47
|
+
- `computed(sources, fn)` — standalone function using `combineLatest` + `map`
|
|
48
|
+
- Also available as `smartstate.computed(sources, fn)`
|
|
49
|
+
- Lazy — only subscribes when subscribed to
|
|
50
|
+
|
|
51
|
+
### Context Protocol Bridge
|
|
52
|
+
- `attachContextProvider(element, { context, statePart, selectorFn? })` — returns cleanup fn
|
|
53
|
+
- Listens for `context-request` CustomEvent on element
|
|
54
|
+
- Supports one-shot and subscription modes
|
|
55
|
+
- Works with Lit @consume(), FAST, or any Context Protocol consumer
|
|
28
56
|
|
|
29
57
|
### State Hash Detection
|
|
30
58
|
- Uses SHA256 hash to detect actual state changes
|
|
31
|
-
-
|
|
59
|
+
- Hash comparison properly awaits async hash calculation
|
|
32
60
|
- Prevents duplicate notifications for identical state values
|
|
33
|
-
- `notifyChange()` is now async to support proper hash comparison
|
|
34
61
|
|
|
35
62
|
### State Validation
|
|
36
63
|
- Basic validation ensures state is not null/undefined
|
|
37
|
-
- `validateState()`
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
## Recent Fixes (v2.0.24+)
|
|
46
|
-
1. Fixed state hash bug - now properly compares hash values instead of promises
|
|
47
|
-
2. Fixed state initialization merge order - initial state now takes precedence
|
|
48
|
-
3. Ensured stateStore is properly typed as potentially undefined
|
|
49
|
-
4. Simplified init mode logic with clear behavior for each mode
|
|
50
|
-
5. Added state validation with extensible validateState() method
|
|
51
|
-
6. Made notifyChange() async to support proper hash comparison
|
|
52
|
-
7. Updated select() to filter undefined states
|
|
53
|
-
|
|
54
|
-
## Dependency Versions (v2.0.30)
|
|
64
|
+
- `validateState()` can be overridden in subclasses
|
|
65
|
+
|
|
66
|
+
### Key Notes
|
|
67
|
+
- `smartstateRef` creates circular ref between StatePart and Smartstate
|
|
68
|
+
- Use `===` not deep equality for StatePart comparison in tests
|
|
69
|
+
- Direct rxjs imports used for: Observable, shareReplay, takeUntil, combineLatest, map
|
|
70
|
+
|
|
71
|
+
## Dependency Versions (v2.0.31)
|
|
55
72
|
- @git.zone/tsbuild: ^4.1.2
|
|
56
73
|
- @git.zone/tsbundle: ^2.9.0
|
|
57
74
|
- @git.zone/tsrun: ^2.0.1
|
|
58
75
|
- @git.zone/tstest: ^3.1.8
|
|
59
76
|
- @push.rocks/smartjson: ^6.0.0
|
|
60
|
-
- @types/node: ^25.3.2
|
|
77
|
+
- @types/node: ^25.3.2
|