Skip to content

Commit 39eae6f

Browse files
authored
feat: export a AsyncIterableSubject type and add it along related references (#54)
1 parent c5bfba4 commit 39eae6f

File tree

5 files changed

+29
-14
lines changed

5 files changed

+29
-14
lines changed

src/AsyncIterableSubject/index.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export { type AsyncIterableSubject };
2+
3+
/**
4+
* Represents a concept of an async iterable object with a notion of a current value, which is
5+
* publicly readable via a property.
6+
*/
7+
type AsyncIterableSubject<T, TCurrVal = T> = AsyncIterable<T> & {
8+
/**
9+
* A React Ref-like object whose inner `current` property shows the most up to date state value.
10+
*/
11+
12+
value: {
13+
readonly current?: T | TCurrVal;
14+
};
15+
};

src/common/AsyncIterableChannel.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { type MutableRefObject } from 'react';
21
import { type MaybeFunction } from './MaybeFunction.js';
2+
import { type AsyncIterableSubject } from '../AsyncIterableSubject/index.js';
33
import { promiseWithResolvers } from './promiseWithResolvers.js';
44
import { callWithArgsOrReturn } from './callWithArgsOrReturn.js';
55

6-
export { AsyncIterableChannel, type AsyncIterableSubject };
6+
export { AsyncIterableChannel, type AsyncIterableChannelSubject };
77

88
class AsyncIterableChannel<T, TInit = T> {
99
#isClosed = false;
@@ -31,7 +31,7 @@ class AsyncIterableChannel<T, TInit = T> {
3131
this.#nextIteration.resolve({ done: true, value: undefined });
3232
}
3333

34-
out: AsyncIterableSubject<T, TInit> = {
34+
out: AsyncIterableChannelSubject<T, TInit> = {
3535
value: (() => {
3636
const self = this;
3737
return {
@@ -64,12 +64,7 @@ class AsyncIterableChannel<T, TInit = T> {
6464
* meaning that multiple iterators can be consumed (iterated) simultaneously and each one would pick up
6565
* the same values as others the moment they were generated through state updates.
6666
*/
67-
type AsyncIterableSubject<T, TInit> = {
68-
/**
69-
* A React Ref-like object whose inner `current` property shows the most up to date state value.
70-
*/
71-
value: Readonly<MutableRefObject<T | TInit>>;
72-
67+
type AsyncIterableChannelSubject<T, TCurrVal = T> = AsyncIterableSubject<T, TCurrVal> & {
7368
/**
7469
* Returns an async iterator to iterate over. All iterators returned by this share the same source
7570
* values - they can be iterated by multiple consumers simultaneously and each would pick up the

src/common/MaybeFunction.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
export { MaybeFunction };
1+
export { type MaybeFunction };
22

33
type MaybeFunction<T, TPossibleArgs extends unknown[] = []> = T | ((...args: TPossibleArgs) => T);

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { iterateFormatted } from './iterateFormatted/index.js';
66
import { useAsyncIterState, type AsyncIterStateResult } from './useAsyncIterState/index.js';
77
import { type MaybeAsyncIterable } from './MaybeAsyncIterable/index.js';
88
import { type ReactAsyncIterable } from './common/ReactAsyncIterable.js';
9+
import { type AsyncIterableSubject } from './AsyncIterableSubject/index.js';
910

1011
export {
1112
useAsyncIter,
@@ -23,6 +24,7 @@ export {
2324
type AsyncIterStateResult,
2425
type MaybeAsyncIterable,
2526
type ReactAsyncIterable,
27+
type AsyncIterableSubject,
2628

2729
/**
2830
* @deprecated use {@link ReactAsyncIterable `ReactAsyncIterable`} instead.

src/useAsyncIterState/index.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ import { callOrReturn } from '../common/callOrReturn.js';
33
import { useRefWithInitialValue } from '../common/hooks/useRefWithInitialValue.js';
44
import { type MaybeFunction } from '../common/MaybeFunction.js';
55
import { type Iterate } from '../Iterate/index.js'; // eslint-disable-line @typescript-eslint/no-unused-vars
6-
import { AsyncIterableChannel, type AsyncIterableSubject } from '../common/AsyncIterableChannel.js';
6+
import {
7+
AsyncIterableChannel,
8+
type AsyncIterableChannelSubject,
9+
} from '../common/AsyncIterableChannel.js';
710

8-
export { useAsyncIterState, type AsyncIterStateResult, type AsyncIterableSubject };
11+
export { useAsyncIterState, type AsyncIterStateResult, type AsyncIterableChannelSubject };
912

1013
/**
1114
* Basically like {@link https://react.dev/reference/react/useState `React.useState`}, only that the value
@@ -148,11 +151,11 @@ type AsyncIterStateResult<TVal, TInitVal> = [
148151
* meaning multiple iterators can be consumed (iterated) simultaneously, each one picking up the
149152
* same values as others the moment they were generated through state updates.
150153
*/
151-
values: AsyncIterableSubject<TVal, TInitVal>,
154+
values: AsyncIterableChannelSubject<TVal, TInitVal>,
152155

153156
/**
154157
* A function which updates the state, causing the paired async iterable to yield the updated state
155158
* value and immediately sets its `.current.value` property to the latest state.
156159
*/
157-
setValue: (update: TVal | ((prevState: TVal | TInitVal) => TVal)) => void,
160+
setValue: (update: MaybeFunction<TVal, [prevState: TVal | TInitVal]>) => void,
158161
];

0 commit comments

Comments
 (0)