muya 1.1.0 → 2.0.0-beta.1
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 +201 -138
- package/cjs/index.js +1 -1
- package/esm/__tests__/create-async.test.js +1 -0
- package/esm/__tests__/test-utils.js +1 -0
- package/esm/create.js +1 -1
- package/esm/index.js +1 -1
- package/esm/subscriber.js +1 -0
- package/esm/types.js +1 -1
- package/esm/use.js +1 -0
- package/esm/utils/__tests__/context.test.js +1 -0
- package/esm/utils/__tests__/is.test.js +1 -0
- package/esm/utils/__tests__/shallow.test.js +1 -0
- package/esm/utils/__tests__/sub-memo.test.js +1 -0
- package/esm/utils/common.js +1 -0
- package/esm/utils/create-context.js +1 -0
- package/esm/utils/create-emitter.js +1 -0
- package/esm/utils/is.js +1 -0
- package/esm/utils/scheduler.js +1 -0
- package/esm/utils/shallow.js +1 -0
- package/esm/utils/sub-memo.js +1 -0
- package/package.json +1 -1
- package/packages/core/__tests__/bench.test.tsx +261 -0
- package/packages/core/__tests__/create-async.test.ts +88 -0
- package/packages/core/__tests__/create.test.tsx +107 -0
- package/packages/core/__tests__/test-utils.ts +40 -0
- package/packages/core/__tests__/use-async.test.tsx +44 -0
- package/packages/core/__tests__/use.test.tsx +76 -0
- package/packages/core/create.ts +67 -0
- package/packages/core/index.ts +4 -0
- package/packages/core/subscriber.ts +121 -0
- package/packages/core/types.ts +15 -0
- package/packages/core/use.ts +59 -0
- package/packages/core/utils/__tests__/context.test.ts +198 -0
- package/packages/core/utils/__tests__/is.test.ts +74 -0
- package/packages/core/utils/__tests__/shallow.test.ts +418 -0
- package/packages/core/utils/__tests__/sub-memo.test.ts +13 -0
- package/packages/core/utils/common.ts +48 -0
- package/packages/core/utils/create-context.ts +60 -0
- package/packages/core/utils/create-emitter.ts +53 -0
- package/packages/core/utils/is.ts +43 -0
- package/packages/core/utils/scheduler.ts +59 -0
- package/{src → packages/core/utils}/shallow.ts +3 -6
- package/packages/core/utils/sub-memo.ts +37 -0
- package/types/__tests__/test-utils.d.ts +20 -0
- package/types/create.d.ts +14 -21
- package/types/index.d.ts +2 -4
- package/types/subscriber.d.ts +25 -0
- package/types/types.d.ts +9 -65
- package/types/use.d.ts +2 -0
- package/types/utils/common.d.ts +15 -0
- package/types/utils/create-context.d.ts +5 -0
- package/types/utils/create-emitter.d.ts +20 -0
- package/types/utils/is.d.ts +11 -0
- package/types/utils/scheduler.d.ts +6 -0
- package/types/utils/sub-memo.d.ts +6 -0
- package/esm/common.js +0 -1
- package/esm/create-base-state.js +0 -1
- package/esm/create-emitter.js +0 -1
- package/esm/create-getter-state.js +0 -1
- package/esm/is.js +0 -1
- package/esm/merge.js +0 -1
- package/esm/select.js +0 -1
- package/esm/shallow.js +0 -1
- package/esm/use-state-value.js +0 -1
- package/src/common.ts +0 -28
- package/src/create-base-state.ts +0 -35
- package/src/create-emitter.ts +0 -24
- package/src/create-getter-state.ts +0 -19
- package/src/create.ts +0 -102
- package/src/index.ts +0 -6
- package/src/is.ts +0 -36
- package/src/merge.ts +0 -41
- package/src/select.ts +0 -33
- package/src/state.test.tsx +0 -647
- package/src/types.ts +0 -94
- package/src/use-state-value.ts +0 -29
- package/types/common.d.ts +0 -7
- package/types/create-base-state.d.ts +0 -10
- package/types/create-emitter.d.ts +0 -7
- package/types/create-getter-state.d.ts +0 -6
- package/types/is.d.ts +0 -10
- package/types/merge.d.ts +0 -2
- package/types/select.d.ts +0 -2
- package/types/use-state-value.d.ts +0 -10
- /package/types/{shallow.d.ts → utils/shallow.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,236 +1,299 @@
|
|
|
1
1
|
|
|
2
2
|
# Muya 🌀
|
|
3
|
-
Welcome to Muya – your new best friend for managing state in React applications! Making state management a breeze, focused on simplicity and scalability for real-world scenarios.
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
[](https://github.com/samuelgjabel/muya/actions/workflows/code-check.yml)
|
|
7
|
-
[](https://bundlephobia.com/result?p=muya)
|
|
4
|
+
Welcome to **Muya v2**—a state management library that makes managing state a breeze, focusing on simplicity and scalability for real-world applications.
|
|
8
5
|
|
|
6
|
+
[](https://github.com/samuelgja/muya/actions/workflows/build.yml)
|
|
7
|
+
[](https://github.com/samuelgja/muya/actions/workflows/code-check.yml)
|
|
8
|
+
[](https://bundlephobia.com/result?p=muya)
|
|
9
9
|
|
|
10
|
+
---
|
|
10
11
|
|
|
11
12
|
## 🚀 Features
|
|
12
|
-
- Easy State Creation: Kickstart your state management with simple and intuitive APIs.
|
|
13
|
-
- Selectors & Merges: Grab exactly what you need from your state and combine multiple states seamlessly.
|
|
14
|
-
- Deep Nesting Support: Handle complex state structures without breaking a sweat.
|
|
15
|
-
- Optimized Rendering: Prevent unnecessary re-renders with smart equality checks.
|
|
16
|
-
- Concurrency Handling: Stay cool under pressure with robust concurrency support.
|
|
17
|
-
- TypeScript Ready: Fully typed for maximum developer sanity.
|
|
18
13
|
|
|
14
|
+
- **Simple State Creation**: Easily create global state with an intuitive API.
|
|
15
|
+
- **Functional Derivations**: Derive / Compute new state using plain functions, embracing functional programming.
|
|
16
|
+
- **Async Support**: Async derived states work out of the box, with support for React Suspense.
|
|
17
|
+
- **Performance Optimizations**: WIP Batch state updates for optimized rendering.
|
|
18
|
+
- **TypeScript Support**: Fully typed for a better developer experience.
|
|
19
|
+
- **Small Bundle Size**: Lightweight and efficient—no unnecessary bloat.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
Info: [Muya v2](https://medium.com/p/106de3d04c43)
|
|
24
|
+
|
|
25
|
+
### 💡 How It Works
|
|
26
|
+
Muya v2 uses its own custom context system to track dependencies and notify components when state changes. When you use a function that accesses state in your component, Muya tracks which states are used and re-renders the component when any of them change.
|
|
27
|
+
|
|
28
|
+
This allows you to write derived state as plain functions, making your code more intuitive and closer to standard JavaScript. No need to define selectors or use special APIs—just use functions!
|
|
29
|
+
|
|
30
|
+
---
|
|
19
31
|
|
|
20
32
|
## 📦 Installation
|
|
21
33
|
|
|
22
34
|
```bash
|
|
23
|
-
|
|
35
|
+
npm install muya
|
|
24
36
|
```
|
|
25
|
-
|
|
37
|
+
|
|
38
|
+
Or using Yarn:
|
|
39
|
+
|
|
26
40
|
```bash
|
|
27
41
|
yarn add muya
|
|
28
42
|
```
|
|
29
|
-
|
|
43
|
+
|
|
44
|
+
Or using Bun:
|
|
45
|
+
|
|
30
46
|
```bash
|
|
31
|
-
|
|
47
|
+
bun add muya
|
|
32
48
|
```
|
|
33
49
|
|
|
50
|
+
---
|
|
51
|
+
|
|
34
52
|
## 📝 Quick Start
|
|
35
53
|
|
|
36
|
-
|
|
37
|
-
import { create } from 'muya'
|
|
54
|
+
Here's how to get started with **Muya v2**:
|
|
38
55
|
|
|
39
|
-
|
|
56
|
+
### Creating State
|
|
40
57
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
58
|
+
```typescript
|
|
59
|
+
import { create } from 'muya';
|
|
60
|
+
|
|
61
|
+
const counter = create(0);
|
|
45
62
|
```
|
|
46
63
|
|
|
47
|
-
###
|
|
48
|
-
Sugar syntax above the `setState` method for partially updating the state.
|
|
49
|
-
```typescript
|
|
50
|
-
import { create } from 'muya'
|
|
64
|
+
### Using State in Components
|
|
51
65
|
|
|
52
|
-
|
|
66
|
+
```tsx
|
|
67
|
+
import React from 'react';
|
|
68
|
+
import { use } from 'muya';
|
|
53
69
|
|
|
54
|
-
function
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
return
|
|
70
|
+
function Counter() {
|
|
71
|
+
const count = use(counter);
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<div>
|
|
75
|
+
<button onClick={() => counter.set((prev) => prev + 1)}>
|
|
76
|
+
Increment
|
|
77
|
+
</button>
|
|
78
|
+
<p>Count: {count}</p>
|
|
79
|
+
</div>
|
|
80
|
+
);
|
|
58
81
|
}
|
|
59
82
|
```
|
|
60
83
|
|
|
84
|
+
---
|
|
61
85
|
|
|
62
|
-
|
|
63
|
-
```tsx
|
|
64
|
-
import { create } from 'muya'
|
|
86
|
+
## 📚 Examples
|
|
65
87
|
|
|
66
|
-
|
|
88
|
+
### Deriving / Selecting State with Functions
|
|
67
89
|
|
|
68
|
-
|
|
69
|
-
const useName = useUser.select((user) => user.name)
|
|
90
|
+
You can derive new state using plain functions:
|
|
70
91
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
92
|
+
```typescript
|
|
93
|
+
const counter = create(0);
|
|
94
|
+
|
|
95
|
+
function doubled() {
|
|
96
|
+
return counter() * 2;
|
|
74
97
|
}
|
|
98
|
+
```
|
|
75
99
|
|
|
100
|
+
Use it in a component:
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
function DoubledCounter() {
|
|
104
|
+
const value = use(doubled);
|
|
105
|
+
|
|
106
|
+
return <p>Doubled Count: {value}</p>;
|
|
107
|
+
}
|
|
76
108
|
```
|
|
77
109
|
|
|
78
|
-
###
|
|
79
|
-
|
|
80
|
-
|
|
110
|
+
### Complex Derivations
|
|
111
|
+
|
|
112
|
+
Create more complex derived states by composing functions:
|
|
81
113
|
|
|
82
|
-
|
|
83
|
-
|
|
114
|
+
```tsx
|
|
115
|
+
import { create, use } from 'muya';
|
|
84
116
|
|
|
85
|
-
const
|
|
117
|
+
const state1 = create(0);
|
|
118
|
+
const state2 = create(0);
|
|
119
|
+
const state3 = create(0);
|
|
86
120
|
|
|
87
|
-
function
|
|
88
|
-
|
|
89
|
-
return <div onClick={() => useName.setState((prev) => 'Jane')}>{fullName}</div>
|
|
121
|
+
function sum() {
|
|
122
|
+
return state1() + state2() + state3();
|
|
90
123
|
}
|
|
91
|
-
```
|
|
92
124
|
|
|
125
|
+
function multiply() {
|
|
126
|
+
return sum() * 2; // Example multiplier
|
|
127
|
+
}
|
|
93
128
|
|
|
94
|
-
|
|
95
|
-
|
|
129
|
+
function isOdd() {
|
|
130
|
+
return multiply() % 2 === 1;
|
|
131
|
+
}
|
|
96
132
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
import { create } from 'muya';
|
|
100
|
-
// state will try to resolve the promise immediately, can hit the suspense boundary
|
|
101
|
-
const counterState = create(Promise.resolve(0));
|
|
133
|
+
function App() {
|
|
134
|
+
const isOddValue = use(isOdd);
|
|
102
135
|
|
|
103
|
-
function Counter() {
|
|
104
|
-
const counter = counterState();
|
|
105
136
|
return (
|
|
106
|
-
<div
|
|
107
|
-
{
|
|
137
|
+
<div>
|
|
138
|
+
<button onClick={() => state1.set((c) => c + 1)}>Increment Counter 1</button>
|
|
139
|
+
<button onClick={() => state2.set((c) => c + 1)}>Increment Counter 2</button>
|
|
140
|
+
<button onClick={() => state3.set((c) => c + 1)}>Increment Counter 3</button>
|
|
141
|
+
<p>Is ODD: {isOddValue ? 'Yes' : 'No'}</p>
|
|
108
142
|
</div>
|
|
109
143
|
);
|
|
110
144
|
}
|
|
111
145
|
```
|
|
112
146
|
|
|
113
|
-
#### Lazy Promise resolution
|
|
114
|
-
```typescript
|
|
115
|
-
import { create } from 'muya';
|
|
116
|
-
// 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
|
|
117
|
-
const counterState = create(() => Promise.resolve(0));
|
|
118
147
|
|
|
119
|
-
|
|
120
|
-
|
|
148
|
+
### Derive state with parameters
|
|
149
|
+
```tsx
|
|
150
|
+
|
|
151
|
+
import React, { useCallback, useState } from 'react';
|
|
152
|
+
import { create, use } from 'muya';
|
|
153
|
+
|
|
154
|
+
const counter1 = create(0);
|
|
155
|
+
const counter2 = create(0);
|
|
156
|
+
|
|
157
|
+
function multipliedSum(multiplier: number) {
|
|
158
|
+
return (counter1() + counter2()) * multiplier;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function MultipliedCounter() {
|
|
162
|
+
const [multiplier, setMultiplier] = useState(1);
|
|
163
|
+
// make sure to use useCallback to memoize the function
|
|
164
|
+
const multiply = useCallback(() => multipliedSum(multiplier), [multiplier]);
|
|
165
|
+
const result = use(multiply);
|
|
166
|
+
|
|
121
167
|
return (
|
|
122
|
-
<div
|
|
123
|
-
{
|
|
168
|
+
<div>
|
|
169
|
+
<button onClick={() => counter1.set((c) => c + 1)}>
|
|
170
|
+
Increment Counter 1
|
|
171
|
+
</button>
|
|
172
|
+
<button onClick={() => counter2.set((c) => c + 1)}>
|
|
173
|
+
Increment Counter 2
|
|
174
|
+
</button>
|
|
175
|
+
<button onClick={() => setMultiplier((m) => m + 1)}>
|
|
176
|
+
Increment Multiplier
|
|
177
|
+
</button>
|
|
178
|
+
<p>Result: {result}</p>
|
|
124
179
|
</div>
|
|
125
180
|
);
|
|
126
181
|
}
|
|
127
182
|
```
|
|
128
183
|
|
|
184
|
+
### Async derives State
|
|
129
185
|
|
|
130
|
-
|
|
186
|
+
```tsx
|
|
187
|
+
import { create } from 'muya';
|
|
131
188
|
|
|
132
|
-
|
|
189
|
+
const counter = create(1);
|
|
133
190
|
|
|
134
|
-
|
|
191
|
+
async function fetchData() {
|
|
192
|
+
const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${counter()}`);
|
|
193
|
+
return response.json();
|
|
194
|
+
}
|
|
135
195
|
|
|
136
|
-
|
|
137
|
-
function
|
|
138
|
-
|
|
196
|
+
// make sure this component is wrapped in a <Suspense> component
|
|
197
|
+
function Component() {
|
|
198
|
+
const data = use(fetchData);
|
|
199
|
+
|
|
200
|
+
return (
|
|
201
|
+
<div>
|
|
202
|
+
<button onClick={() => counter.set((prev) => prev + 1)}>Increment</button>
|
|
203
|
+
<p>{JSON.stringify(data)}</p>
|
|
204
|
+
</div>
|
|
205
|
+
);
|
|
206
|
+
}
|
|
139
207
|
|
|
140
|
-
**Example:**
|
|
141
208
|
|
|
142
|
-
```typescript
|
|
143
|
-
const userState = create({ name: 'John', age: 30 });
|
|
144
209
|
```
|
|
210
|
+
---
|
|
145
211
|
|
|
146
|
-
### `select`
|
|
147
212
|
|
|
148
|
-
Selects a slice of an existing state directly or via a selector function.
|
|
149
213
|
|
|
150
|
-
```typescript
|
|
151
|
-
// userState is ready to use as hook, so you can name it with `use` prefix
|
|
152
|
-
const userState = create({ name: 'John', age: 30 });
|
|
153
|
-
// Direct selection outside the component, is useful for accessing the slices of the state in multiple components
|
|
154
|
-
const userAgeState = userState.select((user) => user.age);
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
### `merge`
|
|
158
|
-
Merges two states into a single state.
|
|
159
|
-
```typescript
|
|
160
|
-
const useName = create(() => 'John');
|
|
161
|
-
const useAge = create(() => 30);
|
|
162
|
-
const useFullName = useName.merge(useAge, (name, age) => ` ${name} and ${age}`);
|
|
163
|
-
```
|
|
164
214
|
|
|
215
|
+
## 📖 Documentation
|
|
165
216
|
|
|
166
|
-
|
|
167
|
-
Sets the state to a new value or a function that returns a new value.
|
|
217
|
+
#### `create`
|
|
168
218
|
|
|
169
219
|
```typescript
|
|
170
|
-
|
|
171
|
-
userState.setState({ name: 'Jane' });
|
|
220
|
+
function create<T>(initialState: T): State<T>;
|
|
172
221
|
```
|
|
173
222
|
|
|
174
|
-
|
|
175
|
-
Partially updates the state with a new value.
|
|
176
|
-
|
|
223
|
+
Create return state block or atom, setting a new value to the state will trigger a re-render of all components using the state.
|
|
177
224
|
```typescript
|
|
178
|
-
const
|
|
179
|
-
|
|
225
|
+
const counter = create(0);
|
|
226
|
+
// set new value
|
|
227
|
+
counter.set(1);
|
|
180
228
|
```
|
|
181
229
|
|
|
182
|
-
|
|
183
|
-
Returns the current state value outside the component.
|
|
184
|
-
|
|
230
|
+
Get the state value outside of react
|
|
185
231
|
```typescript
|
|
186
|
-
const
|
|
187
|
-
|
|
232
|
+
const value = counter();
|
|
233
|
+
// call it like a function
|
|
234
|
+
console.log(value()); // 1
|
|
188
235
|
```
|
|
189
236
|
|
|
190
|
-
|
|
191
|
-
|
|
237
|
+
Each state created by create has the following properties and methods:
|
|
238
|
+
|
|
239
|
+
- id: number: Unique identifier for the state.
|
|
240
|
+
- (): T: The state is callable to get the current value.
|
|
241
|
+
- set(value: T | ((prev: T) => T)): Update the state value.
|
|
242
|
+
- listen(listener: (value: T) => void): () => void: Subscribe to state changes.
|
|
192
243
|
|
|
244
|
+
#### `use` hook
|
|
245
|
+
Use hook to get state value in react component
|
|
193
246
|
```typescript
|
|
194
|
-
|
|
195
|
-
// use inside the component
|
|
196
|
-
const counter = useCounter();
|
|
247
|
+
function use<T>(state: State<T> | (() => T)): T;
|
|
197
248
|
```
|
|
249
|
+
example
|
|
250
|
+
```tsx
|
|
251
|
+
const counter = create(0);
|
|
198
252
|
|
|
199
|
-
|
|
200
|
-
|
|
253
|
+
// in react component
|
|
254
|
+
const count = use(counter);
|
|
255
|
+
```
|
|
201
256
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
const
|
|
257
|
+
Also custom selector to avoid re-rendering the app
|
|
258
|
+
```tsx
|
|
259
|
+
const doubled = create({doubled:true});
|
|
260
|
+
// in react component
|
|
261
|
+
const value = use(doubled, (state) => state.doubled);
|
|
205
262
|
```
|
|
206
263
|
|
|
207
264
|
|
|
208
265
|
|
|
209
|
-
### Access from outside the component
|
|
210
|
-
:warning: Avoid using this method for state management in [React Server Components](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md), especially in Next.js 13+. It may cause unexpected behavior or privacy concerns.
|
|
211
|
-
```typescript
|
|
212
|
-
const userState = create({ name: 'John', age: 30 });
|
|
213
|
-
const user = userState.getState();
|
|
214
|
-
```
|
|
215
|
-
---
|
|
216
266
|
|
|
217
267
|
|
|
218
|
-
###
|
|
219
|
-
:
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
268
|
+
### ⚠️ Notes
|
|
269
|
+
Memoization: When using derived functions with parameters, you should memoize them using useCallback to prevent unnecessary re-renders and prevent function calls.
|
|
270
|
+
```tsx
|
|
271
|
+
Copy code
|
|
272
|
+
const multiply = useCallback(() => multipliedSum(multiplier), [multiplier]);
|
|
273
|
+
```
|
|
274
|
+
Async Functions: Async functions used in use should handle errors appropriately and may need to use React's Suspense for loading states.
|
|
275
|
+
Also keep in note, setting new state in async derives, will cancel the pending previous one in the queue.
|
|
276
|
+
|
|
277
|
+
```tsx
|
|
278
|
+
Copy code
|
|
279
|
+
function App() {
|
|
280
|
+
return (
|
|
281
|
+
<Suspense fallback={<div>Loading...</div>}>
|
|
282
|
+
<DataComponent />
|
|
283
|
+
</Suspense>
|
|
284
|
+
);
|
|
285
|
+
}
|
|
226
286
|
```
|
|
227
287
|
|
|
228
|
-
|
|
229
|
-
|
|
288
|
+
Error Handling: If an async function throws an error, you can catch it using React's error boundaries.
|
|
289
|
+
|
|
290
|
+
### 🤖 Contributing
|
|
291
|
+
Contributions are welcome! Please read the contributing guidelines before submitting a pull request.
|
|
230
292
|
|
|
231
|
-
|
|
293
|
+
### 🧪 Testing
|
|
232
294
|
Muya comes with a robust testing suite. Check out the state.test.tsx for examples on how to write your own tests.
|
|
233
295
|
|
|
234
|
-
## 📜 License
|
|
235
296
|
|
|
236
|
-
|
|
297
|
+
### 🙏 Acknowledgments
|
|
298
|
+
Special thanks to reddit to motivate me for v2 :D
|
|
299
|
+
|
package/cjs/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var h=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var X=Object.getOwnPropertyNames;var N=Object.prototype.hasOwnProperty;var K=(e,t)=>{for(var r in t)h(e,r,{get:t[r],enumerable:!0})},Y=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of X(t))!N.call(e,n)&&n!==r&&h(e,n,{get:()=>t[n],enumerable:!(o=q(t,n))||o.enumerable});return e};var G=e=>Y(h({},"__esModule",{value:!0}),e);var J={};K(J,{EMPTY_SELECTOR:()=>w,create:()=>U,shallow:()=>j,use:()=>H});module.exports=G(J);var w=e=>e;function p(e){return e instanceof Promise}function g(e){return typeof e=="function"}function R(e){return e instanceof Map}function C(e){return e instanceof Set}function P(e){return Array.isArray(e)}function b(e,t){return e===t?!0:!!Object.is(e,t)}function A(e){return typeof e=="function"}function I(e){return e instanceof DOMException&&e.name==="StateAbortError"}function v(e){return e instanceof Error&&e.name!=="StateAbortError"}function l(e){return e===void 0}function M(e,t){t&&t.abort();let r=new AbortController,{signal:o}=r;return{promise:new Promise((i,s)=>{o.addEventListener("abort",()=>{s(new DOMException("Promise was aborted","StateAbortError"))}),e.then(i).catch(s)}),controller:r}}var W=0;function y(){return W++}function E(e,t=(r,o)=>r===o){if(!l(e.current)){if(!l(e.previous)&&t(e.current,e.previous))return!1;e.previous=e.current}return!0}function S(e,t){let r=new Set,o=[];return{clear:()=>{for(let n of o)n();r.clear()},subscribe:n=>(r.add(n),()=>{r.delete(n)}),emit:(...n)=>{for(let i of r)i(...n)},contains:n=>r.has(n),getSnapshot:e,getInitialSnapshot:t,getSize:()=>r.size,subscribeToOtherEmitter(n){let i=n.subscribe(()=>{this.emit()});o.push(i)}}}function D(e){let t=new Set,{onResolveItem:r,onFinish:o}=e,n=performance.now(),i=!1;function s(){let c=performance.now(),f=c-n,{size:m}=t;if(f<.2&&m>0&&m<10){n=c,u();return}i||(i=!0,Promise.resolve().then(()=>{i=!1,n=performance.now(),u()}))}function u(){if(t.size!==0){for(let c of t)r&&r(c),t.delete(c);if(t.size>0){s();return}o()}}function a(c){t.add(c),s()}return a}var $=Symbol("_");function V(e){let t=[];function r(){if(t.length===0)return e;let i=t.at(-1);return i===$?e:i}function o(i,s){t.push(i);let u=s();return p(u)?(async()=>{try{return await u}finally{t.pop()}})():(t.pop(),u)}function n(i){let s=r();return()=>{t.push(s);let u=i();return p(u)?(async()=>{try{return await u}finally{t.pop()}})():(t.pop(),u)}}return{run:o,use:r,wrap:n}}var F=V(void 0);function L(e){let t=[],r={},o={},n=!1,i=S(()=>n?o.current:(n=!0,c()),()=>(n=!0,c()));async function s(){E(o,b)&&(r.controller&&r.controller.abort(),o.current=c(),i.emit())}let u=y(),a={addEmitter(f){let m=f.subscribe(s);t.push(m)},id:u,sub:s},c=function(){let f=F.run(a,e);if(p(f)){let{controller:m,promise:O}=M(f,r.controller);r.controller=m,O?.then(d=>{o.current=d,i.emit()}).catch(d=>{if(!I(d))throw d});let k=O;return o.current=k,k}return o.current=f,f};return c.emitter=i,c.destroy=function(){for(let f of t)f();i.clear()},c.id=u,c.listen=function(f){return i.subscribe(()=>{let m=o.current;if(l(m))throw new Error("The value is undefined");f(m)})},c.abort=function(){r.controller&&r.controller.abort()},c}function U(e,t=b){let r={};function o(){return l(r.current)&&(r.current=g(e)?e():e),r.current}function n(u){let a=o();r.current=A(u)?u(a):u}let i=D({onFinish(){r.current=o(),E(r,t)&&s.emitter.emit()},onResolveItem:n}),s=function(){let u=o(),a=F.use();return a&&!s.emitter.contains(a.sub)&&a.addEmitter(s.emitter),u};return s.listen=function(u){return s.emitter.subscribe(()=>{let a=r.current;if(l(a))throw new Error("The value is undefined");u(a)})},s.emitter=S(()=>s()),s.id=y(),s.set=i,s}var T=require("react");var z=require("react");var x=new WeakMap;function _(e){return{call(){let t=x.get(e);if(t)return t.count++,t.returnType;let o={count:1,returnType:L(e)};return x.set(e,o),o.returnType},destroy(){let t=x.get(e);t&&(t.count--,t.count===0&&(t.returnType.destroy(),x.delete(e)))}}}function H(e,t=w){let r=_(e),o=r.call(),n=o.emitter.getInitialSnapshot??o.emitter.getSnapshot;(0,T.useEffect)(()=>r.destroy,[e]);let i=(0,z.useSyncExternalStore)(o.emitter.subscribe,()=>t(o.emitter.getSnapshot()),()=>t(n()));if((0,T.useDebugValue)(i),p(i))throw i;if(v(i))throw r.destroy(),i;return i}function j(e,t){if(e==t)return!0;if(typeof e!="object"||e==null||typeof t!="object"||t==null)return!1;if(R(e)&&R(t)){if(e.size!==t.size)return!1;for(let[n,i]of e)if(!Object.is(i,t.get(n)))return!1;return!0}if(C(e)&&C(t)){if(e.size!==t.size)return!1;for(let n of e)if(!t.has(n))return!1;return!0}if(P(e)&&P(t)){if(e.length!==t.length)return!1;for(let[n,i]of e.entries())if(!Object.is(i,t[n]))return!1;return!0}let r=Object.keys(e),o=Object.keys(t);if(r.length!==o.length)return!1;for(let n of r)if(!Object.prototype.hasOwnProperty.call(t,n)||!Object.is(e[n],t[n]))return!1;return!0}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{create as r}from"../create";import{waitFor as c}from"@testing-library/react";import{longPromise as m}from"./test-utils";import{isPromise as u}from"../utils/is";import{subscriber as n}from"../subscriber";describe("create",()=>{it("should subscribe to context and notified it with parameters",async()=>{const t=r(1),i=r(2);function s(){return t()+i()}async function a(p){return t()+i()+s()+p}let o=0;const e=n(()=>a(10));expect(u(e.emitter.getSnapshot())).toBe(!0),e.listen(async()=>{o++}),expect(o).toBe(0),expect(await e()).toBe(16),t.set(2),await c(async()=>{}),expect(await e()).toBe(18),expect(o).toBe(4)}),it("should async subscribe to context and notified it",async()=>{const t=r(1),i=r(Promise.resolve(2));async function s(){return await m(),t()+await i()}async function a(){return t()+await i()+await s()}let o=0;const e=n(a);e.listen(()=>{o++}),e(),expect(t.emitter.getSize()).toBe(1),expect(i.emitter.getSize()).toBe(1),expect(e.emitter.getSize()).toBe(1),t.set(2),await c(async()=>{expect(await e()).toBe(8),expect(o).toBe(5)}),i.set(3),await c(async()=>{expect(await e()).toBe(10),expect(o).toBe(10)}),expect(t.emitter.getSize()).toBe(1),expect(i.emitter.getSize()).toBe(1),expect(e.emitter.getSize()).toBe(1),e.destroy(),expect(t.emitter.getSize()).toBe(0),expect(i.emitter.getSize()).toBe(0),expect(e.emitter.getSize()).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};
|
package/esm/create.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{canUpdate as m,generateId as l}from"./utils/common";import{createEmitter as f}from"./utils/create-emitter";import{isEqualBase as T,isFunction as d,isSetValueFunction as p,isUndefined as o}from"./utils/is";import{createScheduler as S}from"./utils/scheduler";import{context as h}from"./subscriber";function y(i,u=T){const r={};function a(){return o(r.current)&&(r.current=d(i)?i():i),r.current}function c(n){const t=a();r.current=p(n)?n(t):n}const s=S({onFinish(){r.current=a(),m(r,u)&&e.emitter.emit()},onResolveItem:c}),e=function(){const n=a(),t=h.use();return t&&!e.emitter.contains(t.sub)&&t.addEmitter(e.emitter),n};return e.listen=function(n){return e.emitter.subscribe(()=>{const t=r.current;if(o(t))throw new Error("The value is undefined");n(t)})},e.emitter=f(()=>e()),e.id=l(),e.set=s,e}export{y as create};
|
package/esm/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./types";import{create as t}from"./create";import{
|
|
1
|
+
export*from"./types";import{create as t}from"./create";import{use as m}from"./use";import{shallow as x}from"./utils/shallow";export{t as create,x as shallow,m as use};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cancelablePromise as p,canUpdate as T,generateId as y}from"./utils/common";import{createContext as F}from"./utils/create-context";import{createEmitter as x}from"./utils/create-emitter";import{isAbortError as h,isEqualBase as C,isPromise as R,isUndefined as E}from"./utils/is";const S=F(void 0);function k(d){const u=[],n={},r={};let s=!1;const o=x(()=>s?r.current:(s=!0,t()),()=>(s=!0,t()));async function a(){T(r,C)&&(n.controller&&n.controller.abort(),r.current=t(),o.emit())}const l=y(),f={addEmitter(e){const i=e.subscribe(a);u.push(i)},id:l,sub:a},t=function(){const e=S.run(f,d);if(R(e)){const{controller:i,promise:m}=p(e,n.controller);n.controller=i,m?.then(c=>{r.current=c,o.emit()}).catch(c=>{if(!h(c))throw c});const b=m;return r.current=b,b}return r.current=e,e};return t.emitter=o,t.destroy=function(){for(const e of u)e();o.clear()},t.id=l,t.listen=function(e){return o.subscribe(()=>{const i=r.current;if(E(i))throw new Error("The value is undefined");e(i)})},t.abort=function(){n.controller&&n.controller.abort()},t}export{S as context,k as subscriber};
|
package/esm/types.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
const t=e=>e;export{t as EMPTY_SELECTOR};
|
package/esm/use.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{useDebugValue as u,useEffect as s,useRef as m}from"react";import{EMPTY_SELECTOR as a}from"./types";import{isAnyOtherError as c,isPromise as T}from"./utils/is";import{useSyncExternalStore as d}from"react";import{subMemo as p}from"./utils/sub-memo";const f=10,E=3;function b(t){const e=m({renders:0,startTime:performance.now()});s(()=>{e.current.renders++,!(performance.now()-e.current.startTime<f)&&(e.current.renders<E||(e.current.startTime=performance.now(),e.current.renders=0,console.warn(`Function ${t.name.length>0?t.name:t} seems to be not memoized, wrap the function to the useCallback or use global defined functions.`)))},[t])}function y(t,e=a){const n=p(t),o=n.call(),i=o.emitter.getInitialSnapshot??o.emitter.getSnapshot;s(()=>n.destroy,[t]);const r=d(o.emitter.subscribe,()=>e(o.emitter.getSnapshot()),()=>e(i()));if(u(r),T(r))throw r;if(c(r))throw n.destroy(),r;return r}export{y as use};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createContext as c}from"../create-context";import{longPromise as r}from"../../__tests__/test-utils";describe("context",()=>{it("should check context",()=>{const e=c({name:"John Doe"}),t=()=>{e.run({name:"Jane Doe"},()=>{expect(e.use()).toEqual({name:"Jane Doe"})})};expect(e.use()).toEqual({name:"John Doe"}),t(),expect(e.use()).toEqual({name:"John Doe"})}),it("should test async context",e=>{const t=c("empty"),o=async()=>new Promise(u=>setTimeout(u,10));t.run("outer",()=>{expect(t.use()).toEqual("outer"),setTimeout(t.wrap(async()=>{try{await o(),expect(t.use()).toEqual("outer"),s()}catch(u){e(u)}}),10),t.run("inner",()=>{expect(t.use()).toEqual("inner"),setTimeout(t.wrap(()=>{try{expect(t.use()).toEqual("inner"),s()}catch(u){e(u)}}),10)}),expect(t.use()).toEqual("outer")});let n=0;function s(){n+=1,n===2&&e()}}),it("should test async nested context",e=>{const t=c(0);t.run(1,()=>{expect(t.use()).toEqual(1),t.run(2,()=>{t.run(3,()=>{expect(t.use()).toEqual(3),setTimeout(t.wrap(()=>{expect(t.use()).toEqual(3)}),10),expect(t.use()).toEqual(3)}),setTimeout(t.wrap(()=>{expect(t.use()).toEqual(2)}),10),expect(t.use()).toEqual(2),t.run(3,()=>{expect(t.use()).toEqual(3),setTimeout(t.wrap(()=>{expect(t.use()).toEqual(3),t.run(4,()=>{expect(t.use()).toEqual(4),setTimeout(t.wrap(()=>{expect(t.use()).toEqual(4),e()}),10),expect(t.use()).toEqual(4)})}),10),expect(t.use()).toEqual(3)}),expect(t.use()).toEqual(2)}),expect(t.use()).toEqual(1)}),expect(t.use()).toEqual(0)}),it("should stress test context with async random code",async()=>{const t=c(0);for(let n=0;n<1e4;n++)t.run(n,()=>{expect(t.use()).toEqual(n)});const o=[];for(let n=0;n<1e4;n++)t.run(n,()=>{expect(t.use()).toEqual(n);const s=new Promise(u=>{setTimeout(t.wrap(()=>{expect(t.use()).toEqual(n),u(n)}),Math.random()*100)});o.push(s)});await Promise.all(o)}),it("should-test-default-value-with-ctx",async()=>{const e=c({counter:1});e.run({counter:10},async()=>{await r(10),expect(e.use()?.counter).toBe(10)}),e.run({counter:12},()=>{expect(e.use()?.counter).toBe(12)})}),it("should test nested context",()=>{const t=c({count:0});function o(){const n=t.use();expect(n?.count).toBe(0),t.run({count:1},()=>{const s=t.use();expect(s?.count).toBe(1),t.run({count:2},()=>{const u=t.use();expect(u?.count).toBe(2)})})}o(),o()}),it("should test nested context with async when promise is returned, but not waited",async()=>{const e=c({count:0});async function t(){await r(10);const n=e.use();expect(n?.count).toBe(1)}async function o(){await t(),e.wrap(t);const n=e.use();expect(n?.count).toBe(1)}e.run({count:1},o)})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Abort as a}from"../common";import{isPromise as e,isFunction as r,isSetValueFunction as t,isMap as o,isSet as s,isArray as u,isEqualBase as i,isAbortError as n}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("isMap",()=>{it("should return true for a Map",()=>{expect(o(new Map)).toBe(!0)}),it("should return false for a non-Map",()=>{expect(o(123)).toBe(!1)})}),describe("isSet",()=>{it("should return true for a Set",()=>{expect(s(new Set)).toBe(!0)}),it("should return false for a non-Set",()=>{expect(s(123)).toBe(!1)})}),describe("isArray",()=>{it("should return true for an array",()=>{expect(u([])).toBe(!0)}),it("should return false for a non-array",()=>{expect(u(123)).toBe(!1)})}),describe("isEqualBase",()=>{it("should return true for equal values",()=>{expect(i(1,1)).toBe(!0)}),it("should return false for non-equal values",()=>{expect(i(1,2)).toBe(!1)})}),describe("isAbortError",()=>{it("should return true for an AbortError",()=>{expect(n(new DOMException("",a.Error))).toBe(!0)}),it("should return false for a non-AbortError",()=>{expect(n(new DOMException("","Error"))).toBe(!1)})});
|
|
@@ -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{subMemo as t}from"../sub-memo";describe("memo-fn",()=>{it("should create memo fn",()=>{function e(){return!0}const o=t(e);expect(o.call().emitter).toBeDefined()})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isUndefined as i}from"./is";var a=(e=>(e.Error="StateAbortError",e))(a||{});function m(r,e){e&&e.abort();const o=new AbortController,{signal:t}=o;return{promise:new Promise((l,n)=>{t.addEventListener("abort",()=>{n(new DOMException("Promise was aborted","StateAbortError"))}),r.then(l).catch(n)}),controller:o}}let s=0;function p(){return s++}function b(r,e=(o,t)=>o===t){if(!i(r.current)){if(!i(r.previous)&&e(r.current,r.previous))return!1;r.previous=r.current}return!0}export{a as Abort,b as canUpdate,m as cancelablePromise,p as generateId};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isPromise as i}from"./is";const a=Symbol("_");function f(s){const t=[];function o(){if(t.length===0)return s;const e=t.at(-1);return e===a?s:e}function u(e,n){t.push(e);const r=n();return i(r)?(async()=>{try{return await r}finally{t.pop()}})():(t.pop(),r)}function c(e){const n=o();return()=>{t.push(n);const r=e();return i(r)?(async()=>{try{return await r}finally{t.pop()}})():(t.pop(),r)}}return{run:u,use:o,wrap:c}}export{f as createContext};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function o(n,s){const t=new Set,i=[];return{clear:()=>{for(const e of i)e();t.clear()},subscribe:e=>(t.add(e),()=>{t.delete(e)}),emit:(...e)=>{for(const r of t)r(...e)},contains:e=>t.has(e),getSnapshot:n,getInitialSnapshot:s,getSize:()=>t.size,subscribeToOtherEmitter(e){const r=e.subscribe(()=>{this.emit()});i.push(r)}}}export{o as createEmitter};
|
package/esm/utils/is.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Abort as e}from"./common";function o(n){return n instanceof Promise}function i(n){return typeof n=="function"}function u(n){return n instanceof Map}function s(n){return n instanceof Set}function a(n){return Array.isArray(n)}function f(n,r){return n===r?!0:!!Object.is(n,r)}function c(n){return typeof n=="function"}function p(n){return n instanceof DOMException&&n.name===e.Error}function k(n){return n instanceof Error&&n.name!==e.Error}function w(n){return n===void 0}export{p as isAbortError,k as isAnyOtherError,a as isArray,f as isEqualBase,i as isFunction,u as isMap,o as isPromise,s as isSet,c as isSetValueFunction,w as isUndefined};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const T=.2,d=10,E=0;function S(f){const n=new Set,{onResolveItem:r,onFinish:a}=f;let o=performance.now(),t=!1;function s(){const e=performance.now(),u=e-o,{size:c}=n;if(u<.2&&c>0&&c<10){o=e,i();return}t||(t=!0,Promise.resolve().then(()=>{t=!1,o=performance.now(),i()}))}function i(){if(n.size!==0){for(const e of n)r&&r(e),n.delete(e);if(n.size>0){s();return}a()}}function l(e){n.add(e),s()}return l}export{S as createScheduler};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isArray as f,isMap as o,isSet as i}from"./is";function b(r,t){if(r==t)return!0;if(typeof r!="object"||r==null||typeof t!="object"||t==null)return!1;if(o(r)&&o(t)){if(r.size!==t.size)return!1;for(const[e,n]of r)if(!Object.is(n,t.get(e)))return!1;return!0}if(i(r)&&i(t)){if(r.size!==t.size)return!1;for(const e of r)if(!t.has(e))return!1;return!0}if(f(r)&&f(t)){if(r.length!==t.length)return!1;for(const[e,n]of r.entries())if(!Object.is(n,t[e]))return!1;return!0}const s=Object.keys(r),c=Object.keys(t);if(s.length!==c.length)return!1;for(const e of s)if(!Object.prototype.hasOwnProperty.call(t,e)||!Object.is(r[e],t[e]))return!1;return!0}export{b as shallow};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{subscriber as c}from"../subscriber";const r=new WeakMap;function s(t){return{call(){const e=r.get(t);if(e)return e.count++,e.returnType;const n={count:1,returnType:c(t)};return r.set(t,n),n.returnType},destroy(){const e=r.get(t);e&&(e.count--,e.count===0&&(e.returnType.destroy(),r.delete(t)))}}}export{s as subMemo};
|