Skip to content

Commit bf1af1b

Browse files
committed
Edit conversion and conversion document
All of the previously converted functions have now be removed, now that more information has been given. There is only one enum, but that may be removed in the future.
1 parent 605fea7 commit bf1af1b

2 files changed

Lines changed: 84 additions & 172 deletions

File tree

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Conversion for `common-web/async.ts`
2+
3+
## `export const readFromGenerator = async <T>(gen: AsyncGenerator<T>, isDone: (last?: T) => Promise<boolean> | boolean, waitFor: Promise<unknown> = Promise.resolve(), maxLength = Number.MAX_SAFE_INTEGER,): Promise<T[]>`
4+
5+
This is redundant and will not be converted. Use `AsyncSequence` instead.
6+
7+
## `export type Deferrable`
8+
9+
This is redundant and will not be converted. Use `CheckedContinuation`, `CheckedThrowingContinuation`, and `withCheckedContinuation` instead.
10+
11+
## `export const createDeferrable = (): Deferrable`
12+
13+
This is redundant and will not be converted.
14+
15+
## `export const createDeferrables = (count: number): Deferrable[]`
16+
17+
This is redundant and will not be converted.
18+
19+
## `export const allComplete = async (deferrables: Deferrable[]): Promise<void>`
20+
21+
This is redundant and will not be converted. Instead, use `await` on the method instead.
22+
23+
## `export class AsyncBuffer<T>`
24+
25+
This is redundant and will not be converted. Use `AsyncStream` instead.
26+
27+
## `export class AsyncBufferFullError extends Error`
28+
29+
This has been converted.
30+
31+
## `export function allFulfilled<T extends readonly unknown[] | []>(promises: T,): Promise<{ -readonly [P in keyof T]: Awaited<T[P]> }>`
32+
33+
This is redundant and will not be converted. Use `withTaskGroup` for parallel `await`s. If an error does happen the first time, simply throw on first error or collect the results.
34+
35+
## `export function allFulfilled<T>(promises: Iterable<T | PromiseLike<T>>,): Promise<Awaited<T>[]>`
36+
37+
This is redundant and will not be converted.
38+
39+
## `export function allFulfilled(promises: Iterable<Promise<unknown>>,): Promise<unknown[]>`
40+
41+
This is redundant and will not be converted.
42+
43+
## `export function handleAllSettledErrors<T extends readonly PromiseSettledResult<unknown>[] | [],>(results: T,)`
44+
45+
This is redundant and will not be converted.
46+
47+
## `export function handleAllSettledErrors<T>(results: PromiseSettledResult<T>[],): T[]`
48+
49+
This is redundant and will not be converted.
50+
51+
## `export function handleAllSettledErrors(results: PromiseSettledResult<unknown>[],): unknown[]`
52+
53+
This is redundant and will not be converted.
54+
55+
## `export function isRejectedResult(result: PromiseSettledResult<unknown>,): result is PromiseRejectedResult`
56+
57+
This is redundant and will not be converted.
58+
59+
## `function extractReason(result: PromiseRejectedResult): unknown`
60+
61+
This is redundant and will not be converted.
62+
63+
## `export function isFulfilledResult<T>(result: PromiseSettledResult<T>,): result is PromiseFulfilledResult<T>`
64+
65+
This is redundant and will not be converted.
66+
67+
## `function extractValue<T>(result: PromiseFulfilledResult<T>): T`
68+
69+
This is redundant and will not be converted.
70+
71+
## `function stringifyReason(reason: unknown): string`
72+
73+
This is redundant and will not be converted.

Sources/ATCommonWeb/TypeScript-bound/Async.swift

Lines changed: 11 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -7,183 +7,22 @@
77

88
import Foundation
99

