webloom-framework 0.1.0 → 0.3.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/README.md +86 -36
- package/dist/{chunk-KGNF36DZ.js → chunk-76BGPI6M.js} +1094 -569
- package/dist/chunk-76BGPI6M.js.map +1 -0
- package/dist/{createPluginHost-CcW9sPNs.d.ts → createPluginHost-BVsUCDKN.d.ts} +139 -161
- package/dist/index.d.ts +134 -29
- package/dist/index.js +948 -146
- package/dist/index.js.map +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/resourceRegistry-BFnjmeGE.d.ts +267 -0
- package/dist/testing.d.ts +3 -3
- package/dist/testing.js +2 -2
- package/docs/api.md +157 -14
- package/docs/migration-baseline.md +20 -12
- package/docs/proposals/browser-runtime-v1/implementation-plan.md +533 -0
- package/docs/proposals/browser-runtime-v1/requirements.md +354 -0
- package/docs/proposals/browser-runtime-v1/verification.md +56 -0
- package/docs/proposals/shared-worker-call-first/SWCF-009-typed-transfer-follow-up.md +34 -0
- package/docs/proposals/shared-worker-call-first/implementation-plan.md +567 -0
- package/package.json +4 -1
- package/dist/chunk-KGNF36DZ.js.map +0 -1
- package/dist/resourceRegistry-BAnqKcp7.d.ts +0 -157
package/README.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# WebLoom
|
|
2
2
|
|
|
3
|
-
WebLoom
|
|
3
|
+
WebLoom 是一个只面向浏览器的插件 Runtime 框架。0.3.0 管理真实的
|
|
4
|
+
`window-main` 和 `shared-worker` JavaScript realm、插件运行单元、实例、
|
|
5
|
+
依赖图、ResourceScope、权限租约、服务桥和资源缓存;路由、存储、日志、
|
|
6
|
+
国际化等产品能力由插件或下游应用注入。
|
|
4
7
|
|
|
5
8
|
## 安装
|
|
6
9
|
|
|
@@ -10,67 +13,112 @@ pnpm add webloom-framework
|
|
|
10
13
|
|
|
11
14
|
WebLoom 是 ESM 单包,提供三个入口:
|
|
12
15
|
|
|
13
|
-
- `webloom-framework
|
|
16
|
+
- `webloom-framework`:浏览器核心,提供 Window/SharedWorker Runtime,不加载 React;
|
|
14
17
|
- `webloom-framework/react`:Provider、capability、Host、Registry 和 Resource Hooks;
|
|
15
18
|
- `webloom-framework/testing`:无产品语义的假 Host、假传输和测试辅助。
|
|
16
19
|
|
|
17
20
|
React 是可选 peer dependency。只使用 `webloom-framework` 时不需要安装 React。
|
|
18
21
|
|
|
19
|
-
## 最小
|
|
22
|
+
## 最小 Window Runtime
|
|
20
23
|
|
|
21
24
|
```ts
|
|
22
|
-
import {
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const host = createPluginHost({
|
|
32
|
-
runtimeUnitImplementationRegistry: {
|
|
33
|
-
get(pluginId, unitId) {
|
|
34
|
-
return pluginId === "hello" && unitId === "hello.window" ? helloSetup : undefined;
|
|
35
|
-
},
|
|
25
|
+
import { createWindowApp, definePlugin } from "webloom-framework";
|
|
26
|
+
|
|
27
|
+
const hello = definePlugin({
|
|
28
|
+
id: "hello",
|
|
29
|
+
provides: ["hello.service"],
|
|
30
|
+
setup(ctx) {
|
|
31
|
+
ctx.provide("hello.service", { value: "world" });
|
|
36
32
|
},
|
|
37
|
-
contextExtension: ({ scope }) => ({
|
|
38
|
-
// 宿主只读扩展;不能替换 pluginId、unitId 或 instanceId。
|
|
39
|
-
scopeKind: scope.identity.kind,
|
|
40
|
-
}),
|
|
41
33
|
});
|
|
42
34
|
|
|
43
|
-
await
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
35
|
+
const app = await createWindowApp({ plugins: [hello] });
|
|
36
|
+
const service = app.capability<{ value: string }>("hello.service");
|
|
37
|
+
console.log(service.value); // world
|
|
38
|
+
|
|
39
|
+
await app.dispose();
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`createWindowApp()` 会固定创建一个 `window-main` Runtime、生成新的
|
|
43
|
+
`runtimeInstanceId`、装配实现并等待初始插件启动。普通插件不需要手工创建
|
|
44
|
+
Implementation Registry 或调用 `host.register()`;`definePlugin()` 返回的静态
|
|
45
|
+
manifest 不包含 `setup` 函数。
|
|
46
|
+
|
|
47
|
+
## SharedWorker Runtime
|
|
48
|
+
|
|
49
|
+
Worker 入口只在 Worker realm 中装配插件:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
// coordinator.worker.ts
|
|
53
|
+
import { definePlugin, startSharedWorkerApp } from "webloom-framework";
|
|
54
|
+
|
|
55
|
+
const coordinator = definePlugin({
|
|
56
|
+
id: "coordinator",
|
|
57
|
+
provides: ["coordinator.service"],
|
|
58
|
+
setup(ctx) {
|
|
59
|
+
ctx.provide("coordinator.service", {
|
|
60
|
+
handle(request: { type: string }) {
|
|
61
|
+
return { type: request.type, instanceId: ctx.instanceId };
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
},
|
|
53
65
|
});
|
|
66
|
+
|
|
67
|
+
startSharedWorkerApp({ id: "coordinator", plugins: [coordinator] });
|
|
54
68
|
```
|
|
55
69
|
|
|
56
|
-
|
|
70
|
+
Window 侧只连接 Worker,不创建第二套 Worker 插件生命周期:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
// Vite: this query emits a real, hashed JavaScript SharedWorker chunk.
|
|
74
|
+
// Do not pass the source `.ts` URL to connectSharedWorker in a production build.
|
|
75
|
+
import coordinatorWorkerUrl from "./coordinator.worker.ts?sharedworker&url";
|
|
76
|
+
import { connectSharedWorker } from "webloom-framework";
|
|
77
|
+
|
|
78
|
+
const runtime = connectSharedWorker({
|
|
79
|
+
id: "coordinator",
|
|
80
|
+
url: coordinatorWorkerUrl,
|
|
81
|
+
});
|
|
82
|
+
const service = runtime.capability("coordinator.service");
|
|
83
|
+
await service.call({ type: "health" });
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`connectSharedWorker()` 同步返回本地句柄;Worker 通过完整 `RuntimeSnapshot` 发布
|
|
87
|
+
状态和服务目录,代理的第一次 `call()` 在有限 deadline 内等待精确匹配。协议不兼容、
|
|
88
|
+
断线、超时和服务撤销都从调用 Promise 返回;框架不自动重连或重放调用。旧代理不会
|
|
89
|
+
静默换绑到新 Worker;Worker 重启后 `runtimeInstanceId`、服务的
|
|
90
|
+
`serviceInstanceId` 和运行单元实例都会变化。
|
|
91
|
+
|
|
92
|
+
Vite 项目必须把 Worker 入口交给 Vite 的 Worker importer(例如
|
|
93
|
+
`?sharedworker&url`),再把构建后导出的 URL 传给框架。框架内部的
|
|
94
|
+
`new SharedWorker(url, { type: "module" })` 只负责运行时连接,不能替调用方的
|
|
95
|
+
Bundler 发现源码 `.ts` 入口。其它 Bundler 应使用等价的独立 SharedWorker
|
|
96
|
+
Rollup entry。仓库的 `pnpm run test:browser` 会先执行生产构建,再从 dist 启动
|
|
97
|
+
真实浏览器验收。
|
|
98
|
+
|
|
99
|
+
Window 插件依赖 Worker capability 时,把已连接的 `RuntimeHandle` 传给
|
|
100
|
+
`createWindowApp({ remoteRuntime: runtime, plugins })`,并在 setup 中通过
|
|
101
|
+
`ctx.serviceBridge.requireProxy()` 获取精确版本的远程代理。Worker 断线时,Window
|
|
102
|
+
Host 会把相关单元置为 `blocked`;新的完整快照到达后按原启用意图重新协调。
|
|
57
103
|
|
|
58
104
|
## 公共字段中文语义
|
|
59
105
|
|
|
60
106
|
| 字段 | 中文含义 |
|
|
61
107
|
| --- | --- |
|
|
62
108
|
| `pluginId` | 插件产品的稳定标识;用于用户启停和依赖图身份。 |
|
|
63
|
-
| `unitId` |
|
|
109
|
+
| `unitId` | 产品在一个 Runtime 中的稳定运行单元标识。 |
|
|
64
110
|
| `instanceId` | 某运行单元一次启动生成的唯一实例标识;重启不得复用。 |
|
|
65
|
-
| `
|
|
66
|
-
| `
|
|
111
|
+
| `runtime` | 真实 JavaScript 运行空间;当前版本仅为 `window-main/shared-worker`。 |
|
|
112
|
+
| `runtimeInstanceId` | 某个 Window 或 SharedWorker 启动生成的不可复用身份。 |
|
|
113
|
+
| `serviceInstanceId` | 某个服务实例的不可复用身份;服务撤销或重建后必须变化。 |
|
|
114
|
+
| `revision` | 完整 RuntimeSnapshot 的单调修订号;只用于观察和目录收敛。 |
|
|
67
115
|
| `scopeId` | 本次生命周期 Scope 的唯一标识。 |
|
|
68
116
|
| `capability` | 插件提供或依赖的服务契约标识。 |
|
|
69
117
|
| `contractVersion` | capability 的精确契约版本。 |
|
|
70
118
|
| `permission` | 字符串形式的权限动作;具体集合由宿主批准。 |
|
|
71
119
|
| `attributes` | 宿主绑定的只读扩展元数据,不包含私密材料。 |
|
|
72
120
|
| `desiredEnabled` | 用户或控制面希望产品启用的持久意图。 |
|
|
73
|
-
| `state` |
|
|
121
|
+
| `state` | 当前 Runtime/运行实例的实际状态,不等于启用意图。 |
|
|
74
122
|
| `blockedBy` | 实例无法启动时缺失的依赖或 Scope 原因。 |
|
|
75
123
|
|
|
76
124
|
## 开发与验收
|
|
@@ -82,6 +130,8 @@ pnpm typecheck
|
|
|
82
130
|
pnpm test
|
|
83
131
|
pnpm build
|
|
84
132
|
pnpm run pack:consumer
|
|
133
|
+
# 会安装/校验 Playwright Chromium,再执行生产 dist fixture
|
|
134
|
+
pnpm run test:browser
|
|
85
135
|
```
|
|
86
136
|
|
|
87
137
|
`pack:consumer` 会在不访问本仓库源码的临时项目中安装 tarball,分别执行
|