8.6 KiB
Capability Spec Delta: drive (drive)
Package: @suaveplan/drive
Status: PROPOSED
Every requirement carries a
**Verified by:**line at authoring time. The named tests are planned; they MUST exist and pass verbatim before this delta is folded intoopenspec/specs/drive/spec.md.
ADDED Requirements
Requirement: Drive.createReadStream SHALL accept a range-options bag overload
Drive.createReadStream(path, signalOrOptions?) SHALL be overloaded to accept either a bare AbortSignal (existing form, preserved) or a RangeReadOptions bag with optional offset, length, and signal. The implementation MUST runtime-discriminate via instanceof AbortSignal. When the options form is passed, the drive MUST forward { offset, length, signal } through the plugin middleware chain via the middleware context's range field.
Scenario: bare signal returns the whole-file stream unchanged
- WHEN
drive.createReadStream("file.bin", abortSignal)is called on a 200 KiB file - THEN the returned stream emits the entire 200 KiB payload and respects
abortSignalfor cancellation
Scenario: options form emits exactly the requested slice
- WHEN
drive.createReadStream("file.bin", { offset: 1024, length: 4096 })is called - THEN the returned stream emits exactly bytes
[1024, 5120)of the source
Scenario: zero-length range yields an immediately-closed stream
- WHEN
drive.createReadStream("file.bin", { offset: 12_345, length: 0 })is called - THEN the returned stream closes immediately with zero enqueued bytes
Verified by: src/drive/drive.test.ts::"createReadStream(path, signal) preserves whole-file behaviour" AND src/drive/drive.test.ts::"createReadStream(path, { offset, length }) emits exactly the requested slice" AND src/drive/drive.test.ts::"createReadStream(path, { length: 0 }) returns an immediately closed stream"
Requirement: Invalid range options SHALL throw DRIVE.RANGE_INVALID synchronously
Drive.createReadStream(path, options) SHALL validate options.offset and options.length synchronously BEFORE constructing the ReadableStream. Either field, when present, MUST satisfy Number.isInteger(x) && x >= 0 && Number.isFinite(x). On violation, the method MUST throw DriveError(DRIVE.RANGE_INVALID, …) with context.field naming the offending field.
Scenario: negative offset throws synchronously
- WHEN
drive.createReadStream("file.bin", { offset: -1 })is called - THEN the call throws
DriveErrorwithcode === "DRIVE.RANGE_INVALID"ANDcontext.field === "offset"AND noReadableStreamis created
Scenario: non-integer length throws synchronously
- WHEN
drive.createReadStream("file.bin", { length: 1.5 })is called - THEN the call throws
DriveErrorwithcode === "DRIVE.RANGE_INVALID"ANDcontext.field === "length"
Scenario: NaN or Infinity rejected
- WHEN
drive.createReadStream("file.bin", { offset: Number.NaN })ORdrive.createReadStream("file.bin", { length: Number.POSITIVE_INFINITY })is called - THEN each call throws
DriveError(DRIVE.RANGE_INVALID, …)synchronously
Verified by: src/drive/drive.test.ts::"createReadStream throws RANGE_INVALID for negative offset" AND src/drive/drive.test.ts::"createReadStream throws RANGE_INVALID for non-integer length" AND src/drive/drive.test.ts::"createReadStream throws RANGE_INVALID for NaN or Infinity"
Requirement: Out-of-bounds range SHALL surface DRIVE.RANGE_OUT_OF_BOUNDS
When the underlying source exposes a known size at stream-start (chunks-plugin manifest, storage stat, or a nativeRange-capable storage that reports size), Drive.createReadStream MUST raise DriveError(DRIVE.RANGE_OUT_OF_BOUNDS, …) synchronously for offset > size or offset + length > size. When size is unknown at start-time, the stream MUST accept the request, emit available bytes, and surface DRIVE.RANGE_OUT_OF_BOUNDS via controller.error on close if the byte count emitted is less than the requested length. The error MUST carry the originating CHUNKS.RANGE_OUT_OF_BOUNDS (when applicable) as cause.
Scenario: offset past EOF rejected synchronously when size is known
- WHEN the file is 1024 bytes and
drive.createReadStream("file.bin", { offset: 2048 })is called via a chunks-plugin-mediated path - THEN the call throws
DriveError(DRIVE.RANGE_OUT_OF_BOUNDS, …)synchronously withcausecarryingCHUNKS.RANGE_OUT_OF_BOUNDS
Scenario: offset+length past EOF rejected synchronously when size is known
- WHEN the file is 1024 bytes and
drive.createReadStream("file.bin", { offset: 900, length: 500 })is called via the chunks plugin - THEN the call throws
DriveError(DRIVE.RANGE_OUT_OF_BOUNDS, …)synchronously
Scenario: short-fall on stream end when size was unknown at start
- WHEN the storage cannot report size and
drive.createReadStream("file.bin", { offset: 0, length: 10_000 })is called and the source closes after 4000 bytes - THEN the stream errors with
DriveError(DRIVE.RANGE_OUT_OF_BOUNDS, …)ANDcontext.emittedBytes === 4000
Verified by: src/drive/drive.test.ts::"createReadStream throws RANGE_OUT_OF_BOUNDS when offset exceeds known size" AND src/drive/drive.test.ts::"createReadStream throws RANGE_OUT_OF_BOUNDS when offset+length exceeds known size" AND src/file-operations/streams.range.test.ts::"stream errors with RANGE_OUT_OF_BOUNDS on short-fall when size is unknown"
Requirement: nativeRange storage capability SHALL be honoured
DriveStorage SHALL accept an optional capabilities.nativeRange?: boolean flag. When true, Drive.createReadStream(path, { offset, length, signal }) MUST forward { offset, length } to storage.createReadStream directly. When false (or absent), the drive MUST wrap the storage stream in a slicing transform that drops bytes before offset and stops emitting after length bytes. Both paths MUST produce identical observable output.
Scenario: storage with nativeRange receives offset/length
- WHEN
storage.capabilities.nativeRange === trueanddrive.createReadStream("file.bin", { offset: 1024, length: 4096 })is invoked - THEN
storage.createReadStreamis called exactly once with{ offset: 1024, length: 4096, signal }and no slicing transform is interposed
Scenario: storage without nativeRange is wrapped in a slicing transform
- WHEN
storage.capabilities?.nativeRangeisundefinedorfalseand the same call is made - THEN
storage.createReadStreamis called with{ signal }only AND the returned stream is wrapped so the consumer observes exactly bytes[1024, 5120)
Verified by: src/file-operations/streams.range.test.ts::"nativeRange storage receives offset and length directly" AND src/file-operations/streams.range.test.ts::"non-nativeRange storage is wrapped in a slicing transform"
Requirement: Range cancellation SHALL propagate via AbortSignal
Drive.createReadStream(path, options) MUST propagate options.signal (or the bare signal in the back-compat form) through the chunks-plugin / mesh / storage pull chain. On abort, in-flight chunk fetches MUST be cancelled, the stream MUST close with controller.error(AbortError), and (over drive+mesh://) the mesh transport MUST emit a cd:error envelope with code: "ABORTED".
Scenario: mid-stream abort cancels chunk fetches
- WHEN
drive.createReadStream("file.bin", { offset: 0, length: 1_048_576, signal })is called andsignal.abort()is invoked after the first chunk emits - THEN the stream closes with an
AbortError, no further chunks are fetched, and the chunks-plugin loop exits at the nextthrowIfAbortedcheckpoint
Verified by: src/file-operations/streams.range.test.ts::"abort mid-range stream cancels in-flight chunk fetches"
Requirement: DRIVE_CODES SHALL include RANGE_INVALID and RANGE_OUT_OF_BOUNDS
DRIVE_CODES SHALL include "RANGE_INVALID" and "RANGE_OUT_OF_BOUNDS" declared via the existing defineCodes("DRIVE", [...] as const) call. Object.isFrozen(DRIVE_CODES) MUST remain true. Every code value MUST start with DRIVE..
Scenario: registry exposes the new codes
- WHEN the test imports
DRIVE_CODESfrom@suaveplan/drive - THEN
DRIVE_CODES.RANGE_INVALID === "DRIVE.RANGE_INVALID"ANDDRIVE_CODES.RANGE_OUT_OF_BOUNDS === "DRIVE.RANGE_OUT_OF_BOUNDS"ANDObject.isFrozen(DRIVE_CODES) === true
Verified by: src/error-codes.spec-conformance.test.ts::"DRIVE_CODES exposes RANGE_INVALID and RANGE_OUT_OF_BOUNDS" AND src/error-codes.spec-conformance.test.ts::"Object.isFrozen(DRIVE_CODES) is true"