bansa 0.0.23 → 0.0.25

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
@@ -21,11 +21,11 @@ The most basic unit of state. It can be updated to any value using the `.set` me
21
21
  It is created by passing a normal value (number/string/object, etc.) to the `$` function.
22
22
 
23
23
  ```javascript
24
- import { $ } from 'bansa';
24
+ import { $ } from "bansa";
25
25
 
26
26
  const $count = $(42);
27
27
 
28
- const $user = $({ name: 'John Doe', age: 30 });
28
+ const $user = $({ name: "John Doe", age: 30 });
29
29
  ```
30
30
 
31
31
  #### Derived State
@@ -38,13 +38,13 @@ It is created by passing a function to `$`. The arguments to this function are a
38
38
  const $countDouble = $((get) => get($count) * 2);
39
39
 
40
40
  const $userMessage = $((get) => {
41
- if (get($count) < 50) return 'no hello.';
42
- return `Hello, ${get($user).name}!`;
41
+ if (get($count) < 50) return "no hello.";
42
+ return `Hello, ${get($user).name}!`;
43
43
  });
44
44
 
45
45
  const $signalExample = $((_, { signal }) => {
46
- signal.then(() => console.log("$signalExample died"));
47
- return fetch(`/users/${get($count)}`, { signal }).then((res) => res.json());
46
+ signal.then(() => console.log("$signalExample died"));
47
+ return fetch(`/users/${get($count)}`, { signal }).then((res) => res.json());
48
48
  });
49
49
  ```
50
50
 
@@ -62,10 +62,10 @@ The second parameter of `get` is an optional `unwrap` option. The default value
62
62
 
63
63
  ```typescript
64
64
  type AtomState<Value> =
65
- | { promise: undefined; error: undefined; value: Value; } // Success
66
- | { promise: undefined; error: any; value?: Value; } // Error
67
- | { promise: PromiseLike<Value>; error: any; value?: Value; } // Loading
68
- | { promise: typeof inactive; error: undefined; value?: Value; } // Inactive
65
+ | { promise: undefined; error: undefined; value: Value } // Success
66
+ | { promise: undefined; error: any; value?: Value } // Error
67
+ | { promise: PromiseLike<Value>; error: any; value?: Value } // Loading
68
+ | { promise: typeof inactive; error: undefined; value?: Value }; // Inactive
69
69
  ```
70
70
 
71
71
  ##### Keeping a state active
@@ -89,7 +89,6 @@ For derived states, `.get()` can throw. It throws the `Promise` during asynchron
89
89
 
90
90
  If a state is inactive, the `.get()` method temporarily transitions it to an active state. Naturally, the state and all its dependencies will be re-executed. "Temporarily" means at least until the end of the current microtask. This means that calling `.get()` synchronously multiple times in a row will not cause everything to re-execute each time.
91
91
 
92
-
93
92
  ### Updating State
94
93
 
95
94
  You can update the value of a primitive state using the `.set(updater)` method. If `updater` is a normal value, the state is updated to that value. If it's a function, the state is updated with `updater(nextValue)`, where `nextValue` is the state's 'pending value'.
@@ -131,8 +130,8 @@ Upon subscription, if the state was inactive, an update is scheduled. During the
131
130
  ```javascript
132
131
  const $count = $(0);
133
132
  const unsubscribe = $count.subscribe((value, { signal }) => {
134
- console.log('value', value);
135
- signal.then(() => console.log('value end', value));
133
+ console.log("value", value);
134
+ signal.then(() => console.log("value end", value));
136
135
  });
137
136
 
138
137
  // value 0
@@ -154,8 +153,8 @@ If you want to subscribe to multiple states simultaneously, you should declare a
154
153
 
155
154
  ```javascript
156
155
  const $merged = $((get) => ({
157
- count: get($count),
158
- countDouble: get($countDouble),
156
+ count: get($count),
157
+ countDouble: get($countDouble),
159
158
  }));
160
159
 
161
160
  $merged.subscribe(({ count, countDouble }) => console.log(`${count} * 2 = ${countDouble}`));
@@ -167,21 +166,21 @@ For a derived state where the function returns a `Promise`, you can use the auto
167
166
 
168
167
  ```javascript
169
168
  const $user = $(async (get) => {
170
- const response = await fetch(`/users/${get($count)}`);
171
- if (!response.ok) throw new Error('Failed to fetch user');
172
- return response.json();
169
+ const response = await fetch(`/users/${get($count)}`);
170
+ if (!response.ok) throw new Error("Failed to fetch user");
171
+ return response.json();
173
172
  });
