muya 1.0.2 → 1.0.3

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 CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  # Muya 🌀
3
2
  Welcome to Muya - Making state management a breeze, focused on simplicity and scalability for real-world scenarios.
4
3
 
@@ -6,8 +5,6 @@ Welcome to Muya - Making state management a breeze, focused on simplicity and sc
6
5
  [![Code quality Check](https://github.com/samuelgja/muya/actions/workflows/code-check.yml/badge.svg)](https://github.com/samuelgja/muya/actions/workflows/code-check.yml)
7
6
  [![Build Size](https://img.shields.io/bundlephobia/minzip/muya?label=Bundle%20size)](https://bundlephobia.com/result?p=muya)
8
7
 
9
-
10
-
11
8
  ## 🚀 Features
12
9
  - Easy State Creation: Kickstart your state management with simple and intuitive APIs.
13
10
  - Selectors & Merges: Grab exactly what you need from your state and combine multiple states seamlessly.
@@ -16,7 +13,6 @@ Welcome to Muya - Making state management a breeze, focused on simplicity and sc
16
13
  - TypeScript Ready: Fully typed for maximum developer sanity.
17
14
  - Small Bundle Size: Lightweight and fast, no bloatware here.
18
15
 
19
-
20
16
  ## 📦 Installation
21
17
 
22
18
  ```bash
@@ -58,7 +54,6 @@ function App() {
58
54
  }
59
55
  ```
60
56
 
61
-
62
57
  ### Selecting parts of the state globally
63
58
  ```tsx
64
59
  import { create } from 'muya'
@@ -75,14 +70,14 @@ function App() {
75
70
 
76
71
  ```
77
72
 
78
- ### Merge two states
73
+ ### Merge any states
79
74
  ```typescript
80
- import { create, shallow } from 'muya'
75
+ import { create, shallow, merge } from 'muya'
81
76
 
82
77
  const useName = create(() => 'John')
83
78
  const useAge = create(() => 30)
84
79
 
85
- const useFullName = useName.merge(useAge, (name, age) => ` ${name} and ${age}`, shallow)
80
+ const useFullName = merge([useName, useAge], (name, age) => `${name} and ${age}`)
86
81
 
87
82
  function App() {
88
83
  const fullName = useFullName()
@@ -90,7 +85,6 @@ function App() {
90
85
  }
91
86
  ```
92
87
 
93
-
94
88
  ### Promise based state and lifecycle management working with React Suspense
95
89
  This methods are useful for handling async data fetching and lazy loading via React Suspense.
96
90
 
@@ -126,7 +120,6 @@ function Counter() {
126
120
  }
127
121
  ```
128
122
 
129
-
130
123
  ## 🔍 API Reference
131
124
 
132
125
  ### `create`
@@ -155,14 +148,13 @@ const userAgeState = userState.select((user) => user.age);
155
148
  ```
156
149
 
157
150
  ### `merge`
158
- Merges two states into a single state.
151
+ Merges any number states into a single state.
159
152
  ```typescript
160
153
  const useName = create(() => 'John');
161
154
  const useAge = create(() => 30);
162
- const useFullName = useName.merge(useAge, (name, age) => ` ${name} and ${age}`);
155
+ const useFullName = merge([useName, useAge], (name, age) => `${name} and ${age}`);
163
156
  ```
164
157
 
165
-
166
158
  ### `setState`
167
159
  Sets the state to a new value or a function that returns a new value.
168
160
 
@@ -204,6 +196,100 @@ const userState = create({ name: 'John', age: 30 });
204
196
  const unsubscribe = userState.subscribe((state) => console.log(state));
205
197
  ```
206
198
 
199
+ ### Promise Handling
200
+
201
+ #### Immediate Promise Resolution
202
+
203
+ ```typescript
204
+ import { create } from 'muya';
205
+
206
+ // State will try to resolve the promise immediately, can hit the suspense boundary
207
+ const counterState = create(Promise.resolve(0));
208
+
209
+ function Counter() {
210
+ const counter = counterState();
211
+ return (
212
+ <div onClick={() => counterState.setState((prev) => prev + 1)}>
213
+ {counter}
214
+ </div>
215
+ );
216
+ }
217
+ ```
218
+
219
+ #### Lazy Promise Resolution
220
+
221
+ ```typescript
222
+ import { create } from 'muya';
223
+
224
+ // State will lazy resolve the promise on first access, this will hit the suspense boundary if the first access is from component and via `counterState.getState()` method
225
+ const counterState = create(() => Promise.resolve(0));
226
+
227
+ function Counter() {
228
+ const counter = counterState();
229
+ return (
230
+ <div onClick={() => counterState.setState((prev) => prev + 1)}>
231
+ {counter}
232
+ </div>
233
+ );
234
+ }
235
+ ```
236
+
237
+ #### Promise Rejection Handling
238
+
239
+ ```typescript
240
+ import { create } from 'muya';
241
+
242
+ // State will reject the promise
243
+ const counterState = create(Promise.reject('Error occurred'));
244
+
245
+ function Counter() {
246
+ try {
247
+ const counter = counterState();
248
+ return <div>{counter}</div>;
249
+ } catch (error) {
250
+ return <div>Error: {error}</div>;
251
+ }
252
+ }
253
+ ```
254
+
255
+ #### Error Throwing
256
+
257
+ ```typescript
258
+ import { create } from 'muya';
259
+
260
+ // State will throw an error
261
+ const counterState = create(() => {
262
+ throw new Error('Error occurred');
263
+ });
264
+
265
+ function Counter() {
266
+ try {
267
+ const counter = counterState();
268
+ return <div>{counter}</div>;
269
+ } catch (error) {
270
+ return <div>Error: {error.message}</div>;
271
+ }
272
+ }
273
+ ```
274
+
275
+ #### Setting a state during promise resolution
276
+
277
+ ```typescript
278
+ import { create } from 'muya';
279
+
280
+ // State will resolve the promise and set the state
281
+ const counterState = create(Promise.resolve(0));
282
+ // this will abort current promise and set the state to 10
283
+ counterState.setState(10);
284
+ function Counter() {
285
+ const counter = counterState();
286
+ return (
287
+ <div onClick={() => counterState.setState((prev) => prev + 1)}>
288
+ {counter}
289
+ </div>
290
+ );
291
+ }
292
+ ```
207
293
 
208
294
 
209
295
  ### Access from outside the component
@@ -214,7 +300,6 @@ const user = userState.getState();
214
300
  ```
215
301
  ---
216
302
 
217
-
218
303
  ### Slicing new references
219
304
  :warning: Slicing data with new references can lead to maximum call stack exceeded error.
220
305
  It's recommended to not use new references for the state slices, if you need so, use `shallow` or other custom equality checks.
package/cjs/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var G=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var F=Object.getOwnPropertyNames;var M=Object.prototype.hasOwnProperty;var C=(t,e)=>{for(var r in e)G(t,r,{get:e[r],enumerable:!0})},L=(t,e,r,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of F(e))!M.call(t,n)&&n!==r&&G(t,n,{get:()=>e[n],enumerable:!(a=z(e,n))||a.enumerable});return t};var W=t=>L(G({},"__esModule",{value:!0}),t);var H={};C(H,{StateKeys:()=>_,create:()=>D,getDefaultValue:()=>y,merge:()=>b,select:()=>g,shallow:()=>v,useStateValue:()=>x});module.exports=W(H);function p(t){return t instanceof Promise}function q(t){return typeof t=="function"}function I(t){return typeof t=="function"}function R(t){return typeof t=="object"&&t!==null}function w(t){return t instanceof Map}function k(t){return t instanceof Set}function V(t){return Array.isArray(t)}function c(t,e){return t===e?!0:!!Object.is(t,e)}var _=(r=>(r.IS_STATE="isState",r.IS_SLICE="isSlice",r))(_||{});function y(t){return p(t)?t:q(t)?t():t}function T(t){let e=new Set;return{subscribe:r=>(e.add(r),()=>{e.delete(r)}),emit:(...r)=>{for(let a of e)a(...r)},getSnapshot:t}}var P=require("use-sync-external-store/shim/with-selector"),h=require("react");function O(t){return t}function j(t,e,r){let a=(0,P.useSyncExternalStoreWithSelector)(t.subscribe,t.getSnapshot,t.getSnapshot,e?n=>e(n):O,r);return(0,h.useDebugValue)(a),a}function x(t,e=a=>a,r){let a=j(t.__internal.emitter,n=>e(n),r);if(p(a))throw a;return a}function m(t){let{baseState:e}=t,r=(a,n)=>x(r,a,n);return r.__internal=e.__internal,r.getState=e.getState,r.reset=e.reset,r.select=e.select,r.merge=e.merge,r.subscribe=e.subscribe,r}function b(t,e,r,a=c){let n,o=T(()=>{let f=r(t.getState(),e.getState());return n!==void 0&&a(n,f)?n:(n=f,f)});t.__internal.emitter.subscribe(()=>{o.emit()}),e.__internal.emitter.subscribe(()=>{o.emit()});let s=l({emitter:o,getGetterState:()=>S,getState:()=>r(t.getState(),e.getState()),reset(){t.reset(),e.reset()}}),S=m({baseState:s});return S}function g(t,e,r=c){let a,n=T(()=>{let S=e(t.getState());return a!==void 0&&r(a,S)?a:(a=S,S)});t.__internal.emitter.subscribe(()=>{n.emit()});let o=l({emitter:n,getGetterState:()=>s,getState:()=>e(t.getState()),reset:t.reset}),s=m({baseState:o});return s}function l(t){let{emitter:e,getGetterState:r,reset:a,getState:n}=t;return{getState:n,reset:a,select(o,s){let S=r();return g(S,o,s)},merge(o,s,S){let f=r();return b(f,o,s,S)},__internal:{emitter:e},subscribe(o){return o(n()),e.subscribe(()=>{o(n())})}}}function D(t,e=c){function r(i,u){return I(u)?u(i):u}let a={updateVersion:0,value:void 0};function n(){return a.value===void 0&&(a.value=y(t)),a.value}function o(){let i=n();return p(i)&&i.then(u=>{a.value=u,f.emit()}),i}function s(i){let u=n(),E=r(u,i);e?.(u,E)||E===u||(a.updateVersion++,a.value=E,f.emit())}function S(i){if(R(i))return s(u=>({...u,...i}));s(i)}let f=T(o),U=l({emitter:f,getGetterState:()=>d,getState:o,reset(){let i=y(t);if(p(i)){i.then(u=>{s(u)});return}s(i)}}),d=m({baseState:U});return d.setState=s,d.updateState=S,d}function v(t,e){if(t==e||Object.is(t,e))return!0;if(typeof t!="object"||t==null||typeof e!="object"||e==null)return!1;if(w(t)&&w(e)){if(t.size!==e.size)return!1;for(let[n,o]of t)if(!Object.is(o,e.get(n)))return!1;return!0}if(k(t)&&k(e)){if(t.size!==e.size)return!1;for(let n of t)if(!e.has(n))return!1;return!0}if(V(t)&&V(e)){if(t.length!==e.length)return!1;for(let[n,o]of t.entries())if(!Object.is(o,e[n]))return!1;return!0}let r=Object.keys(t),a=Object.keys(e);if(r.length!==a.length)return!1;for(let n of r)if(!Object.prototype.hasOwnProperty.call(e,n)||!Object.is(t[n],e[n]))return!1;return!0}
1
+ "use strict";var w=Object.defineProperty;var F=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var W=Object.prototype.hasOwnProperty;var B=(t,e)=>{for(var n in e)w(t,n,{get:e[n],enumerable:!0})},H=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of L(e))!W.call(t,o)&&o!==n&&w(t,o,{get:()=>e[o],enumerable:!(r=F(e,o))||r.enumerable});return t};var J=t=>H(w({},"__esModule",{value:!0}),t);var K={};B(K,{StateKeys:()=>v,create:()=>M,getDefaultValue:()=>y,merge:()=>A,select:()=>g,shallow:()=>U,useStateValue:()=>E});module.exports=J(K);var q=require("use-sync-external-store/shim/with-selector"),I=require("react");function O(t){return t}function R(t,e,n){let r=(0,q.useSyncExternalStoreWithSelector)(t.subscribe,t.getSnapshot,t.getSnapshot,e?o=>e(o):O,n);return(0,I.useDebugValue)(r),r}function k(t,e){e&&e.abort();let n=new AbortController,{signal:r}=n;return{promise:new Promise((a,s)=>{r.addEventListener("abort",()=>{s(new DOMException("Promise was aborted","StateAbortError"))}),t.then(a).catch(s)}),controller:n}}function p(t){return t instanceof Promise}function D(t){return typeof t=="function"}function _(t){return typeof t=="function"}function j(t){return typeof t=="object"&&t!==null}function G(t){return t instanceof Map}function V(t){return t instanceof Set}function h(t){return Array.isArray(t)}function l(t,e){return t===e?!0:!!Object.is(t,e)}function P(t){return t instanceof DOMException&&t.name==="StateAbortError"}function C(t){return t instanceof Error&&t.name!=="StateAbortError"}var v=(n=>(n.IS_STATE="isState",n.IS_SLICE="isSlice",n))(v||{});function y(t){return p(t)?t:D(t)?t():t}function m(t){let e=new Set;return{subscribe:n=>(e.add(n),()=>{e.delete(n)}),emit:(...n)=>{for(let r of e)r(...n)},getSnapshot:t}}function E(t,e=r=>r,n){let r=R(t.__internal.emitter,o=>e(o),n);if(p(r)||C(r))throw r;return r}function T(t){let{baseState:e}=t,n=(r,o)=>E(n,r,o);return n.__internal=e.__internal,n.getState=e.getState,n.reset=e.reset,n.select=e.select,n.subscribe=e.subscribe,n}function g(t,e,n=l){let r,o=m(()=>{let i=e(t.getState());return r!==void 0&&n(r,i)?r:(r=i,i)});t.__internal.emitter.subscribe(()=>{o.emit()});let a=d({emitter:o,getGetterState:()=>s,getState:()=>e(t.getState()),reset:t.reset}),s=T({baseState:a});return s}function d(t){let{emitter:e,getGetterState:n,reset:r,getState:o}=t;return{getState:o,reset:r,select(a,s){let i=n();return g(i,a,s)},__internal:{emitter:e},subscribe(a){return a(o()),e.subscribe(()=>{a(o())})}}}function M(t,e=l){function n(u,S){return _(S)?S(u):S}let r={updateVersion:0,value:void 0};function o(){return r.value===void 0&&(r.value=y(t)),r.value}function a(){let u=o();if(p(u)){let{controller:S,promise:f}=k(u,r.abortController);r.abortController=S,f.then(c=>{r.value=c,b.emit()}).catch(c=>{P(c)||(r.value=new Error(c))})}return u}function s(u){let S=o();r.abortController&&(r.abortController.abort(),r.abortController=void 0);let f=n(S,u);e?.(S,f)||f===S||(r.updateVersion++,r.value=f,b.emit())}function i(u){if(j(u))return s(S=>({...S,...u}));s(u)}let b=m(a),z=d({emitter:b,getGetterState:()=>x,getState:a,reset(){let u=y(t);if(p(u)){let{controller:S,promise:f}=k(u,r.abortController);r.abortController=S,f.then(c=>{s(c)}).catch(c=>{P(c)||(r.value=new Error(c))});return}s(u)}}),x=T({baseState:z});return x.setState=s,x.updateState=i,x}function A(t,e,n=l){let r,o=m(()=>{let i=e(...t.map(b=>b.getState()));return r!==void 0&&n(r,i)?r:(r=i,i)});for(let i of t)i.__internal.emitter.subscribe(()=>{o.emit()});let a=d({emitter:o,getGetterState:()=>s,getState:()=>e(...t.map(i=>i.getState())),reset(){for(let i of t)i.reset()}}),s=T({baseState:a});return s}function U(t,e){if(t==e)return!0;if(typeof t!="object"||t==null||typeof e!="object"||e==null)return!1;if(G(t)&&G(e)){if(t.size!==e.size)return!1;for(let[o,a]of t)if(!Object.is(a,e.get(o)))return!1;return!0}if(V(t)&&V(e)){if(t.size!==e.size)return!1;for(let o of t)if(!e.has(o))return!1;return!0}if(h(t)&&h(e)){if(t.length!==e.length)return!1;for(let[o,a]of t.entries())if(!Object.is(a,e[o]))return!1;return!0}let n=Object.keys(t),r=Object.keys(e);if(n.length!==r.length)return!1;for(let o of n)if(!Object.prototype.hasOwnProperty.call(e,o)||!Object.is(t[o],e[o]))return!1;return!0}
@@ -0,0 +1 @@
1
+ import{cancelablePromise as l,toType as m,useSyncExternalStore as r}from"../common";import{renderHook as s}from"@testing-library/react-hooks";import{createEmitter as n}from"../create-emitter";import{longPromise as i}from"./test-utils";describe("toType",()=>{it("should cast object to specified type",()=>{const t=m({a:1});expect(t.a).toBe(1)})}),describe("useSyncExternalStore",()=>{it("should return the initial state value",()=>{const e=n(()=>0),{result:t}=s(()=>r(e,o=>o));expect(t.current).toBe(0)}),it("should update when the state value changes",()=>{let e=0;const t=n(()=>e),{result:o}=s(()=>r(t,c=>c));e=1,t.emit(),expect(o.current).toBe(1)}),it("should use the selector function",()=>{let e=0;const t=n(()=>({count:e})),{result:o}=s(()=>r(t,c=>c.count));e=1,t.emit(),expect(o.current).toBe(1)}),it("should use the isEqual function",()=>{let e=0;const t=n(()=>({count:e})),o=jest.fn((u,a)=>u===a),{result:c}=s(()=>r(t,u=>u.count,o));e=1,t.emit(),expect(c.current).toBe(1),expect(o).toHaveBeenCalled()}),it("should test cancelable promise to abort",async()=>{const{promise:e,controller:t}=l(i(1e6));t.abort(),expect(e).rejects.toThrow("aborted")}),it("should test cancelable promise to resolve",async()=>{const{promise:e}=l(i(0));expect(await e).toBe(0)})});
@@ -0,0 +1 @@
1
+ import{Abort as l}from"../common";import{isPromise as e,isFunction as r,isSetValueFunction as t,isObject as o,isRef as s,isMap as u,isSet as i,isArray as n,isEqualBase as a,isAbortError as f}from"../is";describe("isPromise",()=>{it("should return true for a Promise",()=>{expect(e(Promise.resolve())).toBe(!0)}),it("should return false for a non-Promise",()=>{expect(e(123)).toBe(!1)})}),describe("isFunction",()=>{it("should return true for a function",()=>{expect(r(()=>{})).toBe(!0)}),it("should return false for a non-function",()=>{expect(r(123)).toBe(!1)})}),describe("isSetValueFunction",()=>{it("should return true for a function",()=>{expect(t(()=>{})).toBe(!0)}),it("should return false for a non-function",()=>{expect(t(123)).toBe(!1)})}),describe("isObject",()=>{it("should return true for an object",()=>{expect(o({})).toBe(!0)}),it("should return false for a non-object",()=>{expect(o(123)).toBe(!1)})}),describe("isRef",()=>{it("should return true for a ref object",()=>{expect(s({isRef:!0})).toBe(!0)}),it("should return false for a non-ref object",()=>{expect(s({})).toBe(!1)})}),describe("isMap",()=>{it("should return true for a Map",()=>{expect(u(new Map)).toBe(!0)}),it("should return false for a non-Map",()=>{expect(u(123)).toBe(!1)})}),describe("isSet",()=>{it("should return true for a Set",()=>{expect(i(new Set)).toBe(!0)}),it("should return false for a non-Set",()=>{expect(i(123)).toBe(!1)})}),describe("isArray",()=>{it("should return true for an array",()=>{expect(n([])).toBe(!0)}),it("should return false for a non-array",()=>{expect(n(123)).toBe(!1)})}),describe("isEqualBase",()=>{it("should return true for equal values",()=>{expect(a(1,1)).toBe(!0)}),it("should return false for non-equal values",()=>{expect(a(1,2)).toBe(!1)})}),describe("isAbortError",()=>{it("should return true for an AbortError",()=>{expect(f(new DOMException("",l.Error))).toBe(!0)}),it("should return false for a non-AbortError",()=>{expect(f(new DOMException("","Error"))).toBe(!1)})});
@@ -0,0 +1 @@
1
+ import{create as t}from"../create";import{renderHook as i,act as x}from"@testing-library/react";import{merge as a}from"../merge";describe("merge",()=>{it("should test merge multiple-state",()=>{const o=t(1),c=t(1),n=t(3),u=a([o,c,n],(s,e,r)=>(expect(s).toBe(1),expect(e).toBe(1),expect(r).toBe(3),`${s} ${e} ${r}`)),p=i(()=>u());expect(p.result.current).toBe("1 1 3")}),it("should test merge multiple-state with isEqual",()=>{const o=t(1),c=t(1),n=t(3),u=a([o,c,n],(s,e,r)=>(expect(s).toBe(1),expect(e).toBe(1),expect(r).toBe(3),`${s} ${e} ${r}`),(s,e)=>s===e),p=i(()=>u());expect(p.result.current).toBe("1 1 3")}),it("should test merge multiple-state with different type",()=>{const o=t(1),c=t("1"),n=t({value:3}),u=t([1,2,3]),p=a([o,c,n,u],(e,r,l,m)=>(expect(e).toBe(1),expect(r).toBe("1"),expect(l).toStrictEqual({value:3}),expect(m).toStrictEqual([1,2,3]),`${e} ${r} ${l.value} ${m.join(" ")}`)),s=i(()=>p());expect(s.result.current).toBe("1 1 3 1 2 3")}),it("should test merge with reset",()=>{const o=t(1),c=t(1),n=t(3),u=a([o,c,n],(s,e,r)=>`${s} ${e} ${r}`),p=i(()=>u());x(()=>{o.setState(2),c.setState(2),n.setState(4)}),expect(p.result.current).toBe("2 2 4"),x(()=>{u.reset()}),expect(p.result.current).toBe("1 1 3")})});
@@ -0,0 +1 @@
1
+ import{shallow as t}from"../shallow";describe("shallow",()=>{it("should return true for identical primitive values",()=>{expect(t(1,1)).toBe(!0),expect(t("a","a")).toBe(!0),expect(t(!0,!0)).toBe(!0)}),it("should return false for different primitive values",()=>{expect(t(1,2)).toBe(!1),expect(t("a","b")).toBe(!1),expect(t(!0,!1)).toBe(!1)}),it("should return true for identical objects",()=>{const e={a:1};expect(t(e,e)).toBe(!0)}),it("should return false for different objects with diff properties",()=>{expect(t({a:1},{a:2})).toBe(!1)}),it("should return true for identical arrays",()=>{const e=[1,2,3];expect(t(e,e)).toBe(!0)}),it("should return true for different arrays with same elements",()=>{expect(t([1,2,3],[1,2,3])).toBe(!0)}),it("should return true for identical Maps",()=>{const e=new Map([["a",1]]);expect(t(e,e)).toBe(!0)}),it("should return true for different Maps with same entries",()=>{expect(t(new Map([["a",1]]),new Map([["a",1]]))).toBe(!0)}),it("should return true for identical Sets",()=>{const e=new Set([1,2,3]);expect(t(e,e)).toBe(!0)}),it("should return true for different Sets with same elements",()=>{expect(t(new Set([1,2,3]),new Set([1,2,3]))).toBe(!0)}),it("should return true for objects with same reference",()=>{const e={a:1};expect(t(e,e)).toBe(!0)}),it("should return true for objects with different references",()=>{expect(t({a:1},{a:1})).toBe(!0)}),it("should return true for arrays with same reference",()=>{const e=[1,2,3];expect(t(e,e)).toBe(!0)}),it("should return true for arrays with different references",()=>{expect(t([1,2,3],[1,2,3])).toBe(!0)}),it("should return true for Maps with same reference",()=>{const e=new Map([["a",1]]);expect(t(e,e)).toBe(!0)}),it("should return true for Maps with different references",()=>{expect(t(new Map([["a",1]]),new Map([["a",1]]))).toBe(!0)}),it("should return true for Sets with same reference",()=>{const e=new Set([1,2,3]);expect(t(e,e)).toBe(!0)}),it("should return true for Sets with different references",()=>{expect(t(new Set([1,2,3]),new Set([1,2,3]))).toBe(!0)}),it("should return true for objects with same keys and values",()=>{const e={a:1,b:2},r={a:1,b:2};expect(t(e,r)).toBe(!0)}),it("should return false for objects with different keys or values",()=>{const e={a:1,b:2},r={a:1,b:3};expect(t(e,r)).toBe(!1)}),it("should return true for arrays with same elements",()=>{const e=[1,2,3],r=[1,2,3];expect(t(e,r)).toBe(!0)}),it("should return false for arrays with different elements",()=>{const e=[1,2,3],r=[1,2,4];expect(t(e,r)).toBe(!1)}),it("should return true for Maps with same entries",()=>{const e=new Map([["a",1],["b",2]]),r=new Map([["a",1],["b",2]]);expect(t(e,r)).toBe(!0)}),it("should return false for Maps with different entries",()=>{const e=new Map([["a",1],["b",2]]),r=new Map([["a",1],["b",3]]);expect(t(e,r)).toBe(!1)}),it("should return true for Sets with same elements",()=>{const e=new Set([1,2,3]),r=new Set([1,2,3]);expect(t(e,r)).toBe(!0)}),it("should return false for Sets with different elements",()=>{const e=new Set([1,2,3]),r=new Set([1,2,4]);expect(t(e,r)).toBe(!1)}),it("should return false for different objects with same properties",()=>{expect(t({a:1},{a:2})).toBe(!1)}),it("should return false for different arrays with same elements",()=>{expect(t([1,2,3],[1,2,4])).toBe(!1)}),it("should return false for different Maps with same entries",()=>{expect(t(new Map([["a",1]]),new Map([["a",2]]))).toBe(!1)}),it("should return false for different Sets with same elements",()=>{expect(t(new Set([1,2,3]),new Set([1,2,4]))).toBe(!1)}),it("should return false for objects with different reference",()=>{expect(t({a:1},{a:2})).toBe(!1)}),it("should return false for arrays with different reference",()=>{expect(t([1,2,3],[1,2,4])).toBe(!1)}),it("should return false for Maps with different reference",()=>{expect(t(new Map([["a",1]]),new Map([["a",2]]))).toBe(!1)}),it("should return false for Sets with different reference",()=>{expect(t(new Set([1,2,3]),new Set([1,2,4]))).toBe(!1)}),it("should return false for objects with different keys or values in",()=>{const e={a:1,b:2},r={a:1,b:3};expect(t(e,r)).toBe(!1)}),it("should return false for arrays with different elements",()=>{const e=[1,2,3],r=[1,2,4];expect(t(e,r)).toBe(!1)}),it("should return false for Maps with different entries",()=>{const e=new Map([["a",1],["b",2]]),r=new Map([["a",1],["b",3]]);expect(t(e,r)).toBe(!1)}),it("should return false for Sets with different elements",()=>{const e=new Set([1,2,3]),r=new Set([1,2,4]);expect(t(e,r)).toBe(!1)}),it("should return false for objects with different keys or values",()=>{const e={a:1,b:2},r={a:1,b:3};expect(t(e,r)).toBe(!1)}),it("should return false for arrays with different elements",()=>{const e=[1,2,3],r=[1,2,4];expect(t(e,r)).toBe(!1)}),it("should return false for Maps with different entries",()=>{const e=new Map([["a",1],["b",2]]),r=new Map([["a",1],["b",3]]);expect(t(e,r)).toBe(!1)}),it("should return false for Sets with different elements",()=>{const e=new Set([1,2,3]),r=new Set([1,2,4]);expect(t(e,r)).toBe(!1)}),it("should return false for objects with different keys or values",()=>{const e={a:1,b:2},r={a:1,b:3};expect(t(e,r)).toBe(!1)}),it("should return false for arrays with different elements",()=>{const e=[1,2,3],r=[1,2,4];expect(t(e,r)).toBe(!1)}),it("should return false for Maps with different entries",()=>{const e=new Map([["a",1],["b",2]]),r=new Map([["a",1],["b",3]]);expect(t(e,r)).toBe(!1)}),it("should return false for Sets with different elements",()=>{const e=new Set([1,2,3]),r=new Set([1,2,4]);expect(t(e,r)).toBe(!1)}),it("should return false for objects with different keys or values",()=>{const e={a:1,b:2},r={a:1,b:3};expect(t(e,r)).toBe(!1)}),it("should return false for arrays with different elements",()=>{const e=[1,2,3],r=[1,2,4];expect(t(e,r)).toBe(!1)}),it("should return false for Maps with different entries",()=>{const e=new Map([["a",1],["b",2]]),r=new Map([["a",1],["b",3]]);expect(t(e,r)).toBe(!1)}),it("should return false for Sets with different elements",()=>{const e=new Set([1,2,3]),r=new Set([1,2,4]);expect(t(e,r)).toBe(!1)}),it("should return false for objects with different keys or values",()=>{const e={a:1,b:2},r={a:1,b:3};expect(t(e,r)).toBe(!1)}),it("should return false for arrays with different elements",()=>{const e=[1,2,3],r=[1,2,4];expect(t(e,r)).toBe(!1)}),it("should return false for Maps with different entries",()=>{const e=new Map([["a",1],["b",2]]),r=new Map([["a",1],["b",3]]);expect(t(e,r)).toBe(!1)}),it("should return false for Sets with different elements",()=>{const e=new Set([1,2,3]),r=new Set([1,2,4]);expect(t(e,r)).toBe(!1)}),it("should return false for objects with different keys or values",()=>{const e={a:1,b:2},r={a:1,b:3};expect(t(e,r)).toBe(!1)}),it("should return false for arrays with different elements",()=>{const e=[1,2,3],r=[1,2,4];expect(t(e,r)).toBe(!1)}),it("should return false for Maps with different entries",()=>{const e=new Map([["a",1],["b",2]]),r=new Map([["a",1],["b",3]]);expect(t(e,r)).toBe(!1)}),it("should return false for Sets with different elements",()=>{const e=new Set([1,2,3]),r=new Set([1,2,4]);expect(t(e,r)).toBe(!1)}),it("should return false for null and non-null values",()=>{expect(t(null,{})).toBe(!1),expect(t({},null)).toBe(!1)}),it("should return false for objects with different number of keys",()=>{expect(t({a:1},{a:1,b:2})).toBe(!1)}),it("should return false for objects with different keys",()=>{expect(t({a:1},{b:1})).toBe(!1)}),it("should return false for objects with different values",()=>{expect(t({a:1},{a:2})).toBe(!1)}),it("should return false for arrays with different lengths",()=>{expect(t([1,2],[1,2,3])).toBe(!1)}),it("should return false for arrays with different elements",()=>{expect(t([1,2,3],[1,2,4])).toBe(!1)}),it("should return false for Maps with different sizes",()=>{expect(t(new Map([["a",1]]),new Map([["a",1],["b",2]]))).toBe(!1)}),it("should return false for Maps with different keys",()=>{expect(t(new Map([["a",1]]),new Map([["b",1]]))).toBe(!1)}),it("should return false for Maps with different values",()=>{expect(t(new Map([["a",1]]),new Map([["a",2]]))).toBe(!1)}),it("should return false for Sets with different sizes",()=>{expect(t(new Set([1,2]),new Set([1,2,3]))).toBe(!1)}),it("should return false for Sets with different elements",()=>{expect(t(new Set([1,2,3]),new Set([1,2,4]))).toBe(!1)}),it("should return true compare simple values",()=>{expect(t(1,1)).toBe(!0),expect(t("a","a")).toBe(!0),expect(t(!0,!0)).toBe(!0)})});
@@ -0,0 +1 @@
1
+ import{Component as t}from"react";function n(e=200){return new Promise(r=>{setTimeout(()=>{r(0)},e)})}class c extends t{constructor(r){super(r),this.state={hasError:!1,error:null}}static getDerivedStateFromError(r){return{hasError:!0,error:r}}componentDidCatch(r,o){console.error("ErrorBoundary caught an error:",r,o)}render(){return this.state.hasError?this.props.fallback:this.props.children}}export{c as ErrorBoundary,n as longPromise};
@@ -0,0 +1 @@
1
+ import{getDefaultValue as t}from"../types";describe("getDefaultValue",()=>{it("should return the value if it is not a function or promise",()=>{expect(t(123)).toBe(123)}),it("should return the resolved value if it is a function",()=>{expect(t(()=>123)).toBe(123)}),it("should return the promise if it is a promise",()=>{const e=Promise.resolve(123);expect(t(e)).toBe(e),expect(t(()=>e)).toBe(e)})});
package/esm/common.js CHANGED
@@ -1 +1 @@
1
- import{useSyncExternalStoreWithSelector as u}from"use-sync-external-store/shim/with-selector";import{useDebugValue as s}from"react";function S(e){return e}function i(e,t,r){const n=u(e.subscribe,e.getSnapshot,e.getSnapshot,t?o=>t(o):S,r);return s(n),n}export{S as toType,i as useSyncExternalStore};
1
+ import{useSyncExternalStoreWithSelector as c}from"use-sync-external-store/shim/with-selector";import{useDebugValue as i}from"react";function l(e){return e}function p(e,r,t){const o=c(e.subscribe,e.getSnapshot,e.getSnapshot,r?n=>r(n):l,t);return i(o),o}var u=(r=>(r.Error="StateAbortError",r))(u||{});function T(e,r){r&&r.abort();const t=new AbortController,{signal:o}=t;return{promise:new Promise((a,s)=>{o.addEventListener("abort",()=>{s(new DOMException("Promise was aborted","StateAbortError"))}),e.then(a).catch(s)}),controller:t}}export{u as Abort,T as cancelablePromise,l as toType,p as useSyncExternalStore};
@@ -1 +1 @@
1
- import{merge as c}from"./merge";import{select as p}from"./select";function y(n){const{emitter:o,getGetterState:s,reset:i,getState:e}=n;return{getState:e,reset:i,select(t,r){const a=s();return p(a,t,r)},merge(t,r,a){const m=s();return c(m,t,r,a)},__internal:{emitter:o},subscribe(t){return t(e()),o.subscribe(()=>{t(e())})}}}export{y as createBaseState};
1
+ import{select as m}from"./select";function p(a){const{emitter:r,getGetterState:o,reset:s,getState:e}=a;return{getState:e,reset:s,select(t,i){const n=o();return m(n,t,i)},__internal:{emitter:r},subscribe(t){return t(e()),r.subscribe(()=>{t(e())})}}}export{p as createBaseState};
@@ -1 +1 @@
1
- import{useStateValue as n}from"./use-state-value";function i(r){const{baseState:t}=r,e=(a,s)=>n(e,a,s);return e.__internal=t.__internal,e.getState=t.getState,e.reset=t.reset,e.select=t.select,e.merge=t.merge,e.subscribe=t.subscribe,e}export{i as createGetterState};
1
+ import{useStateValue as n}from"./use-state-value";function i(a){const{baseState:e}=a,t=(r,s)=>n(t,r,s);return t.__internal=e.__internal,t.getState=e.getState,t.reset=e.reset,t.select=e.select,t.subscribe=e.subscribe,t}export{i as createGetterState};
package/esm/create.js CHANGED
@@ -1 +1 @@
1
- import{createEmitter as d}from"./create-emitter";import{getDefaultValue as S}from"./types";import{isEqualBase as V,isObject as v,isPromise as c,isSetValueFunction as g}from"./is";import{createBaseState as D}from"./create-base-state";import{createGetterState as E}from"./create-getter-state";function y(s,f=V){function T(t,e){return g(e)?e(t):e}const a={updateVersion:0,value:void 0};function o(){return a.value===void 0&&(a.value=S(s)),a.value}function l(){const t=o();return c(t)&&t.then(e=>{a.value=e,n.emit()}),t}function r(t){const e=o(),i=T(e,t);f?.(e,i)||i===e||(a.updateVersion++,a.value=i,n.emit())}function m(t){if(v(t))return r(e=>({...e,...t}));r(t)}const n=d(l),p=D({emitter:n,getGetterState:()=>u,getState:l,reset(){const t=S(s);if(c(t)){t.then(e=>{r(e)});return}r(t)}}),u=E({baseState:p});return u.setState=r,u.updateState=m,u}export{y as create};
1
+ import{createEmitter as v}from"./create-emitter";import{getDefaultValue as S}from"./types";import{isAbortError as f,isEqualBase as E,isObject as g,isPromise as T,isSetValueFunction as C}from"./is";import{createBaseState as D}from"./create-base-state";import{createGetterState as w}from"./create-getter-state";import{cancelablePromise as m}from"./common";function P(i,p=E){function d(e,r){return C(r)?r(e):r}const t={updateVersion:0,value:void 0};function s(){return t.value===void 0&&(t.value=S(i)),t.value}function c(){const e=s();if(T(e)){const{controller:r,promise:o}=m(e,t.abortController);t.abortController=r,o.then(a=>{t.value=a,l.emit()}).catch(a=>{f(a)||(t.value=new Error(a))})}return e}function n(e){const r=s();t.abortController&&(t.abortController.abort(),t.abortController=void 0);const o=d(r,e);p?.(r,o)||o===r||(t.updateVersion++,t.value=o,l.emit())}function b(e){if(g(e))return n(r=>({...r,...e}));n(e)}const l=v(c),V=D({emitter:l,getGetterState:()=>u,getState:c,reset(){const e=S(i);if(T(e)){const{controller:r,promise:o}=m(e,t.abortController);t.abortController=r,o.then(a=>{n(a)}).catch(a=>{f(a)||(t.value=new Error(a))});return}n(e)}}),u=w({baseState:V});return u.setState=n,u.updateState=b,u}export{P as create};
package/esm/is.js CHANGED
@@ -1 +1 @@
1
- function o(n){return n instanceof Promise}function r(n){return typeof n=="function"}function u(n){return typeof n=="function"}function t(n){return typeof n=="object"&&n!==null}function i(n){return t(n)&&n.isRef===!0}function s(n){return n instanceof Map}function f(n){return n instanceof Set}function a(n){return Array.isArray(n)}function c(n,e){return n===e?!0:!!Object.is(n,e)}export{a as isArray,c as isEqualBase,r as isFunction,s as isMap,t as isObject,o as isPromise,i as isRef,f as isSet,u as isSetValueFunction};
1
+ import{Abort as o}from"./common";function u(n){return n instanceof Promise}function i(n){return typeof n=="function"}function s(n){return typeof n=="function"}function t(n){return typeof n=="object"&&n!==null}function f(n){return t(n)&&n.isRef===!0}function c(n){return n instanceof Map}function a(n){return n instanceof Set}function p(n){return Array.isArray(n)}function k(n,r){return n===r?!0:!!Object.is(n,r)}function w(n){return n instanceof DOMException&&n.name===o.Error}function x(n){return n instanceof Error&&n.name!==o.Error}export{w as isAbortError,x as isAnyOtherError,p as isArray,k as isEqualBase,i as isFunction,c as isMap,t as isObject,u as isPromise,f as isRef,a as isSet,s as isSetValueFunction};
package/esm/merge.js CHANGED
@@ -1 +1 @@
1
- import{createBaseState as u}from"./create-base-state";import{createEmitter as s}from"./create-emitter";import{createGetterState as c}from"./create-getter-state";import{isEqualBase as f}from"./is";function T(t,e,i,n=f){let r;const a=s(()=>{const S=i(t.getState(),e.getState());return r!==void 0&&n(r,S)?r:(r=S,S)});t.__internal.emitter.subscribe(()=>{a.emit()}),e.__internal.emitter.subscribe(()=>{a.emit()});const o=u({emitter:a,getGetterState:()=>m,getState:()=>i(t.getState(),e.getState()),reset(){t.reset(),e.reset()}}),m=c({baseState:o});return m}export{T as merge};
1
+ import{createBaseState as s}from"./create-base-state";import{createEmitter as f}from"./create-emitter";import{createGetterState as u}from"./create-getter-state";import{isEqualBase as p}from"./is";function T(e,a,S=p){let r;const o=f(()=>{const t=a(...e.map(m=>m.getState()));return r!==void 0&&S(r,t)?r:(r=t,t)});for(const t of e)t.__internal.emitter.subscribe(()=>{o.emit()});const i=s({emitter:o,getGetterState:()=>n,getState:()=>a(...e.map(t=>t.getState())),reset(){for(const t of e)t.reset()}}),n=u({baseState:i});return n}export{T as merge};
package/esm/shallow.js CHANGED
@@ -1 +1 @@
1
- import{isArray as o,isMap as f,isSet as i}from"./is";function b(t,r){if(t==r||Object.is(t,r))return!0;if(typeof t!="object"||t==null||typeof r!="object"||r==null)return!1;if(f(t)&&f(r)){if(t.size!==r.size)return!1;for(const[n,e]of t)if(!Object.is(e,r.get(n)))return!1;return!0}if(i(t)&&i(r)){if(t.size!==r.size)return!1;for(const n of t)if(!r.has(n))return!1;return!0}if(o(t)&&o(r)){if(t.length!==r.length)return!1;for(const[n,e]of t.entries())if(!Object.is(e,r[n]))return!1;return!0}const s=Object.keys(t),c=Object.keys(r);if(s.length!==c.length)return!1;for(const n of s)if(!Object.prototype.hasOwnProperty.call(r,n)||!Object.is(t[n],r[n]))return!1;return!0}export{b as shallow};
1
+ import{isArray as o,isMap as f,isSet as i}from"./is";function k(t,r){if(t==r)return!0;if(typeof t!="object"||t==null||typeof r!="object"||r==null)return!1;if(f(t)&&f(r)){if(t.size!==r.size)return!1;for(const[n,e]of t)if(!Object.is(e,r.get(n)))return!1;return!0}if(i(t)&&i(r)){if(t.size!==r.size)return!1;for(const n of t)if(!r.has(n))return!1;return!0}if(o(t)&&o(r)){if(t.length!==r.length)return!1;for(const[n,e]of t.entries())if(!Object.is(e,r[n]))return!1;return!0}const s=Object.keys(t),c=Object.keys(r);if(s.length!==c.length)return!1;for(const n of s)if(!Object.prototype.hasOwnProperty.call(r,n)||!Object.is(t[n],r[n]))return!1;return!0}export{k as shallow};
package/esm/types.js CHANGED
@@ -1 +1 @@
1
- import{isFunction as a,isPromise as r}from"./is";var T=(t=>(t.IS_STATE="isState",t.IS_SLICE="isSlice",t))(T||{});function o(e){return r(e)?e:a(e)?e():e}export{T as StateKeys,o as getDefaultValue};
1
+ import{isFunction as r,isPromise as a}from"./is";var T=(t=>(t.IS_STATE="isState",t.IS_SLICE="isSlice",t))(T||{});function S(e){return a(e)?e:r(e)?e():e}export{T as StateKeys,S as getDefaultValue};
@@ -1 +1 @@
1
- import{useSyncExternalStore as n,toType as S}from"./common";import{isPromise as i}from"./is";function m(e,r=t=>S(t),o){const t=n(e.__internal.emitter,a=>r(a),o);if(i(t))throw t;return t}export{m as useStateValue};
1
+ import{useSyncExternalStore as a,toType as i}from"./common";import{isAnyOtherError as s,isPromise as S}from"./is";function f(e,r=t=>i(t),o){const t=a(e.__internal.emitter,n=>r(n),o);if(S(t)||s(t))throw t;return t}export{f as useStateValue};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "muya",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "author": "samuel.gjabel@gmail.com",
5
5
  "description": "👀 Another React state management library",
6
6
  "license": "MIT",
@@ -0,0 +1,63 @@
1
+ import { cancelablePromise, toType, useSyncExternalStore } from '../common'
2
+ import { renderHook } from '@testing-library/react-hooks'
3
+ import { createEmitter } from '../create-emitter'
4
+ import { longPromise } from './test-utils'
5
+
6
+ describe('toType', () => {
7
+ it('should cast object to specified type', () => {
8
+ const object = { a: 1 }
9
+ const result = toType<{ a: number }>(object)
10
+ expect(result.a).toBe(1)
11
+ })
12
+ })
13
+
14
+ describe('useSyncExternalStore', () => {
15
+ it('should return the initial state value', () => {
16
+ const emitter = createEmitter(() => 0)
17
+ const { result } = renderHook(() => useSyncExternalStore(emitter, (state) => state))
18
+ expect(result.current).toBe(0)
19
+ })
20
+
21
+ it('should update when the state value changes', () => {
22
+ let value = 0
23
+ const emitter = createEmitter(() => value)
24
+ const { result } = renderHook(() => useSyncExternalStore(emitter, (state) => state))
25
+
26
+ value = 1
27
+ emitter.emit()
28
+ expect(result.current).toBe(1)
29
+ })
30
+
31
+ it('should use the selector function', () => {
32
+ let value = 0
33
+ const emitter = createEmitter(() => ({ count: value }))
34
+ const { result } = renderHook(() => useSyncExternalStore(emitter, (state: { count: number }) => state.count))
35
+
36
+ value = 1
37
+ emitter.emit()
38
+ expect(result.current).toBe(1)
39
+ })
40
+
41
+ it('should use the isEqual function', () => {
42
+ let value = 0
43
+ const emitter = createEmitter(() => ({ count: value }))
44
+ const isEqual = jest.fn((a, b) => a === b)
45
+ const { result } = renderHook(() => useSyncExternalStore(emitter, (state: { count: number }) => state.count, isEqual))
46
+
47
+ value = 1
48
+ emitter.emit()
49
+ expect(result.current).toBe(1)
50
+ expect(isEqual).toHaveBeenCalled()
51
+ })
52
+
53
+ it('should test cancelable promise to abort', async () => {
54
+ const { promise, controller } = cancelablePromise(longPromise(1000 * 1000))
55
+ controller.abort()
56
+ expect(promise).rejects.toThrow('aborted')
57
+ })
58
+
59
+ it('should test cancelable promise to resolve', async () => {
60
+ const { promise } = cancelablePromise(longPromise(0))
61
+ expect(await promise).toBe(0)
62
+ })
63
+ })
@@ -0,0 +1,84 @@
1
+ import { Suspense } from 'react'
2
+ import { create } from '../create'
3
+ import { renderHook, waitFor, act, render } from '@testing-library/react'
4
+ import { ErrorBoundary, longPromise } from './test-utils'
5
+
6
+ describe('create', () => {
7
+ it('should create test with base value', () => {
8
+ const state = create(0)
9
+ const result = renderHook(() => state())
10
+ expect(result.result.current).toBe(0)
11
+ })
12
+ it('should create test with function', () => {
13
+ const state = create(() => 0)
14
+ const result = renderHook(() => state())
15
+ expect(result.result.current).toBe(0)
16
+ })
17
+ it('should create test with promise', async () => {
18
+ const state = create(Promise.resolve(0))
19
+ const result = renderHook(() => state())
20
+ await waitFor(() => {
21
+ expect(result.result.current).toBe(0)
22
+ })
23
+ })
24
+ it('should create test with promise and wait to be resolved', async () => {
25
+ const state = create(longPromise)
26
+ const result = renderHook(() => state(), { wrapper: ({ children }) => <Suspense fallback={null}>{children}</Suspense> })
27
+
28
+ await waitFor(() => {
29
+ expect(result.result.current).toBe(0)
30
+ })
31
+ })
32
+ it('should create test with lazy promise and wait to be resolved', async () => {
33
+ const state = create(async () => await longPromise())
34
+ const result = renderHook(() => state(), { wrapper: ({ children }) => <Suspense fallback={null}>{children}</Suspense> })
35
+
36
+ await waitFor(() => {
37
+ expect(result.result.current).toBe(0)
38
+ })
39
+ })
40
+ it('should create test with promise and set value during the promise is pending', async () => {
41
+ const state = create(longPromise)
42
+ const result = renderHook(() => state(), { wrapper: ({ children }) => <Suspense fallback={null}>{children}</Suspense> })
43
+
44
+ act(() => {
45
+ state.setState(10)
46
+ })
47
+ await waitFor(() => {
48
+ expect(result.result.current).toBe(10)
49
+ })
50
+ })
51
+
52
+ it('should create test with lazy promise and set value during the promise is pending', async () => {
53
+ const state = create(async () => await longPromise())
54
+ const result = renderHook(() => state(), { wrapper: ({ children }) => <Suspense fallback={null}>{children}</Suspense> })
55
+
56
+ act(() => {
57
+ state.setState(10)
58
+ })
59
+ await waitFor(() => {
60
+ expect(result.result.current).toBe(10)
61
+ })
62
+ })
63
+
64
+ it('should fail inside the hook when the promise is rejected with not abort isWithError', async () => {
65
+ const state = create(Promise.reject('error-message'))
66
+
67
+ function Component() {
68
+ state()
69
+ return null
70
+ }
71
+
72
+ const result = render(
73
+ <ErrorBoundary fallback={<div>An error occurred.</div>}>
74
+ <Suspense fallback={'suspense-error'}>
75
+ <Component />
76
+ </Suspense>
77
+ </ErrorBoundary>,
78
+ )
79
+
80
+ await waitFor(() => {
81
+ expect(result.container.textContent).toBe('An error occurred.')
82
+ })
83
+ })
84
+ })
@@ -0,0 +1,103 @@
1
+ import { Abort } from '../common'
2
+ import {
3
+ isPromise,
4
+ isFunction,
5
+ isSetValueFunction,
6
+ isObject,
7
+ isRef,
8
+ isMap,
9
+ isSet,
10
+ isArray,
11
+ isEqualBase,
12
+ isAbortError,
13
+ } from '../is'
14
+
15
+ describe('isPromise', () => {
16
+ it('should return true for a Promise', () => {
17
+ expect(isPromise(Promise.resolve())).toBe(true)
18
+ })
19
+ it('should return false for a non-Promise', () => {
20
+ expect(isPromise(123)).toBe(false)
21
+ })
22
+ })
23
+
24
+ describe('isFunction', () => {
25
+ it('should return true for a function', () => {
26
+ expect(isFunction(() => {})).toBe(true)
27
+ })
28
+ it('should return false for a non-function', () => {
29
+ expect(isFunction(123)).toBe(false)
30
+ })
31
+ })
32
+
33
+ describe('isSetValueFunction', () => {
34
+ it('should return true for a function', () => {
35
+ expect(isSetValueFunction(() => {})).toBe(true)
36
+ })
37
+ it('should return false for a non-function', () => {
38
+ expect(isSetValueFunction(123)).toBe(false)
39
+ })
40
+ })
41
+
42
+ describe('isObject', () => {
43
+ it('should return true for an object', () => {
44
+ expect(isObject({})).toBe(true)
45
+ })
46
+ it('should return false for a non-object', () => {
47
+ expect(isObject(123)).toBe(false)
48
+ })
49
+ })
50
+
51
+ describe('isRef', () => {
52
+ it('should return true for a ref object', () => {
53
+ expect(isRef({ isRef: true })).toBe(true)
54
+ })
55
+ it('should return false for a non-ref object', () => {
56
+ expect(isRef({})).toBe(false)
57
+ })
58
+ })
59
+
60
+ describe('isMap', () => {
61
+ it('should return true for a Map', () => {
62
+ expect(isMap(new Map())).toBe(true)
63
+ })
64
+ it('should return false for a non-Map', () => {
65
+ expect(isMap(123)).toBe(false)
66
+ })
67
+ })
68
+
69
+ describe('isSet', () => {
70
+ it('should return true for a Set', () => {
71
+ expect(isSet(new Set())).toBe(true)
72
+ })
73
+ it('should return false for a non-Set', () => {
74
+ expect(isSet(123)).toBe(false)
75
+ })
76
+ })
77
+
78
+ describe('isArray', () => {
79
+ it('should return true for an array', () => {
80
+ expect(isArray([])).toBe(true)
81
+ })
82
+ it('should return false for a non-array', () => {
83
+ expect(isArray(123)).toBe(false)
84
+ })
85
+ })
86
+
87
+ describe('isEqualBase', () => {
88
+ it('should return true for equal values', () => {
89
+ expect(isEqualBase(1, 1)).toBe(true)
90
+ })
91
+ it('should return false for non-equal values', () => {
92
+ expect(isEqualBase(1, 2)).toBe(false)
93
+ })
94
+ })
95
+
96
+ describe('isAbortError', () => {
97
+ it('should return true for an AbortError', () => {
98
+ expect(isAbortError(new DOMException('', Abort.Error))).toBe(true)
99
+ })
100
+ it('should return false for a non-AbortError', () => {
101
+ expect(isAbortError(new DOMException('', 'Error'))).toBe(false)
102
+ })
103
+ })