zipcalm 0.0.0-stage → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +260 -2
  3. package/bin/zipcalm.js +191 -0
  4. package/package.json +67 -4
  5. package/server/app.js +309 -0
  6. package/server/boot.js +145 -0
  7. package/server/config/defaults.js +153 -0
  8. package/server/config/index.js +140 -0
  9. package/server/config/schema.js +244 -0
  10. package/server/core/auth/password.js +89 -0
  11. package/server/core/auth/store.js +261 -0
  12. package/server/core/compress/blacklist.js +236 -0
  13. package/server/core/compress/capRegistry.js +171 -0
  14. package/server/core/compress/deleter.js +285 -0
  15. package/server/core/compress/hardlinkScan.js +67 -0
  16. package/server/core/compress/orchestrator.js +783 -0
  17. package/server/core/compress/preflight.js +376 -0
  18. package/server/core/compress/registry.js +240 -0
  19. package/server/core/compress/sourceWalk.js +84 -0
  20. package/server/core/compress/verify.js +47 -0
  21. package/server/core/engineRunner.js +369 -0
  22. package/server/core/fs/list.js +164 -0
  23. package/server/core/fs/platformProfile.js +167 -0
  24. package/server/core/fs/repairNames.js +150 -0
  25. package/server/core/fs/roots.js +178 -0
  26. package/server/core/fs/safePath.js +173 -0
  27. package/server/core/fs/search.js +108 -0
  28. package/server/core/fs/stat.js +110 -0
  29. package/server/core/fs/systemTrash.js +212 -0
  30. package/server/core/fs/writeOps.js +257 -0
  31. package/server/core/hardlink/executor.js +106 -0
  32. package/server/core/hardlink/scanner.js +193 -0
  33. package/server/core/metrics/collector.js +279 -0
  34. package/server/core/metrics/procfs.js +107 -0
  35. package/server/core/task/events.js +82 -0
  36. package/server/core/task/manager.js +987 -0
  37. package/server/core/task/recovery.js +116 -0
  38. package/server/core/task/store.js +240 -0
  39. package/server/http/middleware/auth.js +130 -0
  40. package/server/http/middleware/error.js +54 -0
  41. package/server/http/middleware/logger.js +27 -0
  42. package/server/http/middleware/pathGuard.js +119 -0
  43. package/server/http/router.js +29 -0
  44. package/server/http/routes/auth.js +115 -0
  45. package/server/http/routes/blacklist.js +97 -0
  46. package/server/http/routes/capabilities.js +21 -0
  47. package/server/http/routes/compress.js +339 -0
  48. package/server/http/routes/fs.js +109 -0
  49. package/server/http/routes/hardlink.js +160 -0
  50. package/server/http/routes/health.js +52 -0
  51. package/server/http/routes/metrics.js +36 -0
  52. package/server/http/routes/tasks.js +304 -0
  53. package/server/lib/atomic-json.js +118 -0
  54. package/server/lib/errors.js +145 -0
  55. package/server/lib/fs-probe.js +25 -0
  56. package/server/lib/logger.js +68 -0
  57. package/server/lib/runtime-guard.js +49 -0
  58. package/server/lib/throttle.js +42 -0
  59. package/server/plugins/capabilities/password/index.js +300 -0
  60. package/server/plugins/capabilities/password/methods/aes256.js +31 -0
  61. package/server/plugins/capabilities/password/methods/zip20.js +29 -0
  62. package/server/plugins/formats/_shared/createGuards.js +26 -0
  63. package/server/plugins/formats/_shared/entrySafety.js +174 -0
  64. package/server/plugins/formats/_shared/nameRepair.js +123 -0
  65. package/server/plugins/formats/_shared/streams.js +18 -0
  66. package/server/plugins/formats/_shared/tar/compression.js +114 -0
  67. package/server/plugins/formats/_shared/tar/reader.js +74 -0
  68. package/server/plugins/formats/_shared/tar/writer.js +206 -0
  69. package/server/plugins/formats/_shared/tarFamily.js +207 -0
  70. package/server/plugins/formats/rar/index.js +354 -0
  71. package/server/plugins/formats/rar/js-engine.js +122 -0
  72. package/server/plugins/formats/rar/js-runner.mjs +129 -0
  73. package/server/plugins/formats/rar/unrar.js +266 -0
  74. package/server/plugins/formats/sevenzip/engine.js +355 -0
  75. package/server/plugins/formats/sevenzip/index.js +461 -0
  76. package/server/plugins/formats/sevenzip/wasm-runner.mjs +72 -0
  77. package/server/plugins/formats/tar/index.js +19 -0
  78. package/server/plugins/formats/targz/index.js +19 -0
  79. package/server/plugins/formats/tarzst/index.js +26 -0
  80. package/server/plugins/formats/zip/index.js +587 -0
  81. package/shared/app-version.js +7 -0
  82. package/shared/capabilities.js +21 -0
  83. package/shared/compress-modes.js +38 -0
  84. package/shared/error-codes.js +117 -0
  85. package/shared/format-list.js +101 -0
  86. package/shared/hardlink-hint.js +21 -0
  87. package/shared/task-phase.js +62 -0
  88. package/shared/task-status.js +84 -0
  89. package/web/dist/assets/index-D3zjq7N2.js +131 -0
  90. package/web/dist/assets/index-D9Vdmrb9.css +1 -0
  91. package/web/dist/index.html +18 -0