174
173
  $user.watch(() => {
175
- console.log($user.state);
174
+ console.log($user.state);
176
175
  });
177
176
 
178
177
  const $userName = $((get) => get($user).name);
179
178
 
180
- const faultyAtom = $(() => Promise.reject(new Error('Something went wrong')));
179
+ const faultyAtom = $(() => Promise.reject(new Error("Something went wrong")));
181
180
  faultyAtom.watch(() => {
182
- if (!faultyAtom.state.promise && faultyAtom.state.error) {
183
- console.error('An error occurred:', faultyAtom.state.error.message);
184
- }
181
+ if (!faultyAtom.state.promise && faultyAtom.state.error) {
182
+ console.error("An error occurred:", faultyAtom.state.error.message);
183
+ }
185
184
  });
186
185
  ```
187
186
 
@@ -193,12 +192,12 @@ Like an `AbortSignal`, it can be passed to existing web APIs like `fetch` or `ad
193
192
 
194
193
  ```javascript
195
194
  const $user = $(async (get, { signal }) => {
196
- const count = get($count);
197
- const json = await fetch(`/users/${count}`, { signal }).then((res) => res.json());
198
- signal.then(() => {
199
- console.log(count, json, "not used");
200
- });
201
- return json;
195
+ const count = get($count);
196
+ const json = await fetch(`/users/${count}`, { signal }).then((res) => res.json());
197
+ signal.then(() => {
198
+ console.log(count, json, "not used");
199
+ });
200
+ return json;
202
201
  });
203
202
  ```
204
203
 
