1import { TalkbackFn, TeardownFn, Start, Push, SignalKind } from './types';
2
3declare global {
4 interface SymbolConstructor {
5 readonly observable: symbol;
6 }
7}
8
9/** Placeholder {@link TeardownFn | teardown functions} that's a no-op.
10 * @see {@link TeardownFn} for the definition and usage of teardowns.
11 * @internal
12 */
13export const teardownPlaceholder: TeardownFn = () => {
14 /*noop*/
15};
16
17/** Placeholder {@link TalkbackFn | talkback function} that's a no-op.
18 * @privateRemarks
19 * This is frequently used in the codebase as a no-op initializer value for talkback functions in
20 * the implementation of {@link Operator | Operators}. This is cheaper than initializing the
21 * variables of talkbacks to `undefined` or `null` and performing an extra check before calling
22 * them. Since the {@link Start | Start signal} is assumed to come first and carry a talkback, we can
23 * use this to our advantage and use a no-op placeholder before {@link Start} is received.
24 *
25 * @internal
26 */
27export const talkbackPlaceholder: TalkbackFn = teardownPlaceholder;
28
29/** Wraps the passed {@link TalkbackFn | talkback function} in a {@link Start | Start signal}.
30 * @internal
31 */
32export function start<T>(talkback: TalkbackFn): Start<T> {
33 return {
34 tag: SignalKind.Start,
35 0: talkback,
36 } as Start<T>;
37}
38
39/** Wraps the passed value in a {@link Push | Push signal}.
40 * @internal
41 */
42export function push<T>(value: T): Push<T> {
43 return {
44 tag: SignalKind.Push,
45 0: value,
46 } as Push<T>;
47}
48
49/** Returns the well-known symbol specifying the default AsyncIterator.
50 * @internal
51 */
52export const asyncIteratorSymbol = (): typeof Symbol.asyncIterator =>
53 (typeof Symbol === 'function' && Symbol.asyncIterator) || ('@@asyncIterator' as any);
54
55/** Returns the well-known symbol specifying the default ES Observable.
56 * @privateRemarks
57 * This symbol is used to mark an object as a default ES Observable. By the specification, an object
58 * that abides by the default Observable implementation must carry a method set to this well-known
59 * symbol that returns the Observable implementation. It's common for this object to be an
60 * Observable itself and return itself on this method.
61 *
62 * @see {@link https://github.com/0no-co/wonka/issues/122} for notes on the intercompatibility
63 * between Observable implementations.
64 *
65 * @internal
66 */
67export const observableSymbol = (): typeof Symbol.observable =>
68 (typeof Symbol === 'function' && Symbol.observable) || ('@@observable' as any);