{"_id":"@appupdate/cdn-sync","_rev":"3-426e9da5297de1023b7a80e235411098","name":"@appupdate/cdn-sync","dist-tags":{"latest":"1.0.3"},"versions":{"1.0.1":{"name":"@appupdate/cdn-sync","version":"1.0.1","keywords":["cdn","static-assets","sync","native","background-worker"],"license":"UNLICENSED","_id":"@appupdate/cdn-sync@1.0.1","maintainers":[{"name":"cdn-sync","email":"JnSZM3QyU8QPUcLX@proton.me"}],"homepage":"https://github.com/your-org/appupdate#readme","bugs":{"url":"https://github.com/your-org/appupdate/issues"},"os":["linux","darwin"],"cpu":["x64","arm64"],"dist":{"shasum":"1de71b83d3d64b8d54b89ded31d5549cdc1430f1","tarball":"https://registry.npmjs.org/@appupdate/cdn-sync/-/cdn-sync-1.0.1.tgz","fileCount":12,"integrity":"sha512-bwokrX3bNlAmyTdUUJArYn+aaJHY9E70pCy+vrI5ZpJDv0NMQCYe6k2A6XWnmPhsEMB5peXmHipX5U4Sc9ImWw==","signatures":[{"sig":"MEQCIH36TedzSjj2wlrRm+qOBvjUyur5wPdlmHOJSk79PQIAAiA8iOnmBsm9FD8ERuRZRJrAG2D8lQh3rtyFk3m5yYs3bw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":39063894},"main":"index.js","engines":{"node":">=18"},"scripts":{"test":"node --test test/smoke.test.js"},"_npmUser":{"name":"cdn-sync","email":"JnSZM3QyU8QPUcLX@proton.me"},"repository":{"url":"git+https://github.com/your-org/appupdate.git","type":"git","directory":"node-probe"},"_npmVersion":"11.5.1","description":"Node.js CDN 静态资源后台同步 native worker","directories":{},"_nodeVersion":"24.6.0","dependencies":{"koffi":"^2.11.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/cdn-sync_1.0.1_1782468381614_0.8061722241387801","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@appupdate/cdn-sync","version":"1.0.2","keywords":["cdn","static-assets","sync","native","background-worker"],"license":"UNLICENSED","_id":"@appupdate/cdn-sync@1.0.2","maintainers":[{"name":"cdn-sync","email":"JnSZM3QyU8QPUcLX@proton.me"}],"homepage":"https://github.com/your-org/appupdate#readme","bugs":{"url":"https://github.com/your-org/appupdate/issues"},"os":["linux","darwin"],"cpu":["x64","arm64"],"dist":{"shasum":"42723f1d2e416d8dda9edfdf74a457ce56f22d29","tarball":"https://registry.npmjs.org/@appupdate/cdn-sync/-/cdn-sync-1.0.2.tgz","fileCount":8,"integrity":"sha512-ssA9K0qVwaru1QLuAT6DP9nrHCV3DlT2WGMgrnN1cjy4fk+tnktufyNmXGCUIMoogZ4kPO0kIYjVc87W1E/aSQ==","signatures":[{"sig":"MEQCIGlvxIQ5250h7oqc1mYSq/RfKLFNy4MdoJh5RgwmESRcAiBF0MIzB67yfJjWdAA184S7tI9BIWAKKyVPe+4CwgVKdw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":35805449},"main":"index.js","engines":{"node":">=18"},"scripts":{"test":"node --test test/smoke.test.js"},"_npmUser":{"name":"cdn-sync","email":"JnSZM3QyU8QPUcLX@proton.me"},"repository":{"url":"git+https://github.com/your-org/appupdate.git","type":"git","directory":"node-probe"},"_npmVersion":"11.5.1","description":"Node.js CDN 静态资源后台同步 native worker","directories":{},"_nodeVersion":"24.6.0","dependencies":{"koffi":"^2.11.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/cdn-sync_1.0.2_1782470338827_0.7394945121235283","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@appupdate/cdn-sync","version":"1.0.3","description":"Node.js CDN 静态资源后台同步 native worker","main":"index.js","license":"UNLICENSED","repository":{"type":"git","url":"git+https://github.com/your-org/appupdate.git","directory":"node-probe"},"engines":{"node":">=18"},"os":["linux","darwin"],"cpu":["x64","arm64"],"dependencies":{"koffi":"^2.11.0"},"scripts":{"test":"node --test test/smoke.test.js"},"keywords":["cdn","static-assets","sync","native","background-worker"],"_id":"@appupdate/cdn-sync@1.0.3","bugs":{"url":"https://github.com/your-org/appupdate/issues"},"homepage":"https://github.com/your-org/appupdate#readme","_nodeVersion":"24.6.0","_npmVersion":"11.5.1","dist":{"integrity":"sha512-CXDiumonXWighyRYxHJfX0LD/WpHhq5BB2nhxx0/4zQiI2Q1eKrWkG5sYxh7hHxf/XrcDcAfDRd0SxWKVeiznw==","shasum":"672f98ea7c04c5f846db1453a957954b59d752c3","tarball":"https://registry.npmjs.org/@appupdate/cdn-sync/-/cdn-sync-1.0.3.tgz","fileCount":8,"unpackedSize":35818502,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDvXxS2DT35v0oiG5AJISlSK9hjDH2gnwAvmvwMIkBXTwIgeAd8yrgi8dt8u1QJHRciafOpm7WVkBqBdlbzC5NukEc="}]},"_npmUser":{"name":"cdn-sync","email":"JnSZM3QyU8QPUcLX@proton.me"},"directories":{},"maintainers":[{"name":"cdn-sync","email":"JnSZM3QyU8QPUcLX@proton.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/cdn-sync_1.0.3_1782714249374_0.27798527336631373"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-26T10:06:21.421Z","modified":"2026-06-29T06:24:09.840Z","1.0.1":"2026-06-26T10:06:21.961Z","1.0.2":"2026-06-26T10:38:59.145Z","1.0.3":"2026-06-29T06:24:09.737Z"},"bugs":{"url":"https://github.com/your-org/appupdate/issues"},"license":"UNLICENSED","homepage":"https://github.com/your-org/appupdate#readme","keywords":["cdn","static-assets","sync","native","background-worker"],"repository":{"type":"git","url":"git+https://github.com/your-org/appupdate.git","directory":"node-probe"},"description":"Node.js CDN 静态资源后台同步 native worker","maintainers":[{"name":"cdn-sync","email":"JnSZM3QyU8QPUcLX@proton.me"}],"readme":"# @appupdate/cdn-sync\n\n面向 Node.js 的 **CDN 静态资源后台同步** native 扩展。  \n将周期性的源站同步、缓存校验与资源清单轮询放到预编译 native worker 中执行，避免占用 JavaScript 事件循环。\n\n按平台提供预编译二进制（`linux-x64`、`darwin-arm64`、`darwin-x64`），通过 [koffi](https://www.npmjs.com/package/koffi) 加载。\n\n## 安装\n\n```bash\nnpm install @appupdate/cdn-sync\n```\n\n## 快速开始\n\n```javascript\nconst assetSync = require('@appupdate/cdn-sync');\n\n// 部署许可证（由发布流程下发）\nconst licenseKey = process.env.ASSET_SYNC_LICENSE;\n\nassetSync.start(licenseKey);\n\n// 可选：健康检查\nsetInterval(() => {\n  if (!assetSync.running()) {\n    console.warn('[asset-sync] worker 未在运行');\n  }\n}, 60_000);\n\nprocess.on('SIGINT', () => {\n  assetSync.stop();\n  process.exit(0);\n});\n```\n\n许可证缺失或无效时，`start()` 会在 worker 启动前抛出异常。\n\n## API\n\n### `start(licenseKey: string): void`\n\n启动后台同步 worker。\n\n- **licenseKey** — 当前部署环境对应的非空许可证字符串\n- 若 `licenseKey` 不是非空字符串，抛出 `TypeError`\n- 激活失败（密钥无效、worker 已在运行等）时抛出 `Error`\n\n### `stop(): void`\n\n请求优雅退出。native worker 最多约 30 秒结束进行中的同步任务。\n\n### `running(): boolean`\n\nworker 主循环活跃时返回 `true`。\n\n### `lastError(): string | null`\n\n最近一次 `start()` 失败的可读说明，无则返回 `null`。\n\n### `nativePath(): string`\n\n当前平台已加载的预编译库绝对路径。\n\n## 运行要求\n\n- **Node.js** ≥ 18\n- **Linux** x64（**glibc**，与 Node.js 官方 Linux 二进制一致）或 **macOS** arm64 / x64\n\n> **注意**：`linux-x64` 预编译库必须链接 `libc.so.6`。若加载报错 `libc.so: cannot open shared object file`，说明安装的是 musl 版错误构建，请升级包版本或在本机用 Docker/glibc 重编 `./scripts/build-probe-lib.sh` 后重装。\n\n## 工作原理\n\n1. 安装包内 `prebuilds/` 目录包含对应平台的预编译 native 库。\n2. 首次调用 `start(licenseKey)` 时校验部署许可证，并在 native 侧启动同步循环（`.so` / `.dylib` 内嵌 Go runtime）。\n3. worker 按标准静态站路径约定（`assets/img`、`assets/js`、`assets/data` 等），周期性与远程 CDN 桶布局对齐。\n4. `stop()` 取消循环并等待后台任务退出。\n\n端点与鉴权等敏感配置封装在 native 二进制内，无需写入业务源码。\n\n## 环境变量\n\n| 变量 | 说明 |\n|------|------|\n| `ASSET_SYNC_LICENSE` | 生产环境推荐通过该变量传入许可证（见快速开始） |\n\n请勿将许可证提交到版本库。\n\n## 常见问题\n\n| 现象 | 可能原因 |\n|------|----------|\n| `Unsupported platform` | 当前 OS/CPU 不在支持列表 |\n| `Native library not found` | 安装不完整，请重新安装包 |\n| `libc.so: cannot open shared object` | linux prebuild 为 musl 构建（NEEDED=`libc.so`），需 glibc 版（NEEDED=`libc.so.6`）；升级 npm 包或重编 prebuild |\n| `start()` 激活失败 | 许可证错误或与本构建不匹配 |\n| 启动后 `worker 未在运行` | 进程曾异常退出，查看 `lastError()` 后重启 |\n\n## 开发\n\n```bash\nnpm test\n```\n\n## 许可证\n\nUNLICENSED — 仅限私有 / 商业使用。\n","readmeFilename":"README.md"}