Documentation
¶
Overview ¶
Package pipeline 实现 javdb.pipeline/v1 机器协议核心:typed envelope、 严格 NDJSON/文本解码、输入分类与输出模式。
命令之间通过 NDJSON 组合:生产者按固定 schema 输出逐条 envelope,消费者按 kind 选择 id 或 ref。默认输出文本;显式 --ndjson / --json 互斥。
Index ¶
- Constants
- func ConsumerRef(input Envelope) string
- func ErrorMessage(envelope Envelope) string
- func IsKind(kind Kind) bool
- func RunBatch(writer *Writer, inputs []Envelope, command string, fn BatchFunc) (failures int, outputErr error)
- func WriteMovieRowsText(w, errW io.Writer, movies []map[string]any) error
- type BatchFunc
- type BatchRunner
- type Classification
- type Consumer
- type Envelope
- func CollectInputs(reader *bufio.Reader, streams *invocation.Streams, arg string, ...) ([]Envelope, error)
- func DecodeNDJSON(line string) (Envelope, error)
- func DecodeText(line string) (Envelope, error)
- func ErrorEnvelope(input Envelope, command, stage, code, message string) Envelope
- func New(kind Kind, ref, id string) Envelope
- func ParseBatch(content []byte, kind Kind) ([]Envelope, error)
- type Kind
- type ListProducer
- type MovieListProducer
- type OutputMode
- type Producer
- type Writer
Constants ¶
const Schema = "javdb.pipeline/v1"
Schema 是管道信封的固定 schema。
Variables ¶
This section is empty.
Functions ¶
func ErrorMessage ¶ added in v0.7.2
ErrorMessage 提取上游错误信封的可展示 message;缺失、null 或非字符串值 统一使用稳定回退,避免把协议数据的类型错误泄露成 fmt 的诊断占位符。
Types ¶
type BatchRunner ¶
type BatchRunner struct {
Name string
// Context 是本次命令调用的生命周期;未设置时使用 Background。
Context context.Context
// Kinds 是文本 ref 输入分配的 kind 与消费者接受的 kind。
Kinds []Kind
// ClientFactory 每次批量执行调用一次,返回携带默认 token 的 client。
ClientFactory func() (*javdb.Client, error)
// RunOne 执行单项并返回输出信封。
RunOne func(*javdb.Client, context.Context, Envelope) (Envelope, error)
// RunMany 执行单项并返回多个输出信封(fan-out);设置时优先于 RunOne。
// 调用方负责在返回的信封中携带稳定 ref/id。
RunMany func(*javdb.Client, context.Context, Envelope) ([]Envelope, error)
// Legacy 处理单项既有路径(args 为位置参数列表)。
Legacy func(args []string) error
// RenderText 是 pipeline 文本/人类模式的领域投影;nil 时输出稳定 ref。
RenderText func(io.Writer, Envelope) error
// RenderError 是 pipeline 文本/人类模式的错误投影;nil 使用 Name 前缀。
RenderError func(io.Writer, error) error
// RouteTextThroughPipeline 让单项纯文本输入的非 TTY OutputText 走 Consumer。
// 未启用时保留本地/有副作用命令的既有 Legacy 文本语义;需要稳定记录的
// 只读命令应显式启用此选项。
RouteTextThroughPipeline bool
// LegacyJSON 表示 Legacy 路径已支持显式 --json 输出(保持既有 shape)。
// 为 false 时,单项显式 --json 也走 consumer 路径(RunOne + 信封对象输出),
// 避免本地命令(mark/config 等)在 --json 下静默输出裸文本或无输出。
LegacyJSON bool
// Preflight 在批处理路径开始前校验全部输入(如 download 的全量目标展开
// 与冲突检查);返回错误时整个批处理失败,不做任何写入。
Preflight func([]Envelope) error
// Concurrency 控制批量执行并发度;<= 0 表示串行。
Concurrency int
}
BatchRunner 是只读命令的管道化执行器:
- 单项 + (TTY 文本 或 显式 --json)走 Legacy 既有路径(保持既有 shape 与可选认证/匿名重试行为)。
- 其余情况(多项,或单项显式 --ndjson)走逐项 RunOne:单项失败原位错误 信封并继续,最终非零;批量显式 --json 输出信封数组。
管道执行保持三条不变量:输入索引决定输出顺序;RunMany 只在对应输入槽内 fan-out;错误项只产生错误信封或 stderr 诊断,不伪造成功 ref。
func (*BatchRunner) Execute ¶
func (b *BatchRunner) Execute(streams *invocation.Streams, args []string, ndjson, json bool) error
Execute 是命令 RunE 的通用实现。
func (*BatchRunner) ExecuteWithInputs ¶
func (b *BatchRunner) ExecuteWithInputs(streams *invocation.Streams, inputs []Envelope, mode OutputMode) error
ExecuteWithInputs 处理已收集的输入(调用方已完成分类)。输入分类一旦完成, 不再根据来源(位置参数或 stdin)改变显式 NDJSON/JSON 的 cardinality;只有 纯文本单项的 legacy 分支保留命令原有 JSON/TTY shape。
type Classification ¶
type Classification int
Classification 是 stdin 内容的输入类别。
const ( // ClassificationImage 表示 JPEG/PNG/WEBP 图片字节。 ClassificationImage Classification = iota // ClassificationNDJSON 表示 javdb.pipeline/v1 信封流。 ClassificationNDJSON // ClassificationText 表示逐行纯文本 ref。 ClassificationText )
type Consumer ¶
type Consumer struct {
Name string
// Context 是本次命令调用的生命周期;未设置时使用 Background。
Context context.Context
// AcceptedKinds 是输入项允许的 kind;nil 表示接受任意 kind(文本 ref)。
AcceptedKinds []Kind
// RunOne 执行单项并返回输出信封。
RunOne func(context.Context, Envelope) (Envelope, error)
// RunMany 执行单项并返回多个输出信封(fan-out);设置时优先于 RunOne。
RunMany func(context.Context, Envelope) ([]Envelope, error)
// RenderText 输出默认的人类文本。
RenderText func(io.Writer, Envelope) error
// RenderError 将文本/人类模式的单项错误写到 stderr;nil 使用 Name 前缀。
RenderError func(io.Writer, error) error
// LegacyJSON 输出单项显式 --json 的既有 shape;nil 时输出信封对象。
LegacyJSON func(io.Writer, Envelope) error
// Concurrency 控制批量执行并发度;<= 0 表示串行。并发时结果按输入顺序
// 写出,单项失败不阻塞其他项。
Concurrency int
}
Consumer 把只读命令的单项执行包装成统一输入/输出管道:
- 输入:位置参数或非 TTY stdin(分类:图片 magic → NDJSON → 文本)。
- 消费者严格检查 kind,不兼容输入生成原位错误信封。
- 输出:默认文本;显式 --ndjson/--json 互斥。
- 显式 --json:单项走 LegacyJSON 既有 shape,多项输出信封数组。
func (*Consumer) RunInputs ¶
func (c *Consumer) RunInputs(streams *invocation.Streams, inputs []Envelope, mode OutputMode) error
RunInputs 按输出模式处理已收集的输入;单项失败原位错误信封并继续。 调用方(如 search)可自行完成图片分类后复用本方法。
文本/人类模式(OutputText/OutputHuman)下:
- 成功项:若 RenderText 已设置则调用它渲染人类/稳定文本,否则逐行 ref。
- 失败项:错误原因写 stderr,不向 stdout 写任何内容(不伪造成功 ref)。
NDJSON/JSON 模式下:失败项原位 error 信封写入 stdout(机器契约),保持 输出顺序与单项错误可观测性。
Concurrency > 0 时批量请求并发执行,结果按输入顺序写出。 processAll 只按索引写入独立结果槽,所有 worker 完成后才进入渲染阶段, 因而 fan-out、失败信封和文本输出都不会因请求完成顺序改变协议顺序。
type Envelope ¶
type Envelope struct {
Schema string `json:"schema"`
Kind Kind `json:"kind"`
Ref string `json:"ref,omitempty"`
ID string `json:"id,omitempty"`
Data map[string]any `json:"data,omitempty"`
Meta map[string]any `json:"meta,omitempty"`
}
Envelope 是管道记录。
func CollectInputs ¶
func CollectInputs(reader *bufio.Reader, streams *invocation.Streams, arg string, textKinds []Kind) ([]Envelope, error)
CollectInputs 统一收集输入:位置参数(单个)或非 TTY stdin 批。 位置参数与非空 stdin 同时存在是歧义错误。stdin 按固定顺序分类 (图片 magic → NDJSON → 文本);图片输入显式报错(调用方先行处理)。
func DecodeNDJSON ¶ added in v0.7.1
DecodeNDJSON 严格解码一条 NDJSON 记录;拒绝非对象行、尾随数据与非法信封。
func DecodeText ¶
DecodeText 把一行纯文本解码为 ref(kind 由消费者命令决定)。
func ErrorEnvelope ¶
ErrorEnvelope 构造原位错误信封;不含 secret。
func ParseBatch ¶
ParseBatch 把 stdin 内容按分类解码为信封序列:
- 输入分类固定顺序为图片 magic、NDJSON、文本(由 Classify 完成);
- NDJSON 模式逐行严格解码,混合/非法行返回带行号的错误;
- 文本模式逐行转 ref。
type Kind ¶
type Kind string
Kind 是稳定的记录类别;消费者只接受声明匹配的 kind。
const ( KindMovie Kind = "movie" KindActor Kind = "actor" KindSeries Kind = "series" KindMaker Kind = "maker" KindDirector Kind = "director" KindCode Kind = "code" KindList Kind = "list" KindAccount Kind = "account" KindComment Kind = "comment" KindMagnet Kind = "magnet" KindDownload Kind = "download" KindConfigKey Kind = "config_key" KindError Kind = "error" )
const KindNDJSONInput Kind = "ndjson"
KindNDJSONInput 是 ParseBatch 的哨兵:表示逐行 NDJSON 严格解码。
const KindTag Kind = "tag"
KindTag 是标签目录条目的稳定 kind(kind 集合的最小契约之外按需扩展)。
type ListProducer ¶
type ListProducer struct {
Name string
// ClientFactory 每次执行调用一次。
ClientFactory func() (*javdb.Client, error)
// Fetch 执行并返回列表项。
Fetch func(context.Context, *javdb.Client) ([]map[string]any, error)
// JSON 构造显式 --json 的既有 shape 载荷。
JSON func([]map[string]any) (map[string]any, error)
// ErrNote 可选:输出前写 stderr 注解。
ErrNote func(io.Writer, []map[string]any)
// ItemKind 是信封 kind(默认 movie)。
ItemKind Kind
// ItemRef 提取 (ref, id)(默认 number/id)。
ItemRef func(map[string]any) (string, string)
// RowText 渲染人类文本行(默认 movie 投影行)。
RowText func(io.Writer, io.Writer, []map[string]any) error
}
ListProducer 是"拉取列表"类 producer 命令的通用执行器: 不消费 stdin;默认输出人类文本;显式 --ndjson 输出逐条信封,--json 走 JSON 载荷。
func (*ListProducer) Execute ¶
func (p *ListProducer) Execute(streams *invocation.Streams, ndjson, json bool) error
Execute 是 producer 命令 RunE 的通用实现。
type MovieListProducer ¶
type MovieListProducer = ListProducer
MovieListProducer 是影片列表 producer 的便捷别名。
type OutputMode ¶
type OutputMode int
OutputMode 是命令的输出格式。
const ( // OutputAuto 表示尚未解析显式输出 flag。 OutputAuto OutputMode = iota // OutputHuman 是 TTY 默认:人类可读文本,由命令的 RenderText 渲染。 OutputHuman // OutputText 是非 TTY 默认:稳定记录流,一行一个 ref/URI,便于管道消费。 OutputText // OutputNDJSON 强制逐条信封 NDJSON。 OutputNDJSON // OutputJSON 显式 --json:单项保持命令既有形状,多项输出 JSON 数组。 OutputJSON )
func ResolveOutputMode ¶
func ResolveOutputMode(flagNDJSON, flagJSON bool, outIsTerminal bool) (OutputMode, error)
ResolveOutputMode 校验互斥并解析输出模式:显式 --ndjson/--json 优先且互斥; 未显式指定时,TTY stdout 使用人类文本(OutputHuman),非 TTY stdout 使用 稳定记录流(OutputText)。测试可显式设置 OutIsTerminal 来模拟两种场景。
type Producer ¶
type Producer struct {
Name string
// Produce 执行并返回输出信封序列(空切片表示无结果)。
Produce func(context.Context) ([]Envelope, error)
// RenderText 渲染人类文本。
RenderText func(io.Writer, []Envelope) error
// LegacyJSON 输出显式 --json 的既有 shape。
LegacyJSON func(io.Writer) error
}
Producer 是无位置参数命令的输出器:不消费 stdin,默认走 Text 渲染; 显式 --ndjson 逐条输出信封,--json 走 LegacyJSON。
type Writer ¶
type Writer struct {
// contains filtered or unexported fields
}
Writer 按输出模式逐条写出信封;OutputJSON 模式在 Finish 时按 cardinality 输出(单信封对象,多信封数组)。
func NewWriter ¶
func NewWriter(out io.Writer, mode OutputMode) *Writer
NewWriter 构造按 mode 输出的 writer。