npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@unieai/uad-atomic-write

v0.1.8

Published

Zero-dependency atomic file replacement: exclusive-create random-suffix temp + rename carrying the caller-stated permissions (writeFileAtomic)

Readme

dsh-atomic-write

English | 中文

零依赖的原子文件替换,供绝不允许在磁盘上留下不完整、被符号链接劫持或权限过宽内容的文件型存储共用:用户设置文档(dsh-settings-file)与凭据存储(dsh-credentials-local)。

接口面

import { withFileLock, writeFileAtomic } from '@unieai/uad-atomic-write'

declare const text: string
declare const render: (previous: string) => string

await writeFileAtomic('/home/u/.dsh/settings.yaml', text, { mode: 0o600 })

// Read-modify-write against the same file from several processes.
await withFileLock('/home/u/.dsh/settings.yaml', async () => {
  await writeFileAtomic('/home/u/.dsh/settings.yaml', render(text), { mode: 0o600 })
})

writeFileAtomic 提交一份已经渲染好的字符串。约定按故障利用它的先后顺序列出:

  • 独占创建临时文件wx + 随机后缀):open 拒绝跟随预先埋在可猜测临时路径上的符号链接。
  • 全新 inode 携带 mode 走完 rename:替换权限过宽的旧文件时直接收窄,不存在 chmod 竞态。mode 为必填,让权限决策始终可见于每个调用点(与所有新建 inode 一样受进程 umask 影响)。
  • rename 替换的是符号链接目标本身,绝不写穿到其指向的文件。
  • 同目录兄弟文件保证 rename 落在同一文件系统上,交换保持原子。
  • 自动创建父目录;任何失败都会移除临时文件并重新抛出该失败;读取方只会观察到旧内容或完整的新内容。

withFileLock 跨进程串行化同一文件的写入方,服务于单靠原子提交无法保证安全的读-渲染-提交循环。锁是以 wx 创建的同目录 <filename>.lock,因此读取方从不参与竞争;等待方按指数退避,超时即失败而非无限阻塞。EEXIST 直接表示竞争;只有一次新的 lstat 确认锁路径存在时,EPERM 才表示竞争,从而兼容 Windows 的独占创建行为,又不掩盖无关的权限故障。竞争者绝不移除现有锁:锁龄无法区分已经崩溃的所有者与被暂停但仍存活的写入方。

等待多久是持锁方所跑操作的属性,因此由每次调用经 waitMs 声明。默认值只按纯文件工作量级选定;若持锁方的循环包含一次网络往返——例如刷新过期 token 的凭据变更——就应声明更长的值,否则该文件的其他写入方会在这段时间内全部失败。退避节奏保持固定:它决定竞争者多久问一次,调用方没有理由改变它。

模型体验

无:本包是纯文件系统原语,此处没有任何内容会到达模型请求。

KV Cache 影响

无;此处没有任何内容会进入请求前缀。

已知限制与暂缓事项

  • 原子但不保证持久——不对文件或其所在目录做 fsync,因此崩溃后可能观察到 rename 被回退。此处的文件型存储在启动时重新读取并重新发布,把持久性留作调用方的策略。
  • 仅支持字符串内容——在有消费方需要之前,不提供 Buffer 或流式形态。
  • 遗留锁需要操作者恢复——进程持锁退出时可能留下同级锁文件。后续写入方超时也不会删除它;操作者只有在确认没有写入方仍拥有该锁后才会移除。文件存续时间本身不能安全证明它已无人持有。