Strategies Overview
WIPPluggable upload protocols selected by the intent's strategy field.
A strategy is the piece that actually moves bytes. The engine stays protocol-agnostic: your
backend returns an intent, the engine reads its strategy field, looks the strategy up in the
registry, and calls start(). Swapping S3 POST for multipart, TUS, or a custom endpoint never
touches engine code.
What a strategy does
Each strategy:
- Turns an intent into network calls via the injected
ctx.transport. - Reports progress with
ctx.reportProgressand, if resumable, persists a cursor withctx.persistCursor. - Honors
ctx.signalso pause and cancel abort cleanly.
The shape is Contracts.Strategy.Me<M, C, P, R, K>:
{
id: K // must equal the intent's `strategy` value
resumable: boolean
start(ctx): Promise<void>
}
Built-in strategies
| Strategy | Factory | Use case | Resumable |
|---|---|---|---|
| POST | PostStrategy() | Presigned form uploads (small/medium) | No |
| Multipart | multipartStrategy(opts?) | Large files, concurrent parts | Yes |
Note the casing: PostStrategy (also a type namespace) and multipartStrategy (its type
namespace is MultipartStrategy).
Registering
createStrategyRegistry() returns an empty typed registry; add strategies with .set():
import { PostStrategy, multipartStrategy, createStrategyRegistry } from '@gentleduck/upload/strategies'
const strategies = createStrategyRegistry<Intents, Cursors, Purpose, Result>()
strategies.set(PostStrategy())
strategies.set(multipartStrategy({ maxPartConcurrency: 4 }))
The registry's key types come from your intent map M, so the backend intent response and the
registered strategies stay in sync at compile time. If the backend returns a strategy that
isn't registered, the item fails with a strategy_missing error.
See Strategy Registry for the registry API and writing your own strategy.