@xiongtao.xt/tau-plugins 0.8.0 → 0.9.0

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/SYNC.md ADDED
@@ -0,0 +1,21 @@
1
+ # 同步存储插件
2
+
3
+ 需要 SDK 0.9.0 及以上和包含同步插件支持的 Tau 0.59.0 客户端。插件提供存储操作与配置表单,客户端负责数据库、资源、用量同步和冲突处理;CLI也可调用同一后台入口。
4
+
5
+ 后台从@tau/plugins/sync导入defineSyncProvider、SyncProvider与RemoteFileInfo。defineSyncProvider接收id、name、create(config);id与manifest.id一致,create根据本次任务配置返回提供方。用户只填写服务地址、桶、路径与凭据,没有能力声明或服务商认证流程。
6
+
7
+ 同步存储插件的manifest可声明sync为sync.js,模板从src/sync.ts构建Node后台入口;main.js继续承载UI。@tau/plugins/sync由客户端后台提供,保留模板external配置。普通npm依赖打包进sync.js,Node内置模块保留运行时引用。
8
+
9
+ 提供方只有uploadFile、downloadFile、fileExists、listFiles、createFileIfAbsent五个操作,使用Uint8Array、boolean和RemoteFileInfo[]等现有返回形状。分页在listFiles内部聚合;不新增stat/remove、流式参数、公开游标、目标身份字段或统一错误码。
10
+
11
+ 上传返回false或抛异常的处理由现有客户端控制流承担。createFileIfAbsent保留现有版本提交调用,不要求所有服务使用同一个HTTP头;响应异常后仍由客户端核验提交记录。不能用检查后覆盖偷换其含义,也不要求安装前进行额外探测。同步内容、冲突判断与恢复归客户端。
12
+
13
+ 后台入口同样参与manifest摘要、ZIP检查和安装事务。不要手动删掉完整性字段或把源码路径直接交给宿主执行。构建后通过客户端插件页安装ZIP,启用后在“设置→同步”选择插件并保存配置。
14
+
15
+ ## 配置界面
16
+
17
+ 在前端activate中调用context.settings.register({ id: "sync", title: "同步存储", target: "sync", component: SyncSettings }),每个插件注册一个同步配置分区。客户端将它放在“设置→同步”,插件详情页的设置入口也跳转到这里。
18
+
19
+ 组件接收PluginSettingsProps,使用syncConfig.value初始化表单,提交时await syncConfig.save(config)。配置必须为JSON值;字段与校验由插件定义。保存失败保留输入并展示错误,保存成功后用户使用客户端已有的检查、上传和下载按钮。凭据不要写入日志或context.storage,后者按工作区隔离,不是同步配置的存储位置。
20
+
21
+ 客户端在应用级按插件ID保存配置,并为每次任务提供固定快照。停用插件保留配置;后台任务运行时不能停用或卸载。作者不需要实现会话、dispose、能力探测或同步冲突引擎。CLI也从同一约定目录加载该后台入口,尊重启用意图;任务回收和进程间占用由客户端管理。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xiongtao.xt/tau-plugins",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -18,6 +18,10 @@
18
18
  "default": "./runtime.js"
19
19
  },
20
20
  "./tailwind.css": "./tailwind.css",
21
+ "./sync": {
22
+ "types": "./types/packages/plugins/src/sync.d.ts",
23
+ "default": "./runtime.js"
24
+ },
21
25
  "./whiteboard": {
22
26
  "types": "./types/packages/plugins/src/whiteboard.d.ts",
23
27
  "default": "./runtime.js"
@@ -9,9 +9,8 @@ import type { MarkdownCodec } from "../../markdown/src/index";
9
9
  import type { PluginSettings } from "./settings";
10
10
  import type { PluginSidebar } from "./sidebar";
11
11
  import type { PluginExcerpts, PluginMaterials } from "./excerpts";
12
- export type JsonValue = null | boolean | number | string | JsonValue[] | {
13
- [key: string]: JsonValue;
14
- };
12
+ import type { JsonValue } from "./json";
13
+ export type { JsonValue } from "./json";
15
14
  export interface Disposable {
16
15
  dispose(): void | Promise<void>;
17
16
  }
@@ -0,0 +1,3 @@
1
+ export type JsonValue = null | boolean | number | string | JsonValue[] | {
2
+ [key: string]: JsonValue;
3
+ };
@@ -1,12 +1,19 @@
1
1
  import type { ComponentType } from "react";
2
2
  import type { Disposable, PluginContext } from "./index";
3
+ import type { JsonValue } from "./json";
3
4
  export interface PluginSettingsProps {
4
5
  readonly context: PluginContext;
6
+ readonly syncConfig?: {
7
+ readonly value: JsonValue;
8
+ save(value: JsonValue): Promise<void>;
9
+ };
5
10
  }
6
11
  export interface PluginSettingsDefinition {
7
12
  id: string;
8
13
  title: string;
9
14
  description?: string;
15
+ /** 同步提供方的配置表单挂载到宿主同步设置。 */
16
+ target?: "sync";
10
17
  component: ComponentType<PluginSettingsProps>;
11
18
  }
12
19
  export interface PluginSettingsHandle extends Disposable {
@@ -0,0 +1,23 @@
1
+ import type { JsonValue } from "./json";
2
+ export type { JsonValue } from "./json";
3
+ export interface RemoteFileInfo {
4
+ name: string;
5
+ path: string;
6
+ size: number;
7
+ lastModified?: number;
8
+ hash?: string;
9
+ }
10
+ /** 与现有同步消费者保持相同的字节接口和返回语义。 */
11
+ export interface SyncProvider {
12
+ uploadFile(objectName: string, content: Uint8Array): Promise<boolean>;
13
+ downloadFile(objectName: string): Promise<Uint8Array>;
14
+ fileExists(objectName: string): Promise<boolean>;
15
+ listFiles(prefix?: string): Promise<RemoteFileInfo[]>;
16
+ createFileIfAbsent(objectName: string, content: Uint8Array): Promise<boolean>;
17
+ }
18
+ export interface SyncProviderDefinition {
19
+ id: string;
20
+ name: string;
21
+ create(config: JsonValue): SyncProvider;
22
+ }
23
+ export declare function defineSyncProvider(definition: SyncProviderDefinition): Readonly<SyncProviderDefinition>;