@@ -0,0 +1,82 @@
1
+ // 任务事件总线(SSE 的"发布/订阅"内核,docs/M0/API规范.md §五)
2
+ //
3
+ // 设计要点(每条都对着契约条款):
4
+ // - `seq` 单调递增:每个事件一个序号,客户端用 `since=<seq>` 续传(§五 规则 2);
5
+ // - 环形缓冲保留最近 `retention`(默认 1000)条:`since` 落在窗口内 → 补发增量;
6
+ // 落在窗口外 → 调用方改发 `snapshot`(丢事件不丢状态,§五 规则 1/2);
7
+ // - 死订阅者自愈:`send()` 返回 false 或抛错即剔除,单个坏连接不影响其他订阅者(§五 规则 4);
8
+ // - **与任务执行零耦合**:零订阅者照常发布(发布只入环形缓冲),任务该跑还跑(INV-02/INV-04)。
9
+ //
10
+ // 结构:状态集中在 ctx,扇出/续传等动作是模块级函数;工厂只做装配与暴露最小 API。
11
+
12
+ /** 事件 → 频道映射(心跳/error 属连接级,不按频道过滤) */
13
+ const CHANNEL_OF = { snapshot: 'tasks', task: 'tasks', metrics: 'metrics' };
14
+
15
+ /** 扇出:写失败/返回 false 的订阅者立即剔除(自愈) */
16
+ function fanOut(ctx, frame) {
17
+ const dead = [];
18
+ for (const subscriber of ctx.subscribers) {
19
+ if (subscriber.channels && frame.channel && !subscriber.channels.includes(frame.channel)) continue;
20
+ try {
21
+ if (subscriber.send(frame) === false) dead.push(subscriber);
22
+ } catch {
23
+ dead.push(subscriber);
24
+ }
25
+ }
26
+ for (const subscriber of dead) {
27
+ ctx.subscribers.delete(subscriber);
28
+ ctx.logger.warn('SSE 订阅者写入失败,已剔除', { remaining: ctx.subscribers.size });
29
+ }
30
+ }
31
+
32
+ /**
33
+ * 续传:返回 seq > since 的缓冲事件。
34
+ * `since` 早于缓冲窗口起点 → 返回 null(调用方应改发 snapshot,§五 规则 2)。
35
+ */
36
+ function replayFromRing(ctx, since) {
37
+ if (!Number.isInteger(since)) return null;
38
+ const oldest = ctx.ring.length > 0 ? ctx.ring[0].seq : ctx.seq + 1;
39
+ if (since < oldest - 1) return null;
40
+ return ctx.ring.filter((frame) => frame.seq > since);
41
+ }
42
+
43
+ /**
44
+ * @param {{retention?: number, logger: object}} options
45
+ */
46
+ export function createTaskEvents(options) {
47
+ const ctx = {
48
+ logger: options.logger,
49
+ retention: Number.isInteger(options.retention) ? options.retention : 1000,
50
+ seq: 0,
51
+ /** 环形缓冲:{ seq, event, channel, data }(data 已含 seq) */
52
+ ring: [],
53
+ /** Set<{channels: string[], send: (frame) => boolean}> */
54
+ subscribers: new Set(),
55
+ };
56
+
57
+ function publish(event, data) {
58
+ ctx.seq += 1;
59
+ const frame = { seq: ctx.seq, event, channel: CHANNEL_OF[event] || null, data: { ...data, seq: ctx.seq } };
60
+ ctx.ring.push(frame);
61
+ if (ctx.ring.length > ctx.retention) ctx.ring.shift();
62
+ fanOut(ctx, frame);
63
+ return frame.seq;
64
+ }
65
+
66
+ /** 注册订阅者;返回退订函数(连接断开时必须调用,防泄漏) */
67
+ function subscribe(subscriber) {
68
+ ctx.subscribers.add(subscriber);
69
+ return () => {
70
+ ctx.subscribers.delete(subscriber);
71
+ };
72
+ }
73
+
74
+ return {
75
+ publish,
76
+ subscribe,
77
+ replaySince: (since) => replayFromRing(ctx, since),
78
+ subscriberCount: () => ctx.subscribers.size,
79
+ currentSeq: () => ctx.seq,
80
+ retention: ctx.retention,
81
+ };
82
+ }