march-hare 0.14.0 → 0.17.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/README.md +46 -5
- package/dist/actions/utils.d.ts +19 -17
- package/dist/app/index.d.ts +1 -1
- package/dist/boundary/components/broadcast/utils.d.ts +37 -10
- package/dist/cache/index.d.ts +69 -30
- package/dist/cache/types.d.ts +16 -15
- package/dist/march-hare.js +6 -6
- package/dist/march-hare.js.map +1 -1
- package/dist/march-hare.umd.cjs +1 -1
- package/dist/march-hare.umd.cjs.map +1 -1
- package/dist/resource/types.d.ts +39 -4
- package/dist/resource/utils.d.ts +0 -9
- package/dist/types/index.d.ts +13 -11
- package/dist/utils/utils.d.ts +17 -0
- package/dist/utils.d.ts +0 -2
- package/package.json +1 -1
package/dist/resource/types.d.ts
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
import { Env } from '../boundary/components/env/types.js';
|
|
2
2
|
import { Cache } from '../cache/index.js';
|
|
3
|
-
import { BroadcastPayload, MulticastPayload, Filter } from '../types/index.js';
|
|
3
|
+
import { BroadcastPayload, MulticastPayload, ChanneledAction, Filter } from '../types/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* Helper that constrains `Partial<P>` to a {@link Filter}-compatible
|
|
6
|
+
* shape. Resource params hold primitive leaves by convention, so the
|
|
7
|
+
* auto-broadcast {@link ResourceHandle.action} can use them directly as
|
|
8
|
+
* a channel filter.
|
|
9
|
+
*/
|
|
10
|
+
export type ActionChannel<P extends object> = Partial<P> & Filter;
|
|
4
11
|
/**
|
|
5
12
|
* Dispatch surface exposed on a Resource fetcher's `context`. Restricted
|
|
6
13
|
* to broadcast and multicast actions — unicast targets the calling
|
|
7
|
-
* component, which a Resource fetcher does not have.
|
|
14
|
+
* component, which a Resource fetcher does not have. Channeled
|
|
15
|
+
* dispatches (e.g. `dispatch(action({ UserId: 5 }), payload)`) are
|
|
16
|
+
* accepted on the same overloads — the routing layer reads the
|
|
17
|
+
* action's underlying distribution off its symbol.
|
|
8
18
|
*/
|
|
9
19
|
export type Dispatch = {
|
|
10
|
-
<C extends Filter = never>(action: BroadcastPayload<never, C> | MulticastPayload<never, C>): Promise<void>;
|
|
11
|
-
<P, C extends Filter = never>(action: BroadcastPayload<P, C> | MulticastPayload<P, C>, payload: P): Promise<void>;
|
|
20
|
+
<C extends Filter = never>(action: BroadcastPayload<never, C> | MulticastPayload<never, C> | ChanneledAction<never, C>): Promise<void>;
|
|
21
|
+
<P, C extends Filter = never>(action: BroadcastPayload<P, C> | MulticastPayload<P, C> | ChanneledAction<P, C>, payload: P): Promise<void>;
|
|
12
22
|
};
|
|
13
23
|
/**
|
|
14
24
|
* `context` object passed to every {@link Fetcher}.
|
|
@@ -107,6 +117,31 @@ export type ResourceHandle<T, P extends object = Record<never, never>> = ([
|
|
|
107
117
|
keyof P
|
|
108
118
|
] extends [never] ? (params?: P) => Invocation<T, P> : (params: P) => Invocation<T, P>) & {
|
|
109
119
|
readonly get: [keyof P] extends [never] ? (params?: P) => T | null : (params: P) => T | null;
|
|
120
|
+
/**
|
|
121
|
+
* Broadcast channeled action fired automatically after every successful
|
|
122
|
+
* fetch of this Resource. Always invoke before subscribing: pass no
|
|
123
|
+
* arguments to match every fetch, or a partial-params object to narrow.
|
|
124
|
+
* Matching follows the subscriber-as-filter rule — every key on the
|
|
125
|
+
* subscriber's channel must equal the same key on the dispatch channel,
|
|
126
|
+
* and adding keys progressively narrows the filter.
|
|
127
|
+
*
|
|
128
|
+
* Late-mounting subscribers replay every cached entry whose channel
|
|
129
|
+
* satisfies their filter — the broadcast cache is sharded by
|
|
130
|
+
* `(action, channel)`, so a partial subscriber that mounts after
|
|
131
|
+
* several distinct fetches catches up with all of them rather than
|
|
132
|
+
* just the most recent.
|
|
133
|
+
*
|
|
134
|
+
* Failures do not broadcast — the cache is only written on
|
|
135
|
+
* success (see resource/utils.ts), and the broadcast follows the same
|
|
136
|
+
* gate.
|
|
137
|
+
*
|
|
138
|
+
* ```ts
|
|
139
|
+
* actions.useAction(user.action(), (context, value) => { ... });
|
|
140
|
+
* actions.useAction(user.action({ id: 5 }), (context, value) => { ... });
|
|
141
|
+
* actions.stream(user.action({ id: 5 }), (value) => <span>{value.name}</span>);
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
readonly action: (channel?: ActionChannel<P>) => ChanneledAction<T, ActionChannel<P>>;
|
|
110
145
|
};
|
|
111
146
|
/**
|
|
112
147
|
* Drops cache slots whose stored params match the supplied `where`
|
package/dist/resource/utils.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Cache } from '../cache/index.js';
|
|
2
|
-
import { unset } from '../utils/utils.js';
|
|
3
2
|
import { Env } from '../boundary/components/env/types.js';
|
|
4
3
|
import { Fetcher, ResourceEvictor, ResourceHandle } from './types.js';
|
|
5
4
|
export { Cache } from '../cache/index.js';
|
|
@@ -29,14 +28,6 @@ export declare function defaultCache(fetcher: object): Cache;
|
|
|
29
28
|
* @internal
|
|
30
29
|
*/
|
|
31
30
|
export declare function key(params: object): string;
|
|
32
|
-
/**
|
|
33
|
-
* Re-export of the shared `unset` sentinel from {@link "../utils/index.ts"}.
|
|
34
|
-
*
|
|
35
|
-
* @internal
|
|
36
|
-
*/
|
|
37
|
-
export declare const config: {
|
|
38
|
-
readonly unset: typeof unset;
|
|
39
|
-
};
|
|
40
31
|
/**
|
|
41
32
|
* Per-Resource eviction callbacks. Each `Resource` declaration registers
|
|
42
33
|
* one entry on construction; the public `nuke(...)` (defined in
|
package/dist/types/index.d.ts
CHANGED
|
@@ -550,20 +550,22 @@ export type Payload<A> = A extends {
|
|
|
550
550
|
* By convention, use uppercase keys (e.g., `{UserId: 4}` not `{userId: 4}`)
|
|
551
551
|
* to distinguish filter keys from payload properties.
|
|
552
552
|
*
|
|
553
|
-
*
|
|
554
|
-
*
|
|
553
|
+
* **Matching direction:** the subscriber's filter is the constraint;
|
|
554
|
+
* every key the subscriber supplies must be present and equal on the
|
|
555
|
+
* dispatch channel. Extra keys on the dispatch channel are ignored, so a
|
|
556
|
+
* dispatcher is free to be more specific than any single subscriber
|
|
557
|
+
* needs. A subscriber that supplies no keys (uncalled action or empty
|
|
558
|
+
* filter) matches every dispatch.
|
|
555
559
|
*
|
|
556
560
|
* @example
|
|
557
561
|
* ```ts
|
|
558
|
-
*
|
|
559
|
-
*
|
|
560
|
-
*
|
|
561
|
-
*
|
|
562
|
-
* dispatch(
|
|
563
|
-
* dispatch(
|
|
564
|
-
* dispatch(
|
|
565
|
-
* dispatch([Actions.User, {}], payload); // Matches all
|
|
566
|
-
* dispatch(Actions.User, payload); // Matches ALL handlers
|
|
562
|
+
* actions.useAction(Actions.User({ UserId: 1 }), handler);
|
|
563
|
+
*
|
|
564
|
+
* actions.dispatch(Actions.User({ UserId: 1 }), payload); // Matches (exact)
|
|
565
|
+
* actions.dispatch(Actions.User({ UserId: 2 }), payload); // No match (UserId mismatch)
|
|
566
|
+
* actions.dispatch(Actions.User({ UserId: 1, Role: "admin" }), payload); // Matches (extra dispatch keys ignored)
|
|
567
|
+
* actions.dispatch(Actions.User({}), payload); // No match (subscriber asked for UserId)
|
|
568
|
+
* actions.dispatch(Actions.User, payload); // Matches ALL handlers (uncalled bypasses channel filtering)
|
|
567
569
|
* ```
|
|
568
570
|
*/
|
|
569
571
|
export type Filter = Record<string, string | number | bigint | boolean | symbol>;
|
package/dist/utils/utils.d.ts
CHANGED
|
@@ -5,6 +5,23 @@ import { Stored } from './types.js';
|
|
|
5
5
|
* recorded" from "a legitimately stored null".
|
|
6
6
|
*/
|
|
7
7
|
export declare const unset: unique symbol;
|
|
8
|
+
/**
|
|
9
|
+
* Internal configuration shared across the Resource and Cache layers.
|
|
10
|
+
*
|
|
11
|
+
* - `unset` — re-export of the shared sentinel so consumers can pull
|
|
12
|
+
* both fields from a single object.
|
|
13
|
+
* - `storageNamespace` — global prefix the Cache layer prepends to
|
|
14
|
+
* every key it persists. Lets `Cache.clear()` and the partial-match
|
|
15
|
+
* evictors scope themselves to the library's own entries on shared
|
|
16
|
+
* backends (`localStorage`, `chrome.storage.local`, MMKV) without
|
|
17
|
+
* nuking third-party state on the same origin.
|
|
18
|
+
*
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
export declare const config: {
|
|
22
|
+
readonly unset: typeof unset;
|
|
23
|
+
readonly storageNamespace: "mh:";
|
|
24
|
+
};
|
|
8
25
|
/**
|
|
9
26
|
* Returns a function to force a component re-render. Useful when state is
|
|
10
27
|
* managed externally (e.g., refs) but the UI needs updating.
|
package/dist/utils.d.ts
CHANGED
|
@@ -17,8 +17,6 @@ export declare const describe: {
|
|
|
17
17
|
cache: (name?: string) => string;
|
|
18
18
|
/** Lifecycle action description. `describe.lifecycle("Mount")` → `"march-hare.action.lifecycle/Mount"` */
|
|
19
19
|
lifecycle: (name?: string) => string;
|
|
20
|
-
/** Mount replay sentinel description. Used to create the {@link replay} symbol. */
|
|
21
|
-
replay: (name?: string) => string;
|
|
22
20
|
};
|
|
23
21
|
/**
|
|
24
22
|
* Flat record used for shallow property comparison in {@link changes}.
|