march-hare 0.13.1 → 0.13.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/README.md +20 -0
- package/dist/cache/index.d.ts +89 -7
- package/dist/index.d.ts +1 -1
- package/dist/march-hare.js +9 -8
- 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/index.d.ts +2 -1
- package/dist/resource/utils.d.ts +8 -1
- package/dist/scope/utils.d.ts +4 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -607,6 +607,26 @@ export default function CatCard(): React.ReactElement {
|
|
|
607
607
|
|
|
608
608
|
`Cache()` with no adapter is an in-memory scope – useful in tests or when you want a holdable cache without persistence. Per-params keying via `JSON.stringify(params)` is automatic, so `user({ id: 5 })` and `user({ id: 6 })` are distinct slots.
|
|
609
609
|
|
|
610
|
+
For multi-tenant apps that share a single backing store, add a `key(context)` callback alongside the adapter methods to derive a per-context prefix from the live `<app.Boundary>` Env. The callback receives the same `{ env }` an `app.Resource` fetcher sees; its return value is prepended to every cache slot, so two users on the same device do not see each other's data:
|
|
611
|
+
|
|
612
|
+
```ts
|
|
613
|
+
// app.ts
|
|
614
|
+
type AppEnv = { session: { accessToken: string } | null };
|
|
615
|
+
|
|
616
|
+
export const app = App<AppEnv>({
|
|
617
|
+
env: { session: null },
|
|
618
|
+
cache: Cache<AppEnv>({
|
|
619
|
+
get: (key) => localStorage.getItem(key),
|
|
620
|
+
set: (key, value) => localStorage.setItem(key, value),
|
|
621
|
+
remove: (key) => localStorage.removeItem(key),
|
|
622
|
+
clear: () => localStorage.clear(),
|
|
623
|
+
key: ({ env }) => env.session?.accessToken ?? "",
|
|
624
|
+
}),
|
|
625
|
+
});
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
Successful writes for Alice land under `alice:0:{...}`; Bob's land under `bob:0:{...}`. Return `""`, `null`, or `undefined` to skip prefixing – useful for the signed-out gap, where the scope is genuinely empty.
|
|
629
|
+
|
|
610
630
|
The adapter contract is **strictly synchronous** – `get` / `set` / `remove` / `clear` all return immediately, with no `Promise`. The model-literal read (`{ user: resource.user.get() }`) is evaluated during render and has no place to wait. React Native projects should use [`react-native-mmkv`](https://github.com/mrousavy/react-native-mmkv), which is sync out of the box and drops straight into the contract; `AsyncStorage` is incompatible. Truly async backends (IndexedDB, `chrome.storage.local`) need a sync facade hydrated at app entry – see the [storage recipe](./recipes/storage.md).
|
|
611
631
|
|
|
612
632
|
See the [storage recipe](./recipes/storage.md) for backend adapters (React Native `react-native-mmkv`, browser `localStorage`, browser extension `chrome.storage`), sign-out purge, and the `unset` sentinel that keeps "nothing stored" distinct from "a legitimately stored null".
|
package/dist/cache/index.d.ts
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
import { Adapter, Stored } from './types.js';
|
|
2
|
+
import { Env } from '../boundary/components/env/types.js';
|
|
2
3
|
export type { Adapter, Encoded } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Context passed to {@link CacheConfig.key}. Mirrors the shape an
|
|
6
|
+
* `app.Resource` fetcher receives, restricted to the field the cache
|
|
7
|
+
* needs to scope on: the live per-`<Boundary>` Env. Future-extensible
|
|
8
|
+
* — new fields can land here without breaking the call shape.
|
|
9
|
+
*
|
|
10
|
+
* @template E The Env shape the cache is parameterised by.
|
|
11
|
+
*/
|
|
12
|
+
export type CacheContext<E extends object> = {
|
|
13
|
+
readonly env: E;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Configuration accepted by the {@link Cache} factory. Combines the
|
|
17
|
+
* synchronous {@link Adapter} (`get`/`set`/`remove`/`clear`/`keys?`)
|
|
18
|
+
* with an optional `key(context)` callback in a single flat object,
|
|
19
|
+
* so all the cache's plumbing lives in one literal at the call site.
|
|
20
|
+
*
|
|
21
|
+
* - `key` — derives a per-context cache scope. Called every time
|
|
22
|
+
* a cache key is assembled with the same `{ env }` shape an
|
|
23
|
+
* `app.Resource` fetcher receives; the returned string is prepended
|
|
24
|
+
* to the per-resource namespace and params so different scopes
|
|
25
|
+
* (e.g. one cache slot per access token, locale, or tenant id) can
|
|
26
|
+
* coexist in the same backing store. Return `""`, `null`, or
|
|
27
|
+
* `undefined` to skip prefixing — useful for "not signed in"
|
|
28
|
+
* gaps where the scope is genuinely empty.
|
|
29
|
+
*/
|
|
30
|
+
export type CacheConfig<E extends object> = Adapter & {
|
|
31
|
+
readonly key?: (context: CacheContext<E>) => string | null | undefined;
|
|
32
|
+
};
|
|
3
33
|
/**
|
|
4
34
|
* Persistence-aware cache for a single {@link Resource}. Wraps a
|
|
5
35
|
* **strictly synchronous** {@link Adapter} (localStorage, MMKV,
|
|
@@ -25,6 +55,21 @@ export type { Adapter, Encoded } from './types.js';
|
|
|
25
55
|
* persistent store; when supplied, the adapter is the **only** tier
|
|
26
56
|
* — the Cache does not maintain a separate in-memory mirror.
|
|
27
57
|
*
|
|
58
|
+
* Pass `key(context)` alongside the adapter methods to scope cache
|
|
59
|
+
* slots by the per-`<Boundary>` Env. The returned string is prepended
|
|
60
|
+
* to every cache key the Resource layer assembles, so different
|
|
61
|
+
* tenants / sessions / locales share the adapter without stepping on
|
|
62
|
+
* each other.
|
|
63
|
+
*
|
|
64
|
+
* The `E` generic lives on the {@link Cache} factory and on
|
|
65
|
+
* {@link CacheConfig}: it parameterises the `key(context)` callback
|
|
66
|
+
* at construction time so the caller can read `context.env.X` with
|
|
67
|
+
* full typing. The returned {@link Cache} value is itself
|
|
68
|
+
* env-agnostic — the runtime `scope(env)` method takes the
|
|
69
|
+
* loose {@link Env} record and narrows internally before invoking
|
|
70
|
+
* the callback — which keeps it freely assignable across
|
|
71
|
+
* differently-typed Apps without variance gymnastics.
|
|
72
|
+
*
|
|
28
73
|
* @example
|
|
29
74
|
* ```ts
|
|
30
75
|
* // In-memory, scoped to this instance.
|
|
@@ -38,6 +83,16 @@ export type { Adapter, Encoded } from './types.js';
|
|
|
38
83
|
* clear: () => localStorage.clear(),
|
|
39
84
|
* });
|
|
40
85
|
*
|
|
86
|
+
* // Multi-tenant: writes go under `${accessToken}:…`.
|
|
87
|
+
* type AppEnv = { session: { accessToken: string } | null };
|
|
88
|
+
* const cache = Cache<AppEnv>({
|
|
89
|
+
* get: (key) => localStorage.getItem(key),
|
|
90
|
+
* set: (key, value) => localStorage.setItem(key, value),
|
|
91
|
+
* remove: (key) => localStorage.removeItem(key),
|
|
92
|
+
* clear: () => localStorage.clear(),
|
|
93
|
+
* key: ({ env }) => env.session?.accessToken ?? "",
|
|
94
|
+
* });
|
|
95
|
+
*
|
|
41
96
|
* // Wire it into a Resource — successful runs write through automatically.
|
|
42
97
|
* export const cat = Resource({
|
|
43
98
|
* cache,
|
|
@@ -87,14 +142,41 @@ export type Cache = {
|
|
|
87
142
|
* stored params satisfy a `where` pattern.
|
|
88
143
|
*/
|
|
89
144
|
keys(): Iterable<string>;
|
|
145
|
+
/**
|
|
146
|
+
* Returns the per-context prefix derived from the configured
|
|
147
|
+
* `key(context)`. The returned string is appended with `:` by the
|
|
148
|
+
* Resource layer to compose the full cache key. Always `""` when
|
|
149
|
+
* no `key` option was supplied or when the callback returned an
|
|
150
|
+
* empty value — "no scope" is encoded as the empty string.
|
|
151
|
+
*
|
|
152
|
+
* Takes the loose {@link Env} record at runtime — the typed
|
|
153
|
+
* `E` lives on the `key(context)` callback registered at
|
|
154
|
+
* construction time, which the cache narrows to `E` internally
|
|
155
|
+
* before invoking.
|
|
156
|
+
*
|
|
157
|
+
* @internal Public surface lives on the Resource layer; consumers
|
|
158
|
+
* should not need to call this directly.
|
|
159
|
+
*/
|
|
160
|
+
scope(env: Env | undefined): string;
|
|
90
161
|
};
|
|
91
162
|
/**
|
|
92
|
-
* Constructs a {@link Cache}
|
|
93
|
-
*
|
|
94
|
-
*
|
|
163
|
+
* Constructs a {@link Cache} from `config`. The config object carries
|
|
164
|
+
* the synchronous adapter methods (`get`/`set`/`remove`/`clear`/`keys?`)
|
|
165
|
+
* and, optionally, a `key(context)` callback that scopes every cache
|
|
166
|
+
* slot by the live per-`<Boundary>` Env. Omit `config` entirely for an
|
|
167
|
+
* in-memory cache scoped to this instance.
|
|
168
|
+
*
|
|
169
|
+
* When `key` is supplied, it runs each time the Resource layer
|
|
170
|
+
* assembles a cache key, receiving the same `{ env }` shape an
|
|
171
|
+
* `app.Resource` fetcher sees; its return value is prepended
|
|
172
|
+
* (separated by `:`) to the per-resource namespace and params JSON.
|
|
95
173
|
*
|
|
96
|
-
* @
|
|
97
|
-
*
|
|
98
|
-
*
|
|
174
|
+
* @template E The Env shape `config.key` is typed against. Defaults
|
|
175
|
+
* to the loose {@link Env} record so callers that don't scope by
|
|
176
|
+
* env can keep using `Cache({ ...adapter })` without supplying a
|
|
177
|
+
* generic.
|
|
178
|
+
* @param config Optional adapter-plus-options literal. Omit for an
|
|
179
|
+
* in-memory cache; supply adapter methods alone for a persisted
|
|
180
|
+
* cache; add `key` to also scope writes by the live Env.
|
|
99
181
|
*/
|
|
100
|
-
export declare function Cache(
|
|
182
|
+
export declare function Cache<E extends object = Env>(config?: CacheConfig<E>): Cache;
|
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export { Boundary } from './boundary/index.js';
|
|
|
7
7
|
export { Cache } from './cache/index.js';
|
|
8
8
|
export { Reason, Aborted } from './error/index.js';
|
|
9
9
|
export { annotate } from './annotate/index.js';
|
|
10
|
-
export { Operation, Op, State } from 'immertation';
|
|
10
|
+
export { Operation, Op, State, isBox } from 'immertation';
|
|
11
11
|
export * as utils from './utils/index.js';
|
|
12
12
|
export * as shared from './shared/index.js';
|
|
13
13
|
export type { Fault } from './error/index.js';
|
package/dist/march-hare.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import{jsx as e}from"react/jsx-runtime";import*as
|
|
2
|
-
return e(
|
|
3
|
-
return e(
|
|
4
|
-
return e(
|
|
5
|
-
return e(
|
|
6
|
-
return e(m,{children:/* @__PURE__ */e(A,{initial:t??{},children:/* @__PURE__ */e(b,{children:/* @__PURE__ */e(L,{tap:n,children:/* @__PURE__ */e(R,{children:r})})})})})}const T=e=>"symbol"==typeof e;function W(e){return n.isString(e)||T(e)?e:(n.isObject(e)||n.isFunction(e))&&j.Action in e?e[j.Action]:e}function B(e){if(n.isString(e))return e.startsWith(O());if(T(e))return e.description?.startsWith(O())??!1;if(n.isObject(e)||n.isFunction(e)){if(j.Broadcast in e&&e[j.Broadcast])return!0;if(j.Action in e){const t=e[j.Action];return t.description?.startsWith(O())??!1}}return!1}function F(e){return n.isObject(e)&&j.Channel in e&&"channel"in e}function z(e){const t=W(e),n=T(t)?t.description??"":t;return n.startsWith(S())&&n.slice(S().length)||null}function J(e){if(n.isString(e))return e.startsWith(P());if(T(e))return e.description?.startsWith(P())??!1;if(n.isObject(e)||n.isFunction(e)){if(j.Multicast in e&&e[j.Multicast])return!0;if(j.Action in e){const t=e[j.Action];return t.description?.startsWith(P())??!1}}return!1}const D=(e="",t=N.Unicast)=>{const n=t===N.Broadcast?Symbol(O(e)):t===N.Multicast?Symbol(P(e)):Symbol(w(e)),r=function(t){return{[j.Action]:n,[j.Payload]:void 0,[j.Channel]:t,[j.Name]:e,channel:t}};return Object.defineProperty(r,j.Action,{value:n,enumerable:!1}),Object.defineProperty(r,j.Payload,{value:void 0,enumerable:!1}),Object.defineProperty(r,j.Name,{value:e,enumerable:!1}),t===N.Broadcast&&Object.defineProperty(r,j.Broadcast,{value:!0,enumerable:!1}),t===N.Multicast&&Object.defineProperty(r,j.Multicast,{value:!0,enumerable:!1}),r},H=Symbol(((e="")=>`march-hare/replay${e}`)());function I(e,t,...n){e instanceof d&&e.setCache(t,n[0]);const r=e.listeners(t);return 0===r.length?Promise.resolve():Promise.all(r.map(e=>Promise.resolve(e(...n)))).then(()=>{})}function G(e,t){for(const n of e.keys())if(z(n)===t)return n;return null}const K=/* @__PURE__ */Symbol("march-hare.unset");function V(){const[,e]=t.useReducer(e=>e+1,0);return e}function q(){return{data:K,at:null}}function Q(e,t){return{data:e,at:t}}var X=/* @__PURE__ */(e=>(e[e.Aborted=0]="Aborted",e[e.Errored=1]="Errored",e))(X||{});class Y extends Error{name="AbortError";constructor(e="Aborted"){super(e)}}const Z=t.createContext(null);function ee(e){const t=e??function(){const e=/* @__PURE__ */new Map;return{get:t=>e.get(t)??null,set:(t,n)=>{e.set(t,n)},remove:t=>{e.delete(t)},clear:()=>{e.clear()},keys:()=>e.keys()}}();return{get(e){try{const r=t.get(e);if(n.isNull(r))return q();const o=JSON.parse(r);return Q(o.data,Temporal.Instant.from(o.at))}catch{return q()}},set(e,r){if(r.data!==K&&!n.isNull(r.at))try{t.set(e,JSON.stringify({data:r.data,at:r.at.toString()}))}catch{return}},remove(e){try{t.remove(e)}catch{return}},clear(){try{t.clear()}catch{return}},keys(){try{return t.keys?.()??[]}catch{return[]}}}}const te=/* @__PURE__ */new WeakMap,ne=/* @__PURE__ */new Map,re=[];function oe(e,t,r){const o=n.isNull(r)?"":`${r}:`,s=e=>`${o}${function(e){return JSON.stringify(e)}(e)}`,c=e=>{const r=t.get(s(e));return r.data===K||n.isNull(r.at)?{data:K,at:null}:{data:r.data,at:r.at}},a=(n,r,o,c)=>e({env:n,controller:r,params:o,dispatch:c}).then(e=>(t.set(s(o),Q(e,Temporal.Now.instant())),e)),i=e=>{const n=Object.entries(e);for(const r of[...t.keys()])if(r.startsWith(o))try{const e=JSON.parse(r.slice(o.length));n.every(([t,n])=>e[t]===n)&&t.remove(r)}catch{continue}};function u(e){return{run:a,read:c,evict:i,params:e??{}}}return re.push(i),Object.defineProperty(u,"get",{value:function(e){const{data:t}=c(e??{});return t===K?null:t},enumerable:!1}),u}function se(e,t){const r=e;return n.isUndefined(t)?oe(r,function(e){const t=te.get(e);if(n.isNotNullable(t))return t;const r=ee();return te.set(e,r),r}(r),null):oe(r,t,function(e){const t=ne.get(e);if(n.isNotNullable(t))return t;const r=String(ne.size);return ne.set(e,r),r}(r))}const ce=/* @__PURE__ */Symbol("march-hare.coalesce/default");function ae(e,t){return new Promise((n,r)=>{if(t.aborted)return void r(t.reason);const o=()=>r(t.reason);t.addEventListener("abort",o,{once:!0}),e.then(e=>{t.removeEventListener("abort",o),n(e)},e=>{t.removeEventListener("abort",o),r(e)})})}let ie=(e=21)=>{let t="",n=crypto.getRandomValues(new Uint8Array(e|=0));for(;e--;)t+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[63&n[e]];return t};var ue=/* @__PURE__ */(e=>(e[e.Add=1]="Add",e[e.Remove=2]="Remove",e[e.Update=4]="Update",e[e.Move=8]="Move",e[e.Replace=16]="Replace",e[e.Sort=32]="Sort",e[e.Create=64]="Create",e[e.Fetch=128]="Fetch",e[e.Clone=256]="Clone",e[e.Archive=512]="Archive",e[e.Restore=1024]="Restore",e[e.Merge=2048]="Merge",e[e.Reorder=4096]="Reorder",e[e.Sync=8192]="Sync",e[e.Publish=16384]="Publish",e[e.Link=32768]="Link",e[e.Unlink=65536]="Unlink",e[e.Lock=131072]="Lock",e[e.Unlock=262144]="Unlock",e[e.Import=524288]="Import",e[e.Export=1048576]="Export",e[e.Transfer=2097152]="Transfer",e))(ue||{}),le=/* @__PURE__ */(e=>(e[e.Produce=0]="Produce",e[e.Hydrate=1]="Hydrate",e))(le||{}),fe=/* @__PURE__ */(e=>(e.Property="property",e.Process="process",e.Value="value",e.Operation="operation",e))(fe||{});class de{[o]=!0;static keys=new Set(Object.values(fe));property=null;process=null;value;operation;constructor(e,t){this.value=e,this.operation=t}assign(e,t){const n=new de(this.value,this.operation);return n.property=e,n.process=t,n}}class pe{static immer=(()=>{s();const e=new c;return e.setAutoFreeze(!1),e})();static tag="κ";static id=ie}function he(e,t){const n="string"==typeof t?""===t?[]:t.split("."):t;let r=e;for(const o of n){if(null==r)return;r=r[o]}return r}function me(e){if(n.isNullable(e)||ve(e))return e;if(n.isArray(e))return e.map(e=>me(e));if(n.isObject(e)&&be(e)){const t=Object.entries(e).map(([e,t])=>[e,me(t)]);return{...Object.fromEntries(t),[pe.tag]:e[pe.tag]??pe.id()}}return e}function ye(e){if(Array.isArray(e))return e.filter(e=>pe.tag in e).map(e=>e[pe.tag]??"").join(",");const t=e[pe.tag];if(t)return t;try{return JSON.stringify(e)}catch{return`[unserializable:${typeof e}]`}}function be(e){const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}function ve(e){return n.isNullable(e)||n.isString(e)||n.isNumber(e)||n.isBoolean(e)||"symbol"==typeof e||"bigint"==typeof e}function ge(e,t,r,o,s,c){return function a(i,u=t.path){if(i instanceof de){const t=he(r,u.join("."));if(Object.entries(i).filter(([e,t])=>!de.keys.has(e)&&t instanceof de).forEach(([e,t])=>a(t,u.concat(e))),ve(i.value)){if(e===le.Hydrate)return i.value;const a=u.slice(0,-1),l=a.length>0?he(r,a.join(".")):r;return n.isNullable(l)||we(l,i,u.at(-1),o,s,c),t??i.value}if(e===le.Hydrate){const e=me(a(i.value,u));return we(e,i,null,o,s,c),e}const l=t??me(i.value);return we(l,i,null,o,s,c),n.isNullable(t)?l:(a(i.value,u),t)}if(n.isArray(i))return i.map((e,t)=>a(e,u.concat(t)));if(n.isObject(i)&&!be(i))return i;if(n.isObject(i)){const t=Object.entries(i).map(([e,t])=>[e,a(t,u.concat(e))]),n=Object.fromEntries(t);if(e===le.Hydrate){const e=me(n);return Object.entries(i).forEach(([t,n])=>{n instanceof de&&ve(n.value)&&we(e,n,t,o,s,c)}),e}return n}return i}(t.value)}function we(e,t,n,r,o,s){const c=s(e),a=o.get(c)??[];o.set(c,[t.assign(n,r),...a])}class Oe{#e={};#t;#n=/* @__PURE__ */new Map;#r=/* @__PURE__ */new Set;#o=!1;constructor(e=ye){this.#t=e}static pk(){return ie()}static"κ"=Oe.pk;annotate(e,t){return new de(t,e)}"δ"=this.annotate;get model(){return this.#e}get inspect(){return function(e,t,o,s,c){function a(s){const c=s.at(-1),a=he(e(),s),i=s.slice(0,-1),u=r.isNotEmpty(i)?he(e(),i):e();return[...n.isObject(a)||n.isArray(a)?t.get(o(a))?.filter(e=>n.isNullable(e.property))??[]:[],...n.isObject(u)?t.get(o(u))?.filter(e=>e.property===c)??[]:[]]}return function t(n){return new Proxy(()=>{},{get:(o,i)=>"pending"===i?()=>!r.isEmpty(a(n)):"remaining"===i?()=>r.length(a(n)):"box"===i?()=>({value:he(e(),n),inspect:t(n)}):"is"===i?e=>a(n).some(t=>0!==(t.operation&e)):"draft"===i?()=>r.head(a(n))?.value??he(e(),n):"settled"===i?()=>new Promise(t=>{if(r.isEmpty(a(n)))return t(he(e(),n));const o=()=>{r.isEmpty(a(n))&&(c(o),t(he(e(),n)))};s(o)}):t([...n,String(i)])})}([])}(()=>this.#e,this.#n,this.#t,e=>this.#r.add(e),e=>this.#r.delete(e))}hydrate(e){return this.#o=!0,this.#s(le.Hydrate,()=>e)}produce(e){if(!this.#o)throw new Error("State must be hydrated using hydrate() before calling produce()");return this.#s(le.Produce,e)}#s(e,t){const n=/* @__PURE__ */Symbol("process"),[,r]=pe.immer.produceWithPatches(this.#e,t);return this.#e=r.reduce((t,r)=>pe.immer.applyPatches(t,[{...r,value:ge(e,r,t,n,this.#n,this.#t)}]),this.#e),this.#e=me(this.#e),this.#c(),n}prune(e){this.#n.forEach((t,n)=>{const o=t.filter(t=>t.process!==e);r.isEmpty(o)?this.#n.delete(n):this.#n.set(n,o)}),this.#c()}#c(){this.#r.forEach(e=>e())}observe(e){const t=()=>e(this.#e);return this.#r.add(t),()=>this.#r.delete(t)}}const Pe=t.createContext(/* @__PURE__ */new Map);function Se({action:e,renderer:r}){const o=h(),s=t.useContext(Pe),c=V(),a=t.useMemo(()=>{const t=s.get(e);if(t)return t;const r=new Oe,c=o.getCached(e);n.isNotNullable(c)&&r.hydrate({value:c});const a={state:r,listeners:/* @__PURE__ */new Set};return s.set(e,a),a},[e,o,s]);t.useLayoutEffect(()=>{function t(e){a.state.hydrate({value:e}),a.listeners.forEach(e=>e())}return a.listeners.add(c),o.on(e,t),()=>{a.listeners.delete(c),o.off(e,t)}},[e,o,a]);const i=a.state.model?.value;return n.isNullable(i)?null:r(i,a.state.inspect.value)}function je(e,t){const n=t.split(".");let r=e;for(let o=0;o<n.length-1;o++)r=r[n[o]];return{cursor:r,key:n[n.length-1]}}function Ee(e,t,n){const{cursor:r,key:o}=je(e,t);r[o]=n}function xe(e){return(t,n)=>{t.actions.produce(t=>{Ee(t.model,e,n)})}}function ke(e){return t=>{t.actions.produce(t=>{!function(e,t){const{cursor:n,key:r}=je(e,t);n[r]=!n[r]}(t.model,e)})}}function Ce(e,t){return n=>{n.actions.produce(n=>{Ee(n.model,e,t)})}}function Ne(){const e=t.useRef(null);return t.useMemo(()=>({actions:{dispatch:function(t,n){const r=e.current;if(!r)throw new Error("march-hare: useContext handle dispatched before its paired context.useActions(...) ran. Call context.actions.dispatch from event handlers, not synchronously during render.");return r(t,n)}},useActions:function(...o){const s=function(...e){const o=n.isUndefined(e[0])||n.isFunction(e[0])?{}:e[0],s=n.isFunction(e[0])?e[0]:e[1]??(()=>({})),c=h(),i=t.useContext(Z),u=t.useContext(y),l=g(),d=t.useContext(v),p=t.useContext(_),m=t.useContext(U),b=V(),O=t.useRef(!1),P=t.useRef(null),S=t.useRef(new Oe);O.current||(O.current=!0,P.current=S.current.hydrate(o));const[j,E]=t.useState(()=>S.current.model),C=function(e){const n=t.useRef(e);return n.current=e,t.useMemo(()=>{return t=n,Object.keys(e).reduce((e,n)=>(Object.defineProperty(e,n,{get:()=>t.current[n],enumerable:!0}),e),{});var t},[e])}(s()),N=t.useMemo(()=>new f,[]),A=t.useRef({handlers:/* @__PURE__ */new Map});A.current.handlers=/* @__PURE__ */new Map;const R=function(){const e=t.useRef(/* @__PURE__ */new Set),n=t.useRef(/* @__PURE__ */new Set);return t.useMemo(()=>({broadcast:e.current,multicast:n.current}),[])}(),L=t.useRef(M.Mounting),$=t.useRef(/* @__PURE__ */new Set),T=t.useRef(0),z=t.useCallback((e,t,r)=>{const o=new AbortController,s={controller:o,action:e,payload:t};return u.add(s),$.current.add(s),{model:S.current.model,get phase(){return L.current},task:s,data:C,tasks:u,env:l,actions:{produce(e){if(o.signal.aborted)return;const t=d.current,n=S.current.produce(t=>{d.current=a(d.current,n=>{e({model:t,inspect:S.current.inspect,env:n})})});E(S.current.model),d.current!==t&&c.emit(k,d.current),r.processes.add(n),P.current&&(r.processes.add(P.current),P.current=null)},dispatch(e,t){if(o.signal.aborted)return Promise.resolve();const n=W(e),r=F(e)?e.channel:void 0;return J(e)?i?I(i.emitter,n,t,r):Promise.resolve():I(B(e)?c:N,n,t,r)},annotate:(e,t=ue.Update)=>S.current.annotate(t,e),get inspect(){return S.current.inspect},resource:Object.assign(function(e){const t=(e,t)=>{if(o.signal.aborted)return Promise.resolve();const n=e,r=W(n);return J(n)?i?I(i.emitter,r,t,void 0):Promise.resolve():B(n)?I(c,r,t,void 0):Promise.resolve()},r={exceedsWindow:null,coalesceToken:void 0},s={then:(s,c)=>(()=>{if(n.isNotNullable(r.exceedsWindow)){const{data:t,at:o}=e.read(e.params);if(t!==K&&n.isNotNullable(o)){const e=Temporal.Now.instant().since(o),n=Temporal.Duration.from(r.exceedsWindow);if(Temporal.Duration.compare(e,n)<=0)return Promise.resolve(t)}}if(n.isUndefined(r.coalesceToken))return e.run(l,o,e.params,t);let s=p.get(e.run);n.isUndefined(s)&&(s=/* @__PURE__ */new Map,p.set(e.run,s));const c=s,a=`${JSON.stringify(e.params)}|${function(e){switch(typeof e){case"string":return`s:${e}`;case"number":return`n:${e}`;case"bigint":return`i:${e.toString()}`;case"boolean":return`b:${e}`;case"symbol":return`y:${e.description??String(e)}`;default:return`o:${JSON.stringify(e)}`}}(r.coalesceToken)}`,i=c.get(a);if(i)return ae(i,o.signal);const u=new AbortController,f=e.run(l,u,e.params,t).finally(()=>{c.delete(a)});return c.set(a,f),ae(f,o.signal)})().then(s,c),exceeds:e=>(r.exceedsWindow=e,s),coalesce:e=>(r.coalesceToken=e??ce,s),evict(t){e.evict(t??e.params)}};return s},{nuke:e=>function(e){const t=e??{};for(const n of re)n(t)}(e)}),async final(e){if(o.signal.aborted)return null;const t=W(e),r=J(e)?i?.emitter??null:c;if(!r)return null;const s=r.getCached(t);if(n.isUndefined(s))return null;const a=S.current.inspect;return a.pending()&&await new Promise((e,t)=>{if(o.signal.aborted)return void t(o.signal.reason);const n=()=>t(o.signal.reason);o.signal.addEventListener("abort",n,{once:!0}),a.settled().then(()=>{o.signal.removeEventListener("abort",n),e()})}),r.getCached(t)??null},peek(e){if(o.signal.aborted)return null;const t=W(e),n=J(e)?i?.emitter??null:c;return n?n.getCached(t)??null:null}}}},[j]);t.useLayoutEffect(()=>{function e(e,t,r){return function(o,s){const a=r();if(s===H&&n.isNotNullable(a))return;if(n.isNotNullable(s)&&s!==H&&n.isNotNullable(a)&&!function(e,t){for(const n of Object.keys(e))if(t[n]!==e[n])return!1;return!0}(s,a))return;const l={processes:/* @__PURE__ */new Set},f=Promise.withResolvers(),p=z(e,o,l),h=function(e){const t=W(e),r=n.isString(t)?t:t.description??"";return r.startsWith(w())&&r.slice(r.lastIndexOf("/")+1)||"unknown"}(e),y=performance.now(),v=S.current.model,g=d.current;let O,P=!1;function j(){const e=S.current.model,t=d.current;return{model:v===e?null:{before:v,after:e},env:g===t?null:{before:g,after:t}}}function E(){const t=s===H?void 0:s;return J(e)?i?I(i.emitter,e,o,t):Promise.resolve():I(B(e)?c:N,e,o,t)}function k(e){P=!0;const t=G(A.current.handlers,"Error"),r=n.isNotNullable(t),s=function(e){return e instanceof Error&&"AbortError"===e.name?X.Aborted:X.Errored}(e),a=function(e){return e instanceof Error?e:new Error(String(e))}(e),i={reason:s,error:a,action:h,handled:r,tasks:u,retry:E};c.fire(x,i),r&&t&&N.emit(t,i),m({stage:"end",result:"error",action:{name:h,payload:o},details:{task:p.task,elapsed:performance.now()-y,mutations:j(),error:a,reason:s}})}function C(){for(const e of u)if(e===p.task){u.delete(e),$.current.delete(e);break}l.processes.forEach(e=>S.current.prune(e)),l.processes.size>0&&b(),P||m({stage:"end",result:"success",action:{name:h,payload:o},details:{task:p.task,elapsed:performance.now()-y,mutations:j()}}),f.resolve()}m({stage:"start",action:{name:h,payload:o},details:{task:p.task}});try{O=t(p,o)}catch(M){return k(M),C(),f.promise}return function(e){if(!e||"object"!=typeof e)return!1;const t=Object.prototype.toString.call(e);return"[object Generator]"===t||"[object AsyncGenerator]"===t}(O)?((async()=>{for await(const e of O);})().catch(k).finally(C),f.promise):(Promise.resolve(O).catch(k).finally(C),f.promise)}}T.current++;const t=/* @__PURE__ */new Set;return A.current.handlers.forEach((n,r)=>{for(const{getChannel:o,handler:s}of n){const n=e(r,s,o);if(J(r)){if(i){const e=i.emitter;e.on(r,n),t.add(()=>e.off(r,n))}N.on(r,n),R.multicast.add(r),t.add(()=>N.off(r,n))}else B(r)?(c.on(r,n),N.on(r,n),R.broadcast.add(r),t.add(()=>{c.off(r,n),N.off(r,n)})):(N.on(r,n),t.add(()=>N.off(r,n)))}}),()=>{const e=++T.current,n=new Set(t);queueMicrotask(()=>{if(T.current!==e){for(const e of n)e();return}for(const e of $.current)e.controller.abort(new Y("Component unmounted")),u.delete(e);$.current.clear(),L.current=M.Unmounting;const t=G(A.current.handlers,"Unmount");t&&N.emit(t),L.current=M.Unmounted;for(const e of n)e()})}},[N]),function({unicast:e,broadcast:o,dispatchers:s,scope:c,phase:a,data:i,handlers:u}){const l=t.useRef(null);t.useLayoutEffect(()=>{if(a.current===M.Mounted)return;a.current=M.Mounting;const t=G(u,"Mount");t&&e.emit(t),s.broadcast.forEach(t=>{const r=o.getCached(t);n.isNullable(r)||e.emit(t,r,H)}),c&&s.multicast.forEach(t=>{const r=c.emitter.getCached(t);n.isNullable(r)||e.emit(t,r,H)}),a.current=M.Mounted},[]),t.useLayoutEffect(()=>{if(n.isNotNullable(l.current)){const t=function(e,t){return Object.keys(t).reduce((n,r)=>e[r]!==t[r]?{...n,[r]:t[r]}:n,{})}(l.current,i);if(r.isNotEmpty(Object.keys(t))){const n=G(u,"Update");n&&e.emit(n,t)}}l.current=i},[i,e])}({unicast:N,broadcast:c,dispatchers:R,scope:i,phase:L,data:s(),handlers:A.current.handlers});const D=t.useMemo(()=>({dispatch(e,t){const n=W(e),r=F(e)?e.channel:void 0;return J(e)?i?I(i.emitter,n,t,r):Promise.resolve():I(B(e)?c:N,n,t,r)},get inspect(){return S.current.inspect},stream:(e,n)=>t.createElement(Se,{action:W(e),renderer:n})}),[j,N]),q=t.useMemo(()=>[j,D,C],[j,D,C]);return q.useAction=(e,n)=>{!function(e,n,r){const o=t.useRef(r);t.useLayoutEffect(()=>{o.current=r});const s=t.useRef(n);t.useLayoutEffect(()=>{s.current=n});const c=t.useCallback((e,t)=>o.current(e,t),[]),a=t.useCallback(()=>F(s.current)?s.current.channel:void 0,[]),i=W(n),u=e.current.handlers.get(i)??/* @__PURE__ */new Set;0===u.size&&e.current.handlers.set(i,u),u.add({getChannel:a,handler:c})}(A,e,n)},q.dispatch=q[1].dispatch,q}(...o);return e.current=s.dispatch,s},with:{update:e=>xe(e),invert:e=>ke(e),always:(e,t)=>Ce(e,t)}}),[])}function Me(n){return{Boundary:function({children:n}){const r=t.useMemo(()=>({id:/* @__PURE__ */Symbol("march-hare.scope/instance"),emitter:new d}),[]);/* @__PURE__ */
|
|
7
|
-
return e(
|
|
8
|
-
return
|
|
1
|
+
import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as n from"react";import{G as r,A as o}from"@mobily/ts-belt";import{immerable as s,enablePatches as c,Immer as i,produce as a}from"immer";function u(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var l,f={exports:{}};const d=/* @__PURE__ */u((l||(l=1,function(e){var t=Object.prototype.hasOwnProperty,n="~";function r(){}function o(e,t,n){this.fn=e,this.context=t,this.once=n||!1}function s(e,t,r,s,c){if("function"!=typeof r)throw new TypeError("The listener must be a function");var i=new o(r,s||e,c),a=n?n+t:t;return e._events[a]?e._events[a].fn?e._events[a]=[e._events[a],i]:e._events[a].push(i):(e._events[a]=i,e._eventsCount++),e}function c(e,t){0===--e._eventsCount?e._events=new r:delete e._events[t]}function i(){this._events=new r,this._eventsCount=0}Object.create&&(r.prototype=/* @__PURE__ */Object.create(null),(new r).__proto__||(n=!1)),i.prototype.eventNames=function(){var e,r,o=[];if(0===this._eventsCount)return o;for(r in e=this._events)t.call(e,r)&&o.push(n?r.slice(1):r);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(e)):o},i.prototype.listeners=function(e){var t=this._events[n?n+e:e];if(!t)return[];if(t.fn)return[t.fn];for(var r=0,o=t.length,s=new Array(o);r<o;r++)s[r]=t[r].fn;return s},i.prototype.listenerCount=function(e){var t=this._events[n?n+e:e];return t?t.fn?1:t.length:0},i.prototype.emit=function(e,t,r,o,s,c){var i=n?n+e:e;if(!this._events[i])return!1;var a,u,l=this._events[i],f=arguments.length;if(l.fn){switch(l.once&&this.removeListener(e,l.fn,void 0,!0),f){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,t),!0;case 3:return l.fn.call(l.context,t,r),!0;case 4:return l.fn.call(l.context,t,r,o),!0;case 5:return l.fn.call(l.context,t,r,o,s),!0;case 6:return l.fn.call(l.context,t,r,o,s,c),!0}for(u=1,a=new Array(f-1);u<f;u++)a[u-1]=arguments[u];l.fn.apply(l.context,a)}else{var d,p=l.length;for(u=0;u<p;u++)switch(l[u].once&&this.removeListener(e,l[u].fn,void 0,!0),f){case 1:l[u].fn.call(l[u].context);break;case 2:l[u].fn.call(l[u].context,t);break;case 3:l[u].fn.call(l[u].context,t,r);break;case 4:l[u].fn.call(l[u].context,t,r,o);break;default:if(!a)for(d=1,a=new Array(f-1);d<f;d++)a[d-1]=arguments[d];l[u].fn.apply(l[u].context,a)}}return!0},i.prototype.on=function(e,t,n){return s(this,e,t,n,!1)},i.prototype.once=function(e,t,n){return s(this,e,t,n,!0)},i.prototype.removeListener=function(e,t,r,o){var s=n?n+e:e;if(!this._events[s])return this;if(!t)return c(this,s),this;var i=this._events[s];if(i.fn)i.fn!==t||o&&!i.once||r&&i.context!==r||c(this,s);else{for(var a=0,u=[],l=i.length;a<l;a++)(i[a].fn!==t||o&&!i[a].once||r&&i[a].context!==r)&&u.push(i[a]);u.length?this._events[s]=1===u.length?u[0]:u:c(this,s)}return this},i.prototype.removeAllListeners=function(e){var t;return e?this._events[t=n?n+e:e]&&c(this,t):(this._events=new r,this._eventsCount=0),this},i.prototype.off=i.prototype.removeListener,i.prototype.addListener=i.prototype.on,i.prefixed=n,i.EventEmitter=i,e.exports=i}(f)),f.exports));class p extends d{cache=/* @__PURE__ */new Map;emit(e,...t){return this.cache.set(e,t[0]),super.emit(e,...t)}setCache(e,t){this.cache.set(e,t)}getCached(e){return this.cache.get(e)}fire(e,...t){return super.emit(e,...t)}}const h=n.createContext(new p);function m(){return n.useContext(h)}function y({children:t}){const r=n.useMemo(()=>new p,[]);/* @__PURE__ */
|
|
2
|
+
return e(h.Provider,{value:r,children:t})}const b=n.createContext(/* @__PURE__ */new Set);function v({children:t}){const r=n.useMemo(()=>/* @__PURE__ */new Set,[]);/* @__PURE__ */
|
|
3
|
+
return e(b.Provider,{value:r,children:t})}const g=n.createContext({current:{}});function w(){const e=n.useContext(g);return n.useMemo(()=>new Proxy({},{get:(t,n)=>Reflect.get(e.current,n),has:(t,n)=>n in e.current,ownKeys:()=>Reflect.ownKeys(e.current),getOwnPropertyDescriptor(t,n){const o=Object.getOwnPropertyDescriptor(e.current,n);if(!r.isUndefined(o))return{...o,configurable:!0}},set(){throw new TypeError("Env is read-only outside `context.actions.produce`. Mutate via produce(({ env }) => { env.x = ... }) instead.")}}),[e])}const O=(e="")=>`march-hare.action/${e}`,P=(e="")=>`march-hare.action/broadcast/${e}`,S=(e="")=>`march-hare.action/multicast/${e}`,j=(e="")=>`march-hare.action.lifecycle/${e}`;class x{static Payload=/* @__PURE__ */Symbol("march-hare.brand/Payload");static Broadcast=/* @__PURE__ */Symbol("march-hare.brand/Broadcast");static Multicast=/* @__PURE__ */Symbol("march-hare.brand/Multicast");static Action=/* @__PURE__ */Symbol("march-hare.brand/Action");static Channel=/* @__PURE__ */Symbol("march-hare.brand/Channel");static Name=/* @__PURE__ */Symbol("march-hare.brand/Name");static Lifecycle=/* @__PURE__ */Symbol("march-hare.brand/Lifecycle")}function E(e){const t=/* @__PURE__ */Symbol(`march-hare.action.lifecycle/${e}`),n=function(n){return{[x.Action]:t,[x.Payload]:void 0,[x.Channel]:n,[x.Name]:e,channel:n}};return Object.defineProperty(n,x.Action,{value:t,enumerable:!1}),Object.defineProperty(n,x.Payload,{value:void 0,enumerable:!1}),Object.defineProperty(n,x.Name,{value:e,enumerable:!1}),Object.defineProperty(n,x.Lifecycle,{value:e,enumerable:!1}),n}const k=Symbol(P("Fault")),N=Symbol(P("Env"));class C{static Mount(){return E("Mount")}static Unmount(){return E("Unmount")}static Error(){return E("Error")}static Update(){return E("Update")}static Fault=(()=>{const e={};return Object.defineProperty(e,x.Action,{value:k,enumerable:!1}),Object.defineProperty(e,x.Payload,{value:void 0,enumerable:!1}),Object.defineProperty(e,x.Broadcast,{value:!0,enumerable:!1}),Object.defineProperty(e,x.Name,{value:"Fault",enumerable:!1}),e})();static Env=(()=>{const e={};return Object.defineProperty(e,x.Action,{value:N,enumerable:!1}),Object.defineProperty(e,x.Payload,{value:void 0,enumerable:!1}),Object.defineProperty(e,x.Broadcast,{value:!0,enumerable:!1}),Object.defineProperty(e,x.Name,{value:"Env",enumerable:!1}),e})()}var M=/* @__PURE__ */(e=>(e.Unicast="unicast",e.Broadcast="broadcast",e.Multicast="multicast",e))(M||{}),A=/* @__PURE__ */(e=>(e.Mounting="mounting",e.Mounted="mounted",e.Unmounting="unmounting",e.Unmounted="unmounted",e))(A||{});function _({initial:t,children:o}){const s=n.useRef(t),c=m();return r.isUndefined(c.getCached(N))&&c.setCache(N,s.current),/* @__PURE__ */e(g.Provider,{value:s,children:o})}const U=n.createContext(/* @__PURE__ */new WeakMap);function R({children:t}){const r=n.useMemo(()=>/* @__PURE__ */new WeakMap,[]);/* @__PURE__ */
|
|
4
|
+
return e(U.Provider,{value:r,children:t})}const L=n.createContext(()=>{});function $({tap:t,children:r}){const o=n.useRef(t);n.useLayoutEffect(()=>{o.current=t},[t]);const s=n.useMemo(()=>e=>o.current?.(e),[]);/* @__PURE__ */
|
|
5
|
+
return e(L.Provider,{value:s,children:r})}function T({env:t,tap:n,children:r}){/* @__PURE__ */
|
|
6
|
+
return e(y,{children:/* @__PURE__ */e(_,{initial:t??{},children:/* @__PURE__ */e(v,{children:/* @__PURE__ */e($,{tap:n,children:/* @__PURE__ */e(R,{children:r})})})})})}const W=e=>"symbol"==typeof e;function B(e){return r.isString(e)||W(e)?e:(r.isObject(e)||r.isFunction(e))&&x.Action in e?e[x.Action]:e}function F(e){if(r.isString(e))return e.startsWith(P());if(W(e))return e.description?.startsWith(P())??!1;if(r.isObject(e)||r.isFunction(e)){if(x.Broadcast in e&&e[x.Broadcast])return!0;if(x.Action in e){const t=e[x.Action];return t.description?.startsWith(P())??!1}}return!1}function z(e){return r.isObject(e)&&x.Channel in e&&"channel"in e}function J(e){const t=B(e),n=W(t)?t.description??"":t;return n.startsWith(j())&&n.slice(j().length)||null}function D(e){if(r.isString(e))return e.startsWith(S());if(W(e))return e.description?.startsWith(S())??!1;if(r.isObject(e)||r.isFunction(e)){if(x.Multicast in e&&e[x.Multicast])return!0;if(x.Action in e){const t=e[x.Action];return t.description?.startsWith(S())??!1}}return!1}const H=(e="",t=M.Unicast)=>{const n=t===M.Broadcast?Symbol(P(e)):t===M.Multicast?Symbol(S(e)):Symbol(O(e)),r=function(t){return{[x.Action]:n,[x.Payload]:void 0,[x.Channel]:t,[x.Name]:e,channel:t}};return Object.defineProperty(r,x.Action,{value:n,enumerable:!1}),Object.defineProperty(r,x.Payload,{value:void 0,enumerable:!1}),Object.defineProperty(r,x.Name,{value:e,enumerable:!1}),t===M.Broadcast&&Object.defineProperty(r,x.Broadcast,{value:!0,enumerable:!1}),t===M.Multicast&&Object.defineProperty(r,x.Multicast,{value:!0,enumerable:!1}),r},I=Symbol(((e="")=>`march-hare/replay${e}`)());function G(e,t,...n){e instanceof p&&e.setCache(t,n[0]);const r=e.listeners(t);return 0===r.length?Promise.resolve():Promise.all(r.map(e=>Promise.resolve(e(...n)))).then(()=>{})}function K(e,t){for(const n of e.keys())if(J(n)===t)return n;return null}const V=/* @__PURE__ */Symbol("march-hare.unset");function q(){const[,e]=n.useReducer(e=>e+1,0);return e}function Q(){return{data:V,at:null}}function X(e,t){return{data:e,at:t}}var Y=/* @__PURE__ */(e=>(e[e.Aborted=0]="Aborted",e[e.Errored=1]="Errored",e))(Y||{});class Z extends Error{name="AbortError";constructor(e="Aborted"){super(e)}}const ee=n.createContext(null);function te(e){const t=r.isUndefined(e)?function(){const e=/* @__PURE__ */new Map;return{get:t=>e.get(t)??null,set:(t,n)=>{e.set(t,n)},remove:t=>{e.delete(t)},clear:()=>{e.clear()},keys:()=>e.keys()}}():e,n=e?.key;return{get(e){try{const n=t.get(e);if(r.isNull(n))return Q();const o=JSON.parse(n);return X(o.data,Temporal.Instant.from(o.at))}catch{return Q()}},set(e,n){if(n.data!==V&&!r.isNull(n.at))try{t.set(e,JSON.stringify({data:n.data,at:n.at.toString()}))}catch{return}},remove(e){try{t.remove(e)}catch{return}},clear(){try{t.clear()}catch{return}},keys(){try{return t.keys?.()??[]}catch{return[]}},scope(e){if(r.isUndefined(n)||r.isNullable(e))return"";try{const t=n({env:e});return r.isNullable(t)?"":t}catch{return""}}}}const ne=/* @__PURE__ */new WeakMap,re=/* @__PURE__ */new Map,oe=[];function se(e,t,n,o){const s=r.isNull(n)?"":`${n}:`,c=(e,n)=>{const r=t.scope(e);return`${""===r?"":`${r}:`}${s}${function(e){return JSON.stringify(e)}(n)}`},i=(e,n)=>{const o=t.get(c(n,e));return o.data===V||r.isNull(o.at)?{data:V,at:null}:{data:o.data,at:o.at}},a=(n,r,o,s)=>e({env:n,controller:r,params:o,dispatch:s}).then(e=>(t.set(c(n,o),X(e,Temporal.Now.instant())),e)),u=e=>{const n=o(),r=t.scope(n),c=""===r?s:`${r}:${s}`,i=Object.entries(e);for(const o of[...t.keys()])if(o.startsWith(c))try{const e=JSON.parse(o.slice(c.length));i.every(([t,n])=>e[t]===n)&&t.remove(o)}catch{continue}};function l(e){return{run:a,read:e=>i(e,o()),evict:u,params:e??{}}}return oe.push(u),Object.defineProperty(l,"get",{value:function(e){const{data:t}=i(e??{},o());return t===V?null:t},enumerable:!1}),l}function ce(e,t,n){const o=e,s=n??(()=>{});return r.isUndefined(t)?se(o,function(e){const t=ne.get(e);if(r.isNotNullable(t))return t;const n=te();return ne.set(e,n),n}(o),null,s):se(o,t,function(e){const t=re.get(e);if(r.isNotNullable(t))return t;const n=String(re.size);return re.set(e,n),n}(o),s)}const ie=/* @__PURE__ */Symbol("march-hare.coalesce/default");function ae(e,t){return new Promise((n,r)=>{if(t.aborted)return void r(t.reason);const o=()=>r(t.reason);t.addEventListener("abort",o,{once:!0}),e.then(e=>{t.removeEventListener("abort",o),n(e)},e=>{t.removeEventListener("abort",o),r(e)})})}let ue=(e=21)=>{let t="",n=crypto.getRandomValues(new Uint8Array(e|=0));for(;e--;)t+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[63&n[e]];return t};var le=/* @__PURE__ */(e=>(e[e.Add=1]="Add",e[e.Remove=2]="Remove",e[e.Update=4]="Update",e[e.Move=8]="Move",e[e.Replace=16]="Replace",e[e.Sort=32]="Sort",e[e.Create=64]="Create",e[e.Fetch=128]="Fetch",e[e.Clone=256]="Clone",e[e.Archive=512]="Archive",e[e.Restore=1024]="Restore",e[e.Merge=2048]="Merge",e[e.Reorder=4096]="Reorder",e[e.Sync=8192]="Sync",e[e.Publish=16384]="Publish",e[e.Link=32768]="Link",e[e.Unlink=65536]="Unlink",e[e.Lock=131072]="Lock",e[e.Unlock=262144]="Unlock",e[e.Import=524288]="Import",e[e.Export=1048576]="Export",e[e.Transfer=2097152]="Transfer",e))(le||{}),fe=/* @__PURE__ */(e=>(e[e.Produce=0]="Produce",e[e.Hydrate=1]="Hydrate",e))(fe||{}),de=/* @__PURE__ */(e=>(e.Property="property",e.Process="process",e.Value="value",e.Operation="operation",e))(de||{});class pe{[s]=!0;static keys=new Set(Object.values(de));property=null;process=null;value;operation;constructor(e,t){this.value=e,this.operation=t}assign(e,t){const n=new pe(this.value,this.operation);return n.property=e,n.process=t,n}}class he{static immer=(()=>{c();const e=new i;return e.setAutoFreeze(!1),e})();static tag="κ";static id=ue}function me(e,t){const n="string"==typeof t?""===t?[]:t.split("."):t;let r=e;for(const o of n){if(null==r)return;r=r[o]}return r}function ye(e){if(r.isNullable(e)||ge(e))return e;if(r.isArray(e))return e.map(e=>ye(e));if(r.isObject(e)&&ve(e)){const t=Object.entries(e).map(([e,t])=>[e,ye(t)]);return{...Object.fromEntries(t),[he.tag]:e[he.tag]??he.id()}}return e}function be(e){if(Array.isArray(e))return e.filter(e=>he.tag in e).map(e=>e[he.tag]??"").join(",");const t=e[he.tag];if(t)return t;try{return JSON.stringify(e)}catch{return`[unserializable:${typeof e}]`}}function ve(e){const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}function ge(e){return r.isNullable(e)||r.isString(e)||r.isNumber(e)||r.isBoolean(e)||"symbol"==typeof e||"bigint"==typeof e}function we(e){return r.isObject(e)&&"value"in e&&"inspect"in e}function Oe(e,t,n,o,s,c){return function i(a,u=t.path){if(a instanceof pe){const t=me(n,u.join("."));if(Object.entries(a).filter(([e,t])=>!pe.keys.has(e)&&t instanceof pe).forEach(([e,t])=>i(t,u.concat(e))),ge(a.value)){if(e===fe.Hydrate)return a.value;const i=u.slice(0,-1),l=i.length>0?me(n,i.join(".")):n;return r.isNullable(l)||Pe(l,a,u.at(-1),o,s,c),t??a.value}if(e===fe.Hydrate){const e=ye(i(a.value,u));return Pe(e,a,null,o,s,c),e}const l=t??ye(a.value);return Pe(l,a,null,o,s,c),r.isNullable(t)?l:(i(a.value,u),t)}if(r.isArray(a))return a.map((e,t)=>i(e,u.concat(t)));if(r.isObject(a)&&!ve(a))return a;if(r.isObject(a)){const t=Object.entries(a).map(([e,t])=>[e,i(t,u.concat(e))]),n=Object.fromEntries(t);if(e===fe.Hydrate){const e=ye(n);return Object.entries(a).forEach(([t,n])=>{n instanceof pe&&ge(n.value)&&Pe(e,n,t,o,s,c)}),e}return n}return a}(t.value)}function Pe(e,t,n,r,o,s){const c=s(e),i=o.get(c)??[];o.set(c,[t.assign(n,r),...i])}class Se{#e={};#t;#n=/* @__PURE__ */new Map;#r=/* @__PURE__ */new Set;#o=!1;constructor(e=be){this.#t=e}static pk(){return ue()}static"κ"=Se.pk;annotate(e,t){return new pe(t,e)}"δ"=this.annotate;get model(){return this.#e}get inspect(){return function(e,t,n,s,c){function i(s){const c=s.at(-1),i=me(e(),s),a=s.slice(0,-1),u=o.isNotEmpty(a)?me(e(),a):e();return[...r.isObject(i)||r.isArray(i)?t.get(n(i))?.filter(e=>r.isNullable(e.property))??[]:[],...r.isObject(u)?t.get(n(u))?.filter(e=>e.property===c)??[]:[]]}return function t(n){return new Proxy(()=>{},{get:(r,a)=>"pending"===a?()=>!o.isEmpty(i(n)):"remaining"===a?()=>o.length(i(n)):"box"===a?()=>({value:me(e(),n),inspect:t(n)}):"is"===a?e=>i(n).some(t=>0!==(t.operation&e)):"draft"===a?()=>o.head(i(n))?.value??me(e(),n):"settled"===a?()=>new Promise(t=>{if(o.isEmpty(i(n)))return t(me(e(),n));const r=()=>{o.isEmpty(i(n))&&(c(r),t(me(e(),n)))};s(r)}):t([...n,String(a)])})}([])}(()=>this.#e,this.#n,this.#t,e=>this.#r.add(e),e=>this.#r.delete(e))}hydrate(e){return this.#o=!0,this.#s(fe.Hydrate,()=>e)}produce(e){if(!this.#o)throw new Error("State must be hydrated using hydrate() before calling produce()");return this.#s(fe.Produce,e)}#s(e,t){const n=/* @__PURE__ */Symbol("process"),[,r]=he.immer.produceWithPatches(this.#e,t);return this.#e=r.reduce((t,r)=>he.immer.applyPatches(t,[{...r,value:Oe(e,r,t,n,this.#n,this.#t)}]),this.#e),this.#e=ye(this.#e),this.#c(),n}prune(e){this.#n.forEach((t,n)=>{const r=t.filter(t=>t.process!==e);o.isEmpty(r)?this.#n.delete(n):this.#n.set(n,r)}),this.#c()}#c(){this.#r.forEach(e=>e())}observe(e){const t=()=>e(this.#e);return this.#r.add(t),()=>this.#r.delete(t)}}const je=n.createContext(/* @__PURE__ */new Map);function xe({action:e,renderer:t}){const o=m(),s=n.useContext(je),c=q(),i=n.useMemo(()=>{const t=s.get(e);if(t)return t;const n=new Se,c=o.getCached(e);r.isNotNullable(c)&&n.hydrate({value:c});const i={state:n,listeners:/* @__PURE__ */new Set};return s.set(e,i),i},[e,o,s]);n.useLayoutEffect(()=>{function t(e){i.state.hydrate({value:e}),i.listeners.forEach(e=>e())}return i.listeners.add(c),o.on(e,t),()=>{i.listeners.delete(c),o.off(e,t)}},[e,o,i]);const a=i.state.model?.value;return r.isNullable(a)?null:t(a,i.state.inspect.value)}function Ee(e,t){const n=t.split(".");let r=e;for(let o=0;o<n.length-1;o++)r=r[n[o]];return{cursor:r,key:n[n.length-1]}}function ke(e,t,n){const{cursor:r,key:o}=Ee(e,t);r[o]=n}function Ne(e){return(t,n)=>{t.actions.produce(t=>{ke(t.model,e,n)})}}function Ce(e){return t=>{t.actions.produce(t=>{!function(e,t){const{cursor:n,key:r}=Ee(e,t);n[r]=!n[r]}(t.model,e)})}}function Me(e,t){return n=>{n.actions.produce(n=>{ke(n.model,e,t)})}}function Ae(){const e=n.useRef(null);return n.useMemo(()=>({actions:{dispatch:function(t,n){const r=e.current;if(!r)throw new Error("march-hare: useContext handle dispatched before its paired context.useActions(...) ran. Call context.actions.dispatch from event handlers, not synchronously during render.");return r(t,n)}},useActions:function(...t){const s=function(...e){const t=r.isUndefined(e[0])||r.isFunction(e[0])?{}:e[0],s=r.isFunction(e[0])?e[0]:e[1]??(()=>({})),c=m(),i=n.useContext(ee),u=n.useContext(b),l=w(),f=n.useContext(g),p=n.useContext(U),h=n.useContext(L),y=q(),v=n.useRef(!1),P=n.useRef(null),S=n.useRef(new Se);v.current||(v.current=!0,P.current=S.current.hydrate(t));const[j,x]=n.useState(()=>S.current.model),E=function(e){const t=n.useRef(e);return t.current=e,n.useMemo(()=>{return n=t,Object.keys(e).reduce((e,t)=>(Object.defineProperty(e,t,{get:()=>n.current[t],enumerable:!0}),e),{});var n},[e])}(s()),C=n.useMemo(()=>new d,[]),M=n.useRef({handlers:/* @__PURE__ */new Map});M.current.handlers=/* @__PURE__ */new Map;const _=function(){const e=n.useRef(/* @__PURE__ */new Set),t=n.useRef(/* @__PURE__ */new Set);return n.useMemo(()=>({broadcast:e.current,multicast:t.current}),[])}(),R=n.useRef(A.Mounting),$=n.useRef(/* @__PURE__ */new Set),T=n.useRef(0),W=n.useCallback((e,t,n)=>{const o=new AbortController,s={controller:o,action:e,payload:t};return u.add(s),$.current.add(s),{model:S.current.model,get phase(){return R.current},task:s,data:E,tasks:u,env:l,actions:{produce(e){if(o.signal.aborted)return;const t=f.current,r=S.current.produce(t=>{f.current=a(f.current,n=>{e({model:t,inspect:S.current.inspect,env:n})})});x(S.current.model),f.current!==t&&c.emit(N,f.current),n.processes.add(r),P.current&&(n.processes.add(P.current),P.current=null)},dispatch(e,t){if(o.signal.aborted)return Promise.resolve();const n=B(e),r=z(e)?e.channel:void 0;return D(e)?i?G(i.emitter,n,t,r):Promise.resolve():G(F(e)?c:C,n,t,r)},annotate:(e,t=le.Update)=>S.current.annotate(t,e),get inspect(){return S.current.inspect},resource:Object.assign(function(e){const t=(e,t)=>{if(o.signal.aborted)return Promise.resolve();const n=e,r=B(n);return D(n)?i?G(i.emitter,r,t,void 0):Promise.resolve():F(n)?G(c,r,t,void 0):Promise.resolve()},n={exceedsWindow:null,coalesceToken:void 0},s={then:(s,c)=>(()=>{if(r.isNotNullable(n.exceedsWindow)){const{data:t,at:o}=e.read(e.params);if(t!==V&&r.isNotNullable(o)){const e=Temporal.Now.instant().since(o),r=Temporal.Duration.from(n.exceedsWindow);if(Temporal.Duration.compare(e,r)<=0)return Promise.resolve(t)}}if(r.isUndefined(n.coalesceToken))return e.run(l,o,e.params,t);let s=p.get(e.run);r.isUndefined(s)&&(s=/* @__PURE__ */new Map,p.set(e.run,s));const c=s,i=`${JSON.stringify(e.params)}|${function(e){switch(typeof e){case"string":return`s:${e}`;case"number":return`n:${e}`;case"bigint":return`i:${e.toString()}`;case"boolean":return`b:${e}`;case"symbol":return`y:${e.description??String(e)}`;default:return`o:${JSON.stringify(e)}`}}(n.coalesceToken)}`,a=c.get(i);if(a)return ae(a,o.signal);const u=new AbortController,f=e.run(l,u,e.params,t).finally(()=>{c.delete(i)});return c.set(i,f),ae(f,o.signal)})().then(s,c),exceeds:e=>(n.exceedsWindow=e,s),coalesce:e=>(n.coalesceToken=e??ie,s),evict(t){e.evict(t??e.params)}};return s},{nuke:e=>function(e){const t=e??{};for(const n of oe)n(t)}(e)}),async final(e){if(o.signal.aborted)return null;const t=B(e),n=D(e)?i?.emitter??null:c;if(!n)return null;const s=n.getCached(t);if(r.isUndefined(s))return null;const a=S.current.inspect;return a.pending()&&await new Promise((e,t)=>{if(o.signal.aborted)return void t(o.signal.reason);const n=()=>t(o.signal.reason);o.signal.addEventListener("abort",n,{once:!0}),a.settled().then(()=>{o.signal.removeEventListener("abort",n),e()})}),n.getCached(t)??null},peek(e){if(o.signal.aborted)return null;const t=B(e),n=D(e)?i?.emitter??null:c;return n?n.getCached(t)??null:null}}}},[j]);n.useLayoutEffect(()=>{function e(e,t,n){return function(o,s){const a=n();if(s===I&&r.isNotNullable(a))return;if(r.isNotNullable(s)&&s!==I&&r.isNotNullable(a)&&!function(e,t){for(const n of Object.keys(e))if(t[n]!==e[n])return!1;return!0}(s,a))return;const l={processes:/* @__PURE__ */new Set},d=Promise.withResolvers(),p=W(e,o,l),m=function(e){const t=B(e),n=r.isString(t)?t:t.description??"";return n.startsWith(O())&&n.slice(n.lastIndexOf("/")+1)||"unknown"}(e),b=performance.now(),v=S.current.model,g=f.current;let w,P=!1;function j(){const e=S.current.model,t=f.current;return{model:v===e?null:{before:v,after:e},env:g===t?null:{before:g,after:t}}}function x(){const t=s===I?void 0:s;return D(e)?i?G(i.emitter,e,o,t):Promise.resolve():G(F(e)?c:C,e,o,t)}function E(e){P=!0;const t=K(M.current.handlers,"Error"),n=r.isNotNullable(t),s=function(e){return e instanceof Error&&"AbortError"===e.name?Y.Aborted:Y.Errored}(e),i=function(e){return e instanceof Error?e:new Error(String(e))}(e),a={reason:s,error:i,action:m,handled:n,tasks:u,retry:x};c.fire(k,a),n&&t&&C.emit(t,a),h({stage:"end",result:"error",action:{name:m,payload:o},details:{task:p.task,elapsed:performance.now()-b,mutations:j(),error:i,reason:s}})}function N(){for(const e of u)if(e===p.task){u.delete(e),$.current.delete(e);break}l.processes.forEach(e=>S.current.prune(e)),l.processes.size>0&&y(),P||h({stage:"end",result:"success",action:{name:m,payload:o},details:{task:p.task,elapsed:performance.now()-b,mutations:j()}}),d.resolve()}h({stage:"start",action:{name:m,payload:o},details:{task:p.task}});try{w=t(p,o)}catch(A){return E(A),N(),d.promise}return function(e){if(!e||"object"!=typeof e)return!1;const t=Object.prototype.toString.call(e);return"[object Generator]"===t||"[object AsyncGenerator]"===t}(w)?((async()=>{for await(const e of w);})().catch(E).finally(N),d.promise):(Promise.resolve(w).catch(E).finally(N),d.promise)}}T.current++;const t=/* @__PURE__ */new Set;return M.current.handlers.forEach((n,r)=>{for(const{getChannel:o,handler:s}of n){const n=e(r,s,o);if(D(r)){if(i){const e=i.emitter;e.on(r,n),t.add(()=>e.off(r,n))}C.on(r,n),_.multicast.add(r),t.add(()=>C.off(r,n))}else F(r)?(c.on(r,n),C.on(r,n),_.broadcast.add(r),t.add(()=>{c.off(r,n),C.off(r,n)})):(C.on(r,n),t.add(()=>C.off(r,n)))}}),()=>{const e=++T.current,n=new Set(t);queueMicrotask(()=>{if(T.current!==e){for(const e of n)e();return}for(const e of $.current)e.controller.abort(new Z("Component unmounted")),u.delete(e);$.current.clear(),R.current=A.Unmounting;const t=K(M.current.handlers,"Unmount");t&&C.emit(t),R.current=A.Unmounted;for(const e of n)e()})}},[C]),function({unicast:e,broadcast:t,dispatchers:s,scope:c,phase:i,data:a,handlers:u}){const l=n.useRef(null);n.useLayoutEffect(()=>{if(i.current===A.Mounted)return;i.current=A.Mounting;const n=K(u,"Mount");n&&e.emit(n),s.broadcast.forEach(n=>{const o=t.getCached(n);r.isNullable(o)||e.emit(n,o,I)}),c&&s.multicast.forEach(t=>{const n=c.emitter.getCached(t);r.isNullable(n)||e.emit(t,n,I)}),i.current=A.Mounted},[]),n.useLayoutEffect(()=>{if(r.isNotNullable(l.current)){const t=function(e,t){return Object.keys(t).reduce((n,r)=>e[r]!==t[r]?{...n,[r]:t[r]}:n,{})}(l.current,a);if(o.isNotEmpty(Object.keys(t))){const n=K(u,"Update");n&&e.emit(n,t)}}l.current=a},[a,e])}({unicast:C,broadcast:c,dispatchers:_,scope:i,phase:R,data:s(),handlers:M.current.handlers});const J=n.useMemo(()=>({dispatch(e,t){const n=B(e),r=z(e)?e.channel:void 0;return D(e)?i?G(i.emitter,n,t,r):Promise.resolve():G(F(e)?c:C,n,t,r)},get inspect(){return S.current.inspect},stream:(e,t)=>n.createElement(xe,{action:B(e),renderer:t})}),[j,C]),H=n.useMemo(()=>[j,J,E],[j,J,E]);return H.useAction=(e,t)=>{!function(e,t,r){const o=n.useRef(r);n.useLayoutEffect(()=>{o.current=r});const s=n.useRef(t);n.useLayoutEffect(()=>{s.current=t});const c=n.useCallback((e,t)=>o.current(e,t),[]),i=n.useCallback(()=>z(s.current)?s.current.channel:void 0,[]),a=B(t),u=e.current.handlers.get(a)??/* @__PURE__ */new Set;0===u.size&&e.current.handlers.set(a,u),u.add({getChannel:i,handler:c})}(M,e,t)},H.dispatch=H[1].dispatch,H}(...t);return e.current=s.dispatch,s},with:{update:e=>Ne(e),invert:e=>Ce(e),always:(e,t)=>Me(e,t)}}),[])}function _e(t,r){return{Boundary:function({children:t}){const r=n.useMemo(()=>({id:/* @__PURE__ */Symbol("march-hare.scope/instance"),emitter:new p}),[]);/* @__PURE__ */
|
|
7
|
+
return e(ee.Provider,{value:r,children:t})},useContext:function(){return Ae()},useEnv:function(){return w()},Resource:function(e){return ce(e,t,r)}}}function Ue(n){const r={current:void 0};return{Boundary:function({children:o}){/* @__PURE__ */
|
|
8
|
+
return t(T,{env:n?.env,tap:n?.tap,children:[
|
|
9
|
+
/* @__PURE__ */e(Re,{holder:r}),o]})},useContext:function(){return Ae()},useEnv:function(){return w()},Resource:function(e){return ce(e,n?.cache,()=>r.current)},Scope:()=>_e(n?.cache,()=>r.current)}}function Re({holder:e}){const t=w();return e.current=t,null}const Le={Update:e=>Ne(e),Invert:e=>Ce(e),Always:(e,t)=>Me(e,t)},$e=new Se;function Te(e,t=le.Update){return $e.annotate(t,e)}function We(e,t){return new Promise((n,r)=>{if(t?.aborted)return void r(new Z);const o=setTimeout(n,e);t?.addEventListener("abort",()=>{clearTimeout(o),r(new Z)},{once:!0})})}async function Be(e,t,n){if(t?.aborted)throw new Z;for(;;){if(await n())return;await We(e,t)}}function Fe(e){return e?Boolean(e&&"symbol"!=typeof e):/* @__PURE__ */Symbol(`pk.${Date.now()}.${crypto.randomUUID()}`)}const ze=/* @__PURE__ */Object.freeze(/* @__PURE__ */Object.defineProperty({__proto__:null,pk:Fe,poll:Be,sleep:We,unset:V,"ζ":We,"κ":Fe,"π":Be},Symbol.toStringTag,{value:"Module"})),Je=/* @__PURE__ */Object.freeze(/* @__PURE__ */Object.defineProperty({__proto__:null,Resource:function(e){return ce(e)},Scope:function(){return _e()},useContext:function(){return Ae()},useEnv:function(){return w()}},Symbol.toStringTag,{value:"Module"}));export{Z as Aborted,H as Action,Ue as App,T as Boundary,te as Cache,M as Distribution,C as Lifecycle,le as Op,le as Operation,Y as Reason,Se as State,Le as With,Te as annotate,we as isBox,Je as shared,ze as utils};
|
|
9
10
|
//# sourceMappingURL=march-hare.js.map
|