ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Effect v4 的 Encoding 模块整合:effect/encoding 子模块合并进顶层 Encoding API

Effect v4 的 Encoding 模块整合:effect/encoding 子模块合并进顶层 Encoding API Effect v4 的 Encoding 模块整合effect/encoding 子模块合并进顶层 Encoding API【免费下载链接】effectBuild production-ready applications in TypeScript项目地址: https://gitcode.com/GitHub_Trending/ef/effect本篇围绕 Effect 仓库中一条 Changeset 变更记录.changeset/pre/consolidate-encoding.md展开说明 v4 中effect/encoding子模块Base64、Base64Url、Hex、EncodingError被合并进顶层Encoding模块、函数统一加前缀、子路径导出被移除这一 API 重组的来龙去脉。读完你将掌握新版Encoding的完整函数清单与签名、EncodingError错误模型、Base64/Hex 解码的校验规则以及如何从旧的effect/encoding子路径导入迁移到顶层 API。一、变更内容一条 Changeset 说了什么变更声明位于 consolidate-encoding.md全文仅一段Encoding: consolidateeffect/encodingsub-modules (Base64, Base64Url, Hex, EncodingError) into a top-levelEncodingmodule. Functions are now prefixed:encodeBase64,decodeBase64,encodeHex,decodeHex, etc. Theeffect/encodingsub-path export is removed.按 changesets 规范解读这条记录文件头 YAML frontmatter 为effect: patch即本次变更作用于effect包本身属于补丁级别的 API 结构调整对使用者而言是导入路径的破坏性变更但对包发布流程按 pre 模式管理——该文件位于.changeset/pre/目录对应 v4 预发布阶段仓库当前 effect 包 版本号为4.0.0-rc.115Encoding.ts模块头注释标注since 4.0.0二者互相印证这是 v4 预发布周期内的整合工作。变更包含三件事后文逐一验证Base64、Base64Url、Hex、EncodingError四个子模块的公共能力合并进顶层Encoding模块函数统一加编码类型前缀encodeBase64、decodeBase64、encodeHex、decodeHex等取代子模块内裸名encode/decodeeffect/encoding子路径导出被移除。二、子路径导出的移除从 package.json 验证检查 packages/effect/package.json 的exports字段可以确认第 3 点当前版本中已不存在./encoding这一子路径条目与编码相关的导出仅剩./unstable/encoding后者指向src/unstable/encoding/index.ts包含 Toml、Yaml、Sse、Ndjson 等不稳定文本编解码与本条 Changeset 合并的 Base64/Hex 是不同层面的功能不要混淆。顶层Encoding模块的出口在 packages/effect/src/index.ts 第 167 行export * as Encoding from ./Encoding.ts即使用者只需从主入口effect导入命名空间import { Encoding } from effect而不再需要也不能再写import { Base64 } from effect/encoding之类的子路径导入。三、整合后的完整 API 面整合后的 Encoding.ts 模块头注释给出了整体契约模块在字符串、UTF-8 文本与Uint8Array字节之间转换encode 系列直接返回字符串decode 系列返回Result.Result非法输入以EncodingError形式报告而不是抛异常。函数按 Changeset 所述统一前缀当前完整清单如下。3.1 Base64RFC4648 标准字母表带填充函数签名说明encodeBase64(input: Uint8Array \| string) string字符串输入先按 UTF-8 转字节再编码Uint8Array直接编码输出为标准字母表加填充decodeBase64(str: string) Result.ResultUint8Array, EncodingError解码为字节失败返回Result.faildecodeBase64String(str: string) Result.Resultstring, EncodingError解码为 UTF-8 文本用法示例摘自 Encoding.ts 的 JSDoc 内嵌测试import { Encoding, Result } from effect // 编码字符串 Encoding.encodeBase64(hello) // aGVsbG8 // 编码二进制数据 const bytes new Uint8Array([72, 101, 108, 108, 111]) Encoding.encodeBase64(bytes) // SGVsbG8 // 解码字节 / 文本 Encoding.decodeBase64(SGVsbG8) // Result.succeed(new Uint8Array([72, 101, 108, 108, 111])) Encoding.decodeBase64String(aGVsbG8) // Result.succeed(hello)decodeBase64的校验逻辑Encoding.ts值得注意先stripCrlf去除输入中的\n/\r——这是为了容忍 Base64 常被折行存储的实际情况长度必须是 4 的倍数否则失败消息形如Length must be a multiple of 4, but is N只允许出现在末尾且必须成规则出现倒数第二位的后必须紧跟另一个否则报Found a character, but it is not at the end逐 4 字符组按 6 位查表拼装 3 字节非法字符由内部getBase64Code抛TypeErrorInvalid character ...被外层try/catch捕获后统一转成Result.fail保证函数全程无 throw。3.2 Base64UrlURL 安全字母表去填充函数签名说明encodeBase64Url(input: Uint8Array \| string) string先做标准 Base64再删除并把→-、/→_decodeBase64Url(str: string) Result.ResultUint8Array, EncodingError同时接受填充与未填充两种形式decodeBase64UrlString(str: string) Result.Resultstring, EncodingError解码为 UTF-8 文本Encoding.encodeBase64Url(hello?) // aGVsbG8_ Encoding.decodeBase64Url(SGVsbG8_) // Result.succeed(new Uint8Array([72, 101, 108, 108, 111, 63])) Encoding.decodeBase64UrlString(aGVsbG8_) // Result.succeed(hello?)从实现看Encoding.tsdecodeBase64Url是一条「归一化后复用标准解码」的调用链先校验长度模 4 不为 1、再校验字符集正则/^[-_A-Z0-9]*?{0,2}$/i然后按缺失的填充补回把-/_还原为//最后直接委托给decodeBase64。这解释了为什么 URL 变体的错误消息里module字段写作Base64的情况不存在——URL 分支的自有校验错误带module: Base64Url而还原后的底层解码错误继承标准 Base64 的模块名。3.3 Hex十六进制小写输出函数签名说明encodeHex(input: Uint8Array \| string) string输出小写十六进制文本randomHex(length: number) string生成随机小写 hex基于Math.random()非密码学安全decodeHex(str: string) Result.ResultUint8Array, EncodingError解码字节要求偶数长度decodeHexString(str: string) Result.Resultstring, EncodingError解码为 UTF-8 文本Encoding.encodeHex(hello) // 68656c6c6f Encoding.decodeHex(48656c6c6f) // Result.succeed(new Uint8Array([72, 101, 108, 108, 111])) Encoding.decodeHexString(68656c6c6f) // Result.succeed(hello)两个使用注意点直接来自源码注释decodeHex先把输入经TextEncoder转成字节再校验偶数长度因此非 ASCII 输入会被当作字节序列计长失败消息形如Length must be a multiple of 2, but is N字符映射同时接受0-9、a-f、A-F见内部函数fromHexCharEncoding.ts即解码对大小写不敏感而编码一律小写。randomHex的 JSDoc 明确警告该函数使用Math.random()不用于安全敏感场景需要安全随机值时应使用Crypto服务的randomBytes再经encodeHex编码。实现上它对 16/32 位长度trace/span 标识符的常见长度有专门快路径用单次String.fromCharCode生成扁平字符串以避免 rope 展开销。3.4 统一错误类型 EncodingError整合后的错误面也按 Changeset 所述并入同一模块Encoding.tsexport class EncodingError extends Data.TaggedError(EncodingError){ kind: Decode | Encode module: string input: unknown message: string }kind区分失败发生在解码还是编码阶段module记录报告失败的编码模块Base64/Base64Url/Hexinput保留触发失败的原始输入便于日志定位类型守卫为isEncodingError(u): u is EncodingError基于EncodingErrorTypeId值~effect/Encoding/EncodingError运行时标记判断可安全地对unknown收窄。典型处理写法import { Encoding, Result } from effect const bytes Result.flatMap( Encoding.decodeBase64(urlParam), (b) /* ... */ b ) // 或显式检查 Result.match( Encoding.decodeBase64UrlString(token), { onFailure: (e) e.kind, onSuccess: (s) s } )由于错误是结构化Data.TaggedError而非裸Error它可以参与Effect.catch的类型收窄与匹配这与 Effect 全库「解码类 API 一律返回Result/失败态而非 throw」的约定一致。四、对照 v3迁移指南中的对应关系仓库自带的大型迁移文档 migration/v3-to-v4.md 中Encoding一节约 L10245–L10259补充了旧 API 的去向与本条 Changeset 的整合方向一致Encoding.DecodeException/Encoding.EncodeException→Encoding.EncodingError解码与编码两类异常统一为同一个错误类靠kindDecode/Encode区分两个*TypeId标记 → 共享一个Encoding.EncodingErrorTypeIdEncoding.isDecodeException/Encoding.isEncodeException→Encoding.isEncodingError需要按阶段收窄时再测试kind Decode或kind Encode旧的Encoding.encodeUriComponent/Encoding.decodeUriComponent没有随整合进入新模块迁移指南建议用Result.try包裹encodeURIComponent/decodeURIComponent或直接使用Schema.StringFromUriComponent编解码。从源码结构看当前Encoding模块确实只含 Base64、Base64Url、Hex 三组编解码与统一错误类型不含 URI 组件函数——这与迁移文档的描述相符。五、底层实现速览源码证据整合后所有能力集中在单文件 packages/effect/src/Encoding.ts 中关键内部件模块级共享TextEncoder/TextDecoder实例L616–L617encode*对字符串输入统一先encoder.encode(input)标准 Base64 手写查表实现编码用 64 字母表base64abcL665–L730解码用 96 项逆向表base64codes非法字符位置为 255L732–L8563 字节 → 4 字符组按位拼装 18 | 12 | 6 |Base64Url 编码只是「标准编码 三次 replace」L860–L861去、→-、/→_Hex 编码用预生成的 256 项byteToHex表拼接L865–L873解码逐对字符经fromHexChar转数值后(a 4) | b合并。这些实现细节说明整合后的模块是自包含的纯函数集合无Effect依赖、无 Fiber/Scope 资源可在任何上下文同步调用这也是它能直接并入顶层Encoding命名空间而不引入额外服务依赖的原因。六、迁移清单从旧代码迁移到整合后的模块按以下映射执行旧写法v3 及之前新写法v4import { Base64 } from effect/encoding子路径导入import { Encoding } from effectBase64.encode(x)/Base64.decode(x)Encoding.encodeBase64(x)/Encoding.decodeBase64(x)或decodeBase64StringBase64Url.encode(x)/Base64Url.decode(x)Encoding.encodeBase64Url(x)/Encoding.decodeBase64Url(x)Hex.encode(x)/Hex.decode(x)Encoding.encodeHex(x)/Encoding.decodeHex(x)Encoding.isDecodeException(e)/isEncodeException(e)Encoding.isEncodingError(e)按e.kind区分阶段捕获DecodeException/EncodeException统一处理EncodingErrorkind: Decode \| Encode迁移时的两个行为细节解码不再 throw需按Result处理失败分支decodeBase64Url兼容填充与未填充两种输入而decodeBase64严格要求 4 倍数长度与末尾填充跨端如与只接受 unpadded 的第三方服务对接时按对接方约定选对函数即可。【免费下载链接】effectBuild production-ready applications in TypeScript项目地址: https://gitcode.com/GitHub_Trending/ef/effect创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表