10-
/// Reads values from an `AsyncSequence` until a condition is met or an external signal resolves.
11-
///
12-
/// - Parameters:
13-
/// - sequence: The `AsyncSequence` to read from.
14-
/// - isDone: Asynchronously evaluates whether reading should stop.
15-
/// - waitFor: A `Task<Void, Never>` that triggers an external stop signal when completed.
16-
/// Optional. Defaults to `nil`.
17-
/// - maxLength: The maximum number of elements to collect before stopping. Defaults to `.max`.
18-
///
19-
/// - Returns: An array containing the collected elements from the sequence.
20-
func readFromAsyncSequence<S: AsyncSequence>(
21-
_ sequence: S,
22-
isDone: @escaping (S.Element?) async -> Bool,
23-
waitFor: Task<Void, Never>? = nil,
24-
maxLength: Int = .max
25-
) async -> [S.Element] {
26-
var results: [S.Element] = []
27-
var iterator = sequence.makeAsyncIterator()
28-
var lastValue: S.Element?
10+
/// Errors that can occur with certain Ayncronous buffer tasks.
11+
public enum AsyncBufferFullError: Error, LocalizedError, CustomStringConvertible {
2912

30-
// Define an early stop mechanism
31-
func shouldStop() async -> Bool {
32-
return await isDone(lastValue) || results.count >= maxLength
33-
}
34-
35-
// Handle external stop signal (if provided)
36-
var hasStoppedExternally = false
37-
let externalStopTask = Task {
38-
await waitFor?.value
39-
hasStoppedExternally = true
40-
}
41-
42-
defer { externalStopTask.cancel() } // Cleanup on exit
43-
44-
// Read from sequence
45-
while !hasStoppedExternally, let value = try? await iterator.next() {
46-
lastValue = value
47-
results.append(value)
48-
49-
if await shouldStop() {
50-
break
51-
}
52-
}
53-
54-
return results
55-
}
56-
57-
/// A structure that defines a deferrable, asynchronous event stream.
58-
///
59-
/// This allows you to manually trigger an event that can be awaited in an `AsyncStream`.
60-
struct DeferrableStream {
61-
62-
/// An asynchronous stream of void events.
63-
public let stream: AsyncStream<Void>
64-
65-
/// The continuation that allows externally sending values to the stream.
66-
private let continuation: AsyncStream<Void>.Continuation
67-
68-
/// Initializes a new `DeferrableStream` instance.
69-
public init() {
70-
var cont: AsyncStream<Void>.Continuation!
71-
self.stream = AsyncStream { continuation in
72-
cont = continuation
73-
}
74-
75-
self.continuation = cont
76-
}
77-
78-
/// Resolves the deferrable by yielding a signal to the stream.
79-
public func resolve() {
80-
continuation.yield(())
81-
}
82-
}
83-
84-
/// An asynchronous buffer that stores elements and allows streaming them asynchronously.
85-
/// This actor ensures thread-safe operations and can be used to buffer elements
86-
/// before processing them via an `AsyncStream`.
87-
actor AsyncBuffer<T: Sendable> {
88-
89-
/// Returns the current size of the buffer.
90-
public var size: Int {
91-
buffer.count
92-
}
93-
94-
/// Indicates whether the buffer has been closed.
95-
public var isBufferClosed: Bool {
96-
isClosed
97-
}
98-
99-
/// The internal storage for buffered elements.
100-
private var buffer: [T] = []
101-
102-
/// The continuation for yielding elements to the `AsyncStream`. Optional.
103-
private var continuation: AsyncStream<T>.Continuation?
104-
105-
/// Indicating whether the buffer has been closed. Defaults to `false`.
106-
private var isClosed = false
107-
108-
/// An error to be thrown when the buffer is closed. Optional.
109-
private var toThrow: Error?
110-
111-
/// The maximum size of the buffer. Optional.
112-
private let maxSize: Int?
113-
114-
/// Initializes the `AsyncBuffer`.
115-
///
116-
/// - Parameter maxSize: The maximum number of elements that can be stored in the buffer.
117-
/// Optional. Defaults to `nil`.
118-
public init(maxSize: Int? = nil) {
119-
self.maxSize = maxSize
120-
}
121-
122-
/// Pushes a single item into the buffer.
123-
///
124-
/// If the buffer is closed, the operation will have no effect.
125-
///
126-
/// - Parameter item: The item to be added to the buffer.
127-
public func push(_ item: T) {
128-
guard !isClosed else { return }
129-
buffer.append(item)
130-
yieldItem(item)
131-
}
132-
133-
/// Pushes multiple items into the buffer.
134-
///
135-
/// If the buffer is closed, the operation will have no effect.
136-
///
137-
/// - Parameter items: An array of items to be added to the buffer.
138-
public func pushMany(_ items: [T]) {
139-
guard !isClosed else { return }
140-
buffer.append(contentsOf: items)
141-
for item in items {
142-
yieldItem(item)
143-
}
144-
}
145-
146-
/// Closes the buffer, preventing further additions and ending the stream.
147-
public func close() {
148-
isClosed = true
149-
continuation?.finish()
150-
}
151-
152-
/// Closes the buffer and throws an error.
13+
/// The buffer size has been reached.
15314
///
154-
/// - Parameter error: The error to be associated with the buffer closure.
155-
public func throwError(_ error: Error) {
156-
toThrow = error
157-
isClosed = true
158-
continuation?.finish()
159-
}
15+
/// - Parameter maxSize: The maximum byte size that can be reached.
16+
case bufferSizeTooLarge(maxSize: Int)
16017

161-
/// Returns an `AsyncStream` for consuming buffered elements asynchronously.
162-
///
163-
/// - Returns: An `AsyncStream<T>` that provides elements from the buffer.
164-
public func stream() -> AsyncStream<T> {
165-
return AsyncStream { continuation in
166-
self.continuation = continuation
167-
Task { await self.drainBuffer() }
18+
public var errorDescription: String? {
19+
switch self {
20+
case .bufferSizeTooLarge(let maxSize):
21+
return "Buffer size too large. Max size is \(maxSize) bytes."
16822
}
16923
}
17024

171-
/// Drains the buffer by yielding all remaining elements to the stream.
172-
private func drainBuffer() async {
173-
while !buffer.isEmpty {
174-
let item = buffer.removeFirst()
175-
yieldItem(item)
176-
}
177-
178-
if toThrow != nil || isClosed {
179-
continuation?.finish()
180-
}
181-
}
182-
183-
/// Yields an item to the `AsyncStream`.
184-
///
185-
/// - Parameter item: The item to yield.
186-
private func yieldItem(_ item: T) {
187-
continuation?.yield(item)
25+
public var description: String {
26+
return errorDescription ?? String(describing: self)
18827
}
18928
}

0 commit comments

Comments
 (0)