[{"data":1,"prerenderedAt":129},["ShallowReactive",2],{"home-posts":3,"home-works":87},[4,15,24,33,40,49,57,68,73,80],{"path":5,"title":6,"description":7,"date":8,"tags":9,"minutes":13,"cover":14},"\u002Fposts\u002Fship-a-static-blog-with-nuxt4","用 Nuxt 4 和 Content 把博客钉在静态文件上","不要数据库，不要管理后台。文章是仓库里的 Markdown 文件，构建命令跑完，整个站点变成一叠可以扔到任何地方的 HTML。这篇文章记录这套工作流的完整思路。","2026-08-05",[10,11,12],"nuxt","静态站点","工程化",2,"https:\u002F\u002Fpicsum.photos\u002Fseed\u002Fmoonstream-terminal\u002F1600\u002F1000",{"path":16,"title":17,"description":18,"date":19,"tags":20,"minutes":13,"cover":23},"\u002Fposts\u002Fcss-scroll-driven-animations","滚动驱动动画：让 scroll 监听器退休","animation-timeline 把滚动位置直接变成动画进度，浏览器在合成线程完成一切。本文用阅读进度条和入场动效两个例子，把这套原生 API 讲清楚。","2026-06-18",[21,22],"css","动画","https:\u002F\u002Fpicsum.photos\u002Fseed\u002Fmoonstream-aurora\u002F1600\u002F1000",{"path":25,"title":26,"description":27,"date":28,"tags":29,"minutes":13,"cover":32},"\u002Fposts\u002Fmarkdown-kitchen-sink","Markdown 排版全要素测试","一篇用来检验站点排版系统的文章：标题层级、列表、引用、表格、多语言代码块、图片与分隔线全部在场。改动样式之后，先来这里看一眼。","2026-05-02",[30,31],"markdown","排版",null,{"path":34,"title":35,"description":36,"date":37,"tags":38,"minutes":13,"cover":32},"\u002Fposts\u002Ftypescript-satisfies-in-practice","satisfies、as const 与类型收窄的日常","satisfies 解决的是一个很具体的矛盾：既要校验值符合某个宽类型，又不想丢掉字面量本身的精确类型。三个日常场景说明它和 as const 怎么配合。","2026-03-21",[39],"typescript",{"path":41,"title":42,"description":43,"date":44,"tags":45,"minutes":13,"cover":48},"\u002Fposts\u002Flocal-first-notes","本地优先软件笔记：数据先是你的，然后才是云的","云应用把「打开自己的文件」变成了需要网络许可的操作。本地优先是对这件事的系统性纠偏：本地是事实源，同步只是增强。这篇是我的阅读与实践笔记。","2026-02-14",[46,47],"本地优先","架构","https:\u002F\u002Fpicsum.photos\u002Fseed\u002Fmoonstream-harbor\u002F1600\u002F1000",{"path":50,"title":51,"description":52,"date":53,"tags":54,"minutes":56,"cover":32},"\u002Fposts\u002Fhello-starriver","开站：为什么是星河入梦","给这个站点起名、定规矩的短文。写作的部分留给深夜，工程的部分留给白天，两件事在这里汇合。","2026-01-06",[55],"随笔",1,{"path":58,"title":59,"description":60,"date":61,"tags":62,"minutes":67,"cover":32},"\u002Fposts\u002Fgolang-logger-out","如何自定义处理Golang Cmd的日志输出","当前基于Golang 1.22.2 版本实现","2024-03-21",[63,64,65,66],"golang","linux","LinkError","文件移动",3,{"path":69,"title":70,"description":60,"date":71,"tags":72,"minutes":13,"cover":32},"\u002Fposts\u002Fgolang-linux-file","Golang在linux跨区移动文件失败","2024-03-19",[63,64,65,66],{"path":74,"title":75,"description":60,"date":76,"tags":77,"minutes":13,"cover":32},"\u002Fposts\u002Fgolang-exec-kill","Golang exec.Cmd在Kill后不能关闭进程","2024-03-17",[63,78,79],"exec","kill",{"path":81,"title":82,"description":60,"date":83,"tags":84,"minutes":67,"cover":32},"\u002Fposts\u002Fgolang-redis-seq","Golang基于Redis生成唯一序列","2024-03-15",[63,85,86],"redis","分布式序列号",[88,102,115],{"path":89,"title":90,"description":91,"date":92,"stack":93,"cover":101,"repo":32,"demo":32},"\u002Fworks\u002Fvideo-stream","Video Stream - Rust 视频流服务","基于 Rust、MinIO 与 FFmpeg 的视频上传、转码和私有 HLS 播放服务，支持分片直传、断点续传、任务接管和短时效播放凭证。","2026-07-11",[94,95,96,97,98,99,100],"Rust","Axum","PostgreSQL","MinIO","FFmpeg","HLS","Prometheus","\u002Fimages\u002Fworks\u002Fvideo-stream\u002Fcover.jpg",{"path":103,"title":104,"description":105,"date":106,"stack":107,"cover":114,"repo":32,"demo":32},"\u002Fworks\u002Fhaiyan-io-work","海燕边缘网关 haiyan-io","基于 Rust 的智能硬件边缘网关，把多种现场协议收敛为统一物模型，并提供可靠上云、本地闭环、Web 运维与网关群控。","2026-06-07",[94,108,95,109,110,111,112,113],"Tokio","MQTT","Modbus","OPC UA","gRPC","Vue 3","\u002Fimages\u002Fworks\u002Fhaiyan-io\u002Fcover.jpg",{"path":116,"title":117,"description":118,"date":119,"stack":120,"cover":128,"repo":32,"demo":32},"\u002Fworks\u002Fauth-one","Nexus ID - 多租户身份与 OIDC 平台","基于 Go、PostgreSQL 与 Redis 构建的统一身份中心，覆盖多租户隔离、可撤销会话、MFA、WebAuthn、OIDC 授权服务器、应用授权与安全审计。","2026-03-10",[121,122,96,123,124,125,126,127],"Go","Gin","Redis","Nuxt 4","OIDC","WebAuthn","OpenTelemetry","\u002Fimages\u002Fworks\u002Fauth-one\u002Fcover.jpg",1789524988633]