@qilin-agent/client-ui-slots 0.0.0-stage → 3.1.4
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/LICENSE +21 -0
- package/README.i18n.yaml +55 -0
- package/README.md +108 -2
- package/README.zh.md +109 -0
- package/lib/index.js +587 -0
- package/lib/types/index.d.ts +972 -0
- package/lib/types/renderer.d.ts +262 -0
- package/lib/types/store.d.ts +3 -0
- package/package.json +37 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 kkutysllb
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.i18n.yaml
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading
|
|
2
|
+
# section, a hash of its English and Chinese blocks outside code blocks and generated regions.
|
|
3
|
+
# After editing either side, bring the other along and re-record with:
|
|
4
|
+
# pnpm run verify-translation-pairing --write packages/client/ui-slots/README.md
|
|
5
|
+
/:
|
|
6
|
+
en: 5beac554c13460fd
|
|
7
|
+
zh: 54b7b2e34a797628
|
|
8
|
+
/qilin-agent-client-ui-slots:
|
|
9
|
+
en: 54424b7979721f41
|
|
10
|
+
zh: 3f084b16be3e9f18
|
|
11
|
+
/qilin-agent-client-ui-slots/summary:
|
|
12
|
+
en: 974552cacd652bd5
|
|
13
|
+
zh: 2c51e79b2dc3ffcb
|
|
14
|
+
/qilin-agent-client-ui-slots/table-of-contents:
|
|
15
|
+
en: d152484eb41ac6b4
|
|
16
|
+
zh: 09388d293f9be9cb
|
|
17
|
+
/qilin-agent-client-ui-slots/use-this-package:
|
|
18
|
+
en: 05691d44a0c6c48f
|
|
19
|
+
zh: 434033d5761297f3
|
|
20
|
+
/qilin-agent-client-ui-slots/use-this-package/reusable-component-factories:
|
|
21
|
+
en: 301de67bf2779ae6
|
|
22
|
+
zh: 6e9d405ee1063d53
|
|
23
|
+
/qilin-agent-client-ui-slots/use-this-package/the-five-framework-props-shares:
|
|
24
|
+
en: 45e2933a5e084956
|
|
25
|
+
zh: 938deedaf489f892
|
|
26
|
+
/qilin-agent-client-ui-slots/use-this-package/store-seats:
|
|
27
|
+
en: 0d1c2948112841ec
|
|
28
|
+
zh: fc5a998cea485024
|
|
29
|
+
/qilin-agent-client-ui-slots/use-this-package/declaration-discipline:
|
|
30
|
+
en: 8a41014931ffccd5
|
|
31
|
+
zh: 615f93335a682b01
|
|
32
|
+
/qilin-agent-client-ui-slots/understand-the-implementation:
|
|
33
|
+
en: 983e6c0e71105f65
|
|
34
|
+
zh: 75af8d36dd8223fd
|
|
35
|
+
/qilin-agent-client-ui-slots/understand-the-implementation/registration-and-routing:
|
|
36
|
+
en: 0638aaadacadb6f1
|
|
37
|
+
zh: cb6324ef5c9e1ade
|
|
38
|
+
/qilin-agent-client-ui-slots/understand-the-implementation/the-renderer-contract:
|
|
39
|
+
en: 2b6058e98fb1efe7
|
|
40
|
+
zh: f32e37c8381809b9
|
|
41
|
+
/qilin-agent-client-ui-slots/further-exploration:
|
|
42
|
+
en: 5f9dfd481b3adb72
|
|
43
|
+
zh: c39a3b01252192a4
|
|
44
|
+
/qilin-agent-client-ui-slots/model-experience:
|
|
45
|
+
en: 3120df665299c634
|
|
46
|
+
zh: 67bb5e1fe59dae19
|
|
47
|
+
/qilin-agent-client-ui-slots/model-experience/kv-cache-effect:
|
|
48
|
+
en: ca75c51c89c2c9b0
|
|
49
|
+
zh: de54f3467ef3b9be
|
|
50
|
+
/qilin-agent-client-ui-slots/known-limitations-and-deferred-work:
|
|
51
|
+
en: 093b1c5076ddfd6d
|
|
52
|
+
zh: 3069c423115492fe
|
|
53
|
+
/qilin-agent-client-ui-slots/known-limitations-and-deferred-work/dev-note:
|
|
54
|
+
en: e67f633dc6fe7773
|
|
55
|
+
zh: 3bb0c20c93f16f98
|
package/README.md
CHANGED
|
@@ -1,3 +1,109 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
description: "Slot registry pure core for the qilin web client: ordinary extension slots, reusable Component Factories, derived props types, store seats, and the renderer install contract."
|
|
3
|
+
kind: "package-library"
|
|
4
|
+
---
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
# @qilin-agent/client-ui-slots
|
|
7
|
+
|
|
8
|
+
English | [中文](README.zh.md)
|
|
9
|
+
|
|
10
|
+
## Summary
|
|
11
|
+
|
|
12
|
+
`qilin-client-ui-slots` lets web client plugins define and compose typed UI regions. Ordinary Slots provide parent-owned extension positions; Component Factories provide reusable assemblies with caller-selected local Components. Both APIs derive scoped state, injection, locale, and child-render props from declaration-merged types and report conflicting definitions during plugin loading. Pair this React-free package with `ui-renderer` when the client needs rendering.
|
|
13
|
+
|
|
14
|
+
## Table of Contents
|
|
15
|
+
|
|
16
|
+
- [Use this package](#use-this-package)
|
|
17
|
+
- [Understand the implementation](#understand-the-implementation)
|
|
18
|
+
- [Further Exploration](#further-exploration)
|
|
19
|
+
- [Model Experience](#model-experience)
|
|
20
|
+
- [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
|
|
21
|
+
- [Dev Note](#dev-note)
|
|
22
|
+
|
|
23
|
+
-----
|
|
24
|
+
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## Use this package
|
|
27
|
+
|
|
28
|
+
Compose UI through this package whenever you write a client plugin: register a component into a slot your parent declared, or declare child slots your component renders. The four kinds cover the composition shapes — `single` (one occupant), `list` (ordered entries), `keyed` (dispatch by a key), and `chain` (entries elect themselves).
|
|
29
|
+
|
|
30
|
+
### Reusable Component Factories
|
|
31
|
+
|
|
32
|
+
Use a Component Factory when one package defines an assembly that unrelated parents render independently. Declare its complete type in `SlotFactoryMap`, install the definition with `ctx.slots.registerFactory()`, render occurrences through the injected `renderFactorySlot()`, and select each declared local Component through the call's `slots` option. The definition reads that choice through `useFactorySlot(name, fallback)`.
|
|
33
|
+
|
|
34
|
+
Factory `children` remain ordinary global Slots and must match `SlotMap`, while local `slots` select one Component per occurrence. An occurrence inherits its render-position scope; `renderFactorySlot()` does not accept a Session identity. Shared Store handles use ordinary scope resolution. A Store factory stays lazy until an occurrence first materializes, then creates one handle for that render position and rejects a persistent Store spec whose key would collide across occurrences.
|
|
35
|
+
|
|
36
|
+
### The five framework props shares
|
|
37
|
+
|
|
38
|
+
Every registered component receives props composed from five framework shares: the runtime share (`owner` from the parent's render call site, plus the session standard kit and global seat), the child-render share (`renderSlot` statically narrowed to declared children), the Factory-render share (`renderFactorySlot`), the store share (the declared handle's selector hook and draft-stripped actions), and the business share (inferred from `inject`). Components reference the derived props aliases; they never re-type a share locally.
|
|
39
|
+
|
|
40
|
+
### Store seats
|
|
41
|
+
|
|
42
|
+
A register call may declare a store seat with `store: defineStore(...)`: `init` infers the state schema and `actions` is the complete draft-transform write set. Components read through the selector hook and write through the baked callbacks; the engine implementation of `defineStore` lives in the runtime package and satisfies the `DefineStore` contract exported here.
|
|
43
|
+
|
|
44
|
+
### Declaration discipline
|
|
45
|
+
|
|
46
|
+
Declaring a slot is claiming it: the registering entry becomes the only entry allowed to render that key, and registering into an undeclared slot, declaring an already-declared child, mounting one shared handle under two scopes, or registering a chain without `select` throws at load. An entry's disposer collapses its declared child slots recursively — ledger rows, contributions, and store mounts die on one lifecycle axis.
|
|
47
|
+
|
|
48
|
+
-----
|
|
49
|
+
|
|
50
|
+
<a id="understand-the-implementation"></a>
|
|
51
|
+
## Understand the implementation
|
|
52
|
+
|
|
53
|
+
<details>
|
|
54
|
+
<summary>Implementation internals — click to expand</summary>
|
|
55
|
+
|
|
56
|
+
The ordinary Slot design is one table: declaration = render authorization = runtime spec. `SlotMap` is declared empty here and merged by consumers via `declare module` augmentation, exactly like `SlotFactoryMap` and the standard-kit interfaces (`SessionStandardProps`, `GlobalStandardProps`). Factory definitions use a separate single-definition ledger because their occurrences have no parent declaration.
|
|
57
|
+
|
|
58
|
+
### Registration and routing
|
|
59
|
+
|
|
60
|
+
`SlotCore` seeds the a-priori `'root'` slot at construction and enforces load-time validation. `ChainSelect` selectors run in ascending `priority` order (ties in registration order); the first non-null return elects its entry and becomes the component's `matched` prop, and all-null falls to the owner's `renderSlotChain` fallback (`ChainRenderOpts`). Each key carries a declaration epoch that advances only on declaration and collapse; `ui-renderer` uses it for `ctx.slots.inject`, independently from ordinary entry versions. Live inspection uses strict `type: 'slot' | 'factory'` nodes and nests Factory-owned child Slots under their definition.
|
|
61
|
+
|
|
62
|
+
### The renderer contract
|
|
63
|
+
|
|
64
|
+
`renderer.ts` carries the installation contract (`SlotRenderer`, `SlotRendererHost`) plus `StaleAuthorizationError`/`SlotOwnershipError`; ui-renderer owns both the implementation and its plugin-lifecycle installation. Engine products and the renderer host contract carry bare snapshot sources (`getSnapshot`/`subscribe`), never React hooks — hook binding belongs to the render machinery. Factory crashes use the ordinary supervision channel, and an idempotent effect retains per-position Store handles only after commit.
|
|
65
|
+
|
|
66
|
+
</details>
|
|
67
|
+
|
|
68
|
+
-----
|
|
69
|
+
|
|
70
|
+
<a id="further-exploration"></a>
|
|
71
|
+
## Further Exploration
|
|
72
|
+
|
|
73
|
+
These pages cover the engine, the renderer, and the composition model.
|
|
74
|
+
|
|
75
|
+
- [ui-renderer](../ui-renderer/README.md) — the React slot renderer implementing this package's install contract.
|
|
76
|
+
- [Slot system standard](../../../.agents/notes/implemented/architecture/2026-07-22-slot-type-chain-implementation.md) — the definitive composition model.
|
|
77
|
+
- [Component Factories](../../../.agents/notes/implemented/architecture/2026-09-10-component-factories-and-local-slots.md) — reusable definitions, local Component selection, and occurrence lifetimes.
|
|
78
|
+
- [Web client architecture](../../../.agents/notes/implemented/architecture/2026-07-19-gui-web-client-architecture.md) — the loading chain and object layer this registry plugs into.
|
|
79
|
+
|
|
80
|
+
-----
|
|
81
|
+
|
|
82
|
+
<a id="model-experience"></a>
|
|
83
|
+
## Model Experience
|
|
84
|
+
|
|
85
|
+
None, as the package is a browser-side UI plugin layer that registers nothing model-facing.
|
|
86
|
+
|
|
87
|
+
#### KV Cache effect
|
|
88
|
+
|
|
89
|
+
None; this package neither assembles nor sends a provider request.
|
|
90
|
+
|
|
91
|
+
## Known Limitations and Deferred Work
|
|
92
|
+
|
|
93
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
These limits define the registry's scaling behavior and accepted type noise; they are current package constraints.
|
|
97
|
+
|
|
98
|
+
- **`isLive` scans all records linearly** — fine at UI-plugin registration counts (tens); revisit with an entry→record backref if ledgers ever grow hot.
|
|
99
|
+
- **The `__renders` phantom anchor is visible on `PropsRenderSlots`** — the same accepted noise as the type-chain design's `__accepts`: generic method signatures compare loosely across key unions, so the contravariant marker is what enforces "component key set ⊆ children declaration".
|
|
100
|
+
|
|
101
|
+
<a id="dev-note"></a>
|
|
102
|
+
### Dev Note
|
|
103
|
+
|
|
104
|
+
<details>
|
|
105
|
+
<summary>Working context for maintainers — click to expand</summary>
|
|
106
|
+
|
|
107
|
+
None.
|
|
108
|
+
|
|
109
|
+
</details>
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "qilin Web 客户端的 slot 注册表纯核心:普通扩展 slots、可复用 Component Factory、推导 props 类型、store 席位与渲染器安装约定。"
|
|
3
|
+
kind: "package-library"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# @qilin-agent/client-ui-slots
|
|
7
|
+
|
|
8
|
+
[English](README.md) | 中文
|
|
9
|
+
|
|
10
|
+
## 概述
|
|
11
|
+
|
|
12
|
+
`qilin-client-ui-slots` 让 Web 客户端插件定义并组合带类型检查的 UI 区域。普通 Slots 提供 parent-owned 扩展位置;Component Factory 提供带调用方所选局部 Component 的可复用装配。两套 API 都从声明合并类型推导 scoped state、injection、locale 与 child-render props,并在插件加载期间报告冲突 definition。客户端需要渲染时,将这个不依赖 React 的包与 `ui-renderer` 配合使用。
|
|
13
|
+
|
|
14
|
+
## 目录
|
|
15
|
+
|
|
16
|
+
- [使用本包](#use-this-package)
|
|
17
|
+
- [理解实现](#understand-the-implementation)
|
|
18
|
+
- [进一步探索](#further-exploration)
|
|
19
|
+
- [模型体验](#model-experience)
|
|
20
|
+
- [已知限制与延期工作](#known-limitations-and-deferred-work)
|
|
21
|
+
- [开发备注](#dev-note)
|
|
22
|
+
|
|
23
|
+
-----
|
|
24
|
+
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## 使用本包
|
|
27
|
+
|
|
28
|
+
编写客户端插件时都通过本包组合 UI:把组件注册进父级已声明的 slot,或声明组件将要渲染的子 slot。四种 kind 覆盖组合形态——`single`(单个占位者)、`list`(有序条目)、`keyed`(按键分派)与 `chain`(条目自行提名)。
|
|
29
|
+
|
|
30
|
+
### 可复用 Component Factory
|
|
31
|
+
|
|
32
|
+
当一个包定义装配、而互不相关的 parents 需要独立渲染它时,使用 Component Factory。在 `SlotFactoryMap` 中声明完整类型,通过 `ctx.slots.registerFactory()` 安装 definition,通过注入的 `renderFactorySlot()` 渲染 occurrences,并通过调用的 `slots` 选项选择每个已声明的局部 Component。definition 通过 `useFactorySlot(name, fallback)` 读取该选择。
|
|
33
|
+
|
|
34
|
+
Factory `children` 仍是普通全局 Slots 且必须与 `SlotMap` 匹配,而局部 `slots` 为每个 occurrence 选择一个 Component。occurrence 继承其渲染位置的 scope;`renderFactorySlot()` 不接受 Session identity。共享 Store handle 使用普通 scope 解析。Store factory 保持 lazy,直到 occurrence 首次物化时才为该渲染位置创建一个 handle;若持久化 Store spec 会让 persistence key 在 occurrences 之间冲突,renderer 会拒绝它。
|
|
35
|
+
|
|
36
|
+
### 五个框架 props share
|
|
37
|
+
|
|
38
|
+
每个已注册组件都会收到由五个框架 share 组合而成的 props:运行时 share(父级 render 调用点的 `owner`,加上会话标准工具包与全局席位)、child render share(静态缩窄到已声明 children 的 `renderSlot`)、Factory render share(`renderFactorySlot`)、store share(已声明 handle 的 selector 钩子与移除 draft 的 actions),以及业务 share(从 `inject` 推导)。组件引用推导出的 props 别名;它们绝不在本地重新定义任何 share 的类型。
|
|
39
|
+
|
|
40
|
+
### Store 席位
|
|
41
|
+
|
|
42
|
+
register 调用可以用 `store: defineStore(...)` 声明 store 席位:`init` 推断状态 schema,`actions` 是完整的 draft-transform 写入集合。组件经 selector 钩子读取、经烘焙回调写入;`defineStore` 的引擎实现位于运行时包,并满足这里导出的 `DefineStore` 约定。
|
|
43
|
+
|
|
44
|
+
### 声明纪律
|
|
45
|
+
|
|
46
|
+
声明即认领:注册条目成为唯一被允许渲染该键的条目;注册未声明 slot、声明已声明过的子项、在两个 scope 下挂载同一个共享句柄、或注册缺少 `select` 的 chain,都会在加载时抛出。条目的 disposer 会递归移除其声明的子 slot——账本行、贡献与 store 挂载都随同一生命周期结束而移除。
|
|
47
|
+
|
|
48
|
+
-----
|
|
49
|
+
|
|
50
|
+
<a id="understand-the-implementation"></a>
|
|
51
|
+
## 理解实现
|
|
52
|
+
|
|
53
|
+
<details>
|
|
54
|
+
<summary>实现细节——点击展开</summary>
|
|
55
|
+
|
|
56
|
+
普通 Slot 设计就是一张表:声明 = 渲染授权 = 运行时规范。`SlotMap` 在这里声明为空,由消费方通过 `declare module` 增补合并;`SlotFactoryMap` 和标准工具包接口(`SessionStandardProps`、`GlobalStandardProps`)也采用同一方式。Factory definition 使用独立的单 definition ledger,因为其 occurrences 没有 parent 声明。
|
|
57
|
+
|
|
58
|
+
### 注册与路由
|
|
59
|
+
|
|
60
|
+
`SlotCore` 在构造时预置 `'root'` slot,并强制执行加载时验证。`ChainSelect` selector 按升序 `priority` 运行(相同值按注册顺序);第一个非 null 返回值选中其条目,并成为组件的 `matched` prop;全部返回 null 时使用 owner 的 `renderSlotChain` fallback(`ChainRenderOpts`)。每个 key 都携带一个 declaration epoch,它只在声明与移除时递增;`ui-renderer` 将其用于 `ctx.slots.inject`,且与普通条目版本相互独立。实时检查使用严格的 `type: 'slot' | 'factory'` 节点,并把 Factory-owned child Slots 嵌套在其 definition 下。
|
|
61
|
+
|
|
62
|
+
### 渲染器约定
|
|
63
|
+
|
|
64
|
+
`renderer.ts` 携带安装约定(`SlotRenderer`、`SlotRendererHost`)以及 `StaleAuthorizationError`/`SlotOwnershipError`;ui-renderer 负责实现,并在其插件生命周期中完成安装。引擎产物与渲染器宿主约定携带裸快照 source(`getSnapshot`/`subscribe`),绝不携带 React 钩子——钩子绑定属于渲染机制。Factory 崩溃使用普通监督通道,幂等 effect 仅在 commit 后保留逐渲染位置 Store handle。
|
|
65
|
+
|
|
66
|
+
</details>
|
|
67
|
+
|
|
68
|
+
-----
|
|
69
|
+
|
|
70
|
+
<a id="further-exploration"></a>
|
|
71
|
+
## 进一步探索
|
|
72
|
+
|
|
73
|
+
以下页面覆盖引擎、渲染器与组合模型。
|
|
74
|
+
|
|
75
|
+
- [ui-renderer](../ui-renderer/README.zh.md)——实现本包安装约定的 React slot 渲染器。
|
|
76
|
+
- [slot 系统标准](../../../.agents/notes/implemented/architecture/2026-07-22-slot-type-chain-implementation.zh.md)——权威组合模型。
|
|
77
|
+
- [Component Factory](../../../.agents/notes/implemented/architecture/2026-09-10-component-factories-and-local-slots.zh.md)——可复用 definitions、局部 Component 选择与 occurrence 生命周期。
|
|
78
|
+
- [Web 客户端架构](../../../.agents/notes/implemented/architecture/2026-07-19-gui-web-client-architecture.zh.md)——本注册表接入的加载链与对象层。
|
|
79
|
+
|
|
80
|
+
-----
|
|
81
|
+
|
|
82
|
+
<a id="model-experience"></a>
|
|
83
|
+
## 模型体验
|
|
84
|
+
|
|
85
|
+
无。该包是浏览器端 UI 接线层,不注册任何面向模型的内容。
|
|
86
|
+
|
|
87
|
+
#### KV Cache 影响
|
|
88
|
+
|
|
89
|
+
无;该包既不组装也不发送提供方请求。
|
|
90
|
+
|
|
91
|
+
## 已知限制与延期工作
|
|
92
|
+
|
|
93
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
这些限制定义注册表的规模扩展特性与已接受的类型噪声;它们是当前包约束。
|
|
97
|
+
|
|
98
|
+
- **`isLive` 会线性扫描所有记录**:在 UI 插件的注册规模(数十项)下没有问题;如果账本变得频繁访问,再使用条目→记录反向引用改进。
|
|
99
|
+
- **`__renders` 幻象锚点在 `PropsRenderSlots` 上可见**:这是与类型链设计的 `__accepts` 相同且已接受的噪声;泛型方法签名在 key 联合之间比较宽松,因此必须依靠逆变标记强制执行「组件 key 集合 ⊆ children 声明」。
|
|
100
|
+
|
|
101
|
+
<a id="dev-note"></a>
|
|
102
|
+
### 开发备注
|
|
103
|
+
|
|
104
|
+
<details>
|
|
105
|
+
<summary>维护者的工作上下文——点击展开</summary>
|
|
106
|
+
|
|
107
|
+
无。
|
|
108
|
+
|
|
109
|
+
</details>
|