Release Helper Tools 0.2.0
Verify / verify (push) Canceled after 0s

This commit is contained in:
2026-09-02 01:01:56 +02:00
parent 5fffd48642
commit 6c763fcb5a
30 changed files with 2022 additions and 51 deletions
+84
View File
@@ -21,6 +21,13 @@ assertBoundedBytes(value: BytesLike, maximum?: number, label?: string): Uint8Arr
assertBoundedItems(count: number, maximum?: number, label?: string): number;
assertPositiveSafeInteger(value: number, label: string): number;
asUint8Array(value: BytesLike): Uint8Array;
interface ByteRange { offset: number; length: number; end: number }
assertSafeOffset(value: number, label?: string): number;
checkedOffsetAdd(offset: number, length: number, maximum?: number, label?: string): number;
checkedByteRange(availableBytes: number, offset: number, length: number, label?: string): ByteRange;
class ByteCursor { /* bounded typed reads, seek/skip and subcursors */ }
ownedBytes(input: BytesLike, maximumBytes?: number): Uint8Array;
```
`HelperLimitError` extends `RangeError` and exposes numeric `actual` and `limit`
@@ -28,6 +35,10 @@ properties. Per-operation ceilings can be made narrower. They are compatibility
and denial-of-service boundaries, not a substitute for an application-wide
memory budget.
`ByteCursor` defaults to the shared 16 MiB input ceiling and never advances
after a failed read. It is non-owning by default; `readBytes(length, true)`,
`bytes(true)` and bounded `ownedBytes` make explicit retained copies.
## Encoding and URLs
```ts
@@ -65,6 +76,18 @@ opens or fetches the result.
```ts
type DigestAlgorithm = "SHA-1" | "SHA-256" | "SHA-384" | "SHA-512";
type ChecksumAlgorithm = "CRC-32" | "Adler-32" | "FNV-1a-32";
interface IncrementalChecksum {
readonly algorithm: ChecksumAlgorithm;
readonly bytesProcessed: number;
update(input: BytesLike): this;
digest(): number;
digestHex(): string;
reset(): this;
}
createIncrementalChecksum(algorithm: ChecksumAlgorithm, maximumBytes?: number): IncrementalChecksum;
crc32(input: BytesLike, maximumBytes?: number): number;
adler32(input: BytesLike, maximumBytes?: number): number;
@@ -88,6 +111,26 @@ Digests use Web Crypto. SHA-1 is available only for interoperability. Checksums
and hashes do not establish authorship, and none of these functions is a
password-hashing API.
## Byte sources
```ts
type ByteSource = Blob | ReadableStream<BytesLike> | AsyncIterable<BytesLike>;
interface ByteSourceProgress { processedBytes: number; totalBytes?: number }
iterateByteChunks(source: ByteSource, options?: ConsumeByteSourceOptions): AsyncGenerator<Uint8Array>;
consumeByteSource(source: ByteSource, consume: (chunk: Uint8Array) => void | Promise<void>, options?: ConsumeByteSourceOptions): Promise<number>;
checksumByteSource(source: ByteSource, checksum?: ChecksumAlgorithm | IncrementalChecksum, options?: ConsumeByteSourceOptions): Promise<number>;
digestByteSource(source: ByteSource, algorithm?: DigestAlgorithm, options?: DigestByteSourceOptions): Promise<Uint8Array>;
digestByteSourceHex(source: ByteSource, algorithm?: DigestAlgorithm, options?: DigestByteSourceOptions): Promise<string>;
```
Every source is bounded and supports cancellation and progress. A supplied
`knownTotalBytes` is an exact contract rather than an unchecked progress hint.
CRC-32,
Adler-32 and FNV-1a are genuinely incremental and constant-memory. Web Crypto
does not expose incremental SHA state, so `digestByteSource` retains chunks up
to the caller's explicit ceiling before invoking its one-shot digest API.
## Network
```ts
@@ -140,6 +183,9 @@ createObjectUrlLease(
blob: Blob,
urlApi?: Pick<typeof URL, "createObjectURL" | "revokeObjectURL">,
): ObjectUrlLease;
createObjectUrlLeasePool<TKey = string>(urlApi?: UrlApi): ObjectUrlLeasePool<TKey>;
planBlobDownloads(input: Iterable<BlobDownload>, options?: PlanBlobDownloadsOptions): readonly PlannedBlobDownload[];
triggerBlobDownloads(input: Iterable<BlobDownload>, options?: TriggerBlobDownloadsOptions): TriggeredBlobDownloads;
triggerBlobDownload(
blob: Blob,
filename: string,
@@ -151,6 +197,44 @@ triggerBlobDownload(
object URL revocation for the next task. Long-lived previews should instead
keep a lease and call `revoke()` when replaced or unmounted.
Batch planning consumes at most the configured item ceiling, preserves input
order by default, sanitizes every name and adds
stable ` (2)`, ` (3)` suffixes for case-insensitive collisions. All batch URLs
are revocable as one group. Browsers may still ask users to permit multiple
downloads.
## Worker jobs
```ts
const WORKER_JOB_PROTOCOL = "add-ideas.worker-job/v1";
startWorkerJob<TPayload, TResult, TProgress, TError>(
worker: WorkerJobEndpoint,
payload: TPayload,
options?: StartWorkerJobOptions<TProgress, TError>,
): WorkerJobHandle<TResult>;
createWorkerJobMessageHandler<TPayload, TResult, TProgress, TError>(
run: (payload: TPayload, context: WorkerJobContext<TProgress>) => TResult | Promise<TResult>,
postMessage: (response: WorkerJobResponse<TResult, TProgress, TError>) => void,
options: WorkerJobHandlerOptions<TError>,
): (event: MessageEvent<WorkerJobCommand<TPayload>>) => void;
```
The client filters responses by protocol and job ID, forwards progress,
propagates abort reasons, enforces a hard timeout by terminating disposable
workers and removes all listeners when settled. Worker handlers expose the
same deadline and cancellation signal for cooperative asynchronous work.
## Display
```ts
formatBytes(bytes: number, options?: FormatBytesOptions): string;
```
Formatting is deterministic and defaults to IEC units. It supports SI units,
fixed precision, signed quantities and an explicit invalid-value label.
## Remaining groups
| Group | Exports |