Move docs/ package mirror into document-navigator plugin
Relocate the ~6k-file docs tree from the repo root into plugins/document-navigator/docs/ so the plugin is self-contained and portable. docs/superpowers/ (specs and plans) stays at the repo root. Moved via cp+rm rather than git mv because directory rename() fails with EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the identical-content files at commit time. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
# `mime/mime`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
`MimeTransform` is a universal stream transform that decides the MIME
|
||||
type of a buffered binary payload and (in `enrich` mode) attaches the
|
||||
detection result to the payload under `mime`. It delegates to
|
||||
`@suaveplan/mime` for both magic-bytes and extension-based detection,
|
||||
layering a single composite path on top: magic bytes win when they match,
|
||||
then the caller's `payload.name` is consulted for an extension match, then
|
||||
`application/octet-stream` is the final fallback. The transform never
|
||||
throws for unknown bytes — the fallback is the documented success path —
|
||||
and emits a typed `mime:detected` event in every mode.
|
||||
|
||||
The class extends `@suaveplan/streams::BaseTransform`, so the same
|
||||
`on`/`off`/`toTransformStream`/`dispose` surface every streams consumer
|
||||
uses is available without any glue.
|
||||
|
||||
## Features
|
||||
|
||||
- Magic-bytes detection via `@suaveplan/mime::detectFromMagicBytes`, with
|
||||
the underlying priority preserved on the result.
|
||||
- Extension fallback via `@suaveplan/mime::detectFromExtension` (only
|
||||
consulted when magic bytes return `null` and `payload.name` is a string).
|
||||
- `application/octet-stream` final fallback with `priority: 0` and
|
||||
`source: "fallback"`.
|
||||
- `mime:detected` event emitted via the inherited
|
||||
`BaseTransform.on`/`emit` API.
|
||||
- `enrich` mode (default) shallow-clones the payload with `mime` attached;
|
||||
`passthrough` mode returns the original input reference unchanged.
|
||||
- Raises `InvalidPayloadError` when the payload is missing the mandatory
|
||||
`bytes: Uint8Array` field.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { MimeTransform } from "@suaveplan/streams-metadata";
|
||||
|
||||
const transform = new MimeTransform();
|
||||
const result = await transform.process({
|
||||
bytes: new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]),
|
||||
name: "image.png",
|
||||
});
|
||||
console.log(result.mime?.mimeType); // "image/png"
|
||||
console.log(result.mime?.source); // "magic-bytes"
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import { MimeTransform } from "@suaveplan/streams-metadata";
|
||||
|
||||
const transform = new MimeTransform({ mode: "passthrough" });
|
||||
|
||||
transform.on("mime:detected", (r) => {
|
||||
if (r.source === "fallback") {
|
||||
console.warn("Unknown MIME — defaulting to application/octet-stream");
|
||||
} else {
|
||||
console.log(`MIME: ${r.mimeType} (priority ${r.priority}, via ${r.source})`);
|
||||
}
|
||||
});
|
||||
|
||||
const input = { bytes: new Uint8Array(), name: "song.mp3" };
|
||||
const out = await transform.process(input);
|
||||
console.log(out === input); // true
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `class MimeTransform extends BaseTransform<{}, StreamsMetadataEvents>`:
|
||||
- `constructor(options?: MimeTransformOptions)` — accepts `{ mode? }`,
|
||||
defaulting to `"enrich"`.
|
||||
- `async process<T = unknown>(input: T, options?: ProcessOptions): Promise<T>`
|
||||
— runs detection, emits `mime:detected`, returns the enriched payload
|
||||
(or original input reference in `passthrough` mode). Honours
|
||||
`options.signal` via `BaseTransform.assertNotAborted`. Throws
|
||||
`InvalidPayloadError` (`STREAMS_METADATA.INVALID_PAYLOAD`) when
|
||||
`input.bytes` is not a `Uint8Array`.
|
||||
- `name: "mime"` — stable name carried by every instance.
|
||||
- Inherits `on` / `off` / `dispose` / `toTransformStream` from
|
||||
`BaseTransform`.
|
||||
- `interface MimeTransformOptions`:
|
||||
- `mode?: MetadataMode` — `"enrich"` (default) or `"passthrough"`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- Detection precedence is exactly: magic bytes → extension → fallback. The
|
||||
contract guarantees every call returns a `MimeDetectionResult`, so
|
||||
consumers never need to handle a `null` / `undefined` return.
|
||||
- The magic-bytes branch consults `detectFromExtension(payload.name)` only
|
||||
to recover the extension string; the MIME type itself always comes from
|
||||
the magic-bytes layer (which has higher confidence than extension).
|
||||
- `passthrough` mode is reference-stable — the returned value is `===` the
|
||||
input. Useful for pipelines that need MIME observation without mutating
|
||||
the byte payload contract.
|
||||
- Listener exceptions are caught by `BaseTransform.emit` and never bubble
|
||||
out of `process` — observability cannot break the pipeline.
|
||||
Reference in New Issue
Block a user