# multipart-stream 总体架构

## 1. 架构目标

1. 核心只处理 `Bytes` 和结构化 metadata，不依赖 HTTP、网络、文件系统或 async。
2. parser、writer、mixed stream 和 pipeline 均使用显式生命周期与 sticky failure。
3. 大型正文按事件或输出 chunk 流动，核心不整体缓冲文件。
4. 公共具体类型由 facade 或非 `internal` 公共 package 拥有。
5. portable core 支持多 target，Native CLI 与外部 oracle 保持在集成边界。

## 2. 目录结构和模块职责


| 模块              | 主要 package/目录                                | 职责                                                           |
| ----------------- | ------------------------------------------------ | -------------------------------------------------------------- |
| model             | `src/model`                                      | 公共 metadata、events、limits、errors、diagnostics             |
| internal/syntax   | `src/internal/syntax`                            | Content-Type、Content-Disposition、参数、header、filename 策略 |
| internal/boundary | `src/internal/boundary`                          | KMP matcher、delimiter suffix 分类、比较/retained 统计         |
| parser            | `src/parser`                                     | framing 状态机、ordered events、EOF、limits、stats             |
| writer            | `src/writer`                                     | writer 生命周期、canonical framing、plan 和 emitter            |
| facade            | `src`、`src/cmd`、`src/examples`、`test/interop` | facade、CLI、示例、互操作和 benchmark 入口                     |
| form              | `src/form`                                       | 有界字段 collector、callback sink/source、charset view         |
| mixed             | `src/mixed`                                      | legacy`multipart/mixed` 增量 leaf-event 转换                   |
| pipeline          | `src/pipeline`、`src/native`                     | 事务 sink、quota、audit、metrics 和宿主 source                 |

完整目录：

```text
multipart-stream/
├── moon.mod
├── README.md
├── LICENSE
├── src/
│   ├── moon.pkg                    # root facade
│   ├── model/
│   ├── internal/{syntax,boundary}/
│   ├── parser/
│   ├── writer/
│   ├── form/
│   ├── mixed/
│   ├── pipeline/
│   ├── native/
│   ├── cmd/{mpstream,benchmark}/
│   └── examples/{basic,limits}/
├── test/{conformance,interop,mutation}/
├── bench/
├── docs/
│   ├── 项目申请书.md
│   └── 架构说明.md
└── .github/workflows/ci.yml
```

`moon.mod` 使用 `source = "src"`，所以 `src/` 是 module package 根；`.mbt` 文件名只
组织同一 package 内的声明，不创建命名空间。

## 3. 公开类型所有权

- `model` 拥有 `Limits`、`PartMeta`、`MultipartEvent`、`MultipartError`、
  `ParserStats` 和诊断类型。
- `parser`、`writer`、`form`、`mixed`、`pipeline` 分别拥有其有 identity 的状态对象
  和领域错误。
- 根 facade 通过 `pub using` 提供统一入口，不重新定义第二套 wrapper 类型。
- `internal/syntax` 只允许重导出不泄漏 internal 类型的安全纯函数；matcher 类型不应
  出现在根公开接口。
- `pkg.generated.mbti` 只能由 `moon info` 生成，用于审查类型所有权和 API 变化。

## 4. 核心接口边界

```moonbit
MultipartParser::new(String, Limits) -> MultipartParser raise MultipartError
MultipartParser::feed(MultipartParser, Bytes)
  -> Array[MultipartEvent] raise MultipartError
MultipartParser::finish(MultipartParser)
  -> Array[MultipartEvent] raise MultipartError

MultipartWriter::new(String, Limits) -> MultipartWriter raise MultipartError
MultipartWriter::begin_part(MultipartWriter, PartMeta) -> Bytes raise MultipartError
MultipartWriter::write(MultipartWriter, Bytes) -> Bytes raise MultipartError
MultipartWriter::end_part(MultipartWriter) -> Bytes raise MultipartError
MultipartWriter::finish(MultipartWriter) -> Bytes raise MultipartError

plan(String, Array[PlannedPart], Limits) -> MultipartPlan raise MultipartError
UploadPipeline::feed(UploadPipeline, Bytes) -> Unit raise UploadError
UploadPipeline::finish(UploadPipeline) -> UploadReceipt raise UploadError
```

## 5. Parser 数据流

```text
Content-Type
 -> validate boundary
 -> MultipartParser
Bytes chunk
 -> total limit
 -> Preamble / Headers / Body / Epilogue state
 -> KMP matcher + bounded pending suffix
 -> PartBegin / PartData / PartEnd / MessageEnd
 -> form collector / mixed stream / upload pipeline / user sink
```

CRLF preceding delimiter 属于 framing，不属于正文。parser 只在候选确认失配后发出安全
正文；语法、EOF 或限制错误后进入 sticky failed，后续调用不能产生成功结束。

## 6. Writer 和已知长度发送数据流

```text
boundary + limits
 -> begin_part: delimiter + canonical headers
 -> write: raw bytes + counters
 -> end_part
 -> finish: closing delimiter

PlannedPart(body_length)
 -> plan exact Content-Length
 -> PlannedEmitter
 -> validate actual bytes for every part
 -> finish only when lengths exactly match
```

固定 boundary 用于测试和可复现输出；生产流式调用由宿主提供外部熵。严格碰撞扫描只
适用于正文可预扫描的场景。

## 7. Upload pipeline 数据流

```text
source -> parser -> MixedStream? -> UploadPipeline
       -> UploadSink -> host temporary storage
       -> AuditedSink / MeasuredSink decorators
       -> commit receipt or exactly-once abort
```

pipeline 只允许一个 active leaf；data 到达前检查 part/aggregate quota。CRC-32 只作
偶然损坏审计，宿主需要安全完整性时通过同一 sink 流式计算密码学摘要。

## 8. 错误边界

- 协议错误：content type、boundary、header、framing、EOF；
- 资源错误：total、header、part、count、mixed depth、aggregate quota；
- 生命周期错误：Done/Failed 后调用、writer/emitter 调用顺序；
- 宿主错误：source/sink 失败，与协议错误分层传播；
- 诊断默认只含 phase、offset、kind、limit 等信息，不包含正文或敏感 header value。

## 9. 并发与一致性模型

当前 API 为同步、单 owner、无锁状态机；单个 parser/writer/pipeline 实例不得并发调用。
不同请求使用独立实例，可以由宿主并发调度。核心调用期间不执行任意异步任务；callback
adapter 按输入顺序同步调用，宿主负责线程安全和 backpressure。

## 10. Target 范围

- model、syntax、matcher、parser、writer、form、mixed、pipeline 与根 facade 目标为
  wasm、wasm-gc、JavaScript、Native；
- `cmd/mpstream`、benchmark、Go/curl oracle 可以限定 Native；
- target 限制必须写在对应 `moon.pkg`，不得让 Native 依赖污染 portable core。
