webloom-framework 0.2.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 +11 -8
- package/dist/{chunk-URY3E6UH.js → chunk-76BGPI6M.js} +771 -312
- package/dist/chunk-76BGPI6M.js.map +1 -0
- package/dist/{createPluginHost-ChJNBTsX.d.ts → createPluginHost-BVsUCDKN.d.ts} +67 -88
- package/dist/index.d.ts +15 -200
- package/dist/index.js +276 -884
- 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 +20 -19
- package/docs/migration-baseline.md +2 -2
- package/docs/proposals/browser-runtime-v1/implementation-plan.md +7 -1
- package/docs/proposals/browser-runtime-v1/requirements.md +6 -1
- package/docs/proposals/browser-runtime-v1/verification.md +20 -13
- 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 +1 -1
- package/dist/chunk-URY3E6UH.js.map +0 -1
- package/dist/resourceRegistry-MNM1c7od.d.ts +0 -157
package/dist/react.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as react from 'react';
|
|
3
3
|
import { ReactNode } from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import { m as PluginHost, ad as PluginState, a as PluginGraph, c as PluginReverseDep, aa as PluginIntentSubmissionResult, P as PluginManifest, aF as ResourceStoreApi, aD as ResourceSnapshot } from './createPluginHost-BVsUCDKN.js';
|
|
5
5
|
|
|
6
6
|
declare const PluginHostContext: react.Context<PluginHost | undefined>;
|
|
7
7
|
interface PluginHostProviderProps {
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { i as PluginSetup, aL as RuntimeUnitImplementationRegistry, R as RuntimeKind, ae as PluginStateKind, r as RemoteServiceReference, s as RemoteServiceMessageCodec, ah as PluginUnitState, au as RemoteServiceProxy, m as PluginHost, L as LifecycleDisposeResult, M as MessageBus, K as LifecycleScopeKind, o as LifecycleScopeIdentity, n as LifecycleScope, a9 as PluginIntentSnapshot, a7 as PluginIntentController, ax as RemoteServiceTransport, am as RemoteServiceBridge, ao as RemoteServiceCallContext, aC as ResourceRegistry, aA as ResourceDefinition } from './createPluginHost-BVsUCDKN.js';
|
|
2
|
+
|
|
3
|
+
interface RuntimeUnitImplementation {
|
|
4
|
+
/** 产品标识。 */
|
|
5
|
+
pluginId: string;
|
|
6
|
+
/** 稳定运行单元标识。 */
|
|
7
|
+
unitId: string;
|
|
8
|
+
/** 当前环境的可执行入口。 */
|
|
9
|
+
setup: PluginSetup;
|
|
10
|
+
}
|
|
11
|
+
/** 创建一个拒绝重复注册、按产品和单元查找实现的运行时注册表。 */
|
|
12
|
+
declare function createRuntimeUnitImplementationRegistry(implementations?: readonly RuntimeUnitImplementation[]): RuntimeUnitImplementationRegistry & {
|
|
13
|
+
register(implementation: RuntimeUnitImplementation): void;
|
|
14
|
+
unregister(pluginId: string, unitId: string): void;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
declare const RUNTIME_PROTOCOL_VERSION = "webloom.runtime.v2";
|
|
18
|
+
declare const RUNTIME_SNAPSHOT_TYPE = "webloom.runtime.snapshot";
|
|
19
|
+
declare const RUNTIME_ERROR_TYPE = "webloom.runtime.error";
|
|
20
|
+
interface RuntimeErrorMessage {
|
|
21
|
+
type: typeof RUNTIME_ERROR_TYPE;
|
|
22
|
+
protocolVersion: string;
|
|
23
|
+
code: "runtime_initialization_failed" | "protocol_mismatch" | "transport_unavailable";
|
|
24
|
+
message: string;
|
|
25
|
+
pluginId?: string;
|
|
26
|
+
unitId?: string;
|
|
27
|
+
phase?: "startup" | "snapshot";
|
|
28
|
+
}
|
|
29
|
+
interface RuntimeSnapshot {
|
|
30
|
+
type: typeof RUNTIME_SNAPSHOT_TYPE;
|
|
31
|
+
protocolVersion: string;
|
|
32
|
+
runtimeId: string;
|
|
33
|
+
runtimeKind: RuntimeKind;
|
|
34
|
+
runtimeInstanceId: string;
|
|
35
|
+
revision: number;
|
|
36
|
+
state: "starting" | "ready" | "stopping" | "failed" | "disposed";
|
|
37
|
+
units: readonly RuntimeSnapshotUnit[];
|
|
38
|
+
services: readonly RemoteServiceReference[];
|
|
39
|
+
}
|
|
40
|
+
interface RuntimeSnapshotUnit {
|
|
41
|
+
pluginId: string;
|
|
42
|
+
unitId: string;
|
|
43
|
+
runtime: RuntimeKind;
|
|
44
|
+
instanceId?: string;
|
|
45
|
+
state: PluginStateKind;
|
|
46
|
+
}
|
|
47
|
+
declare function createRuntimeMessageCodec(): RemoteServiceMessageCodec;
|
|
48
|
+
/** 只验证外层结构;协议版本接受由 RuntimeHandle 单独处理。 */
|
|
49
|
+
declare function isRuntimeSnapshot(input: unknown): input is RuntimeSnapshot;
|
|
50
|
+
declare function isRuntimeSnapshotProtocol(input: RuntimeSnapshot): boolean;
|
|
51
|
+
declare function isRuntimeError(input: unknown): input is RuntimeErrorMessage;
|
|
52
|
+
/** 将 Host 的 PluginUnitState 映射成不会泄露领域配置的运行时快照。 */
|
|
53
|
+
declare function unitSnapshotFromState(state: PluginUnitState, runtime: RuntimeKind): RuntimeSnapshotUnit;
|
|
54
|
+
|
|
55
|
+
type RuntimeAppState = "starting" | "ready" | "stopping" | "failed" | "disposed" | "disconnected";
|
|
56
|
+
interface RuntimeStatusSnapshot {
|
|
57
|
+
runtimeId: string;
|
|
58
|
+
runtimeKind: RuntimeKind;
|
|
59
|
+
runtimeInstanceId: string;
|
|
60
|
+
state: RuntimeAppState;
|
|
61
|
+
revision: number;
|
|
62
|
+
units: readonly RuntimeSnapshotUnit[];
|
|
63
|
+
services: readonly RemoteServiceReference[];
|
|
64
|
+
error?: string;
|
|
65
|
+
}
|
|
66
|
+
type RuntimeStatusListener = (snapshot: RuntimeStatusSnapshot) => void;
|
|
67
|
+
interface WindowApp {
|
|
68
|
+
readonly runtimeKind: "window-main";
|
|
69
|
+
readonly runtimeId: string;
|
|
70
|
+
readonly runtimeInstanceId: string;
|
|
71
|
+
/** 已由 createWindowApp 装配并注册完成的本地 Host。 */
|
|
72
|
+
readonly host: PluginHost;
|
|
73
|
+
state(): RuntimeStatusSnapshot;
|
|
74
|
+
/** 获取当前本地 capability;停止或销毁后同步抛错。 */
|
|
75
|
+
capability<T>(capabilityId: string): T;
|
|
76
|
+
subscribe(listener: RuntimeStatusListener): () => void;
|
|
77
|
+
dispose(reason?: string): Promise<LifecycleDisposeResult>;
|
|
78
|
+
}
|
|
79
|
+
interface RuntimeHandle {
|
|
80
|
+
readonly runtimeKind: "shared-worker";
|
|
81
|
+
readonly runtimeId: string;
|
|
82
|
+
/** 当前已观察到的 Worker 启动身份;首份快照前为 undefined。 */
|
|
83
|
+
readonly runtimeInstanceId?: string;
|
|
84
|
+
state(): RuntimeStatusSnapshot;
|
|
85
|
+
capability<T = unknown>(capabilityId: string, options?: {
|
|
86
|
+
contractVersion?: string;
|
|
87
|
+
}): RemoteServiceProxy & {
|
|
88
|
+
readonly serviceType?: T;
|
|
89
|
+
};
|
|
90
|
+
subscribe(listener: RuntimeStatusListener): () => void;
|
|
91
|
+
dispose(reason?: string): Promise<void>;
|
|
92
|
+
}
|
|
93
|
+
/** 跨 realm 初始化失败;不把 required 插件错误包装成成功状态。 */
|
|
94
|
+
interface RuntimeInitializationErrorDetails {
|
|
95
|
+
pluginId?: string;
|
|
96
|
+
unitId?: string;
|
|
97
|
+
phase: "validate" | "register" | "startup" | "snapshot";
|
|
98
|
+
error: string;
|
|
99
|
+
}
|
|
100
|
+
declare class RuntimeInitializationError extends Error {
|
|
101
|
+
readonly code: "runtime_initialization_failed";
|
|
102
|
+
readonly details: RuntimeInitializationErrorDetails;
|
|
103
|
+
constructor(details: RuntimeInitializationErrorDetails);
|
|
104
|
+
}
|
|
105
|
+
declare class RuntimeUnavailableError extends Error {
|
|
106
|
+
readonly code: "transport_unavailable";
|
|
107
|
+
constructor(message?: string);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
interface SharedWorkerLike {
|
|
111
|
+
readonly port: MessagePort;
|
|
112
|
+
onerror?: (event: Event) => void;
|
|
113
|
+
addEventListener?(type: "error", listener: (event: Event) => void): void;
|
|
114
|
+
removeEventListener?(type: "error", listener: (event: Event) => void): void;
|
|
115
|
+
}
|
|
116
|
+
type SharedWorkerFactory = (url: string | URL, options: {
|
|
117
|
+
type: "module";
|
|
118
|
+
name?: string;
|
|
119
|
+
credentials?: RequestCredentials;
|
|
120
|
+
}) => SharedWorkerLike;
|
|
121
|
+
/**
|
|
122
|
+
* 临时迁移接缝:下游 typed transfer API 完成前允许领域代码在同一
|
|
123
|
+
* 物理端口安装 listener。它不参与 Runtime 授权,也不传 connectionId。
|
|
124
|
+
*/
|
|
125
|
+
interface SharedWorkerConnectionContext {
|
|
126
|
+
readonly worker: SharedWorkerLike;
|
|
127
|
+
readonly port: MessagePort;
|
|
128
|
+
}
|
|
129
|
+
interface ConnectSharedWorkerOptions {
|
|
130
|
+
id: string;
|
|
131
|
+
url: string | URL;
|
|
132
|
+
name?: string;
|
|
133
|
+
credentials?: RequestCredentials;
|
|
134
|
+
defaultCallTimeoutMs?: number;
|
|
135
|
+
/** SWCF-009 完成前的临时同端口迁移接缝。 */
|
|
136
|
+
onConnection?: (context: SharedWorkerConnectionContext) => void;
|
|
137
|
+
}
|
|
138
|
+
/** 创建生产 RuntimeHandle;测试工厂不属于生产公共选项。 */
|
|
139
|
+
declare function connectSharedWorker(options: ConnectSharedWorkerOptions): RuntimeHandle;
|
|
140
|
+
/** 仅由 `webloom-framework/testing` 暴露的 SharedWorker 工厂注入入口。 */
|
|
141
|
+
declare function connectSharedWorkerForTesting(options: ConnectSharedWorkerOptions, workerFactory: SharedWorkerFactory): RuntimeHandle;
|
|
142
|
+
|
|
143
|
+
declare function createMessageBus(): MessageBus;
|
|
144
|
+
|
|
145
|
+
interface CreateResourceScopeOptions {
|
|
146
|
+
/** 可选固定作用域标识;生产代码通常省略,让实现生成不可复用 ID。 */
|
|
147
|
+
scopeId?: string;
|
|
148
|
+
/** 运行实例标识;省略时与 scopeId 同源生成。 */
|
|
149
|
+
instanceId?: string;
|
|
150
|
+
/** 作用域类型。 */
|
|
151
|
+
kind: LifecycleScopeKind;
|
|
152
|
+
/** 绑定插件和宿主只读属性。 */
|
|
153
|
+
metadata?: Omit<Partial<LifecycleScopeIdentity>, "scopeId" | "instanceId" | "kind">;
|
|
154
|
+
/** 测试或宿主诊断使用的状态变更回调。 */
|
|
155
|
+
onChange?: (scope: LifecycleScope) => void;
|
|
156
|
+
/** 子作用域生成最终清理结果后的内部通知;用于更新父级登记。 */
|
|
157
|
+
onDisposeResult?: (result: LifecycleDisposeResult) => void;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* 创建一个可嵌套的生命周期作用域。
|
|
161
|
+
*
|
|
162
|
+
* `createResourceScope` 是 `createLifecycleScope` 的同义入口,方便不同
|
|
163
|
+
* 模块按“作用域”或“资源”语义调用;两者不代表两套实现。
|
|
164
|
+
*/
|
|
165
|
+
declare function createLifecycleScope(options: CreateResourceScopeOptions): LifecycleScope;
|
|
166
|
+
/** 语义别名:资源管理代码通常以 ResourceScope 称呼同一原语。 */
|
|
167
|
+
declare const createResourceScope: typeof createLifecycleScope;
|
|
168
|
+
type ResourceScopeOptions = CreateResourceScopeOptions;
|
|
169
|
+
|
|
170
|
+
interface CreatePluginIntentControllerOptions {
|
|
171
|
+
/** 当前控制面启动身份;Worker 重启时应传入新值。 */
|
|
172
|
+
authorityInstanceId?: string;
|
|
173
|
+
/** Worker 恢复后读取的平台意图。 */
|
|
174
|
+
initial?: Partial<PluginIntentSnapshot>;
|
|
175
|
+
/** 将候选快照原子写入平台存储;缺省表示内存控制面(测试用)。 */
|
|
176
|
+
persist?: (snapshot: PluginIntentSnapshot) => Promise<void>;
|
|
177
|
+
/** 有界去重记录数量,避免 commandId 永久增长。 */
|
|
178
|
+
maxCommandRecords?: number;
|
|
179
|
+
}
|
|
180
|
+
/** 创建单一控制面上的插件意图控制器。 */
|
|
181
|
+
declare function createPluginIntentController(options?: CreatePluginIntentControllerOptions): PluginIntentController;
|
|
182
|
+
|
|
183
|
+
interface CreateServiceBridgeOptions {
|
|
184
|
+
/** 要接受的精确服务协议版本。 */
|
|
185
|
+
protocolVersion: string;
|
|
186
|
+
/** 实际端口 RPC 传输;桥不负责重放请求。 */
|
|
187
|
+
transport: RemoteServiceTransport;
|
|
188
|
+
/** 默认总 deadline;必须有限且大于零。 */
|
|
189
|
+
defaultCallTimeoutMs?: number;
|
|
190
|
+
}
|
|
191
|
+
/** 创建一个无连接握手、无增量 revision 状态机的服务桥。 */
|
|
192
|
+
declare function createServiceBridge(options: CreateServiceBridgeOptions): RemoteServiceBridge;
|
|
193
|
+
|
|
194
|
+
interface RemoteServicePortCallMessage {
|
|
195
|
+
type: string;
|
|
196
|
+
protocolVersion: string;
|
|
197
|
+
callId: string;
|
|
198
|
+
capabilityId: string;
|
|
199
|
+
contractVersion: string;
|
|
200
|
+
serviceInstanceId: string;
|
|
201
|
+
operationId?: string;
|
|
202
|
+
grantId?: string;
|
|
203
|
+
request: unknown;
|
|
204
|
+
}
|
|
205
|
+
interface RemoteServicePortResultMessage {
|
|
206
|
+
type: string;
|
|
207
|
+
protocolVersion: string;
|
|
208
|
+
callId: string;
|
|
209
|
+
serviceInstanceId: string;
|
|
210
|
+
result: unknown;
|
|
211
|
+
}
|
|
212
|
+
interface RemoteServicePortErrorMessage {
|
|
213
|
+
type: string;
|
|
214
|
+
protocolVersion: string;
|
|
215
|
+
callId: string;
|
|
216
|
+
serviceInstanceId: string;
|
|
217
|
+
error: {
|
|
218
|
+
name?: string;
|
|
219
|
+
message: string;
|
|
220
|
+
code: string;
|
|
221
|
+
details?: Readonly<Record<string, unknown>>;
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
interface RemoteServicePortCancelMessage {
|
|
225
|
+
type: string;
|
|
226
|
+
protocolVersion: string;
|
|
227
|
+
callId: string;
|
|
228
|
+
serviceInstanceId: string;
|
|
229
|
+
}
|
|
230
|
+
type RemoteServicePortResponseMessage = RemoteServicePortResultMessage | RemoteServicePortErrorMessage;
|
|
231
|
+
interface CreateMessagePortServiceTransportOptions {
|
|
232
|
+
/** 已由实际 Worker / Window 连接产生的双工端口。 */
|
|
233
|
+
port: MessagePort;
|
|
234
|
+
/** 可选 transferable 提取器;默认只发送结构化克隆数据。 */
|
|
235
|
+
transferForRequest?: (request: unknown, context: RemoteServiceCallContext) => readonly Transferable[];
|
|
236
|
+
/** dispose 时是否关闭端口;默认不关闭,由端口所有者决定。 */
|
|
237
|
+
closeOnDispose?: boolean;
|
|
238
|
+
/** wire 消息 codec;默认 webloom.remote-service.v2。 */
|
|
239
|
+
codec?: RemoteServiceMessageCodec;
|
|
240
|
+
/** 直接使用 transport 时的默认总 deadline。 */
|
|
241
|
+
defaultCallTimeoutMs?: number;
|
|
242
|
+
}
|
|
243
|
+
/** 创建一条不携带连接身份、不会自动重放的 MessagePort transport。 */
|
|
244
|
+
declare function createMessagePortServiceTransport(options: CreateMessagePortServiceTransportOptions): RemoteServiceTransport & {
|
|
245
|
+
dispose(): void;
|
|
246
|
+
};
|
|
247
|
+
/** Provider 侧调用消息的结构化输入。 */
|
|
248
|
+
interface MessagePortServiceCallInput {
|
|
249
|
+
message: RemoteServicePortCallMessage;
|
|
250
|
+
/** Provider 的权威目录命中的服务引用。 */
|
|
251
|
+
reference: RemoteServiceReference;
|
|
252
|
+
signal: AbortSignal;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* 资源注册表实现
|
|
257
|
+
*
|
|
258
|
+
* 设计缘由:管理资源定义的注册和查询,支持 owner-aware 生命周期。
|
|
259
|
+
* 重复 id 抛错,disable 时可回收。
|
|
260
|
+
*/
|
|
261
|
+
|
|
262
|
+
/** 资源注册表实现 */
|
|
263
|
+
declare function createResourceRegistry(): ResourceRegistry;
|
|
264
|
+
/** Internal runtime hook; deliberately absent from ResourceRegistry's public type. */
|
|
265
|
+
declare function registerOwnedResource(registry: ResourceRegistry, ownerId: string, definition: ResourceDefinition<any, any>): void;
|
|
266
|
+
|
|
267
|
+
export { createMessageBus as A, createMessagePortServiceTransport as B, type ConnectSharedWorkerOptions as C, createPluginIntentController as D, createResourceRegistry as E, createResourceScope as F, createRuntimeMessageCodec as G, createRuntimeUnitImplementationRegistry as H, createServiceBridge as I, isRuntimeError as J, isRuntimeSnapshot as K, isRuntimeSnapshotProtocol as L, type MessagePortServiceCallInput as M, registerOwnedResource as N, unitSnapshotFromState as O, type SharedWorkerFactory as P, connectSharedWorkerForTesting as Q, type RuntimeHandle as R, type SharedWorkerConnectionContext as S, type WindowApp as W, type RuntimeStatusSnapshot as a, type RuntimeStatusListener as b, type CreateMessagePortServiceTransportOptions as c, type CreatePluginIntentControllerOptions as d, type CreateResourceScopeOptions as e, type CreateServiceBridgeOptions as f, RUNTIME_ERROR_TYPE as g, RUNTIME_PROTOCOL_VERSION as h, RUNTIME_SNAPSHOT_TYPE as i, type RemoteServicePortCallMessage as j, type RemoteServicePortCancelMessage as k, type RemoteServicePortErrorMessage as l, type RemoteServicePortResponseMessage as m, type RemoteServicePortResultMessage as n, type ResourceScopeOptions as o, type RuntimeAppState as p, type RuntimeErrorMessage as q, RuntimeInitializationError as r, type RuntimeInitializationErrorDetails as s, type RuntimeSnapshot as t, type RuntimeSnapshotUnit as u, RuntimeUnavailableError as v, type RuntimeUnitImplementation as w, type SharedWorkerLike as x, connectSharedWorker as y, createLifecycleScope as z };
|
package/dist/testing.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
1
|
+
import { ao as RemoteServiceCallContext, C as CreatePluginHostOptions, m as PluginHost, ax as RemoteServiceTransport } from './createPluginHost-BVsUCDKN.js';
|
|
2
|
+
export { t as CapabilityRegistry, u as ContextExtensionInput, v as ContributionAdapter, w as ContributionAdapterInput, x as ContributionHandle, a0 as PermissionPolicyInput, a1 as PermissionPolicyResult, a3 as PluginConfigStore, aG as RuntimeUnitAttributesInput, aH as RuntimeUnitAvailabilityInput, aM as RuntimeUnitParentScopeInput, aN as RuntimeUnitSnapshot, aR as StartupCapabilityError, aT as StartupPluginError, b1 as createCapabilityRegistry, b2 as createInMemoryPluginConfigStore, b3 as createPluginHost, b5 as createResourceStore } from './createPluginHost-BVsUCDKN.js';
|
|
3
|
+
export { c as CreateMessagePortServiceTransportOptions, d as CreatePluginIntentControllerOptions, e as CreateResourceScopeOptions, f as CreateServiceBridgeOptions, M as MessagePortServiceCallInput, j as RemoteServicePortCallMessage, k as RemoteServicePortCancelMessage, l as RemoteServicePortErrorMessage, m as RemoteServicePortResponseMessage, n as RemoteServicePortResultMessage, o as ResourceScopeOptions, w as RuntimeUnitImplementation, P as SharedWorkerFactory, Q as connectSharedWorkerForTesting, z as createLifecycleScope, A as createMessageBus, B as createMessagePortServiceTransport, D as createPluginIntentController, E as createResourceRegistry, F as createResourceScope, H as createRuntimeUnitImplementationRegistry, I as createServiceBridge } from './resourceRegistry-BFnjmeGE.js';
|
|
4
4
|
|
|
5
5
|
interface FakeTransportCall {
|
|
6
6
|
/** 调用请求体。 */
|
package/dist/testing.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createPluginHost } from './chunk-
|
|
2
|
-
export { StartupCapabilityError, StartupPluginError, createCapabilityRegistry, createInMemoryPluginConfigStore, createLifecycleScope, createMessageBus, createMessagePortServiceTransport, createPluginHost, createPluginIntentController,
|
|
1
|
+
import { createPluginHost } from './chunk-76BGPI6M.js';
|
|
2
|
+
export { StartupCapabilityError, StartupPluginError, connectSharedWorkerForTesting, createCapabilityRegistry, createInMemoryPluginConfigStore, createLifecycleScope, createMessageBus, createMessagePortServiceTransport, createPluginHost, createPluginIntentController, createResourceRegistry, createResourceScope, createResourceStore, createRuntimeUnitImplementationRegistry, createServiceBridge } from './chunk-76BGPI6M.js';
|
|
3
3
|
|
|
4
4
|
// src/testing/fakes.ts
|
|
5
5
|
function createFakeRemoteServiceTransport(options = {}) {
|
package/docs/api.md
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
## 浏览器 Runtime
|
|
4
4
|
|
|
5
|
-
WebLoom
|
|
5
|
+
WebLoom 0.3.0 只支持两个真实 JavaScript realm:`window-main` 和
|
|
6
6
|
`shared-worker`。`runtime` 是受限的 `RuntimeKind`,不是可自由填写的环境标签;
|
|
7
|
-
不支持的 runtime 在装配边界 fail closed
|
|
7
|
+
不支持的 runtime 在装配边界 fail closed。不实现 Server、Service Worker 或
|
|
8
8
|
其它服务端 PluginHost。
|
|
9
9
|
|
|
10
10
|
一次 Runtime 启动会生成不可复用的 `runtimeInstanceId`。每个插件运行单元启动
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
会生成不可复用的运行单元 `instanceId`。同一 SharedWorker 接收多个 Window 连接
|
|
12
|
+
时,Worker 单元仍只有一个实例;端口本身隔离请求和取消空间,物理端口身份不进入
|
|
13
|
+
公共 Runtime 或 RemoteService wire。
|
|
14
14
|
|
|
15
15
|
## 普通插件 API
|
|
16
16
|
|
|
@@ -70,7 +70,7 @@ Window 入口:
|
|
|
70
70
|
import coordinatorWorkerUrl from "./coordinator.worker.ts?sharedworker&url";
|
|
71
71
|
import { connectSharedWorker } from "webloom-framework";
|
|
72
72
|
|
|
73
|
-
const runtime =
|
|
73
|
+
const runtime = connectSharedWorker({
|
|
74
74
|
id: "coordinator",
|
|
75
75
|
url: coordinatorWorkerUrl,
|
|
76
76
|
});
|
|
@@ -79,10 +79,11 @@ const storage = runtime.capability("storage.service");
|
|
|
79
79
|
await storage.call({ key: "hello" });
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
-
连接入口必须创建真实的 `new SharedWorker(url, { type: "module" })
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
连接入口必须创建真实的 `new SharedWorker(url, { type: "module" })`,并同步返回
|
|
83
|
+
本地 `RuntimeHandle`。Worker 只发布完整 `RuntimeSnapshot`;`capability()` 总是
|
|
84
|
+
返回惰性代理,第一次 `call()` 在同一个有限 deadline 内等待目录和远程执行。断线、
|
|
85
|
+
协议不兼容、Worker 重启或 Provider 实例变化都会同步撤销旧代理。显式重建只建立
|
|
86
|
+
新句柄和新代理,不会重放可能产生外部副作用的调用,也不会静默替换旧代理的绑定。
|
|
86
87
|
|
|
87
88
|
这里的 `url` 必须是 Bundler 产出的 JavaScript Worker URL。Vite 使用
|
|
88
89
|
`?sharedworker&url` 或等价的独立 Rollup entry;不要把
|
|
@@ -95,10 +96,8 @@ Worker 重启或 Provider 实例变化都会同步撤销旧代理。重连只建
|
|
|
95
96
|
| --- | --- |
|
|
96
97
|
| `runtimeId` | Worker 的逻辑标识 |
|
|
97
98
|
| `runtimeInstanceId` | 当前 Worker 物理启动身份 |
|
|
98
|
-
| `
|
|
99
|
-
| `
|
|
100
|
-
| `ready()` | 等待握手和完整 baseline;不可自动重连的断线、failed 或 disposed 后持续拒绝 `RuntimeUnavailableError`,自动重连时只等待新的 readiness generation |
|
|
101
|
-
| `capability()` | 获取绑定 Runtime、Provider、契约版本和 revision 的代理 |
|
|
99
|
+
| `state()` | `starting / ready / disconnected / failed / stopping / disposed` 快照 |
|
|
100
|
+
| `capability()` | 立即获取惰性代理;第一次 `call()` 精确绑定 Runtime/service instance |
|
|
102
101
|
| `subscribe()` | 观察 Runtime/Unit/服务快照 |
|
|
103
102
|
| `dispose()` | 同步撤销本句柄,异步关闭连接资源 |
|
|
104
103
|
|
|
@@ -117,21 +116,23 @@ const app = await createWindowApp({
|
|
|
117
116
|
contractVersion: "coordinator.service.v1",
|
|
118
117
|
sourceRuntime: "shared-worker",
|
|
119
118
|
}],
|
|
120
|
-
|
|
119
|
+
setup(ctx) {
|
|
121
120
|
const coordinator = ctx.serviceBridge?.requireProxy({
|
|
122
121
|
capabilityId: "coordinator.service",
|
|
123
122
|
contractVersion: "coordinator.service.v1",
|
|
124
123
|
runtime: "shared-worker",
|
|
125
124
|
}, ctx.scope);
|
|
126
|
-
|
|
125
|
+
if (!coordinator) throw new Error("Remote service bridge is unavailable");
|
|
126
|
+
ctx.provide("window.coordinator", coordinator);
|
|
127
127
|
},
|
|
128
128
|
})],
|
|
129
129
|
});
|
|
130
130
|
```
|
|
131
131
|
|
|
132
|
-
`remoteRuntime` 只向 Host
|
|
133
|
-
|
|
134
|
-
|
|
132
|
+
`remoteRuntime` 只向 Host 投影当前完整快照中的服务和单元状态;setup 函数不会进入
|
|
133
|
+
Worker。这里的 `coordinator` 是惰性代理,业务在调用边界执行
|
|
134
|
+
`await coordinator.call({ type: "health" })`。断线时 Host 同步撤销页面插件的 Scope
|
|
135
|
+
和远程代理,显式重建后的新代理必须重新取得,不会静默重绑旧引用。
|
|
135
136
|
|
|
136
137
|
## 生命周期和 Scope
|
|
137
138
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
| WebLoom 起始提交 | `f1c801655c3132c57b66045ff6d5e642fba4a8ea` |
|
|
9
9
|
| Node | `v22.13.1` |
|
|
10
10
|
| pnpm | `11.5.1` |
|
|
11
|
-
| 下一发布包版本 | `0.
|
|
11
|
+
| 下一发布包版本 | `0.3.0` |
|
|
12
12
|
| npm 包名 | `webloom-framework` |
|
|
13
13
|
| 发布来源提交 | `a5ace48` |
|
|
14
14
|
| 已发布基线标签 | `v0.1.0` |
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
## 当前工作区发布状态
|
|
22
22
|
|
|
23
|
-
当前工作区正在准备 `webloom-framework@0.
|
|
23
|
+
当前工作区正在准备 `webloom-framework@0.3.0`,但该版本尚未发布到 npm;下游在发布
|
|
24
24
|
责任人完成正式发布前继续使用本地工作区依赖。`v0.1.0` / npm `0.1.0` 是已发布基线,
|
|
25
25
|
不是本轮未发布代码的验收替代品。
|
|
26
26
|
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
# WebLoom 浏览器双运行时施工单
|
|
2
2
|
|
|
3
|
+
> SharedWorker 的 `hello`、RemoteService `handshake`、`baseline/resync`、握手超时和
|
|
4
|
+
> 自动重连要求,已被[SharedWorker call-first 消融施工单](../shared-worker-call-first/implementation-plan.md)
|
|
5
|
+
> 覆盖。其余 Runtime、PluginHost、生命周期和安全边界继续有效。
|
|
6
|
+
|
|
3
7
|
## 1. 施工目标
|
|
4
8
|
|
|
5
9
|
把 WebLoom 从字符串运行标签和手工初始化装配,升级为真实的 `window-main + shared-worker` 浏览器双运行时;删除无执行语义的 `lifetime` 与插件分类 `kind`;用高层 API 封装 SharedWorker、MessagePort 和远程 capability。
|
|
6
10
|
|
|
7
|
-
需求基线见[浏览器双运行时迭代需求](./requirements.md)
|
|
11
|
+
需求基线见[浏览器双运行时迭代需求](./requirements.md)。本施工单保留基础双运行时的
|
|
12
|
+
历史实施顺序;SharedWorker 连接相关条款已由上方 call-first 施工单取代,不再作为
|
|
13
|
+
当前 hello/handshake/baseline/reconnect 行为的真值。
|
|
8
14
|
|
|
9
15
|
## 2. 施工边界
|
|
10
16
|
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
# WebLoom 浏览器双运行时迭代需求
|
|
2
2
|
|
|
3
|
+
> SharedWorker 连接协议现已采用 call-first 方向。本文涉及 `hello`、握手、baseline、
|
|
4
|
+
> resync、`ready()` 和自动重连的条款,由
|
|
5
|
+
> [SharedWorker call-first 消融施工单](../shared-worker-call-first/implementation-plan.md)
|
|
6
|
+
> 覆盖;其他产品目标和安全要求不变。
|
|
7
|
+
|
|
3
8
|
## 1. 文档信息
|
|
4
9
|
|
|
5
10
|
- 项目:WebLoom
|
|
6
11
|
- 迭代:浏览器双运行时 v1
|
|
7
|
-
-
|
|
12
|
+
- 状态:基础 Runtime 已实施;SharedWorker 连接部分由 call-first 施工单收口
|
|
8
13
|
- 文档性质:破坏性简化迭代;不代表当前代码已经具备本文能力
|
|
9
14
|
- 关联施工单:[浏览器双运行时施工单](./implementation-plan.md)
|
|
10
15
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 浏览器双运行时验证记录
|
|
2
2
|
|
|
3
3
|
更新时间:2026-09-09
|
|
4
4
|
|
|
5
5
|
## 当前已通过
|
|
6
6
|
|
|
7
|
-
- WebLoom TypeScript typecheck:通过。
|
|
8
|
-
- Vitest:
|
|
7
|
+
- WebLoom 0.3.0 TypeScript typecheck:通过。
|
|
8
|
+
- Vitest:16 个测试文件、107 个测试通过;SharedWorker 的 Node 部分明确使用
|
|
9
9
|
`MessageChannel` transport simulation。
|
|
10
10
|
- `pnpm lint:boundaries`:通过。
|
|
11
11
|
- `pnpm build`:通过。
|
|
@@ -14,19 +14,22 @@
|
|
|
14
14
|
- `git diff --check`:通过。
|
|
15
15
|
|
|
16
16
|
本轮还覆盖了 Window Host 的 `remoteRuntime` 投影、跨 Runtime 精确契约依赖、
|
|
17
|
-
断线后 blocked/
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
断线后 blocked/reconcile、required 元数据防降级、显式 `unitId` 投影、
|
|
18
|
+
惰性 call deadline、SharedWorker 错误连接收敛、stopping/disposed 后拒绝新连接,
|
|
19
|
+
以及 dispose 后旧代理永久失效。
|
|
20
20
|
|
|
21
21
|
## 真实浏览器证据
|
|
22
22
|
|
|
23
23
|
仓库新增 `scripts/browser-runtime-fixture/` 和 `pnpm run test:browser`。fixture
|
|
24
24
|
先由 Vite 生产构建,再从临时 dist preview 启动真实 HTML Window、module
|
|
25
25
|
SharedWorker 和两个页面,断言 Window/Worker realm marker、Worker setup 只执行
|
|
26
|
-
一次、共享 Worker
|
|
27
|
-
|
|
26
|
+
一次、共享 Worker/runtime/service 实例身份;同时覆盖显式 dispose 后重建新句柄和新
|
|
27
|
+
代理、旧代理失效、协议版本不兼容和构建后 Worker URL。
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
当前执行结果:通过;最终 fixture 连续 10/10 次通过。terminal 场景先等待触发页和观察页
|
|
30
|
+
都报告 connected、ready、subscription installed,再触发 shutdown;两端均收到
|
|
31
|
+
`ready → stopping → disposed`。另有末态后连接页面收到 `starting → disposed`,不补发
|
|
32
|
+
历史 `stopping`。仓库声明 Playwright 1.63.0,已安装 Chromium;runner 会在
|
|
30
33
|
每次验收前执行 `playwright install chromium`,缺少浏览器时仍 fail closed 为
|
|
31
34
|
`unsupported`/退出码 2,不回退为 Node 或同页面 MessageChannel。
|
|
32
35
|
|
|
@@ -43,7 +46,11 @@ SharedWorker 和两个页面,断言 Window/Worker realm marker、Worker setup
|
|
|
43
46
|
client 通过 `connectSharedWorker()` 复用同一物理端口,保留原有 Coordinator RPC、
|
|
44
47
|
私钥隔离、session epoch、owner fence、final-I/O lease 和 localStorage bridge。
|
|
45
48
|
Keymaster typecheck、production build 以及 215-file Vitest batch 已通过。
|
|
46
|
-
- `webloom-framework@0.
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
- `webloom-framework@0.3.0` 仍是待发布工作区版本;npm registry 当前没有该版本,
|
|
50
|
+
下游使用本地 tarball 完成消费者验证,release-boundary 已切换为精确 `0.3.0`。
|
|
51
|
+
Keymaster 的 release-boundary 现在还会动态查询 registry 的精确版本、tarball
|
|
52
|
+
integrity,并与 frozen lockfile 比对;当前门禁因 registry 404 失败。因此“npm
|
|
53
|
+
0.3.0 发布后重新安装并验收”尚未完成。Keymaster 另有
|
|
54
|
+
`pnpm verify:webloom-registry`,会在全新临时目录生成 lockfile、执行 registry-only
|
|
55
|
+
`npm ci` 并导入三个公共入口;当前同样因 404 fail closed。没有在本轮伪造 registry
|
|
56
|
+
版本或自动发布。
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# SWCF-009 typed capability/transfer 后续施工单
|
|
2
|
+
|
|
3
|
+
## 状态与版本边界
|
|
4
|
+
|
|
5
|
+
本施工单从 `webloom-framework@0.3.0` 的 call-first 迁移中正式拆出,目标后续
|
|
6
|
+
版本(暂定 `0.4.0`)。因此 0.3.0 保留 `connectSharedWorker()` 的
|
|
7
|
+
`onConnection` 和 `startSharedWorkerApp()` 的 `onPortConnect` 作为 Keymaster
|
|
8
|
+
迁移接缝,但不得把这两个接缝描述成最终公共架构。
|
|
9
|
+
|
|
10
|
+
0.3.0 的已完成范围是 Runtime v2、惰性 ServiceBridge、call/result/error/cancel
|
|
11
|
+
传输、完整快照、Provider/revocation fence、Demo 和 Keymaster 的 v2 service wire。
|
|
12
|
+
0.3.0 不宣称 SWCF-009 或 npm registry 发布完成。
|
|
13
|
+
|
|
14
|
+
## 后续不变量
|
|
15
|
+
|
|
16
|
+
- capability method 必须声明 request transferables 和 result transferables;未声明的
|
|
17
|
+
capability 只能走 structured clone。
|
|
18
|
+
- transfer list 由 capability 适配器产生,调用方不得取得裸 Runtime `MessagePort`,也
|
|
19
|
+
不得用 `any` 或全局消息监听绕过 capability 边界。
|
|
20
|
+
- request/result 的 transferable 所有权、取消、deadline、dispose、Worker 重启和
|
|
21
|
+
late-result fence 都必须有类型级和真实浏览器测试。
|
|
22
|
+
- Keymaster Coordinator 的主请求、事件和 Local `localStorage` page bridge 必须迁入
|
|
23
|
+
typed API;owner/session/grant/handover/final-I/O fence 与 `UpgradeGate.handshake`
|
|
24
|
+
必须保持原顺序和语义。
|
|
25
|
+
|
|
26
|
+
## 收口门禁
|
|
27
|
+
|
|
28
|
+
1. 先实现并导出 typed request/result transfer descriptor 和测试入口。
|
|
29
|
+
2. 迁移 Keymaster Coordinator 的所有主 RPC、事件及 transferable 操作;保留领域
|
|
30
|
+
`connectionId` 仅在其自身协议中使用。
|
|
31
|
+
3. 通过真实浏览器双 Tab、断线/重启、lock/unlock、A → B → A、Local bridge、迟到
|
|
32
|
+
result 和安全 fence 回归。
|
|
33
|
+
4. 从生产入口删除 `onConnection`、`onPortConnect`;把 worker factory 保持在 testing
|
|
34
|
+
入口,并重新执行三仓 typecheck、build、pack/registry consumer 和发布验收。
|