@coralai/sps-plugin-storage-sync 0.1.0 → 0.2.1

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.
package/dist/index.d.ts CHANGED
@@ -24,13 +24,14 @@ export declare const name = "storage-sync";
24
24
  export declare const category = "\u5B58\u50A8";
25
25
  export declare const description = "\u5DE5\u4F5C\u533A \u2192 \u5BF9\u8C61\u5B58\u50A8\u540C\u6B65:\u6309\u4EA7\u54C1\u58F0\u660E\u7684\u8303\u56F4,\u628A\u7528\u6237\u4EA7\u7269\u589E\u91CF\u642C\u5230 S3 \u517C\u5BB9\u6876\u3002";
26
26
  interface ApplyCtx {
27
- effect(fn: () => void): void;
27
+ effect(fn: () => (() => void) | void): void;
28
28
  logger?: {
29
29
  info(msg: string): void;
30
30
  warn(msg: string): void;
31
31
  };
32
32
  reflect: {
33
33
  get(name: string): unknown;
34
+ provide(name: string, value?: unknown): () => void;
34
35
  };
35
36
  }
36
37
  export declare function apply(ctx: ApplyCtx, config: StorageSyncConfig): void;
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { MinioBackend } from './MinioBackend.js';
1
2
  import { runSyncPass } from './syncRunner.js';
2
3
  export { Config } from './schema.js';
3
4
  export const name = 'storage-sync';
@@ -58,6 +59,25 @@ export function apply(ctx, config) {
58
59
  ctx.logger?.warn?.(`[sps-sync] 一轮失败(忽略): ${err instanceof Error ? err.message : String(err)}`);
59
60
  }
60
61
  };
62
+ // 🔴 **把桶的读写能力提供出去** —— 宿主不认识桶,但别的插件可能需要读它
63
+ // (实例:`gameforge-art` 读 `library/public/audio/<product>/` 当 BGM 兜底)。
64
+ // 2026-08-28 事故:宿主删掉 `sps.storage` 时只扫了自己仓内的消费方,
65
+ // 没查线上装着的插件 ⇒ gameforge-art 永远 PENDING、六个 art.* 能力全缺席。
66
+ // ⇒ 契约留在 `@coralai/sps-plugin-api`,**实现跟着持有桶凭据的这个插件走**。
67
+ const backend = new MinioBackend(config);
68
+ // 🔴 `ctx.effect(fn)` **立即执行 fn**,并把 fn 的返回值当卸载时的 disposer。
69
+ // 第一版写成 `const d = provide(...); ctx.effect(() => d())` ——
70
+ // 那当场就把刚 provide 的服务撤销了,而且**没有任何报错**:
71
+ // apply 照常跑完、日志照常打,只有 inject 它的插件永远 PENDING。
72
+ // (2026-08-28 实测:线上 `reflect.get('sps.storage')` 拿不到,
73
+ // 而同一次装配里 `[sps-sync] 常驻` 已经打出来了。)
74
+ // ⇒ 本仓先例是 `ctx.effect(() => ctx[AGENTS].register(f))` —— register 返回 unregister。
75
+ ctx.effect(() => ctx.reflect.provide('sps.storage', {
76
+ configured: () => Boolean(config.endpoint && config.bucket && config.enabled !== false),
77
+ get: (key) => backend.get(key),
78
+ list: (prefix) => backend.list(prefix),
79
+ put: (key, bytes, contentType) => backend.put(key, bytes, contentType),
80
+ }));
61
81
  log(`[sps-sync] 常驻:间隔=${intervalMs}ms 范围=近 ${sinceDays || '∞'} 天`);
62
82
  void tick().finally(schedule);
63
83
  // 插件卸载/重挂时停掉循环 —— 否则改一次配置就多一个循环在跑。
package/dist/schema.js CHANGED
@@ -15,7 +15,7 @@ import Schema from '@deepseek-ai/schemastery';
15
15
  export const Config = Schema.object({
16
16
  enabled: Schema.boolean()
17
17
  .default(false)
18
- .description('是否开启同步。**默认关** —— 没配桶时开着只会每轮打日志。'),
18
+ .description('是否开启同步。默认关 —— 没配桶时开着只会每轮打日志。'),
19
19
  endpoint: Schema.string().description('S3 兼容端点,如 http://127.0.0.1:9000'),
20
20
  bucket: Schema.string().description('桶名。插件只认这一个名字,不认识桶里的语义分区。'),
21
21
  accessKey: Schema.string().role('secret').description('访问密钥 ID'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coralai/sps-plugin-storage-sync",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "工作区 → 对象存储同步:把节点本地盘上的用户产物搬到共享面(S3 兼容桶)。",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -28,7 +28,7 @@
28
28
  "access": "public"
29
29
  },
30
30
  "dependencies": {
31
- "@coralai/sps-plugin-api": "^0.13.0"
31
+ "@coralai/sps-plugin-api": "^0.14.0"
32
32
  },
33
33
  "optionalDependencies": {
34
34
  "minio": "^8.0.7"