@@ -207,19 +206,13 @@ const $user = $(async (get, { signal }) => {
207
206
  By default, equality is checked with `Object.is`, so for objects or arrays, an update can occur if the reference is different even if the content is the same. To perform additional equality checks, you can provide an `equals` option when declaring the state. In this case, it first checks with `Object.is`, and if they are different, it checks again with the `equals` function. If either returns true, the value change is ignored.
208
207
 
209
208
  ```javascript
210
- const $user = $(
211
- { id: 1, name: 'Alice' },
212
- { equals: (next, prev) => next.id === prev.id },
213
- );
209
+ const $user = $({ id: 1, name: "Alice" }, { equals: (next, prev) => next.id === prev.id });
214
210
 
215
- const $user2 = $(
216
- (get) => get($user),
217
- { equals: (next, prev) => next.name === prev.name },
218
- );
211
+ const $user2 = $((get) => get($user), { equals: (next, prev) => next.name === prev.name });
219
212
 
220
- userAtom.set({ id: 1, name: 'Bob' });
213
+ userAtom.set({ id: 1, name: "Bob" });
221
214
 
222
- userAtom.set({ id: 2, name: 'Alice' });
215
+ userAtom.set({ id: 2, name: "Alice" });
223
216
  ```
224
217
 
225
218
  In the example above, the first update is ignored because the `id` is the same. The second update has a different `id`, so `$user` is updated, but since the `name` is the same, `$user2` is not updated.
@@ -243,7 +236,10 @@ For reference, the value that `$$`'s `get` function returns instead of throwing
243
236
  ```javascript
244
237
  const o = () => o;
245
238
  const toUndefined = () => undefined;
246
- Object.setPrototypeOf(o, new Proxy(o, { get: (_, k) => k === Symbol.toPrimitive ? toUndefined : o }));
239
+ Object.setPrototypeOf(
240
+ o,
241
+ new Proxy(o, { get: (_, k) => (k === Symbol.toPrimitive ? toUndefined : o) }),
242
+ );
247
243
  ```
248
244
 
249
245
  The `o` in this code returns the same value no matter how many properties are accessed or functions are called. For example, `o.a.b.c().d()().asdf()()()() === o` is `true`. Therefore, it allows most state-merging functions composed of selectors and simple methods like filter/map/reduce to execute without issues. However, it's not a silver bullet, so some caution is needed, and it should preferably be used only for state merging.
@@ -264,11 +260,11 @@ For example, the following shows a situation where not splitting the state enoug
264
260
  const $userId = $(123);
265
261
  const $postId = $(456);
266
262
  const $pageData = $(async (get, { signal }) => {
267
- const user = await fetch(`/users/${get($userId)}`, { signal }).then((res) => res.json());
268
- const post = await fetch(`/posts/${get($postId)}`, { signal }).then((res) => res.json());
269
- userElm.innerHTML = user.name;
270
- postElm.innerHTML = post.html;
271
- commentElm.innerHTML = `Hello ${user.name}! Comment to ${post.author}.`;
263
+ const user = await fetch(`/users/${get($userId)}`, { signal }).then((res) => res.json());
264
+ const post = await fetch(`/posts/${get($postId)}`, { signal }).then((res) => res.json());
265
+ userElm.innerHTML = user.name;
266
+ postElm.innerHTML = post.html;
267
+ commentElm.innerHTML = `Hello ${user.name}! Comment to ${post.author}.`;
272
268
  });
273
269
  ```
274
270
 
@@ -277,17 +273,23 @@ This code looks simple and clean, but if only one of `userId` or `postId` is upd
277
273
  ```javascript
278
274
  const $userId = $(123);
279
275
  const $user = $((get) => fetch(`/users/${get($userId)}`, { signal }).then((res) => res.json()));
280
- $user.subscribe((user) => { userElm.innerHTML = user.name; });
276
+ $user.subscribe((user) => {
277
+ userElm.innerHTML = user.name;
278
+ });
281
279
 
282
280
  const $postId = $(456);
283
281
  const $post = $((get) => fetch(`/posts/${get($postId)}`, { signal }).then((res) => res.json()));
284
- $post.subscribe((post) => { postElm.innerHTML = post.html; });
282
+ $post.subscribe((post) => {
283
+ postElm.innerHTML = post.html;
284
+ });
285
285
 
286
286
  const $pageData = $$((get) => ({
287
- userName: get($user).name,
288
- postAuthor: get($post).author,
287
+ userName: get($user).name,
288
+ postAuthor: get($post).author,
289
289
  }));
290
- $pageData.subscribe(({ userName, postAuthor }) => { commentElm.innerHTML = `Hello ${userName}! Comment to ${postAuthor}.`; });
290
+ $pageData.subscribe(({ userName, postAuthor }) => {
291
+ commentElm.innerHTML = `Hello ${userName}! Comment to ${postAuthor}.`;
292
+ });
291
293
  ```
292
294
 
293
295
  The number of lines of code has increased slightly, but the previously mentioned problems have been resolved.
@@ -377,30 +379,32 @@ Now, you can read from `$reader` and write to `$writer`. Since `$shared` does no
377
379
 
378
380
  ```javascript
379
381
  const delayedState = (initial, minDelay, maxDelay) => {
380
- const $value = $(initial);
381
- const $delayedValue = $(initial);
382
-
383
- const $eventStartTime = $(0);
384
- const $eventLastTime = $(0);
385
- const $delayedTime = $((get) => Math.min(get($eventStartTime) + maxDelay, get($eventLastTime) + minDelay));
386
- const $delayedInfo = $((get) => ({
387
- value: get($value),
388
- time: get($delayedTime),
389
- }));
390
- $delayedInfo.subscribe(({ value, time }, { signal }) => {
391
- const timeout = Math.max(0, time - Date.now());
392
- const timer = setTimeout(() => $delayedValue.set(value), timeout);
393
- signal.then(() => clearTimeout(timer));
394
- });
395
-
396
- const update = (value, eager = false) => {
397
- const now = eager ? -Infinity : Date.now();
398
- if ($value.get() === $delayedValue.get()) $eventStartTime.set(now);
399
- $eventLastTime.set(now);
400
- $value.set(value);
401
- };
402
-
403
- return [$delayedValue, update];
382
+ const $value = $(initial);
383
+ const $delayedValue = $(initial);
384
+
385
+ const $eventStartTime = $(0);
386
+ const $eventLastTime = $(0);
387
+ const $delayedTime = $((get) =>
388
+ Math.min(get($eventStartTime) + maxDelay, get($eventLastTime) + minDelay),
389
+ );
390
+ const $delayedInfo = $((get) => ({
391
+ value: get($value),
392
+ time: get($delayedTime),
393
+ }));
394
+ $delayedInfo.subscribe(({ value, time }, { signal }) => {
395
+ const timeout = Math.max(0, time - Date.now());
396
+ const timer = setTimeout(() => $delayedValue.set(value), timeout);
397
+ signal.then(() => clearTimeout(timer));
398
+ });
399
+
400
+ const update = (value, eager = false) => {
401
+ const now = eager ? -Infinity : Date.now();
402
+ if ($value.get() === $delayedValue.get()) $eventStartTime.set(now);
403
+ $eventLastTime.set(now);
404
+ $value.set(value);
405
+ };
406
+
407
+ return [$delayedValue, update];
404
408
  };
405
409
  ```
406
410
 
@@ -414,46 +418,46 @@ $inputValue.subscribe(console.log);
414
418
 
415
419
  ```javascript
416
420
  const $windowScroll = $((_, { signal }) => {
417
- let lastTime = Date.now();
418
- const $scrollY = $(window.scrollY);
419
- const $scrollOnTop = $((get) => get($scrollY) === 0);
420
-
421
- const $scrollMovingAvgY = $(0);
422
- const $scrollDirectionY = $((get) => Math.sign(get($scrollMovingAvgY)));
423
-
424
- const onScrollChange = () => {
425
- const now = Date.now();
426
- lastTime = now;
427
-
428
- const alpha = 0.995 ** (now - lastTime);
429
- const scrollY = window.scrollY;
430
- const deltaY = scrollY - $scrollY.get();
431
- const movingAvgY = alpha * $scrollMovingAvgY.get() + (1 - alpha) * deltaY;
432
-
433
- $scrollY.set(scrollY);
434
- $scrollMovingAvgY.set(movingAvgY);
435
- };
436
- window.addEventListener('scroll', onScrollChange, {
437
- passive: true,
438
- signal,
439
- });
440
- window.addEventListener('resize', onScrollChange, {
441
- passive: true,
442
- signal,
443
- });
444
-
445
- return {
446
- $scrollY,
447
- $scrollOnTop,
448
- $scrollMovingAvgY,
449
- $scrollDirectionY,
450
- };
421
+ let lastTime = Date.now();
422
+ const $scrollY = $(window.scrollY);
423
+ const $scrollOnTop = $((get) => get($scrollY) === 0);
424
+
425
+ const $scrollMovingAvgY = $(0);
426
+ const $scrollDirectionY = $((get) => Math.sign(get($scrollMovingAvgY)));
427
+
428
+ const onScrollChange = () => {
429
+ const now = Date.now();
430
+ lastTime = now;
431
+
432
+ const alpha = 0.995 ** (now - lastTime);
433
+ const scrollY = window.scrollY;
434
+ const deltaY = scrollY - $scrollY.get();
435
+ const movingAvgY = alpha * $scrollMovingAvgY.get() + (1 - alpha) * deltaY;
436
+
437
+ $scrollY.set(scrollY);
438
+ $scrollMovingAvgY.set(movingAvgY);
439
+ };
440
+ window.addEventListener("scroll", onScrollChange, {
441
+ passive: true,
442
+ signal,
443
+ });
444
+ window.addEventListener("resize", onScrollChange, {
445
+ passive: true,
446
+ signal,
447
+ });
448
+
449
+ return {
450
+ $scrollY,
451
+ $scrollOnTop,
452
+ $scrollMovingAvgY,
453
+ $scrollDirectionY,
454
+ };
451
455
  });
452
456
 
453
457
  const $navHidden = $((get) => {
454
- const { $scrollOnTop, $scrollDirectionY } = get($windowScroll);
455
- const scrollOnTop = get($scrollOnTop);
456
- const directionY = get($scrollDirectionY);
457
- return !scrollOnTop && directionY > 0;
458
+ const { $scrollOnTop, $scrollDirectionY } = get($windowScroll);
459
+ const scrollOnTop = get($scrollOnTop);
460
+ const directionY = get($scrollDirectionY);
461
+ return !scrollOnTop && directionY > 0;
458
462
  });
459
- ```
463
+ ```
@@ -0,0 +1,83 @@
1
+ //#region src/atom.d.ts
2
+ type Atom<Value> = PrimitiveAtom<Value> | DerivedAtom<Value>;
3
+ type CommonAtom<Value> = {
4
+ readonly get: () => Value;
5
+ readonly watch: (watcher: AtomWatcher) => () => void;
6
+ readonly subscribe: (subscriber: AtomSubscribe<Value>) => () => void;
7
+ readonly state: AtomState<Value>;
8
+ };
9
+ type PrimitiveAtom<Value> = CommonAtom<Value> & {
10
+ readonly set: (value: AtomUpdater<Value>) => void;
11
+ readonly state: AtomSuccessState<Value>;
12
+ };
13
+ type DerivedAtom<Value> = CommonAtom<Value>;
14
+ type AtomWatcher = () => void;
15
+ type AtomSubscribe<Value> = (value: Value, options: AtomSubscriberOptions) => void;
16
+ type AtomInit<Value> = Value | AtomGetter<Value>;
17
+ type AtomUpdater<Value> = Value | AtomReducer<Value>;
18
+ type AtomInactiveState<Value> = {
19
+ promise: typeof inactive;
20
+ error: any;
21
+ value?: Value;
22
+ };
23
+ type AtomPromiseState<Value> = {
24
+ promise: PromiseLike<Value>;
25
+ error: any;
26
+ value?: Value;
27
+ };
28
+ type AtomSuccessState<Value> = {
29
+ promise: undefined;
30
+ error: undefined;
31
+ value: Value;
32
+ };
33
+ type AtomErrorState<Value> = {
34
+ promise: undefined;
35
+ error: any;
36
+ value?: Value;
37
+ };
38
+ type AtomState<Value> = AtomInactiveState<Value> | AtomPromiseState<Value> | AtomSuccessState<Value> | AtomErrorState<Value>;
39
+ type AtomSubscriberOptions = {
40
+ readonly signal: ThenableSignal;
41
+ };
42
+ type AtomGetter<Value> = (get: GetAtom, options: AtomGetOptions) => Value | PromiseLike<Value>;
43
+ type AtomReducer<Value> = (value: Value) => Value;
44
+ type AtomGetOptions = {
45
+ readonly signal: ThenableSignal;
46
+ };
47
+ type ThenableSignal = AbortSignal & {
48
+ then: (f: () => void) => void;
49
+ };
50
+ type GetAtom = {
51
+ <Value>(anotherAtom: Atom<Value>, unwrap?: true): Value;
52
+ <Value>(anotherAtom: Atom<Value>, unwrap: false): AtomState<Value>;
53
+ };
54
+ type CreateAtom = {
55
+ <Value>(init: AtomGetter<Value>, options?: AtomOptions<Value>): DerivedAtom<Value>;
56
+ <Value>(init: Value, options?: AtomOptions<Value>): PrimitiveAtom<Value>;
57
+ <Value>(init: Value | AtomGetter<Value>, options?: AtomOptions<Value>): Atom<Value>;
58
+ };
59
+ type AtomOptions<Value> = {
60
+ equals?: AtomEquals<Value>;
61
+ persist?: boolean;
62
+ eager?: boolean;
63
+ };
64
+ type AtomEquals<Value> = (value: Value, prevValue: Value) => boolean;
65
+ type AtomScope = {
66
+ <Value>(baseAtom: PrimitiveAtom<Value>): PrimitiveAtom<Value>;
67
+ <Value>(baseAtom: DerivedAtom<Value>): DerivedAtom<Value>;
68
+ <Value>(baseAtom: Atom<Value>): Atom<Value>;
69
+ <Value>(baseAtom: PrimitiveAtom<Value>, strict: true): PrimitiveAtom<Value> | undefined;
70
+ <Value>(baseAtom: DerivedAtom<Value>, strict: true): DerivedAtom<Value> | undefined;
71
+ <Value>(baseAtom: Atom<Value>, strict: true): Atom<Value> | undefined;
72
+ };
73
+ type SetLike<Key> = Key[] | Set<Key> | (Key extends object ? WeakSet<Key> : never);
74
+ type MapLike<Key, Value> = Map<Key, Value> | (Key extends object ? WeakMap<Key, Value> : never) | (Key extends string | number | symbol ? Record<Key, Value> : never);
75
+ declare const inactive: Promise<never>;
76
+ declare const $: CreateAtom;
77
+ declare const isAtom: (x: unknown) => x is Atom<unknown>;
78
+ declare const isPrimitiveAtom: (x: unknown) => x is PrimitiveAtom<unknown>;
79
+ type AtomValuePair<Value> = [Atom<Value>, Value | PrimitiveAtom<Value>] | [DerivedAtom<Value>, Value | Atom<Value>];
80
+ declare const createScope: <T extends AtomValuePair<unknown>[]>(parentScope?: AtomScope | null, atomValuePairs?: T) => AtomScope;
81
+ //#endregion
82
+ export { $, Atom, AtomEquals, AtomErrorState, AtomGetOptions, AtomGetter, AtomInactiveState, AtomInit, AtomOptions, AtomPromiseState, AtomReducer, AtomScope, AtomState, AtomSubscribe, AtomSubscriberOptions, AtomSuccessState, AtomUpdater, AtomValuePair, AtomWatcher, CommonAtom, DerivedAtom, GetAtom, MapLike, PrimitiveAtom, SetLike, ThenableSignal, createScope, inactive, isAtom, isPrimitiveAtom };
83
+ //# sourceMappingURL=atom.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atom.d.mts","names":[],"sources":["../src/atom.ts"],"mappings":"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"}