Puter SpaceInfo 存储空间对象指南:解读 `capacity` 与 `used` 字段及完整数据链路
发布时间:2026/9/9 22:46:28来源:尧图网络
Puter SpaceInfo 存储空间对象指南解读capacity与used字段及完整数据链路【免费下载链接】puter The Internet Computer! Free, Open-Source, and Self-Hostable.项目地址: https://gitcode.com/GitHub_Trending/pu/puterSpaceInfo是 Puter 云端文件系统中用于描述用户存储空间配额与实际用量的对象。本指南将围绕 src/docs/src/Objects/spaceinfo.md 中定义的字段展开结合配套的puter.fs.space()API 文档、put-js SDK 实现与后端存储统计源码帮助你准确理解capacity/used的字节语义、调用权限与限流边界以及从浏览器调用到数据库聚合统计的完整链路进而能在自己的应用中可靠地实现剩余空间检测配额展示等功能。SpaceInfo 对象定义SpaceInfo是 Puter 返回的存储空间信息载体对象本身不携带任何方法只通过两个数值属性反映某个用户Actor当前的存储状态。其官方定义只有两个字段属性类型说明capacityNumber用户可用的总存储容量单位为字节bytesusedNumber用户已使用的存储空间单位为字节bytes在 puter-js 中types.js 以 JSDoc 形式给出了同构的 TypeScript 类型描述/** typedef {Object} SpaceInfo * property {number} capacity Total storage capacity available to the user, in bytes. * property {number} used Amount of storage space used by the user, in bytes. */需要特别注意的是两个字段的值都是未加工的字节数而不是经过 KB/MB/GB 换算后的展示值。做展示时需要自行换算例如把used换算成可读字符串通常用used / capacity计算使用百分比。capacity并不等同于还能再写多少字节剩余可用空间应通过capacity - used计算put-js 上传前的预检查正是这样计算的下文会说明。哪个接口返回 SpaceInfoSpaceInfo不会凭空出现它由 Puter 文件系统模块的space操作产生。配套文档 FS/space.md 中定义了两种等价的调用形态puter.fs.space()—— 通过文件系统命名空间调用puter.space()—— 直接挂载在puter实例上的别名调用示例中即为这种写法。调用签名与返回值如下puter.fs.space() // 返回 Promiseresolve 为一个 SpaceInfo 对象 // { capacity: Number 总容量 bytes, used: Number 已用 bytes }该方法没有入参。官方文档给出的一段最小可运行示例嵌入script srchttps://js.puter.com/v2//script加载 SDK 后即可在浏览器执行html body script srchttps://js.puter.com/v2//script script // Retrieves the storage space capacity and usage for the current user, and prints them to the browser console puter.space().then((space){ console.log(space) }); /script /body /html从 SDK 源码看space操作定义在 space.js它经由defineOperation脚手架注册实际请求的底层端点就是/dfconst space defineOperation({ request () { return { endpoint: /df }; }, });同时在 FileSystem/index.js 中以space space形式挂到fs模块上并在 index.js 通过registerModule(fs, ...)暴露为puter.fs从而支持puter.fs.space()与puter.space()两种访问路径。调用约束权限、Actor 门禁与限流在把SpaceInfo用于生产逻辑前需要了解它的访问约束这部分在 FS/space.md 的提示框中有明确说明该方法需要访问用户存储空间的权限。如果用户尚未授权方法将返回错误error。这意味着只有当当前 App/用户 Actor 拥有相应存储读取授权时space()才能成功解析否则 Promise 会以错误结束。你需要在自己的应用中处理 reject 分支而不是只依赖 then。后端同样有双保险。/df路由在 LegacyFSController.ts 注册并在处理函数中强制要求 Actorrouter.all(/df, { ...apiOptions, rateLimit: FS_DF_LIMIT }, this.df);其处理函数df首先执行this.#requireActor(req)拿到并校验当前 Actor然后取userId查询配额最后把结果映射为 SpaceInfo 的字段名返回/** GET|POST /df — user storage allowance. */ df async (req: Request, res: Response): Promisevoid { this.#requireActor(req); const userId this.#getActorUserId(req); const allowance await this.services.fs.getUsersStorageAllowance(userId); res.json({ used: allowance.curr, capacity: allowance.max, }); };可以看到后端内部使用curr/max这一对命名而对外暴露时统一转成used/capacity。这一内部语义 → 对外协议的映射点正是理解 SpaceInfo 字段来源的关键。相关测试也覆盖了/df的 Actor 门禁见 LegacyFSController.test.ts。此外/df是一个被限流的端点。速率限制值定义在 limits.tsexport const FS_DF_LIMIT userWindow(fs:df, 60, 30, 15);userWindow(fs:df, 60, 30, 15)表示这是以用户为维度的限流窗口key 为fs:df在 60 秒窗口内允许多次调用、当速率达到某阈值时会触发更严格的 30/15 档位限制具体语义由userWindow的实现按窗口/桶参数解释。因此不要把space()写进高频轮询循环更合适的做法是低频刷新或事件驱动刷新例如上传前、进入设置页时各调一次。从/df到字节数SpaceInfo 的底层统计链路capacity与used并不是凭空捏造的数字它们由后端存储层实时聚合计算得出。完整链路如下浏览器端puter.fs.space()→PUT/GET /df见 space.js控制器LegacyFSController.df调用文件系统服务的getUsersStorageAllowance见 LegacyFSController.tsFSService.getUsersStorageAllowance 做参数校验后把查询委托给存储层fsEntrystore最终由 FSEntryStore.getUserStorageAllowance 完成真正的聚合。第 4 步的 SQL 聚合逻辑直接决定了 SpaceInfo 两个字段的含义值得逐行拆解// used 的统计对当前用户全部 fsentries 的 size 字段求和 SELECT COALESCE(SUM(size), 0) AS totalUsage FROM fsentries WHERE user_id ? // capacity 的基准读取 user 表上的 free_storage 配额列 SELECT free_storage FROM user WHERE id ? LIMIT 1要点如下used的来源对fsentries表中该user_id的所有条目执行SUM(size)空结果用COALESCE(..., 0)兜底为 0。所以used是当前用户所有文件占用的实时累计字节数。capacity的基准来源优先取用户表的free_storage列若该列为空例如未显式配置则回退到全局配置项storage_capacity配置模板见 config.template.jsonc。配额奖励事件查询后会以 best-effort 方式向storage.quota.bonus事件发出负载为{ userId, extra }的事件并等待处理emitAndWait若事件监听方返回了正的extra值会累加到max上。事件异常会被捕获忽略不影响主流程。is_storage_limited开关若配置了is_storage_limited false即不限制存储capacity的含义会变为设备当前可用空间优先取配置项available_device_storage否则调用statfs(process.cwd())读取文件系统空闲字节数bavail * bsize此时max curr freeOnDisk若statfs失败则回退为Number.MAX_SAFE_INTEGER相当于几乎无限。由此可以推断自托管部署时SpaceInfo.capacity的具体数值强烈依赖你在 config.template.jsonc 中如何设置storage_capacity、is_storage_limited、available_device_storage这几个键云托管版则由账号配额体系决定。换句话说同样的space()调用在不同部署形态下返回的 capacity 语义可能不同——这是把 SpaceInfo 写入业务逻辑前必须留意的边界条件。实战用 SpaceInfo 做上传前的空间预检查put-js 内部已经把 SpaceInfo 用于真实业务场景这是理解它价值的最佳范例。在 upload/index.js 中上传操作会先判断文件大小是否超过阈值SPACE_CHECK_MIN_BYTES超过时先调用this.space()预检查剩余空间不足则直接以NOT_ENOUGH_SPACE错误码拒绝从而避免先把大文件传上去、再被服务端以空间不足拒绝的浪费// we want to avoid uploading files in case there is not enough storage space. // the user uploads a very large folder/file and then the server rejects it because there is not enough space storage await this.space(); if (/* 预计占用 capacity - used */) { return error({ code: NOT_ENOUGH_SPACE, message: Not enough storage space available. }); }对应测试在 upload/index.test.js 中用fs.space vi.fn(...)注入{ capacity, used }分别验证空间足够时不会调用space()恰好用满时拒绝上传等分支同时 operations.test.js 验证了space()对{ capacity: 10, used: 4 }这类响应形状以及回调式调用space(success)的兼容性。在自己的应用中复刻这套模式时推荐按以下模板处理const { capacity, used } await puter.fs.space(); const remaining capacity - used; // 单位均为 bytes if (fileSize remaining) { // 提示用户空间不足可参考 puter-js 的 usage-limit 弹窗 // storageLimitPrompt.js 中 showUsageLimitDialog 的做法 return; } // 继续上传另有一处可复用的细节当文件较小时直接上传通常比先调用一次space()更划算——SDK 用SPACE_CHECK_MIN_BYTES阈值做了同样的取舍见 upload/index.js 与相关测试。小结SpaceInfo是仅含capacity总容量与used已用两个 Number 字段的存储快照对象值均为字节见 spaceinfo.md。它由puter.fs.space()/puter.space()产生对应后端GET|POST /df端点调用需要存储访问授权且受FS_DF_LIMIT用户级限流保护。used是fsentries表SUM(size)的实时聚合capacity的取值受free_storage、storage_capacity、storage.quota.bonus事件以及自托管is_storage_limited/available_device_storage配置共同决定。真实用法参考 put-js 上传预检查用capacity - used判断剩余空间超出即返回NOT_ENOUGH_SPACE。如需进一步探索可继续阅读 SpaceInfo 官方定义、配套方法文档 FS/space.md、SDK 实现 space.js 以及后端统计核心 FSEntryStore.ts。【免费下载链接】puter The Internet Computer! Free, Open-Source, and Self-Hostable.项目地址: https://gitcode.com/GitHub_Trending/pu/puter创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网