diff --git a/.changeset/nice-moons-run.md b/.changeset/nice-moons-run.md new file mode 100644 index 0000000000..0096d51788 --- /dev/null +++ b/.changeset/nice-moons-run.md @@ -0,0 +1,5 @@ +--- +"effect": minor +--- + +expose .length property on MutableList diff --git a/packages/effect/src/MutableList.ts b/packages/effect/src/MutableList.ts index 1027aaaa5c..2009bc8cd8 100644 --- a/packages/effect/src/MutableList.ts +++ b/packages/effect/src/MutableList.ts @@ -21,6 +21,7 @@ export type TypeId = typeof TypeId */ export interface MutableList extends Iterable, Pipeable, Inspectable { readonly [TypeId]: TypeId + readonly length: number /** @internal */ head: LinkedListNode | undefined @@ -28,7 +29,7 @@ export interface MutableList extends Iterable, Pipeable, Inspectable { tail: LinkedListNode | undefined } -const MutableListProto: Omit, "head" | "tail"> = { +const MutableListProto: Omit, "head" | "tail" | "length"> = { [TypeId]: TypeId, [Symbol.iterator](this: MutableList): Iterator { let done = false @@ -72,7 +73,7 @@ const MutableListProto: Omit, "head" | "tail"> = { } interface MutableListImpl extends MutableList { - _length: number + length: number } /** @internal */ @@ -101,7 +102,7 @@ export const empty = (): MutableList => { const list = Object.create(MutableListProto) list.head = undefined list.tail = undefined - list._length = 0 + list.length = 0 return list } @@ -141,7 +142,7 @@ export const isEmpty = (self: MutableList): boolean => length(self) === 0 * @since 2.0.0 * @category getters */ -export const length = (self: MutableList): number => (self as MutableListImpl)._length +export const length = (self: MutableList): number => (self as MutableListImpl).length /** * Returns the last element of the list, if it exists. @@ -185,7 +186,7 @@ export const forEach: { * @since 2.0.0 */ export const reset = (self: MutableList): MutableList => { - ;(self as MutableListImpl)._length = 0 + ;(self as MutableListImpl).length = 0 self.head = undefined self.tail = undefined return self @@ -215,7 +216,7 @@ export const append: { node.prev = self.tail self.tail = node } - ;(self as MutableListImpl)._length += 1 + ;(self as MutableListImpl).length += 1 return self }) @@ -269,7 +270,7 @@ export const prepend: { if (self.tail === undefined) { self.tail = node } - ;(self as MutableListImpl)._length += 1 + ;(self as MutableListImpl).length += 1 return self }) @@ -291,7 +292,7 @@ const remove = (self: MutableList, node: LinkedListNode): void => { self.tail = undefined self.head = undefined } - if ((self as MutableListImpl)._length > 0) { - ;(self as MutableListImpl)._length -= 1 + if ((self as MutableListImpl).length > 0) { + ;(self as MutableListImpl).length -= 1 } } diff --git a/packages/effect/src/internal/mailbox.ts b/packages/effect/src/internal/mailbox.ts index 875de46fbc..07b8d40d63 100644 --- a/packages/effect/src/internal/mailbox.ts +++ b/packages/effect/src/internal/mailbox.ts @@ -54,8 +54,6 @@ type MailboxState = { readonly exit: Exit } -const asDone = core.exitAs([[] as Array, true] as const) - class MailboxImpl implements Api.Mailbox { readonly [TypeId]: Api.TypeId = TypeId readonly [ReadonlyTypeId]: Api.ReadonlyTypeId = ReadonlyTypeId @@ -145,8 +143,7 @@ class MailboxImpl implements Api.Mailbox { return core.suspend(() => { if (this.state._tag !== "Open") { return core.succeed(false) - } - if (MutableList.length(this.messages) >= this.capacity) { + } else if (this.messages.length >= this.capacity) { return core.map(this.offerRemaining([message]), Arr.isEmptyArray) } MutableList.append(this.messages, message) @@ -157,8 +154,7 @@ class MailboxImpl implements Api.Mailbox { unsafeOffer(message: A): boolean { if (this.state._tag !== "Open") { return false - } - if (MutableList.length(this.messages) >= this.capacity) { + } else if (this.messages.length >= this.capacity) { return false } MutableList.append(this.messages, message) @@ -181,7 +177,7 @@ class MailboxImpl implements Api.Mailbox { if (this.state._tag !== "Open") { return Arr.fromIterable(messages) } - const free = this.capacity - MutableList.length(this.messages) + const free = this.capacity - this.messages.length if (free === 0) { return Arr.fromIterable(messages) } @@ -234,7 +230,7 @@ class MailboxImpl implements Api.Mailbox { } end = this.done(core.exitVoid) takeAll: Effect, done: boolean], E> = core.suspend(() => { - const len = MutableList.length(this.messages) + const len = this.messages.length if (len > 0) { const messages = listToArray(this.messages, len) MutableList.reset(this.messages) @@ -244,17 +240,19 @@ class MailboxImpl implements Api.Mailbox { this.releaseCapacity(len) return core.succeed([messages, false]) } else if (this.state._tag === "Done") { - return asDone(this.state.exit) + return core.exitAs(this.state.exit, [[], true]) } return core.zipRight(this.awaitTake, this.takeAll) }) takeN(n: number): Effect, done: boolean], E> { return core.suspend(() => { if (n <= 0) { - return this.state._tag === "Done" ? asDone(this.state.exit) : core.succeed([[], false]) + return this.state._tag === "Done" + ? core.exitAs(this.state.exit, [[], true]) + : core.succeed([[], false]) } n = Math.min(n, this.capacity) - if (n <= MutableList.length(this.messages)) { + if (n <= this.messages.length) { const messages = new Array(n) for (let i = 0; i < n; i++) { messages[i] = MutableList.shift(this.messages)! @@ -269,7 +267,7 @@ class MailboxImpl implements Api.Mailbox { }) } take: Effect, E> = core.suspend(() => { - if (MutableList.length(this.messages) > 0) { + if (this.messages.length > 0) { const message = MutableList.shift(this.messages)! this.releaseCapacity(1) return core.succeed(Option.some(message)) @@ -290,7 +288,7 @@ class MailboxImpl implements Api.Mailbox { }) }) unsafeSize(): Option.Option { - return this.state._tag !== "Done" ? Option.some(MutableList.length(this.messages)) : Option.none() + return this.state._tag !== "Done" ? Option.some(this.messages.length) : Option.none() } size = core.sync(() => this.unsafeSize()) }