| 2046 | } |
| 2047 | |
| 2048 | class UnboundedPubSub<in out A> implements PubSub.Atomic<A> { |
| 2049 | publisherHead: Node<A> = { |
| 2050 | value: AbsentValue, |
| 2051 | replayIndex: undefined, |
| 2052 | subscribers: 0, |
| 2053 | next: null |
| 2054 | } |
| 2055 | publisherTail = this.publisherHead |
| 2056 | publisherIndex = 0 |
| 2057 | subscribersIndex = 0 |
| 2058 | |
| 2059 | readonly capacity = Number.MAX_SAFE_INTEGER |
| 2060 | readonly replayBuffer: ReplayBuffer<A> | undefined |
| 2061 | |
| 2062 | constructor(replayBuffer: ReplayBuffer<A> | undefined) { |
| 2063 | this.replayBuffer = replayBuffer |
| 2064 | } |
| 2065 | |
| 2066 | replayWindow(): PubSub.ReplayWindow<A> { |
| 2067 | return this.replayBuffer ? new ReplayWindowImpl(this.replayBuffer) : emptyReplayWindow |
| 2068 | } |
| 2069 | |
| 2070 | isEmpty(): boolean { |
| 2071 | return this.publisherHead === this.publisherTail |
| 2072 | } |
| 2073 | |
| 2074 | isFull(): boolean { |
| 2075 | return false |
| 2076 | } |
| 2077 | |
| 2078 | size(): number { |
| 2079 | return this.publisherIndex - this.subscribersIndex |
| 2080 | } |
| 2081 | |
| 2082 | publish(value: A): boolean { |
| 2083 | const replayIndex = this.replayBuffer?.offer(value) |
| 2084 | const subscribers = this.publisherTail.subscribers |
| 2085 | if (subscribers !== 0) { |
| 2086 | const node: Node<A> = { |
| 2087 | value, |
| 2088 | replayIndex, |
| 2089 | subscribers, |
| 2090 | next: null |
| 2091 | } |
| 2092 | this.publisherTail.next = node |
| 2093 | this.publisherTail = this.publisherTail.next |
| 2094 | this.publisherIndex += 1 |
| 2095 | } |
| 2096 | return true |
| 2097 | } |
| 2098 | |
| 2099 | publishAll(elements: Iterable<A>): Array<A> { |
| 2100 | if (this.publisherTail.subscribers !== 0) { |
| 2101 | for (const a of elements) { |
| 2102 | this.publish(a) |
| 2103 | } |
| 2104 | } else if (this.replayBuffer) { |
| 2105 | this.replayBuffer.offerAll(elements) |
nothing calls this directly
no outgoing calls
no test coverage detected