@smartdoca/web-plugin-registry 0.1.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/dist/LICENSE +661 -0
- package/dist/LICENSING.md +57 -0
- package/dist/LICENSING.zh-CN.md +48 -0
- package/dist/index.d.ts +238 -0
- package/dist/index.js +394 -0
- package/package.json +19 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Licensing
|
|
2
|
+
|
|
3
|
+
[简体中文](LICENSING.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
Doca uses a dual-licensing model for code owned by the Doca copyright holders.
|
|
6
|
+
|
|
7
|
+
## Open-source license
|
|
8
|
+
|
|
9
|
+
Unless a file or package says otherwise, Doca-owned code in this repository is
|
|
10
|
+
available under the GNU Affero General Public License version 3 only
|
|
11
|
+
(`AGPL-3.0-only`). The full license text is in [LICENSE](LICENSE).
|
|
12
|
+
|
|
13
|
+
The AGPL permits commercial use. When its conditions apply, it requires the
|
|
14
|
+
corresponding source to remain available under the AGPL, including for modified
|
|
15
|
+
versions offered to users over a network. “Open source” and “free of charge” are
|
|
16
|
+
not the same thing, and the AGPL obligations do not depend on whether an operator
|
|
17
|
+
charges money.
|
|
18
|
+
|
|
19
|
+
## Commercial license
|
|
20
|
+
|
|
21
|
+
Organizations that want to use Doca-owned code in a proprietary product without
|
|
22
|
+
the AGPL obligations may obtain a separate commercial license from the Doca
|
|
23
|
+
copyright holders. A commercial license exists only when both parties have
|
|
24
|
+
entered into a written agreement. This repository does not itself grant that
|
|
25
|
+
alternative license.
|
|
26
|
+
|
|
27
|
+
## Packages and editors
|
|
28
|
+
|
|
29
|
+
The same licensing direction applies to Doca-owned packages and editors,
|
|
30
|
+
including the Doca plugin SDK and the Slate, presentation, spreadsheet,
|
|
31
|
+
Markdown, and canvas editor packages. Each released npm artifact must:
|
|
32
|
+
|
|
33
|
+
- carry an accurate license field and license notice;
|
|
34
|
+
- link to the public source repository and the exact source tag for that version;
|
|
35
|
+
- include the build scripts and dependency lock needed to produce the artifact;
|
|
36
|
+
- preserve all notices and license obligations of third-party components.
|
|
37
|
+
|
|
38
|
+
The historical archives under `vendor/` are development and recovery inputs.
|
|
39
|
+
They are not the long-term public distribution channel. Before the public
|
|
40
|
+
release, active editor dependencies must be rebuilt from their public tagged
|
|
41
|
+
sources, published to npm, and consumed by Doca through registry versions.
|
|
42
|
+
|
|
43
|
+
## Third-party software and assets
|
|
44
|
+
|
|
45
|
+
The dual license covers only material for which the Doca copyright holders can
|
|
46
|
+
grant these rights. Third-party libraries, fonts, media, generated artifacts,
|
|
47
|
+
and other bundled material retain their own licenses. Their notices and source
|
|
48
|
+
or attribution requirements must be followed independently.
|
|
49
|
+
|
|
50
|
+
No trademark rights are granted by either the AGPL or this licensing summary.
|
|
51
|
+
|
|
52
|
+
## Contributions
|
|
53
|
+
|
|
54
|
+
Dual licensing requires the project to retain the rights needed to offer future
|
|
55
|
+
commercial licenses. See [CONTRIBUTING.md](CONTRIBUTING.md) before submitting
|
|
56
|
+
code. This document is a project policy summary, not a substitute for the
|
|
57
|
+
license text or legal advice.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# 许可说明
|
|
2
|
+
|
|
3
|
+
[English](LICENSING.md)
|
|
4
|
+
|
|
5
|
+
Doca 对其版权所有者拥有权利的代码采用双许可模式。
|
|
6
|
+
|
|
7
|
+
## 开源许可证
|
|
8
|
+
|
|
9
|
+
除非文件或包中另有说明,本仓库内由 Doca 版权所有者拥有的代码默认采用
|
|
10
|
+
GNU Affero General Public License version 3 only(`AGPL-3.0-only`)。完整条款见
|
|
11
|
+
[LICENSE](LICENSE)。
|
|
12
|
+
|
|
13
|
+
AGPL 允许商业使用。当其条件适用时,分发软件或将修改后的版本作为网络服务提供给
|
|
14
|
+
用户,需要继续按 AGPL 提供对应源码。是否收费并不是 AGPL 义务的判断条件,“开源”
|
|
15
|
+
也不等于“免费”。
|
|
16
|
+
|
|
17
|
+
## 商业许可证
|
|
18
|
+
|
|
19
|
+
希望在闭源产品中使用 Doca 自研代码、且不希望承担 AGPL 义务的组织,可以向 Doca
|
|
20
|
+
版权所有者申请单独的商业许可证。只有双方签署书面协议后,商业许可证才成立;本仓库
|
|
21
|
+
本身不授予该替代许可证。
|
|
22
|
+
|
|
23
|
+
## 子包与编辑器
|
|
24
|
+
|
|
25
|
+
同一许可方向适用于 Doca 自研的子包和编辑器,包括插件 SDK,以及 Slate 富文本、
|
|
26
|
+
演示文稿、表格、Markdown 和画板编辑器。每个正式发布的 npm 制品必须:
|
|
27
|
+
|
|
28
|
+
- 使用准确的许可证字段并携带许可证说明;
|
|
29
|
+
- 链接公开源码仓库以及与该版本精确对应的 Git tag;
|
|
30
|
+
- 提供生成该制品所需的构建脚本和依赖锁文件;
|
|
31
|
+
- 保留所有第三方组件要求的许可证及声明。
|
|
32
|
+
|
|
33
|
+
`vendor/` 中的历史压缩包是开发和恢复输入,不作为长期公开分发渠道。正式开源前,
|
|
34
|
+
当前使用的编辑器依赖应从公开且已打 tag 的源码重新构建并发布到 npm,Doca 再改为
|
|
35
|
+
使用 registry 版本。
|
|
36
|
+
|
|
37
|
+
## 第三方软件与素材
|
|
38
|
+
|
|
39
|
+
双许可只覆盖 Doca 版权所有者有权授予许可的内容。第三方库、字体、媒体、生成产物及
|
|
40
|
+
其他随附内容继续适用各自许可证,其声明、源码提供或署名要求需要独立履行。
|
|
41
|
+
|
|
42
|
+
AGPL 和本文均不授予商标使用权。
|
|
43
|
+
|
|
44
|
+
## 外部贡献
|
|
45
|
+
|
|
46
|
+
双许可要求项目持续保有提供商业许可证所需的权利。提交代码前请阅读
|
|
47
|
+
[CONTRIBUTING.zh-CN.md](CONTRIBUTING.zh-CN.md)。本文只是项目政策摘要,不能替代
|
|
48
|
+
许可证原文或专业法律意见。
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
export type ClientPluginTarget = "web" | "mobile";
|
|
2
|
+
export type PluginLocale = "zh" | "en";
|
|
3
|
+
export type RegistryDisposer = () => void;
|
|
4
|
+
export type RegistryConflictCode = "DUPLICATE_CONTRIBUTION_ID" | "DUPLICATE_CONTRIBUTION_PATH" | "INVALID_CONTRIBUTION" | "EVENT_SEQUENCE_CONFLICT";
|
|
5
|
+
export declare class RegistryConflictError extends Error {
|
|
6
|
+
readonly code: RegistryConflictCode;
|
|
7
|
+
readonly contributionId: string;
|
|
8
|
+
readonly name = "RegistryConflictError";
|
|
9
|
+
constructor(code: RegistryConflictCode, message: string, contributionId: string);
|
|
10
|
+
}
|
|
11
|
+
export interface ClientPluginManifest {
|
|
12
|
+
readonly pluginId: string;
|
|
13
|
+
readonly version: string;
|
|
14
|
+
readonly targets: readonly ClientPluginTarget[];
|
|
15
|
+
readonly routes?: readonly string[];
|
|
16
|
+
readonly navigation?: readonly string[];
|
|
17
|
+
readonly adminPanels?: readonly string[];
|
|
18
|
+
readonly conversationKinds?: readonly string[];
|
|
19
|
+
}
|
|
20
|
+
export interface OwnedContribution {
|
|
21
|
+
readonly id: string;
|
|
22
|
+
readonly pluginId: string;
|
|
23
|
+
readonly order?: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* A synchronous, effect-owned registry. Registration either succeeds
|
|
27
|
+
* atomically or leaves no record behind; the returned disposer is idempotent.
|
|
28
|
+
*/
|
|
29
|
+
export declare class EffectRegistry<T extends OwnedContribution> {
|
|
30
|
+
#private;
|
|
31
|
+
readonly point: string;
|
|
32
|
+
readonly conflictKey?: ((contribution: T) => string | undefined) | undefined;
|
|
33
|
+
constructor(point: string, conflictKey?: ((contribution: T) => string | undefined) | undefined);
|
|
34
|
+
register(contribution: T): RegistryDisposer;
|
|
35
|
+
get(id: string): T | undefined;
|
|
36
|
+
getByConflictKey(key: string): T | undefined;
|
|
37
|
+
list(): readonly T[];
|
|
38
|
+
}
|
|
39
|
+
export interface RouteMatch {
|
|
40
|
+
readonly path: string;
|
|
41
|
+
readonly params: Readonly<Record<string, string>>;
|
|
42
|
+
}
|
|
43
|
+
export interface WebRouteContribution<Context = unknown, View = unknown> extends OwnedContribution {
|
|
44
|
+
readonly path: string;
|
|
45
|
+
render(context: Context, match: RouteMatch): View;
|
|
46
|
+
}
|
|
47
|
+
export interface WebNavigationContribution<Icon = unknown> extends OwnedContribution {
|
|
48
|
+
readonly scope: string;
|
|
49
|
+
readonly path: string;
|
|
50
|
+
readonly labelKey: string;
|
|
51
|
+
readonly icon?: Icon;
|
|
52
|
+
readonly entitlement?: string;
|
|
53
|
+
}
|
|
54
|
+
export interface WebAdminPanelContribution<Context = unknown, View = unknown, Icon = unknown> extends OwnedContribution {
|
|
55
|
+
readonly tab: string;
|
|
56
|
+
readonly group: string;
|
|
57
|
+
readonly labelKey: string;
|
|
58
|
+
readonly icon?: Icon;
|
|
59
|
+
render(context: Context): View;
|
|
60
|
+
}
|
|
61
|
+
export interface WebSettingsFieldContribution<Context = unknown, View = unknown> extends OwnedContribution {
|
|
62
|
+
readonly path: string;
|
|
63
|
+
readonly labelKey: string;
|
|
64
|
+
render(context: Context): View;
|
|
65
|
+
}
|
|
66
|
+
export interface WebAIBlockContribution<Context = unknown, View = unknown> extends OwnedContribution {
|
|
67
|
+
readonly kind: string;
|
|
68
|
+
render(payload: unknown, context: Context): View;
|
|
69
|
+
}
|
|
70
|
+
export interface WebSearchResultContribution<Context = unknown, View = unknown> extends OwnedContribution {
|
|
71
|
+
readonly kind: string;
|
|
72
|
+
render(result: unknown, context: Context): View;
|
|
73
|
+
}
|
|
74
|
+
export type KnowledgeSourceSelection = "document" | "file" | "folder" | "url" | "config";
|
|
75
|
+
export interface WebKnowledgeSourceContribution<Context = unknown, View = unknown> extends OwnedContribution {
|
|
76
|
+
readonly sourceKind: string;
|
|
77
|
+
/** Plugin catalog key shown on the knowledge-relations page. */
|
|
78
|
+
readonly labelKey?: string;
|
|
79
|
+
/**
|
|
80
|
+
* Host picker used to bind one target.
|
|
81
|
+
* `config` means the plugin renders its own form and calls `context.bind`.
|
|
82
|
+
*/
|
|
83
|
+
readonly selection?: KnowledgeSourceSelection;
|
|
84
|
+
render(config: unknown, context: Context): View;
|
|
85
|
+
}
|
|
86
|
+
export interface WebFilePickerContribution<Context = unknown, View = unknown> extends OwnedContribution {
|
|
87
|
+
readonly capability: string;
|
|
88
|
+
render(context: Context): View;
|
|
89
|
+
}
|
|
90
|
+
export interface PluginMessagesContribution extends OwnedContribution {
|
|
91
|
+
readonly messages: Readonly<Record<PluginLocale, Readonly<Record<string, string>>>>;
|
|
92
|
+
}
|
|
93
|
+
export interface WebPluginTypes {
|
|
94
|
+
readonly View: unknown;
|
|
95
|
+
readonly Icon: unknown;
|
|
96
|
+
readonly RouteContext: unknown;
|
|
97
|
+
readonly AdminContext: unknown;
|
|
98
|
+
readonly SettingsContext: unknown;
|
|
99
|
+
readonly AIBlockContext: unknown;
|
|
100
|
+
readonly SearchResultContext: unknown;
|
|
101
|
+
readonly KnowledgeSourceContext: unknown;
|
|
102
|
+
readonly FilePickerContext: unknown;
|
|
103
|
+
}
|
|
104
|
+
export type DefaultWebPluginTypes = {
|
|
105
|
+
readonly View: unknown;
|
|
106
|
+
readonly Icon: unknown;
|
|
107
|
+
readonly RouteContext: unknown;
|
|
108
|
+
readonly AdminContext: unknown;
|
|
109
|
+
readonly SettingsContext: unknown;
|
|
110
|
+
readonly AIBlockContext: unknown;
|
|
111
|
+
readonly SearchResultContext: unknown;
|
|
112
|
+
readonly KnowledgeSourceContext: unknown;
|
|
113
|
+
readonly FilePickerContext: unknown;
|
|
114
|
+
};
|
|
115
|
+
export interface WebPluginBundle<T extends WebPluginTypes = DefaultWebPluginTypes> {
|
|
116
|
+
readonly manifest: ClientPluginManifest;
|
|
117
|
+
readonly routes?: readonly WebRouteContribution<T["RouteContext"], T["View"]>[];
|
|
118
|
+
readonly navigation?: readonly WebNavigationContribution<T["Icon"]>[];
|
|
119
|
+
readonly adminPanels?: readonly WebAdminPanelContribution<T["AdminContext"], T["View"], T["Icon"]>[];
|
|
120
|
+
readonly settingsFields?: readonly WebSettingsFieldContribution<T["SettingsContext"], T["View"]>[];
|
|
121
|
+
readonly aiBlocks?: readonly WebAIBlockContribution<T["AIBlockContext"], T["View"]>[];
|
|
122
|
+
readonly searchResults?: readonly WebSearchResultContribution<T["SearchResultContext"], T["View"]>[];
|
|
123
|
+
readonly knowledgeSources?: readonly WebKnowledgeSourceContribution<T["KnowledgeSourceContext"], T["View"]>[];
|
|
124
|
+
readonly filePickers?: readonly WebFilePickerContribution<T["FilePickerContext"], T["View"]>[];
|
|
125
|
+
readonly messages?: readonly PluginMessagesContribution[];
|
|
126
|
+
}
|
|
127
|
+
export declare class WebPluginRegistry<T extends WebPluginTypes = DefaultWebPluginTypes> {
|
|
128
|
+
#private;
|
|
129
|
+
readonly routes: EffectRegistry<WebRouteContribution<T["RouteContext"], T["View"]>>;
|
|
130
|
+
readonly navigation: EffectRegistry<WebNavigationContribution<T["Icon"]>>;
|
|
131
|
+
readonly adminPanels: EffectRegistry<WebAdminPanelContribution<T["AdminContext"], T["View"], T["Icon"]>>;
|
|
132
|
+
readonly settingsFields: EffectRegistry<WebSettingsFieldContribution<T["SettingsContext"], T["View"]>>;
|
|
133
|
+
readonly aiBlocks: EffectRegistry<WebAIBlockContribution<T["AIBlockContext"], T["View"]>>;
|
|
134
|
+
readonly searchResults: EffectRegistry<WebSearchResultContribution<T["SearchResultContext"], T["View"]>>;
|
|
135
|
+
readonly knowledgeSources: EffectRegistry<WebKnowledgeSourceContribution<T["KnowledgeSourceContext"], T["View"]>>;
|
|
136
|
+
readonly filePickers: EffectRegistry<WebFilePickerContribution<T["FilePickerContext"], T["View"]>>;
|
|
137
|
+
readonly messages: EffectRegistry<PluginMessagesContribution>;
|
|
138
|
+
register(bundle: WebPluginBundle<T>): RegistryDisposer;
|
|
139
|
+
manifests(): readonly ClientPluginManifest[];
|
|
140
|
+
resolveRoute(path: string): {
|
|
141
|
+
readonly contribution: WebRouteContribution<T["RouteContext"], T["View"]>;
|
|
142
|
+
readonly match: RouteMatch;
|
|
143
|
+
} | undefined;
|
|
144
|
+
translate(locale: string | undefined, key: string, values?: Readonly<Record<string, unknown>>): string;
|
|
145
|
+
}
|
|
146
|
+
export interface MobileRouteContribution<Context = unknown, View = unknown> extends OwnedContribution {
|
|
147
|
+
readonly path: string;
|
|
148
|
+
render(context: Context, match: RouteMatch): View;
|
|
149
|
+
}
|
|
150
|
+
export interface MobileTabContribution<Icon = unknown> extends OwnedContribution {
|
|
151
|
+
readonly route: string;
|
|
152
|
+
readonly labelKey: string;
|
|
153
|
+
readonly icon?: Icon;
|
|
154
|
+
}
|
|
155
|
+
export interface MobilePluginTypes {
|
|
156
|
+
readonly View: unknown;
|
|
157
|
+
readonly Icon: unknown;
|
|
158
|
+
readonly RouteContext: unknown;
|
|
159
|
+
readonly NodeContext: unknown;
|
|
160
|
+
readonly FilePickerContext: unknown;
|
|
161
|
+
}
|
|
162
|
+
export type DefaultMobilePluginTypes = {
|
|
163
|
+
readonly View: unknown;
|
|
164
|
+
readonly Icon: unknown;
|
|
165
|
+
readonly RouteContext: unknown;
|
|
166
|
+
readonly NodeContext: unknown;
|
|
167
|
+
readonly FilePickerContext: unknown;
|
|
168
|
+
};
|
|
169
|
+
export interface MobilePluginBundle<T extends MobilePluginTypes = DefaultMobilePluginTypes> {
|
|
170
|
+
readonly manifest: ClientPluginManifest;
|
|
171
|
+
readonly routes?: readonly MobileRouteContribution<T["RouteContext"], T["View"]>[];
|
|
172
|
+
readonly tabs?: readonly MobileTabContribution<T["Icon"]>[];
|
|
173
|
+
readonly aiNodes?: readonly WebAIBlockContribution<T["NodeContext"], T["View"]>[];
|
|
174
|
+
readonly searchResults?: readonly WebSearchResultContribution<T["NodeContext"], T["View"]>[];
|
|
175
|
+
readonly filePickers?: readonly WebFilePickerContribution<T["FilePickerContext"], T["View"]>[];
|
|
176
|
+
readonly messages?: readonly PluginMessagesContribution[];
|
|
177
|
+
}
|
|
178
|
+
export declare class MobilePluginRegistry<T extends MobilePluginTypes = DefaultMobilePluginTypes> {
|
|
179
|
+
#private;
|
|
180
|
+
readonly routes: EffectRegistry<MobileRouteContribution<T["RouteContext"], T["View"]>>;
|
|
181
|
+
readonly tabs: EffectRegistry<MobileTabContribution<T["Icon"]>>;
|
|
182
|
+
readonly aiNodes: EffectRegistry<WebAIBlockContribution<T["NodeContext"], T["View"]>>;
|
|
183
|
+
readonly searchResults: EffectRegistry<WebSearchResultContribution<T["NodeContext"], T["View"]>>;
|
|
184
|
+
readonly filePickers: EffectRegistry<WebFilePickerContribution<T["FilePickerContext"], T["View"]>>;
|
|
185
|
+
readonly messages: EffectRegistry<PluginMessagesContribution>;
|
|
186
|
+
register(bundle: MobilePluginBundle<T>): RegistryDisposer;
|
|
187
|
+
manifests(): readonly ClientPluginManifest[];
|
|
188
|
+
}
|
|
189
|
+
export interface ConversationEvent<Payload = unknown> {
|
|
190
|
+
readonly kind: string;
|
|
191
|
+
readonly id: string;
|
|
192
|
+
readonly seq: number;
|
|
193
|
+
readonly type: string;
|
|
194
|
+
readonly payload: Payload;
|
|
195
|
+
readonly schemaVersion?: number;
|
|
196
|
+
readonly settled?: boolean;
|
|
197
|
+
readonly turnId?: string;
|
|
198
|
+
readonly stepId?: string;
|
|
199
|
+
}
|
|
200
|
+
export interface ConversationDefinition<State = unknown, Node = unknown> extends OwnedContribution {
|
|
201
|
+
readonly kind: string;
|
|
202
|
+
isStart(event: ConversationEvent): boolean;
|
|
203
|
+
start(event: ConversationEvent): State;
|
|
204
|
+
update(state: State, event: ConversationEvent): State;
|
|
205
|
+
materialize(state: State, context: {
|
|
206
|
+
readonly key: string;
|
|
207
|
+
readonly events: readonly ConversationEvent[];
|
|
208
|
+
}): Node;
|
|
209
|
+
}
|
|
210
|
+
export interface MaterializedConversationNode<Node = unknown> {
|
|
211
|
+
readonly key: string;
|
|
212
|
+
readonly kind: string;
|
|
213
|
+
readonly id: string;
|
|
214
|
+
readonly firstSeq: number;
|
|
215
|
+
readonly lastSeq: number;
|
|
216
|
+
readonly settled: boolean;
|
|
217
|
+
readonly definitionId: string;
|
|
218
|
+
readonly value: Node;
|
|
219
|
+
}
|
|
220
|
+
export interface GenericConversationFact {
|
|
221
|
+
readonly type: "generic-event";
|
|
222
|
+
readonly kind: string;
|
|
223
|
+
readonly id: string;
|
|
224
|
+
readonly events: readonly ConversationEvent[];
|
|
225
|
+
}
|
|
226
|
+
export type ConversationNode<Node = unknown> = MaterializedConversationNode<Node> | MaterializedConversationNode<GenericConversationFact>;
|
|
227
|
+
/**
|
|
228
|
+
* Stores events by stable (kind,id,seq) and replays each stream from sorted
|
|
229
|
+
* sequence numbers for every projection. Arrival order never affects output.
|
|
230
|
+
*/
|
|
231
|
+
export declare class ConversationAssembler<Node = unknown> {
|
|
232
|
+
#private;
|
|
233
|
+
readonly definitions: EffectRegistry<ConversationDefinition<unknown, Node>>;
|
|
234
|
+
append(event: ConversationEvent): boolean;
|
|
235
|
+
appendAll(events: readonly ConversationEvent[]): readonly ConversationNode<Node>[];
|
|
236
|
+
clear(kind?: string, id?: string): void;
|
|
237
|
+
snapshot(): readonly ConversationNode<Node>[];
|
|
238
|
+
}
|