webloom-framework 0.3.0 → 0.4.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 +70 -42
- package/dist/advanced.d.ts +168 -0
- package/dist/advanced.js +441 -0
- package/dist/advanced.js.map +1 -0
- package/dist/chunk-4DSINPZD.js +158 -0
- package/dist/chunk-4DSINPZD.js.map +1 -0
- package/dist/chunk-JHJZIO2H.js +4018 -0
- package/dist/chunk-JHJZIO2H.js.map +1 -0
- package/dist/chunk-RAQOFUZY.js +1737 -0
- package/dist/chunk-RAQOFUZY.js.map +1 -0
- package/dist/chunk-YOIH6H36.js +433 -0
- package/dist/chunk-YOIH6H36.js.map +1 -0
- package/dist/index.d.ts +39 -259
- package/dist/index.js +38 -1359
- package/dist/index.js.map +1 -1
- package/dist/messageBus-CtrwkjrO.d.ts +5 -0
- package/dist/messagePortServiceTransport-B0FyJr43.d.ts +264 -0
- package/dist/react.d.ts +41 -28
- package/dist/react.js +79 -88
- package/dist/react.js.map +1 -1
- package/dist/runtimeTypes-DquUCHz-.d.ts +1640 -0
- package/dist/sharedWorkerHost-Cb2a1_KD.d.ts +190 -0
- package/dist/testing.d.ts +18 -17
- package/dist/testing.js +23 -15
- package/dist/testing.js.map +1 -1
- package/dist/windowRuntime-B6Ue8jso.d.ts +23 -0
- package/docs/api.md +148 -111
- package/docs/proposals/webloom-v4/implementation-plan.md +443 -0
- package/docs/proposals/webloom-v4/requirements.md +555 -0
- package/docs/proposals/webloom-v4/verification.md +84 -0
- package/package.json +9 -2
- package/dist/chunk-76BGPI6M.js +0 -4261
- package/dist/chunk-76BGPI6M.js.map +0 -1
- package/dist/createPluginHost-BVsUCDKN.d.ts +0 -1318
- package/dist/resourceRegistry-BFnjmeGE.d.ts +0 -267
package/dist/advanced.js
ADDED
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
export { createPluginIntentController } from './chunk-4DSINPZD.js';
|
|
2
|
+
import { bridgeForRuntimeHandle } from './chunk-RAQOFUZY.js';
|
|
3
|
+
export { bridgeForRuntimeHandle, createCapabilityBridge, createMessagePortRuntimeTransport, createMessagePortServiceProvider, validateTransferables } from './chunk-RAQOFUZY.js';
|
|
4
|
+
import { hostForWindowApp, materializePluginDefinitions, UpgradeGateRejectedError } from './chunk-JHJZIO2H.js';
|
|
5
|
+
export { RUNTIME_CALL_TYPE, RUNTIME_CANCEL_TYPE, RUNTIME_CREDIT_TYPE, RUNTIME_ERROR_MESSAGE_TYPE, RUNTIME_ERROR_TYPE, RUNTIME_NEXT_TYPE, RUNTIME_PROTOCOL_VERSION, RUNTIME_RESULT_TYPE, RUNTIME_SNAPSHOT_TYPE, StartupCapabilityError, StartupPluginError, buildPluginGraph, createCapabilityRegistry, createInMemoryPluginConfigStore, createLifecycleScope, createPermissionLease, createPluginHost, createResourceRegistry, createResourceScope, createRuntimeMessageCodec, createRuntimeUnitImplementationRegistry, createScopedTaskScheduler, createWindowAppFromHost, dependenciesOfManifest, hostForWindowApp, invokeCapabilityHandler, isRuntimeSnapshot, providesOfManifest, registerOwnedResource, reverseDependentsOf, selectRuntimeUnit, validatePluginGraph } from './chunk-JHJZIO2H.js';
|
|
6
|
+
|
|
7
|
+
// src/lifecycle/permissionVerifier.ts
|
|
8
|
+
function verifyPermissionLease(options) {
|
|
9
|
+
options.lease.assert(options.permission);
|
|
10
|
+
if (options.binding) options.lease.assertBinding(options.binding);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// src/lifecycle/scopedRegistry.ts
|
|
14
|
+
function definitionId(value) {
|
|
15
|
+
if (!value || typeof value !== "object") return void 0;
|
|
16
|
+
const id = value.id;
|
|
17
|
+
return typeof id === "string" && id.length > 0 ? id : void 0;
|
|
18
|
+
}
|
|
19
|
+
function defaultRegistrationRules() {
|
|
20
|
+
return [{ method: "register", idArgument: 0, unregisterMethod: "unregister" }];
|
|
21
|
+
}
|
|
22
|
+
function createScopedRegistryFacade(target, scope, options) {
|
|
23
|
+
const rules = options.registrations ?? defaultRegistrationRules();
|
|
24
|
+
const byMethod = new Map(rules.map((rule) => [rule.method, rule]));
|
|
25
|
+
const unregisterMethods = new Set(
|
|
26
|
+
rules.map((rule) => rule.unregisterMethod).filter((method) => Boolean(method))
|
|
27
|
+
);
|
|
28
|
+
const ownedRegistrations = /* @__PURE__ */ new Set();
|
|
29
|
+
const objectTarget = target;
|
|
30
|
+
const remember = (rule, id, result, args) => {
|
|
31
|
+
const unregisterMethod = rule.unregisterMethod;
|
|
32
|
+
if (typeof result !== "function" && (!unregisterMethod || id === void 0)) return result;
|
|
33
|
+
const key = rule.method + ":" + (id ?? "returned");
|
|
34
|
+
let active = true;
|
|
35
|
+
let removeScopeRevoke = () => void 0;
|
|
36
|
+
let removeScopeCleanup = () => void 0;
|
|
37
|
+
const entry = {};
|
|
38
|
+
const clearOwnership = (removeDispose = true) => {
|
|
39
|
+
if (!active) return false;
|
|
40
|
+
active = false;
|
|
41
|
+
ownedRegistrations.delete(entry);
|
|
42
|
+
removeScopeRevoke();
|
|
43
|
+
if (removeDispose) removeScopeCleanup();
|
|
44
|
+
return true;
|
|
45
|
+
};
|
|
46
|
+
const invokeUnregister = (...offArgs) => {
|
|
47
|
+
if (typeof result === "function") {
|
|
48
|
+
return result.apply(target, offArgs);
|
|
49
|
+
}
|
|
50
|
+
const unregister = objectTarget[unregisterMethod];
|
|
51
|
+
if (typeof unregister !== "function") return void 0;
|
|
52
|
+
const unregisterArgument = rule.unregisterArgument ?? rule.idArgument ?? 0;
|
|
53
|
+
const unregisterArgs = [...args];
|
|
54
|
+
unregisterArgs[unregisterArgument] = id;
|
|
55
|
+
return unregister.apply(target, unregisterArgs);
|
|
56
|
+
};
|
|
57
|
+
const cleanup = async (_reason) => {
|
|
58
|
+
if (!active) {
|
|
59
|
+
if (entry.revokedCleanup) await entry.revokedCleanup;
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (!clearOwnership()) return;
|
|
63
|
+
await invokeUnregister();
|
|
64
|
+
};
|
|
65
|
+
const revokeNow = (_reason) => {
|
|
66
|
+
if (!clearOwnership(false)) return;
|
|
67
|
+
try {
|
|
68
|
+
const pending = invokeUnregister();
|
|
69
|
+
if (pending && typeof pending.then === "function") {
|
|
70
|
+
const revokedCleanup = Promise.resolve(pending).then(() => void 0);
|
|
71
|
+
entry.revokedCleanup = revokedCleanup;
|
|
72
|
+
revokedCleanup.catch(() => void 0);
|
|
73
|
+
}
|
|
74
|
+
} catch (error) {
|
|
75
|
+
entry.revokedCleanup = Promise.reject(error);
|
|
76
|
+
entry.revokedCleanup.catch(() => void 0);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
entry.id = id;
|
|
80
|
+
entry.unregisterMethod = unregisterMethod;
|
|
81
|
+
entry.revokeNow = revokeNow;
|
|
82
|
+
Object.defineProperty(entry, "active", {
|
|
83
|
+
enumerable: true,
|
|
84
|
+
configurable: false,
|
|
85
|
+
get: () => active,
|
|
86
|
+
set: (value) => {
|
|
87
|
+
active = value;
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
entry.removeScopeCleanup = removeScopeCleanup;
|
|
91
|
+
ownedRegistrations.add(entry);
|
|
92
|
+
removeScopeCleanup = scope.onDispose(
|
|
93
|
+
cleanup,
|
|
94
|
+
options.name + ":" + key,
|
|
95
|
+
"after-teardown"
|
|
96
|
+
);
|
|
97
|
+
entry.removeScopeCleanup = removeScopeCleanup;
|
|
98
|
+
removeScopeRevoke = scope.onRevoke(revokeNow);
|
|
99
|
+
if (typeof result === "function") {
|
|
100
|
+
return (...offArgs) => {
|
|
101
|
+
if (!clearOwnership()) return void 0;
|
|
102
|
+
return result.apply(target, offArgs);
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
return result;
|
|
106
|
+
};
|
|
107
|
+
return new Proxy(target, {
|
|
108
|
+
get(current, property, receiver) {
|
|
109
|
+
const value = Reflect.get(current, property, receiver);
|
|
110
|
+
if (typeof value !== "function") return value;
|
|
111
|
+
const rule = typeof property === "string" ? byMethod.get(property) : void 0;
|
|
112
|
+
if (rule) {
|
|
113
|
+
return (...args) => {
|
|
114
|
+
scope.assertActive();
|
|
115
|
+
const callArgs = [...args];
|
|
116
|
+
if (rule.bindPluginIdArgument !== void 0 && scope.identity.pluginId) {
|
|
117
|
+
const claimedPluginId = callArgs[rule.bindPluginIdArgument];
|
|
118
|
+
if (claimedPluginId !== void 0 && claimedPluginId !== scope.identity.pluginId) {
|
|
119
|
+
throw new Error(
|
|
120
|
+
'Registry owner "' + String(claimedPluginId) + '" does not match plugin instance "' + scope.identity.pluginId + '"'
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
callArgs[rule.bindPluginIdArgument] = scope.identity.pluginId;
|
|
124
|
+
}
|
|
125
|
+
if (rule.ownerPluginIdProperty && scope.identity.pluginId) {
|
|
126
|
+
const definition = callArgs[rule.idArgument ?? 0];
|
|
127
|
+
if (definition && typeof definition === "object") {
|
|
128
|
+
const claimedPluginId = definition[rule.ownerPluginIdProperty];
|
|
129
|
+
if (claimedPluginId !== void 0 && claimedPluginId !== scope.identity.pluginId) {
|
|
130
|
+
throw new Error(
|
|
131
|
+
'Registry owner "' + String(claimedPluginId) + '" does not match plugin instance "' + scope.identity.pluginId + '"'
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const result = value.apply(target, callArgs);
|
|
137
|
+
const id = rule.idArgument === void 0 ? void 0 : definitionId(callArgs[rule.idArgument]);
|
|
138
|
+
return remember(rule, id, result, callArgs);
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
if (typeof property === "string" && unregisterMethods.has(property)) {
|
|
142
|
+
return (...args) => {
|
|
143
|
+
scope.assertActive();
|
|
144
|
+
const id = definitionId(args[0]) ?? (typeof args[0] === "string" ? args[0] : void 0);
|
|
145
|
+
const owned = [...ownedRegistrations].find(
|
|
146
|
+
(entry) => entry.active && entry.id === id && entry.unregisterMethod === property
|
|
147
|
+
);
|
|
148
|
+
if (!owned) {
|
|
149
|
+
throw new Error(
|
|
150
|
+
'Registry resource "' + (id ?? "unknown") + '" is not owned by this plugin instance'
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
const result = value.apply(target, args);
|
|
154
|
+
owned.active = false;
|
|
155
|
+
ownedRegistrations.delete(owned);
|
|
156
|
+
owned.removeScopeCleanup();
|
|
157
|
+
return result;
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
return value.bind(target);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// src/lifecycle/upgradeGate.ts
|
|
166
|
+
function validGeneration(value) {
|
|
167
|
+
return Number.isSafeInteger(value) && value >= 0;
|
|
168
|
+
}
|
|
169
|
+
function uniqueStrings(values) {
|
|
170
|
+
return [...new Set(values.filter((value) => typeof value === "string" && value.length > 0))];
|
|
171
|
+
}
|
|
172
|
+
function makeSessionId() {
|
|
173
|
+
try {
|
|
174
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
175
|
+
return `upgrade-session:${crypto.randomUUID()}`;
|
|
176
|
+
}
|
|
177
|
+
} catch {
|
|
178
|
+
}
|
|
179
|
+
return `upgrade-session:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;
|
|
180
|
+
}
|
|
181
|
+
function buildIsCompatible(options, buildId) {
|
|
182
|
+
try {
|
|
183
|
+
if (options.isBuildCompatible) return options.isBuildCompatible(buildId);
|
|
184
|
+
} catch {
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
return buildId === options.buildId || options.compatibleBuildIds?.has(buildId) === true;
|
|
188
|
+
}
|
|
189
|
+
function createUpgradeGate(options) {
|
|
190
|
+
if (!options.protocolVersion || !options.buildId || !options.authorityInstanceId) {
|
|
191
|
+
throw new Error("\u5347\u7EA7\u95E8\u7981\u7684 protocolVersion\u3001buildId \u548C authorityInstanceId \u5FC5\u987B\u6709\u6548");
|
|
192
|
+
}
|
|
193
|
+
if (!validGeneration(options.handoverGeneration)) {
|
|
194
|
+
throw new Error("\u5347\u7EA7\u95E8\u7981\u7684 handoverGeneration \u5FC5\u987B\u662F\u975E\u8D1F\u5B89\u5168\u6574\u6570");
|
|
195
|
+
}
|
|
196
|
+
const contractVersions = uniqueStrings(options.supportedContractVersions);
|
|
197
|
+
if (contractVersions.length === 0) {
|
|
198
|
+
throw new Error("\u5347\u7EA7\u95E8\u7981\u81F3\u5C11\u9700\u8981\u4E00\u4E2A supportedContractVersions");
|
|
199
|
+
}
|
|
200
|
+
let currentState = "active";
|
|
201
|
+
let closeReason = "upgrade gate closed";
|
|
202
|
+
const leases = /* @__PURE__ */ new Set();
|
|
203
|
+
const sessions = /* @__PURE__ */ new Set();
|
|
204
|
+
const sessionByObject = /* @__PURE__ */ new WeakMap();
|
|
205
|
+
const emptyWaiters = /* @__PURE__ */ new Set();
|
|
206
|
+
const notifyEmpty = () => {
|
|
207
|
+
if (leases.size !== 0) return;
|
|
208
|
+
for (const resolve of [...emptyWaiters]) {
|
|
209
|
+
emptyWaiters.delete(resolve);
|
|
210
|
+
resolve();
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
const removeLease = (record) => {
|
|
214
|
+
if (!leases.delete(record)) return;
|
|
215
|
+
record.session.leases.delete(record);
|
|
216
|
+
record.removeExternalAbort?.();
|
|
217
|
+
record.removeExternalAbort = void 0;
|
|
218
|
+
notifyEmpty();
|
|
219
|
+
};
|
|
220
|
+
const revokeSession = (record, reason) => {
|
|
221
|
+
if (record.revoked) return;
|
|
222
|
+
record.revoked = true;
|
|
223
|
+
record.reason = reason;
|
|
224
|
+
try {
|
|
225
|
+
record.controller.abort(new UpgradeGateRejectedError(reason));
|
|
226
|
+
} catch {
|
|
227
|
+
record.controller.abort();
|
|
228
|
+
}
|
|
229
|
+
for (const lease of [...record.leases]) revokeLease(lease, reason);
|
|
230
|
+
sessions.delete(record);
|
|
231
|
+
};
|
|
232
|
+
const revokeLease = (record, reason) => {
|
|
233
|
+
if (record.revoked) return;
|
|
234
|
+
record.revoked = true;
|
|
235
|
+
record.reason = reason;
|
|
236
|
+
try {
|
|
237
|
+
record.controller.abort(new UpgradeGateRejectedError(reason));
|
|
238
|
+
} catch {
|
|
239
|
+
record.controller.abort();
|
|
240
|
+
}
|
|
241
|
+
removeLease(record);
|
|
242
|
+
};
|
|
243
|
+
const assertAccepting = () => {
|
|
244
|
+
if (currentState === "active") return;
|
|
245
|
+
throw new UpgradeGateRejectedError(currentState === "draining" ? "draining" : "closed", closeReason);
|
|
246
|
+
};
|
|
247
|
+
const handshake = (input) => {
|
|
248
|
+
if (currentState !== "active") {
|
|
249
|
+
return { accepted: false, reason: currentState === "draining" ? "draining" : "closed" };
|
|
250
|
+
}
|
|
251
|
+
if (typeof input.connectionId !== "string" || input.connectionId.length === 0 || input.protocolVersion !== options.protocolVersion || typeof input.protocolVersion !== "string" || typeof input.buildId !== "string" || typeof input.authorityInstanceId !== "string" || input.authorityInstanceId.length === 0) {
|
|
252
|
+
return { accepted: false, reason: "protocol-mismatch" };
|
|
253
|
+
}
|
|
254
|
+
if (!buildIsCompatible(options, input.buildId)) {
|
|
255
|
+
return { accepted: false, reason: "build-incompatible" };
|
|
256
|
+
}
|
|
257
|
+
if (!validGeneration(input.handoverGeneration)) {
|
|
258
|
+
return { accepted: false, reason: "stale-generation" };
|
|
259
|
+
}
|
|
260
|
+
if (input.handoverGeneration < options.handoverGeneration) {
|
|
261
|
+
return { accepted: false, reason: "stale-generation" };
|
|
262
|
+
}
|
|
263
|
+
if (input.handoverGeneration > options.handoverGeneration) {
|
|
264
|
+
return { accepted: false, reason: "future-generation" };
|
|
265
|
+
}
|
|
266
|
+
const contractVersion = contractVersions.find((version) => input.supportedContractVersions.includes(version));
|
|
267
|
+
if (!contractVersion) return { accepted: false, reason: "contract-mismatch" };
|
|
268
|
+
const sessionRecord = {
|
|
269
|
+
sessionId: makeSessionId(),
|
|
270
|
+
connectionId: input.connectionId,
|
|
271
|
+
contractVersion,
|
|
272
|
+
controller: new AbortController(),
|
|
273
|
+
revoked: false,
|
|
274
|
+
reason: "upgrade session closed",
|
|
275
|
+
leases: /* @__PURE__ */ new Set()
|
|
276
|
+
};
|
|
277
|
+
const session = {
|
|
278
|
+
connectionId: sessionRecord.connectionId,
|
|
279
|
+
sessionId: sessionRecord.sessionId,
|
|
280
|
+
authorityInstanceId: options.authorityInstanceId,
|
|
281
|
+
handoverGeneration: options.handoverGeneration,
|
|
282
|
+
contractVersion,
|
|
283
|
+
get revoked() {
|
|
284
|
+
return sessionRecord.revoked || !sessions.has(sessionRecord);
|
|
285
|
+
},
|
|
286
|
+
signal: sessionRecord.controller.signal,
|
|
287
|
+
assertActive() {
|
|
288
|
+
if (sessionRecord.revoked || !sessions.has(sessionRecord)) {
|
|
289
|
+
throw new UpgradeGateRejectedError(sessionRecord.reason, "\u5347\u7EA7\u63E1\u624B\u4F1A\u8BDD\u5DF2\u5931\u6548");
|
|
290
|
+
}
|
|
291
|
+
if (currentState === "closed") {
|
|
292
|
+
throw new UpgradeGateRejectedError("closed", closeReason);
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
admit(input2) {
|
|
296
|
+
return admitForSession(sessionRecord, input2);
|
|
297
|
+
},
|
|
298
|
+
close(reason = "upgrade session closed") {
|
|
299
|
+
revokeSession(sessionRecord, reason);
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
sessionRecord.session = session;
|
|
303
|
+
sessions.add(sessionRecord);
|
|
304
|
+
sessionByObject.set(session, sessionRecord);
|
|
305
|
+
return {
|
|
306
|
+
accepted: true,
|
|
307
|
+
mode: options.mode ?? "cold-switch",
|
|
308
|
+
handoverGeneration: options.handoverGeneration,
|
|
309
|
+
contractVersion,
|
|
310
|
+
connectionId: sessionRecord.connectionId,
|
|
311
|
+
sessionId: sessionRecord.sessionId,
|
|
312
|
+
session
|
|
313
|
+
};
|
|
314
|
+
};
|
|
315
|
+
const admitForSession = (sessionRecord, input) => {
|
|
316
|
+
if (sessionRecord.revoked || !sessions.has(sessionRecord)) {
|
|
317
|
+
throw new UpgradeGateRejectedError(sessionRecord.reason, "\u5347\u7EA7\u63E1\u624B\u4F1A\u8BDD\u5DF2\u5931\u6548");
|
|
318
|
+
}
|
|
319
|
+
assertAccepting();
|
|
320
|
+
if (input.signal?.aborted) {
|
|
321
|
+
throw new UpgradeGateRejectedError("caller-aborted", "I/O \u5728\u53D6\u5F97\u63A5\u7BA1\u79DF\u7EA6\u524D\u5DF2\u53D6\u6D88");
|
|
322
|
+
}
|
|
323
|
+
const record = {
|
|
324
|
+
session: sessionRecord,
|
|
325
|
+
operation: input.operation,
|
|
326
|
+
controller: new AbortController(),
|
|
327
|
+
revoked: false,
|
|
328
|
+
reason: "upgrade I/O lease released"
|
|
329
|
+
};
|
|
330
|
+
leases.add(record);
|
|
331
|
+
sessionRecord.leases.add(record);
|
|
332
|
+
if (input.signal) {
|
|
333
|
+
const onAbort = () => revokeLease(record, "caller-aborted");
|
|
334
|
+
input.signal.addEventListener("abort", onAbort, { once: true });
|
|
335
|
+
record.removeExternalAbort = () => input.signal?.removeEventListener("abort", onAbort);
|
|
336
|
+
}
|
|
337
|
+
const lease = {
|
|
338
|
+
connectionId: sessionRecord.connectionId,
|
|
339
|
+
sessionId: sessionRecord.sessionId,
|
|
340
|
+
authorityInstanceId: options.authorityInstanceId,
|
|
341
|
+
handoverGeneration: options.handoverGeneration,
|
|
342
|
+
contractVersion: sessionRecord.contractVersion,
|
|
343
|
+
operation: record.operation,
|
|
344
|
+
get revoked() {
|
|
345
|
+
return record.revoked || !leases.has(record);
|
|
346
|
+
},
|
|
347
|
+
signal: record.controller.signal,
|
|
348
|
+
assertActive() {
|
|
349
|
+
if (record.revoked || !leases.has(record)) {
|
|
350
|
+
throw new UpgradeGateRejectedError(record.reason, "\u5347\u7EA7 I/O \u79DF\u7EA6\u5DF2\u5931\u6548");
|
|
351
|
+
}
|
|
352
|
+
if (currentState === "closed") {
|
|
353
|
+
throw new UpgradeGateRejectedError("closed", closeReason);
|
|
354
|
+
}
|
|
355
|
+
},
|
|
356
|
+
release() {
|
|
357
|
+
if (record.revoked) return;
|
|
358
|
+
record.revoked = true;
|
|
359
|
+
record.reason = "upgrade I/O lease released";
|
|
360
|
+
removeLease(record);
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
return lease;
|
|
364
|
+
};
|
|
365
|
+
const admit = (input) => {
|
|
366
|
+
const sessionRecord = sessionByObject.get(input.session);
|
|
367
|
+
if (!sessionRecord) {
|
|
368
|
+
throw new UpgradeGateRejectedError("invalid-session", "I/O \u5FC5\u987B\u4F7F\u7528\u5F53\u524D\u95E8\u7981\u63E1\u624B\u8FD4\u56DE\u7684\u4F1A\u8BDD");
|
|
369
|
+
}
|
|
370
|
+
return admitForSession(sessionRecord, input);
|
|
371
|
+
};
|
|
372
|
+
const beginDrain = (reason = "upgrade handover draining") => {
|
|
373
|
+
if (currentState !== "active") return;
|
|
374
|
+
closeReason = reason;
|
|
375
|
+
currentState = "draining";
|
|
376
|
+
};
|
|
377
|
+
const drain = async (timeoutMs) => {
|
|
378
|
+
beginDrain();
|
|
379
|
+
if (leases.size === 0) return { state: currentState, drained: true, pending: 0 };
|
|
380
|
+
if (timeoutMs !== void 0 && (!Number.isFinite(timeoutMs) || timeoutMs < 0)) {
|
|
381
|
+
throw new Error("\u5347\u7EA7\u6392\u7A7A timeoutMs \u5FC5\u987B\u662F\u975E\u8D1F\u6709\u9650\u6570");
|
|
382
|
+
}
|
|
383
|
+
let timeout;
|
|
384
|
+
let timerResolve;
|
|
385
|
+
const empty = new Promise((resolve) => {
|
|
386
|
+
emptyWaiters.add(resolve);
|
|
387
|
+
timerResolve = resolve;
|
|
388
|
+
});
|
|
389
|
+
const timeoutPromise = timeoutMs === void 0 ? void 0 : new Promise((resolve) => {
|
|
390
|
+
timeout = setTimeout(resolve, timeoutMs);
|
|
391
|
+
});
|
|
392
|
+
if (timeoutPromise) await Promise.race([empty, timeoutPromise]);
|
|
393
|
+
else await empty;
|
|
394
|
+
if (timeout !== void 0) clearTimeout(timeout);
|
|
395
|
+
if (timerResolve) emptyWaiters.delete(timerResolve);
|
|
396
|
+
const pending = leases.size;
|
|
397
|
+
return { state: currentState, drained: pending === 0, pending };
|
|
398
|
+
};
|
|
399
|
+
const close = (reason = "upgrade gate closed") => {
|
|
400
|
+
if (currentState === "closed") return;
|
|
401
|
+
closeReason = reason;
|
|
402
|
+
currentState = "closed";
|
|
403
|
+
for (const session of [...sessions]) revokeSession(session, reason);
|
|
404
|
+
for (const lease of [...leases]) revokeLease(lease, reason);
|
|
405
|
+
notifyEmpty();
|
|
406
|
+
};
|
|
407
|
+
return {
|
|
408
|
+
get state() {
|
|
409
|
+
return currentState;
|
|
410
|
+
},
|
|
411
|
+
mode: options.mode ?? "cold-switch",
|
|
412
|
+
authorityInstanceId: options.authorityInstanceId,
|
|
413
|
+
handoverGeneration: options.handoverGeneration,
|
|
414
|
+
handshake,
|
|
415
|
+
assertAccepting,
|
|
416
|
+
admit,
|
|
417
|
+
beginDrain,
|
|
418
|
+
drain,
|
|
419
|
+
close,
|
|
420
|
+
activeIo: () => leases.size
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// src/advanced.ts
|
|
425
|
+
async function registerPlugins(app, definitions) {
|
|
426
|
+
const host = hostForWindowApp(app);
|
|
427
|
+
const materialized = materializePluginDefinitions(definitions, app.runtimeKind);
|
|
428
|
+
for (const definition of materialized) host.registerImplementation({ pluginId: definition.manifest.id, unitId: definition.unitId, setup: definition.setup, capabilities: definition.capabilities });
|
|
429
|
+
await host.registerAll(materialized.map((definition) => definition.manifest));
|
|
430
|
+
}
|
|
431
|
+
async function attachRemote(app, runtime) {
|
|
432
|
+
const host = hostForWindowApp(app);
|
|
433
|
+
const bridge = bridgeForRuntimeHandle(runtime);
|
|
434
|
+
host.attachRemote(bridge);
|
|
435
|
+
await host.reconcile();
|
|
436
|
+
return () => host.detachRemote("Remote Runtime detached");
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
export { attachRemote, createScopedRegistryFacade, createUpgradeGate, registerPlugins, verifyPermissionLease };
|
|
440
|
+
//# sourceMappingURL=advanced.js.map
|
|
441
|
+
//# sourceMappingURL=advanced.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lifecycle/permissionVerifier.ts","../src/lifecycle/scopedRegistry.ts","../src/lifecycle/upgradeGate.ts","../src/advanced.ts"],"names":["input"],"mappings":";;;;;;;AAmBO,SAAS,sBAAsB,OAAA,EAA6C;AACjF,EAAA,OAAA,CAAQ,KAAA,CAAM,MAAA,CAAO,OAAA,CAAQ,UAAU,CAAA;AACvC,EAAA,IAAI,QAAQ,OAAA,EAAS,OAAA,CAAQ,KAAA,CAAM,aAAA,CAAc,QAAQ,OAAO,CAAA;AAClE;;;ACWA,SAAS,aAAa,KAAA,EAAoC;AACxD,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,UAAU,OAAO,MAAA;AAChD,EAAA,MAAM,KAAM,KAAA,CAA2B,EAAA;AACvC,EAAA,OAAO,OAAO,EAAA,KAAO,QAAA,IAAY,EAAA,CAAG,MAAA,GAAS,IAAI,EAAA,GAAK,MAAA;AACxD;AAEA,SAAS,wBAAA,GAAyD;AAChE,EAAA,OAAO,CAAC,EAAE,MAAA,EAAQ,UAAA,EAAY,YAAY,CAAA,EAAG,gBAAA,EAAkB,cAAc,CAAA;AAC/E;AAGO,SAAS,0BAAA,CACd,MAAA,EACA,KAAA,EACA,OAAA,EACG;AACH,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,aAAA,IAAiB,wBAAA,EAAyB;AAChE,EAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,KAAS,CAAC,IAAA,CAAK,MAAA,EAAQ,IAAI,CAAC,CAAC,CAAA;AACjE,EAAA,MAAM,oBAAoB,IAAI,GAAA;AAAA,IAC5B,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,KAAS,IAAA,CAAK,gBAAgB,CAAA,CAAE,MAAA,CAAO,CAAC,MAAA,KAA6B,OAAA,CAAQ,MAAM,CAAC;AAAA,GACjG;AAWA,EAAA,MAAM,kBAAA,uBAAyB,GAAA,EAAuB;AACtD,EAAA,MAAM,YAAA,GAAe,MAAA;AAErB,EAAA,MAAM,QAAA,GAAW,CACf,IAAA,EACA,EAAA,EACA,QACA,IAAA,KACY;AACZ,IAAA,MAAM,mBAAmB,IAAA,CAAK,gBAAA;AAC9B,IAAA,IAAI,OAAO,MAAA,KAAW,UAAA,KAAe,CAAC,gBAAA,IAAoB,EAAA,KAAO,SAAY,OAAO,MAAA;AACpF,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,MAAA,GAAS,GAAA,IAAO,EAAA,IAAM,UAAA,CAAA;AACvC,IAAA,IAAI,MAAA,GAAS,IAAA;AACb,IAAA,IAAI,oBAAgC,MAAM,MAAA;AAC1C,IAAA,IAAI,qBAAiC,MAAM,MAAA;AAC3C,IAAA,MAAM,QAAQ,EAAC;AACf,IAAA,MAAM,cAAA,GAAiB,CAAC,aAAA,GAAgB,IAAA,KAAkB;AACxD,MAAA,IAAI,CAAC,QAAQ,OAAO,KAAA;AACpB,MAAA,MAAA,GAAS,KAAA;AACT,MAAA,kBAAA,CAAmB,OAAO,KAAK,CAAA;AAC/B,MAAA,iBAAA,EAAkB;AAClB,MAAA,IAAI,eAAe,kBAAA,EAAmB;AACtC,MAAA,OAAO,IAAA;AAAA,IACT,CAAA;AACA,IAAA,MAAM,gBAAA,GAAmB,IAAI,OAAA,KAAgC;AAC3D,MAAA,IAAI,OAAO,WAAW,UAAA,EAAY;AAChC,QAAA,OAAQ,MAAA,CAAuB,KAAA,CAAM,MAAA,EAAQ,OAAO,CAAA;AAAA,MACtD;AACA,MAAA,MAAM,UAAA,GAAa,aAAa,gBAAiB,CAAA;AACjD,MAAA,IAAI,OAAO,UAAA,KAAe,UAAA,EAAY,OAAO,MAAA;AAC7C,MAAA,MAAM,kBAAA,GAAqB,IAAA,CAAK,kBAAA,IAAsB,IAAA,CAAK,UAAA,IAAc,CAAA;AACzE,MAAA,MAAM,cAAA,GAAiB,CAAC,GAAG,IAAI,CAAA;AAC/B,MAAA,cAAA,CAAe,kBAAkB,CAAA,GAAI,EAAA;AACrC,MAAA,OAAO,UAAA,CAAW,KAAA,CAAM,MAAA,EAAQ,cAAc,CAAA;AAAA,IAChD,CAAA;AACA,IAAA,MAAM,OAAA,GAAU,OAAO,OAAA,KAAmC;AACxD,MAAA,IAAI,CAAC,MAAA,EAAQ;AACX,QAAA,IAAI,KAAA,CAAM,cAAA,EAAgB,MAAM,KAAA,CAAM,cAAA;AACtC,QAAA;AAAA,MACF;AACA,MAAA,IAAI,CAAC,gBAAe,EAAG;AACvB,MAAA,MAAM,gBAAA,EAAiB;AAAA,IACzB,CAAA;AACA,IAAA,MAAM,SAAA,GAAY,CAAC,OAAA,KAA0B;AAC3C,MAAA,IAAI,CAAC,cAAA,CAAe,KAAK,CAAA,EAAG;AAC5B,MAAA,IAAI;AACF,QAAA,MAAM,UAAU,gBAAA,EAAiB;AACjC,QAAA,IAAI,OAAA,IAAW,OAAQ,OAAA,CAAiC,IAAA,KAAS,UAAA,EAAY;AAC3E,UAAA,MAAM,iBAAiB,OAAA,CAAQ,OAAA,CAAQ,OAAO,CAAA,CAAE,IAAA,CAAK,MAAM,KAAA,CAAS,CAAA;AACpE,UAAA,KAAA,CAAM,cAAA,GAAiB,cAAA;AACvB,UAAA,cAAA,CAAe,KAAA,CAAM,MAAM,KAAA,CAAS,CAAA;AAAA,QACtC;AAAA,MACF,SAAS,KAAA,EAAO;AAGd,QAAA,KAAA,CAAM,cAAA,GAAiB,OAAA,CAAQ,MAAA,CAAO,KAAK,CAAA;AAC3C,QAAA,KAAA,CAAM,cAAA,CAAe,KAAA,CAAM,MAAM,MAAS,CAAA;AAAA,MAC5C;AAAA,IACF,CAAA;AACA,IAAA,KAAA,CAAM,EAAA,GAAK,EAAA;AACX,IAAA,KAAA,CAAM,gBAAA,GAAmB,gBAAA;AACzB,IAAA,KAAA,CAAM,SAAA,GAAY,SAAA;AAClB,IAAA,MAAA,CAAO,cAAA,CAAe,OAAO,QAAA,EAAU;AAAA,MACrC,UAAA,EAAY,IAAA;AAAA,MACZ,YAAA,EAAc,KAAA;AAAA,MACd,KAAK,MAAM,MAAA;AAAA,MACX,GAAA,EAAK,CAAC,KAAA,KAAmB;AAAE,QAAA,MAAA,GAAS,KAAA;AAAA,MAAO;AAAA,KAC5C,CAAA;AACD,IAAA,KAAA,CAAM,kBAAA,GAAqB,kBAAA;AAC3B,IAAA,kBAAA,CAAmB,IAAI,KAAK,CAAA;AAC5B,IAAA,kBAAA,GAAqB,KAAA,CAAM,SAAA;AAAA,MACzB,OAAA;AAAA,MACA,OAAA,CAAQ,OAAO,GAAA,GAAM,GAAA;AAAA,MACrB;AAAA,KACF;AACA,IAAA,KAAA,CAAM,kBAAA,GAAqB,kBAAA;AAC3B,IAAA,iBAAA,GAAoB,KAAA,CAAM,SAAS,SAAS,CAAA;AAE5C,IAAA,IAAI,OAAO,WAAW,UAAA,EAAY;AAChC,MAAA,OAAO,IAAI,OAAA,KAAuB;AAChC,QAAA,IAAI,CAAC,cAAA,EAAe,EAAG,OAAO,MAAA;AAC9B,QAAA,OAAQ,MAAA,CAAuB,KAAA,CAAM,MAAA,EAAQ,OAAO,CAAA;AAAA,MACtD,CAAA;AAAA,IACF;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA;AAEA,EAAA,OAAO,IAAI,MAAM,MAAA,EAAQ;AAAA,IACvB,GAAA,CAAI,OAAA,EAAS,QAAA,EAAU,QAAA,EAAU;AAC/B,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,GAAA,CAAI,OAAA,EAAS,UAAU,QAAQ,CAAA;AACrD,MAAA,IAAI,OAAO,KAAA,KAAU,UAAA,EAAY,OAAO,KAAA;AACxC,MAAA,MAAM,OAAO,OAAO,QAAA,KAAa,WAAW,QAAA,CAAS,GAAA,CAAI,QAAQ,CAAA,GAAI,MAAA;AACrE,MAAA,IAAI,IAAA,EAAM;AACR,QAAA,OAAO,IAAI,IAAA,KAAoB;AAC7B,UAAA,KAAA,CAAM,YAAA,EAAa;AACnB,UAAA,MAAM,QAAA,GAAW,CAAC,GAAG,IAAI,CAAA;AACzB,UAAA,IAAI,IAAA,CAAK,oBAAA,KAAyB,MAAA,IAAa,KAAA,CAAM,SAAS,QAAA,EAAU;AACtE,YAAA,MAAM,eAAA,GAAkB,QAAA,CAAS,IAAA,CAAK,oBAAoB,CAAA;AAC1D,YAAA,IAAI,eAAA,KAAoB,MAAA,IAAa,eAAA,KAAoB,KAAA,CAAM,SAAS,QAAA,EAAU;AAChF,cAAA,MAAM,IAAI,KAAA;AAAA,gBACR,qBAAsB,MAAA,CAAO,eAAe,IAC5C,oCAAA,GAAyC,KAAA,CAAM,SAAS,QAAA,GAAW;AAAA,eACrE;AAAA,YACF;AACA,YAAA,QAAA,CAAS,IAAA,CAAK,oBAAoB,CAAA,GAAI,KAAA,CAAM,QAAA,CAAS,QAAA;AAAA,UACvD;AACA,UAAA,IAAI,IAAA,CAAK,qBAAA,IAAyB,KAAA,CAAM,QAAA,CAAS,QAAA,EAAU;AACzD,YAAA,MAAM,UAAA,GAAa,QAAA,CAAS,IAAA,CAAK,UAAA,IAAc,CAAC,CAAA;AAChD,YAAA,IAAI,UAAA,IAAc,OAAO,UAAA,KAAe,QAAA,EAAU;AAChD,cAAA,MAAM,eAAA,GAAmB,UAAA,CAAuC,IAAA,CAAK,qBAAqB,CAAA;AAC1F,cAAA,IAAI,eAAA,KAAoB,MAAA,IAAa,eAAA,KAAoB,KAAA,CAAM,SAAS,QAAA,EAAU;AAChF,gBAAA,MAAM,IAAI,KAAA;AAAA,kBACR,qBAAsB,MAAA,CAAO,eAAe,IAC5C,oCAAA,GAAyC,KAAA,CAAM,SAAS,QAAA,GAAW;AAAA,iBACrE;AAAA,cACF;AAAA,YACF;AAAA,UACF;AACA,UAAA,MAAM,MAAA,GAAU,KAAA,CAAsB,KAAA,CAAM,MAAA,EAAQ,QAAQ,CAAA;AAC5D,UAAA,MAAM,EAAA,GAAK,KAAK,UAAA,KAAe,MAAA,GAAY,SAAY,YAAA,CAAa,QAAA,CAAS,IAAA,CAAK,UAAU,CAAC,CAAA;AAC7F,UAAA,OAAO,QAAA,CAAS,IAAA,EAAM,EAAA,EAAI,MAAA,EAAQ,QAAQ,CAAA;AAAA,QAC5C,CAAA;AAAA,MACF;AAIA,MAAA,IAAI,OAAO,QAAA,KAAa,QAAA,IAAY,iBAAA,CAAkB,GAAA,CAAI,QAAQ,CAAA,EAAG;AACnE,QAAA,OAAO,IAAI,IAAA,KAAoB;AAC7B,UAAA,KAAA,CAAM,YAAA,EAAa;AACnB,UAAA,MAAM,EAAA,GAAK,YAAA,CAAa,IAAA,CAAK,CAAC,CAAC,CAAA,KAAM,OAAO,IAAA,CAAK,CAAC,CAAA,KAAM,QAAA,GAAW,IAAA,CAAK,CAAC,CAAA,GAAI,MAAA,CAAA;AAC7E,UAAA,MAAM,KAAA,GAAQ,CAAC,GAAG,kBAAkB,CAAA,CAAE,IAAA;AAAA,YAAK,CAAC,UAC1C,KAAA,CAAM,MAAA,IAAU,MAAM,EAAA,KAAO,EAAA,IAAM,MAAM,gBAAA,KAAqB;AAAA,WAChE;AACA,UAAA,IAAI,CAAC,KAAA,EAAO;AACV,YAAA,MAAM,IAAI,KAAA;AAAA,cACR,qBAAA,IAA0B,MAAM,SAAA,CAAA,GAAa;AAAA,aAC/C;AAAA,UACF;AACA,UAAA,MAAM,MAAA,GAAU,KAAA,CAAsB,KAAA,CAAM,MAAA,EAAQ,IAAI,CAAA;AACxD,UAAA,KAAA,CAAM,MAAA,GAAS,KAAA;AACf,UAAA,kBAAA,CAAmB,OAAO,KAAK,CAAA;AAC/B,UAAA,KAAA,CAAM,kBAAA,EAAmB;AACzB,UAAA,OAAO,MAAA;AAAA,QACT,CAAA;AAAA,MACF;AACA,MAAA,OAAQ,KAAA,CAAsB,KAAK,MAAM,CAAA;AAAA,IAC3C;AAAA,GACD,CAAA;AACH;;;ACzKA,SAAS,gBAAgB,KAAA,EAAwB;AAC/C,EAAA,OAAO,MAAA,CAAO,aAAA,CAAc,KAAK,CAAA,IAAK,KAAA,IAAS,CAAA;AACjD;AAEA,SAAS,cAAc,MAAA,EAAqC;AAC1D,EAAA,OAAO,CAAC,GAAG,IAAI,GAAA,CAAI,OAAO,MAAA,CAAO,CAAC,KAAA,KAAU,OAAO,UAAU,QAAA,IAAY,KAAA,CAAM,MAAA,GAAS,CAAC,CAAC,CAAC,CAAA;AAC7F;AAEA,SAAS,aAAA,GAAwB;AAC/B,EAAA,IAAI;AACF,IAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,OAAO,MAAA,CAAO,eAAe,UAAA,EAAY;AAC5E,MAAA,OAAO,CAAA,gBAAA,EAAmB,MAAA,CAAO,UAAA,EAAY,CAAA,CAAA;AAAA,IAC/C;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,mBAAmB,IAAA,CAAK,GAAA,EAAI,CAAE,QAAA,CAAS,EAAE,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,MAAA,GAAS,QAAA,CAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAC1F;AAEA,SAAS,iBAAA,CAAkB,SAAmC,OAAA,EAA0B;AACtF,EAAA,IAAI;AACF,IAAA,IAAI,OAAA,CAAQ,iBAAA,EAAmB,OAAO,OAAA,CAAQ,kBAAkB,OAAO,CAAA;AAAA,EACzE,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAO,YAAY,OAAA,CAAQ,OAAA,IAAW,QAAQ,kBAAA,EAAoB,GAAA,CAAI,OAAO,CAAA,KAAM,IAAA;AACrF;AAGO,SAAS,kBAAkB,OAAA,EAAgD;AAChF,EAAA,IAAI,CAAC,QAAQ,eAAA,IAAmB,CAAC,QAAQ,OAAA,IAAW,CAAC,QAAQ,mBAAA,EAAqB;AAChF,IAAA,MAAM,IAAI,MAAM,iHAA0D,CAAA;AAAA,EAC5E;AACA,EAAA,IAAI,CAAC,eAAA,CAAgB,OAAA,CAAQ,kBAAkB,CAAA,EAAG;AAChD,IAAA,MAAM,IAAI,MAAM,0GAAoC,CAAA;AAAA,EACtD;AACA,EAAA,MAAM,gBAAA,GAAmB,aAAA,CAAc,OAAA,CAAQ,yBAAyB,CAAA;AACxE,EAAA,IAAI,gBAAA,CAAiB,WAAW,CAAA,EAAG;AACjC,IAAA,MAAM,IAAI,MAAM,wFAAsC,CAAA;AAAA,EACxD;AAEA,EAAA,IAAI,YAAA,GAAiC,QAAA;AACrC,EAAA,IAAI,WAAA,GAAc,qBAAA;AAClB,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAiB;AACpC,EAAA,MAAM,QAAA,uBAAe,GAAA,EAAmB;AACxC,EAAA,MAAM,eAAA,uBAAsB,OAAA,EAAuC;AACnE,EAAA,MAAM,YAAA,uBAAmB,GAAA,EAAgB;AAEzC,EAAA,MAAM,cAAc,MAAM;AACxB,IAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AACvB,IAAA,KAAA,MAAW,OAAA,IAAW,CAAC,GAAG,YAAY,CAAA,EAAG;AACvC,MAAA,YAAA,CAAa,OAAO,OAAO,CAAA;AAC3B,MAAA,OAAA,EAAQ;AAAA,IACV;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,WAAA,GAAc,CAAC,MAAA,KAAwB;AAC3C,IAAA,IAAI,CAAC,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA,EAAG;AAC5B,IAAA,MAAA,CAAO,OAAA,CAAQ,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA;AACnC,IAAA,MAAA,CAAO,mBAAA,IAAsB;AAC7B,IAAA,MAAA,CAAO,mBAAA,GAAsB,MAAA;AAC7B,IAAA,WAAA,EAAY;AAAA,EACd,CAAA;AAEA,EAAA,MAAM,aAAA,GAAgB,CAAC,MAAA,EAAuB,MAAA,KAAmB;AAC/D,IAAA,IAAI,OAAO,OAAA,EAAS;AACpB,IAAA,MAAA,CAAO,OAAA,GAAU,IAAA;AACjB,IAAA,MAAA,CAAO,MAAA,GAAS,MAAA;AAChB,IAAA,IAAI;AACF,MAAA,MAAA,CAAO,UAAA,CAAW,KAAA,CAAM,IAAI,wBAAA,CAAyB,MAAM,CAAC,CAAA;AAAA,IAC9D,CAAA,CAAA,MAAQ;AACN,MAAA,MAAA,CAAO,WAAW,KAAA,EAAM;AAAA,IAC1B;AACA,IAAA,KAAA,MAAW,KAAA,IAAS,CAAC,GAAG,MAAA,CAAO,MAAM,CAAA,EAAG,WAAA,CAAY,OAAO,MAAM,CAAA;AACjE,IAAA,QAAA,CAAS,OAAO,MAAM,CAAA;AAAA,EACxB,CAAA;AAEA,EAAA,MAAM,WAAA,GAAc,CAAC,MAAA,EAAqB,MAAA,KAAmB;AAC3D,IAAA,IAAI,OAAO,OAAA,EAAS;AACpB,IAAA,MAAA,CAAO,OAAA,GAAU,IAAA;AACjB,IAAA,MAAA,CAAO,MAAA,GAAS,MAAA;AAChB,IAAA,IAAI;AACF,MAAA,MAAA,CAAO,UAAA,CAAW,KAAA,CAAM,IAAI,wBAAA,CAAyB,MAAM,CAAC,CAAA;AAAA,IAC9D,CAAA,CAAA,MAAQ;AACN,MAAA,MAAA,CAAO,WAAW,KAAA,EAAM;AAAA,IAC1B;AACA,IAAA,WAAA,CAAY,MAAM,CAAA;AAAA,EACpB,CAAA;AAEA,EAAA,MAAM,kBAAkB,MAAM;AAC5B,IAAA,IAAI,iBAAiB,QAAA,EAAU;AAC/B,IAAA,MAAM,IAAI,wBAAA,CAAyB,YAAA,KAAiB,UAAA,GAAa,UAAA,GAAa,UAAU,WAAW,CAAA;AAAA,EACrG,CAAA;AAEA,EAAA,MAAM,SAAA,GAAY,CAAC,KAAA,KAAoD;AACrE,IAAA,IAAI,iBAAiB,QAAA,EAAU;AAC7B,MAAA,OAAO,EAAE,QAAA,EAAU,KAAA,EAAO,QAAQ,YAAA,KAAiB,UAAA,GAAa,aAAa,QAAA,EAAS;AAAA,IACxF;AACA,IAAA,IACE,OAAO,KAAA,CAAM,YAAA,KAAiB,QAAA,IAC3B,KAAA,CAAM,YAAA,CAAa,MAAA,KAAW,CAAA,IAC9B,KAAA,CAAM,eAAA,KAAoB,OAAA,CAAQ,eAAA,IAClC,OAAO,KAAA,CAAM,eAAA,KAAoB,QAAA,IACjC,OAAO,KAAA,CAAM,OAAA,KAAY,QAAA,IACzB,OAAO,KAAA,CAAM,mBAAA,KAAwB,QAAA,IACrC,KAAA,CAAM,mBAAA,CAAoB,MAAA,KAAW,CAAA,EACxC;AACA,MAAA,OAAO,EAAE,QAAA,EAAU,KAAA,EAAO,MAAA,EAAQ,mBAAA,EAAoB;AAAA,IACxD;AACA,IAAA,IAAI,CAAC,iBAAA,CAAkB,OAAA,EAAS,KAAA,CAAM,OAAO,CAAA,EAAG;AAC9C,MAAA,OAAO,EAAE,QAAA,EAAU,KAAA,EAAO,MAAA,EAAQ,oBAAA,EAAqB;AAAA,IACzD;AACA,IAAA,IAAI,CAAC,eAAA,CAAgB,KAAA,CAAM,kBAAkB,CAAA,EAAG;AAC9C,MAAA,OAAO,EAAE,QAAA,EAAU,KAAA,EAAO,MAAA,EAAQ,kBAAA,EAAmB;AAAA,IACvD;AACA,IAAA,IAAI,KAAA,CAAM,kBAAA,GAAqB,OAAA,CAAQ,kBAAA,EAAoB;AACzD,MAAA,OAAO,EAAE,QAAA,EAAU,KAAA,EAAO,MAAA,EAAQ,kBAAA,EAAmB;AAAA,IACvD;AACA,IAAA,IAAI,KAAA,CAAM,kBAAA,GAAqB,OAAA,CAAQ,kBAAA,EAAoB;AACzD,MAAA,OAAO,EAAE,QAAA,EAAU,KAAA,EAAO,MAAA,EAAQ,mBAAA,EAAoB;AAAA,IACxD;AACA,IAAA,MAAM,eAAA,GAAkB,iBAAiB,IAAA,CAAK,CAAC,YAAY,KAAA,CAAM,yBAAA,CAA0B,QAAA,CAAS,OAAO,CAAC,CAAA;AAC5G,IAAA,IAAI,CAAC,eAAA,EAAiB,OAAO,EAAE,QAAA,EAAU,KAAA,EAAO,QAAQ,mBAAA,EAAoB;AAC5E,IAAA,MAAM,aAAA,GAA+B;AAAA,MACnC,WAAW,aAAA,EAAc;AAAA,MACzB,cAAc,KAAA,CAAM,YAAA;AAAA,MACpB,eAAA;AAAA,MACA,UAAA,EAAY,IAAI,eAAA,EAAgB;AAAA,MAChC,OAAA,EAAS,KAAA;AAAA,MACT,MAAA,EAAQ,wBAAA;AAAA,MACR,MAAA,sBAAY,GAAA;AAAI,KAClB;AACA,IAAA,MAAM,OAAA,GAA0B;AAAA,MAC9B,cAAc,aAAA,CAAc,YAAA;AAAA,MAC5B,WAAW,aAAA,CAAc,SAAA;AAAA,MACzB,qBAAqB,OAAA,CAAQ,mBAAA;AAAA,MAC7B,oBAAoB,OAAA,CAAQ,kBAAA;AAAA,MAC5B,eAAA;AAAA,MACA,IAAI,OAAA,GAAU;AACZ,QAAA,OAAO,aAAA,CAAc,OAAA,IAAW,CAAC,QAAA,CAAS,IAAI,aAAa,CAAA;AAAA,MAC7D,CAAA;AAAA,MACA,MAAA,EAAQ,cAAc,UAAA,CAAW,MAAA;AAAA,MACjC,YAAA,GAAe;AACb,QAAA,IAAI,cAAc,OAAA,IAAW,CAAC,QAAA,CAAS,GAAA,CAAI,aAAa,CAAA,EAAG;AACzD,UAAA,MAAM,IAAI,wBAAA,CAAyB,aAAA,CAAc,MAAA,EAAQ,wDAAW,CAAA;AAAA,QACtE;AACA,QAAA,IAAI,iBAAiB,QAAA,EAAU;AAC7B,UAAA,MAAM,IAAI,wBAAA,CAAyB,QAAA,EAAU,WAAW,CAAA;AAAA,QAC1D;AAAA,MACF,CAAA;AAAA,MACA,MAAMA,MAAAA,EAAO;AACX,QAAA,OAAO,eAAA,CAAgB,eAAeA,MAAK,CAAA;AAAA,MAC7C,CAAA;AAAA,MACA,KAAA,CAAM,SAAS,wBAAA,EAA0B;AACvC,QAAA,aAAA,CAAc,eAAe,MAAM,CAAA;AAAA,MACrC;AAAA,KACF;AACA,IAAA,aAAA,CAAc,OAAA,GAAU,OAAA;AACxB,IAAA,QAAA,CAAS,IAAI,aAAa,CAAA;AAC1B,IAAA,eAAA,CAAgB,GAAA,CAAI,SAAS,aAAa,CAAA;AAC1C,IAAA,OAAO;AAAA,MACL,QAAA,EAAU,IAAA;AAAA,MACV,IAAA,EAAM,QAAQ,IAAA,IAAQ,aAAA;AAAA,MACtB,oBAAoB,OAAA,CAAQ,kBAAA;AAAA,MAC5B,eAAA;AAAA,MACA,cAAc,aAAA,CAAc,YAAA;AAAA,MAC5B,WAAW,aAAA,CAAc,SAAA;AAAA,MACzB;AAAA,KACF;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,eAAA,GAAkB,CACtB,aAAA,EACA,KAAA,KACmB;AACnB,IAAA,IAAI,cAAc,OAAA,IAAW,CAAC,QAAA,CAAS,GAAA,CAAI,aAAa,CAAA,EAAG;AACzD,MAAA,MAAM,IAAI,wBAAA,CAAyB,aAAA,CAAc,MAAA,EAAQ,wDAAW,CAAA;AAAA,IACtE;AACA,IAAA,eAAA,EAAgB;AAChB,IAAA,IAAI,KAAA,CAAM,QAAQ,OAAA,EAAS;AACzB,MAAA,MAAM,IAAI,wBAAA,CAAyB,gBAAA,EAAkB,wEAAiB,CAAA;AAAA,IACxE;AAEA,IAAA,MAAM,MAAA,GAAsB;AAAA,MAC1B,OAAA,EAAS,aAAA;AAAA,MACT,WAAW,KAAA,CAAM,SAAA;AAAA,MACjB,UAAA,EAAY,IAAI,eAAA,EAAgB;AAAA,MAChC,OAAA,EAAS,KAAA;AAAA,MACT,MAAA,EAAQ;AAAA,KACV;AACA,IAAA,MAAA,CAAO,IAAI,MAAM,CAAA;AACjB,IAAA,aAAA,CAAc,MAAA,CAAO,IAAI,MAAM,CAAA;AAC/B,IAAA,IAAI,MAAM,MAAA,EAAQ;AAChB,MAAA,MAAM,OAAA,GAAU,MAAM,WAAA,CAAY,MAAA,EAAQ,gBAAgB,CAAA;AAC1D,MAAA,KAAA,CAAM,OAAO,gBAAA,CAAiB,OAAA,EAAS,SAAS,EAAE,IAAA,EAAM,MAAM,CAAA;AAC9D,MAAA,MAAA,CAAO,sBAAsB,MAAM,KAAA,CAAM,MAAA,EAAQ,mBAAA,CAAoB,SAAS,OAAO,CAAA;AAAA,IACvF;AAEA,IAAA,MAAM,KAAA,GAAwB;AAAA,MAC5B,cAAc,aAAA,CAAc,YAAA;AAAA,MAC5B,WAAW,aAAA,CAAc,SAAA;AAAA,MACzB,qBAAqB,OAAA,CAAQ,mBAAA;AAAA,MAC7B,oBAAoB,OAAA,CAAQ,kBAAA;AAAA,MAC5B,iBAAiB,aAAA,CAAc,eAAA;AAAA,MAC/B,WAAW,MAAA,CAAO,SAAA;AAAA,MAClB,IAAI,OAAA,GAAU;AACZ,QAAA,OAAO,MAAA,CAAO,OAAA,IAAW,CAAC,MAAA,CAAO,IAAI,MAAM,CAAA;AAAA,MAC7C,CAAA;AAAA,MACA,MAAA,EAAQ,OAAO,UAAA,CAAW,MAAA;AAAA,MAC1B,YAAA,GAAe;AACb,QAAA,IAAI,OAAO,OAAA,IAAW,CAAC,MAAA,CAAO,GAAA,CAAI,MAAM,CAAA,EAAG;AACzC,UAAA,MAAM,IAAI,wBAAA,CAAyB,MAAA,CAAO,MAAA,EAAQ,iDAAc,CAAA;AAAA,QAClE;AAEA,QAAA,IAAI,iBAAiB,QAAA,EAAU;AAC7B,UAAA,MAAM,IAAI,wBAAA,CAAyB,QAAA,EAAU,WAAW,CAAA;AAAA,QAC1D;AAAA,MACF,CAAA;AAAA,MACA,OAAA,GAAU;AACR,QAAA,IAAI,OAAO,OAAA,EAAS;AACpB,QAAA,MAAA,CAAO,OAAA,GAAU,IAAA;AACjB,QAAA,MAAA,CAAO,MAAA,GAAS,4BAAA;AAChB,QAAA,WAAA,CAAY,MAAM,CAAA;AAAA,MACpB;AAAA,KACF;AACA,IAAA,OAAO,KAAA;AAAA,EACT,CAAA;AAEA,EAAA,MAAM,KAAA,GAAQ,CAAC,KAAA,KAA+D;AAC5E,IAAA,MAAM,aAAA,GAAgB,eAAA,CAAgB,GAAA,CAAI,KAAA,CAAM,OAAO,CAAA;AACvD,IAAA,IAAI,CAAC,aAAA,EAAe;AAClB,MAAA,MAAM,IAAI,wBAAA,CAAyB,iBAAA,EAAmB,gGAAqB,CAAA;AAAA,IAC7E;AACA,IAAA,OAAO,eAAA,CAAgB,eAAe,KAAK,CAAA;AAAA,EAC7C,CAAA;AAEA,EAAA,MAAM,UAAA,GAAa,CAAC,MAAA,GAAS,2BAAA,KAAgC;AAC3D,IAAA,IAAI,iBAAiB,QAAA,EAAU;AAC/B,IAAA,WAAA,GAAc,MAAA;AACd,IAAA,YAAA,GAAe,UAAA;AAAA,EACjB,CAAA;AAEA,EAAA,MAAM,KAAA,GAAQ,OAAO,SAAA,KAAoD;AACvE,IAAA,UAAA,EAAW;AACX,IAAA,IAAI,MAAA,CAAO,IAAA,KAAS,CAAA,EAAG,OAAO,EAAE,OAAO,YAAA,EAAc,OAAA,EAAS,IAAA,EAAM,OAAA,EAAS,CAAA,EAAE;AAC/E,IAAA,IAAI,SAAA,KAAc,WAAc,CAAC,MAAA,CAAO,SAAS,SAAS,CAAA,IAAK,YAAY,CAAA,CAAA,EAAI;AAC7E,MAAA,MAAM,IAAI,MAAM,qFAAyB,CAAA;AAAA,IAC3C;AACA,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI,YAAA;AACJ,IAAA,MAAM,KAAA,GAAQ,IAAI,OAAA,CAAc,CAAC,OAAA,KAAY;AAC3C,MAAA,YAAA,CAAa,IAAI,OAAO,CAAA;AACxB,MAAA,YAAA,GAAe,OAAA;AAAA,IACjB,CAAC,CAAA;AACD,IAAA,MAAM,iBAAiB,SAAA,KAAc,MAAA,GACjC,SACA,IAAI,OAAA,CAAc,CAAC,OAAA,KAAY;AAC7B,MAAA,OAAA,GAAU,UAAA,CAAW,SAAS,SAAS,CAAA;AAAA,IACzC,CAAC,CAAA;AACL,IAAA,IAAI,gBAAgB,MAAM,OAAA,CAAQ,KAAK,CAAC,KAAA,EAAO,cAAc,CAAC,CAAA;AAAA,SACzD,MAAM,KAAA;AACX,IAAA,IAAI,OAAA,KAAY,MAAA,EAAW,YAAA,CAAa,OAAO,CAAA;AAC/C,IAAA,IAAI,YAAA,EAAc,YAAA,CAAa,MAAA,CAAO,YAAY,CAAA;AAClD,IAAA,MAAM,UAAU,MAAA,CAAO,IAAA;AACvB,IAAA,OAAO,EAAE,KAAA,EAAO,YAAA,EAAc,OAAA,EAAS,OAAA,KAAY,GAAG,OAAA,EAAQ;AAAA,EAChE,CAAA;AAEA,EAAA,MAAM,KAAA,GAAQ,CAAC,MAAA,GAAS,qBAAA,KAA0B;AAChD,IAAA,IAAI,iBAAiB,QAAA,EAAU;AAC/B,IAAA,WAAA,GAAc,MAAA;AACd,IAAA,YAAA,GAAe,QAAA;AACf,IAAA,KAAA,MAAW,WAAW,CAAC,GAAG,QAAQ,CAAA,EAAG,aAAA,CAAc,SAAS,MAAM,CAAA;AAClE,IAAA,KAAA,MAAW,SAAS,CAAC,GAAG,MAAM,CAAA,EAAG,WAAA,CAAY,OAAO,MAAM,CAAA;AAC1D,IAAA,WAAA,EAAY;AAAA,EACd,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,IAAI,KAAA,GAAQ;AAAE,MAAA,OAAO,YAAA;AAAA,IAAc,CAAA;AAAA,IACnC,IAAA,EAAM,QAAQ,IAAA,IAAQ,aAAA;AAAA,IACtB,qBAAqB,OAAA,CAAQ,mBAAA;AAAA,IAC7B,oBAAoB,OAAA,CAAQ,kBAAA;AAAA,IAC5B,SAAA;AAAA,IACA,eAAA;AAAA,IACA,KAAA;AAAA,IACA,UAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,QAAA,EAAU,MAAM,MAAA,CAAO;AAAA,GACzB;AACF;;;AC3SA,eAAsB,eAAA,CAAgB,KAAgB,WAAA,EAAgE;AACpH,EAAA,MAAM,IAAA,GAAO,iBAAiB,GAAG,CAAA;AACjC,EAAA,MAAM,YAAA,GAAe,4BAAA,CAA6B,WAAA,EAAa,GAAA,CAAI,WAAW,CAAA;AAC9E,EAAA,KAAA,MAAW,cAAc,YAAA,EAAc,IAAA,CAAK,uBAAuB,EAAE,QAAA,EAAU,WAAW,QAAA,CAAS,EAAA,EAAI,MAAA,EAAQ,UAAA,CAAW,QAAQ,KAAA,EAAO,UAAA,CAAW,OAAO,YAAA,EAAc,UAAA,CAAW,cAAc,CAAA;AAClM,EAAA,MAAM,IAAA,CAAK,YAAY,YAAA,CAAa,GAAA,CAAI,CAAC,UAAA,KAAe,UAAA,CAAW,QAAQ,CAAC,CAAA;AAC9E;AAGA,eAAsB,YAAA,CAAa,KAAgB,OAAA,EAA6C;AAC9F,EAAA,MAAM,IAAA,GAAO,iBAAiB,GAAG,CAAA;AACjC,EAAA,MAAM,MAAA,GAA2B,uBAAuB,OAAO,CAAA;AAC/D,EAAA,IAAA,CAAK,aAAa,MAAM,CAAA;AACxB,EAAA,MAAM,KAAK,SAAA,EAAU;AACrB,EAAA,OAAO,MAAM,IAAA,CAAK,YAAA,CAAa,yBAAyB,CAAA;AAC1D","file":"advanced.js","sourcesContent":["// 权限租约的最终边界验证器。\n//\n// Context 中的 permissions 只用于限制误用;RPC handler、最终存储写入或\n// 签名提交处必须调用这里,不能信任请求体自带的 pluginId / owner / 世代。\n\nimport type {\n PermissionLease,\n PluginPermission,\n} from \"../contracts/lifecycle.js\";\n\nexport interface VerifyPermissionLeaseOptions {\n /** 已由受信装配层创建的租约。 */\n lease: PermissionLease;\n /** 本次实际操作所需的最小权限。 */\n permission: PluginPermission;\n /** 从端口 / 当前会话权威取得的绑定值。 */\n binding?: Parameters<PermissionLease[\"assertBinding\"]>[0];\n}\n/** 在最终 RPC / I/O 边界执行一次 fail-closed 校验。 */\nexport function verifyPermissionLease(options: VerifyPermissionLeaseOptions): void {\n options.lease.assert(options.permission);\n if (options.binding) options.lease.assertBinding(options.binding);\n}\n","// 把已有 Registry 绑定到插件实例作用域。\n//\n// 该 facade 不改变 Registry 的业务类型,只在注册方法周围登记所有权:\n// 资源创建成功后立刻绑定 instance scope,停止时按 after-teardown 阶段\n// 注销。setup 前后 snapshot 仍保留作旧插件兼容兜底,但新注册不依赖它。\n\nimport type { LifecycleScope } from \"../contracts/lifecycle.js\";\n\nexport interface ScopedRegistryRegistration {\n /** 注册方法名,例如 register / registerFeature。 */\n method: string;\n /** 从参数哪个位置读取带 id 的定义。 */\n idArgument?: number;\n /** 没有返回取消函数时使用的注销方法。 */\n unregisterMethod?: string;\n /** 注销方法的参数位置;默认使用 idArgument。 */\n unregisterArgument?: number;\n /** 含 ownerPluginId 参数的注册方法;由 Host 绑定当前插件身份。 */\n bindPluginIdArgument?: number;\n /** 定义对象中的 ownerPluginId 字段;存在时必须与当前插件一致。 */\n ownerPluginIdProperty?: string;\n}\n\nexport interface CreateScopedRegistryFacadeOptions {\n /** 日志和作用域资源中显示的注册表名。 */\n name: string;\n /** 注册方法规则;缺省只包装 register(item)。 */\n registrations?: readonly ScopedRegistryRegistration[];\n}\n\ntype AnyFunction = (...args: any[]) => any;\ntype RegistryTarget = Record<PropertyKey, any>;\n\nfunction definitionId(value: unknown): string | undefined {\n if (!value || typeof value !== \"object\") return undefined;\n const id = (value as { id?: unknown }).id;\n return typeof id === \"string\" && id.length > 0 ? id : undefined;\n}\n\nfunction defaultRegistrationRules(): ScopedRegistryRegistration[] {\n return [{ method: \"register\", idArgument: 0, unregisterMethod: \"unregister\" }];\n}\n\n/** 创建一个只对当前插件实例开放的 Registry 视图。 */\nexport function createScopedRegistryFacade<T extends object>(\n target: T,\n scope: LifecycleScope,\n options: CreateScopedRegistryFacadeOptions\n): T {\n const rules = options.registrations ?? defaultRegistrationRules();\n const byMethod = new Map(rules.map((rule) => [rule.method, rule]));\n const unregisterMethods = new Set(\n rules.map((rule) => rule.unregisterMethod).filter((method): method is string => Boolean(method))\n );\n interface OwnedRegistration {\n id?: string;\n unregisterMethod?: string;\n active: boolean;\n /** revoke 时同步失效的入口;异步 dispose 只作为兜底。 */\n revokeNow: (reason: string) => void;\n /** revoke 已触发但尚未完成的底层注销;dispose 需要等待它。 */\n revokedCleanup?: Promise<void>;\n removeScopeCleanup: () => void;\n }\n const ownedRegistrations = new Set<OwnedRegistration>();\n const objectTarget = target as RegistryTarget;\n\n const remember = (\n rule: ScopedRegistryRegistration,\n id: string | undefined,\n result: unknown,\n args: unknown[]\n ): unknown => {\n const unregisterMethod = rule.unregisterMethod;\n if (typeof result !== \"function\" && (!unregisterMethod || id === undefined)) return result;\n const key = rule.method + \":\" + (id ?? \"returned\");\n let active = true;\n let removeScopeRevoke: () => void = () => undefined;\n let removeScopeCleanup: () => void = () => undefined;\n const entry = {} as OwnedRegistration;\n const clearOwnership = (removeDispose = true): boolean => {\n if (!active) return false;\n active = false;\n ownedRegistrations.delete(entry);\n removeScopeRevoke();\n if (removeDispose) removeScopeCleanup();\n return true;\n };\n const invokeUnregister = (...offArgs: unknown[]): unknown => {\n if (typeof result === \"function\") {\n return (result as AnyFunction).apply(target, offArgs);\n }\n const unregister = objectTarget[unregisterMethod!];\n if (typeof unregister !== \"function\") return undefined;\n const unregisterArgument = rule.unregisterArgument ?? rule.idArgument ?? 0;\n const unregisterArgs = [...args];\n unregisterArgs[unregisterArgument] = id;\n return unregister.apply(target, unregisterArgs);\n };\n const cleanup = async (_reason: string): Promise<void> => {\n if (!active) {\n if (entry.revokedCleanup) await entry.revokedCleanup;\n return;\n }\n if (!clearOwnership()) return;\n await invokeUnregister();\n };\n const revokeNow = (_reason: string): void => {\n if (!clearOwnership(false)) return;\n try {\n const pending = invokeUnregister();\n if (pending && typeof (pending as PromiseLike<unknown>).then === \"function\") {\n const revokedCleanup = Promise.resolve(pending).then(() => undefined);\n entry.revokedCleanup = revokedCleanup;\n revokedCleanup.catch(() => undefined);\n }\n } catch (error) {\n // revoke 必须继续同步撤权;把同步失败留给 dispose 的结果,不能\n // 重新暴露旧注册项,也不能让失败 Promise 变成未处理异常。\n entry.revokedCleanup = Promise.reject(error);\n entry.revokedCleanup.catch(() => undefined);\n }\n };\n entry.id = id;\n entry.unregisterMethod = unregisterMethod;\n entry.revokeNow = revokeNow;\n Object.defineProperty(entry, \"active\", {\n enumerable: true,\n configurable: false,\n get: () => active,\n set: (value: boolean) => { active = value; },\n });\n entry.removeScopeCleanup = removeScopeCleanup;\n ownedRegistrations.add(entry);\n removeScopeCleanup = scope.onDispose(\n cleanup,\n options.name + \":\" + key,\n \"after-teardown\"\n );\n entry.removeScopeCleanup = removeScopeCleanup;\n removeScopeRevoke = scope.onRevoke(revokeNow);\n\n if (typeof result === \"function\") {\n return (...offArgs: unknown[]) => {\n if (!clearOwnership()) return undefined;\n return (result as AnyFunction).apply(target, offArgs);\n };\n }\n return result;\n };\n\n return new Proxy(target, {\n get(current, property, receiver) {\n const value = Reflect.get(current, property, receiver);\n if (typeof value !== \"function\") return value;\n const rule = typeof property === \"string\" ? byMethod.get(property) : undefined;\n if (rule) {\n return (...args: unknown[]) => {\n scope.assertActive();\n const callArgs = [...args];\n if (rule.bindPluginIdArgument !== undefined && scope.identity.pluginId) {\n const claimedPluginId = callArgs[rule.bindPluginIdArgument];\n if (claimedPluginId !== undefined && claimedPluginId !== scope.identity.pluginId) {\n throw new Error(\n \"Registry owner \\\"\" + String(claimedPluginId) +\n \"\\\" does not match plugin instance \\\"\" + scope.identity.pluginId + \"\\\"\"\n );\n }\n callArgs[rule.bindPluginIdArgument] = scope.identity.pluginId;\n }\n if (rule.ownerPluginIdProperty && scope.identity.pluginId) {\n const definition = callArgs[rule.idArgument ?? 0];\n if (definition && typeof definition === \"object\") {\n const claimedPluginId = (definition as Record<string, unknown>)[rule.ownerPluginIdProperty];\n if (claimedPluginId !== undefined && claimedPluginId !== scope.identity.pluginId) {\n throw new Error(\n \"Registry owner \\\"\" + String(claimedPluginId) +\n \"\\\" does not match plugin instance \\\"\" + scope.identity.pluginId + \"\\\"\"\n );\n }\n }\n }\n const result = (value as AnyFunction).apply(target, callArgs);\n const id = rule.idArgument === undefined ? undefined : definitionId(callArgs[rule.idArgument]);\n return remember(rule, id, result, callArgs);\n };\n }\n // 插件主动注销只能操作自己在本作用域登记过的 id;例如\n // protected-outpoint 的 unregisterByOwner 属于领域批量操作,不在这里\n // 冒充单条资源注销,仍由领域接口自己做 owner 校验。\n if (typeof property === \"string\" && unregisterMethods.has(property)) {\n return (...args: unknown[]) => {\n scope.assertActive();\n const id = definitionId(args[0]) ?? (typeof args[0] === \"string\" ? args[0] : undefined);\n const owned = [...ownedRegistrations].find((entry) =>\n entry.active && entry.id === id && entry.unregisterMethod === property\n );\n if (!owned) {\n throw new Error(\n \"Registry resource \\\"\" + (id ?? \"unknown\") + \"\\\" is not owned by this plugin instance\"\n );\n }\n const result = (value as AnyFunction).apply(target, args);\n owned.active = false;\n ownedRegistrations.delete(owned);\n owned.removeScopeCleanup();\n return result;\n };\n }\n return (value as AnyFunction).bind(target);\n },\n }) as T;\n}\n","// Worker / 页面升级接管门禁。\n//\n// 这是一个本地写入栅栏,不是 leader 选举器,也不是跨 Worker 调度器:\n// - handshake 只校验协议、构建、接管世代和精确契约版本;\n// - active 期间才发放新的 I/O 租约;\n// - beginDrain 同步关闭新入口,已有 I/O 可以继续排空;\n// - drain 超时返回未排空,调用方不能据此开放下一代写入。\n//\n// 真正的存储 / 签名服务仍必须在最终边界重复校验 authorityInstanceId 和\n// handoverGeneration。这个模块只能提供可复用的接管语义,不能替代服务端校验。\n\nimport type {\n CreateUpgradeGateOptions,\n UpgradeDrainResult,\n UpgradeGate,\n UpgradeGateState,\n UpgradeHandshake,\n UpgradeHandshakeResult,\n UpgradeIoLease,\n UpgradeSession,\n} from \"../contracts/lifecycle.js\";\nimport { UpgradeGateRejectedError } from \"../contracts/lifecycle.js\";\n\ninterface LeaseRecord {\n session: SessionRecord;\n operation: \"read\" | \"write\";\n controller: AbortController;\n revoked: boolean;\n reason: string;\n removeExternalAbort?: () => void;\n}\n\ninterface SessionRecord {\n sessionId: string;\n connectionId: string;\n contractVersion: string;\n controller: AbortController;\n revoked: boolean;\n reason: string;\n leases: Set<LeaseRecord>;\n session?: UpgradeSession;\n}\n\nfunction validGeneration(value: number): boolean {\n return Number.isSafeInteger(value) && value >= 0;\n}\n\nfunction uniqueStrings(values: readonly string[]): string[] {\n return [...new Set(values.filter((value) => typeof value === \"string\" && value.length > 0))];\n}\n\nfunction makeSessionId(): string {\n try {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return `upgrade-session:${crypto.randomUUID()}`;\n }\n } catch {\n // 会话标识用于防止误绑定;真正的授权仍由握手和最终边界校验。\n }\n return `upgrade-session:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;\n}\n\nfunction buildIsCompatible(options: CreateUpgradeGateOptions, buildId: string): boolean {\n try {\n if (options.isBuildCompatible) return options.isBuildCompatible(buildId);\n } catch {\n return false;\n }\n return buildId === options.buildId || options.compatibleBuildIds?.has(buildId) === true;\n}\n\n/** 创建一个绑定当前构建和接管世代的升级门禁。 */\nexport function createUpgradeGate(options: CreateUpgradeGateOptions): UpgradeGate {\n if (!options.protocolVersion || !options.buildId || !options.authorityInstanceId) {\n throw new Error(\"升级门禁的 protocolVersion、buildId 和 authorityInstanceId 必须有效\");\n }\n if (!validGeneration(options.handoverGeneration)) {\n throw new Error(\"升级门禁的 handoverGeneration 必须是非负安全整数\");\n }\n const contractVersions = uniqueStrings(options.supportedContractVersions);\n if (contractVersions.length === 0) {\n throw new Error(\"升级门禁至少需要一个 supportedContractVersions\");\n }\n\n let currentState: UpgradeGateState = \"active\";\n let closeReason = \"upgrade gate closed\";\n const leases = new Set<LeaseRecord>();\n const sessions = new Set<SessionRecord>();\n const sessionByObject = new WeakMap<UpgradeSession, SessionRecord>();\n const emptyWaiters = new Set<() => void>();\n\n const notifyEmpty = () => {\n if (leases.size !== 0) return;\n for (const resolve of [...emptyWaiters]) {\n emptyWaiters.delete(resolve);\n resolve();\n }\n };\n\n const removeLease = (record: LeaseRecord) => {\n if (!leases.delete(record)) return;\n record.session.leases.delete(record);\n record.removeExternalAbort?.();\n record.removeExternalAbort = undefined;\n notifyEmpty();\n };\n\n const revokeSession = (record: SessionRecord, reason: string) => {\n if (record.revoked) return;\n record.revoked = true;\n record.reason = reason;\n try {\n record.controller.abort(new UpgradeGateRejectedError(reason));\n } catch {\n record.controller.abort();\n }\n for (const lease of [...record.leases]) revokeLease(lease, reason);\n sessions.delete(record);\n };\n\n const revokeLease = (record: LeaseRecord, reason: string) => {\n if (record.revoked) return;\n record.revoked = true;\n record.reason = reason;\n try {\n record.controller.abort(new UpgradeGateRejectedError(reason));\n } catch {\n record.controller.abort();\n }\n removeLease(record);\n };\n\n const assertAccepting = () => {\n if (currentState === \"active\") return;\n throw new UpgradeGateRejectedError(currentState === \"draining\" ? \"draining\" : \"closed\", closeReason);\n };\n\n const handshake = (input: UpgradeHandshake): UpgradeHandshakeResult => {\n if (currentState !== \"active\") {\n return { accepted: false, reason: currentState === \"draining\" ? \"draining\" : \"closed\" };\n }\n if (\n typeof input.connectionId !== \"string\"\n || input.connectionId.length === 0\n || input.protocolVersion !== options.protocolVersion\n || typeof input.protocolVersion !== \"string\"\n || typeof input.buildId !== \"string\"\n || typeof input.authorityInstanceId !== \"string\"\n || input.authorityInstanceId.length === 0\n ) {\n return { accepted: false, reason: \"protocol-mismatch\" };\n }\n if (!buildIsCompatible(options, input.buildId)) {\n return { accepted: false, reason: \"build-incompatible\" };\n }\n if (!validGeneration(input.handoverGeneration)) {\n return { accepted: false, reason: \"stale-generation\" };\n }\n if (input.handoverGeneration < options.handoverGeneration) {\n return { accepted: false, reason: \"stale-generation\" };\n }\n if (input.handoverGeneration > options.handoverGeneration) {\n return { accepted: false, reason: \"future-generation\" };\n }\n const contractVersion = contractVersions.find((version) => input.supportedContractVersions.includes(version));\n if (!contractVersion) return { accepted: false, reason: \"contract-mismatch\" };\n const sessionRecord: SessionRecord = {\n sessionId: makeSessionId(),\n connectionId: input.connectionId,\n contractVersion,\n controller: new AbortController(),\n revoked: false,\n reason: \"upgrade session closed\",\n leases: new Set(),\n };\n const session: UpgradeSession = {\n connectionId: sessionRecord.connectionId,\n sessionId: sessionRecord.sessionId,\n authorityInstanceId: options.authorityInstanceId,\n handoverGeneration: options.handoverGeneration,\n contractVersion,\n get revoked() {\n return sessionRecord.revoked || !sessions.has(sessionRecord);\n },\n signal: sessionRecord.controller.signal,\n assertActive() {\n if (sessionRecord.revoked || !sessions.has(sessionRecord)) {\n throw new UpgradeGateRejectedError(sessionRecord.reason, \"升级握手会话已失效\");\n }\n if (currentState === \"closed\") {\n throw new UpgradeGateRejectedError(\"closed\", closeReason);\n }\n },\n admit(input) {\n return admitForSession(sessionRecord, input);\n },\n close(reason = \"upgrade session closed\") {\n revokeSession(sessionRecord, reason);\n },\n };\n sessionRecord.session = session;\n sessions.add(sessionRecord);\n sessionByObject.set(session, sessionRecord);\n return {\n accepted: true,\n mode: options.mode ?? \"cold-switch\",\n handoverGeneration: options.handoverGeneration,\n contractVersion,\n connectionId: sessionRecord.connectionId,\n sessionId: sessionRecord.sessionId,\n session,\n };\n };\n\n const admitForSession = (\n sessionRecord: SessionRecord,\n input: { operation: \"read\" | \"write\"; signal?: AbortSignal }\n ): UpgradeIoLease => {\n if (sessionRecord.revoked || !sessions.has(sessionRecord)) {\n throw new UpgradeGateRejectedError(sessionRecord.reason, \"升级握手会话已失效\");\n }\n assertAccepting();\n if (input.signal?.aborted) {\n throw new UpgradeGateRejectedError(\"caller-aborted\", \"I/O 在取得接管租约前已取消\");\n }\n\n const record: LeaseRecord = {\n session: sessionRecord,\n operation: input.operation,\n controller: new AbortController(),\n revoked: false,\n reason: \"upgrade I/O lease released\",\n };\n leases.add(record);\n sessionRecord.leases.add(record);\n if (input.signal) {\n const onAbort = () => revokeLease(record, \"caller-aborted\");\n input.signal.addEventListener(\"abort\", onAbort, { once: true });\n record.removeExternalAbort = () => input.signal?.removeEventListener(\"abort\", onAbort);\n }\n\n const lease: UpgradeIoLease = {\n connectionId: sessionRecord.connectionId,\n sessionId: sessionRecord.sessionId,\n authorityInstanceId: options.authorityInstanceId,\n handoverGeneration: options.handoverGeneration,\n contractVersion: sessionRecord.contractVersion,\n operation: record.operation,\n get revoked() {\n return record.revoked || !leases.has(record);\n },\n signal: record.controller.signal,\n assertActive() {\n if (record.revoked || !leases.has(record)) {\n throw new UpgradeGateRejectedError(record.reason, \"升级 I/O 租约已失效\");\n }\n // beginDrain 不撤销已发租约;它只阻止新 I/O,给已提交操作一个排空窗口。\n if (currentState === \"closed\") {\n throw new UpgradeGateRejectedError(\"closed\", closeReason);\n }\n },\n release() {\n if (record.revoked) return;\n record.revoked = true;\n record.reason = \"upgrade I/O lease released\";\n removeLease(record);\n },\n };\n return lease;\n };\n\n const admit = (input: Parameters<UpgradeGate[\"admit\"]>[0]): UpgradeIoLease => {\n const sessionRecord = sessionByObject.get(input.session);\n if (!sessionRecord) {\n throw new UpgradeGateRejectedError(\"invalid-session\", \"I/O 必须使用当前门禁握手返回的会话\");\n }\n return admitForSession(sessionRecord, input);\n };\n\n const beginDrain = (reason = \"upgrade handover draining\") => {\n if (currentState !== \"active\") return;\n closeReason = reason;\n currentState = \"draining\";\n };\n\n const drain = async (timeoutMs?: number): Promise<UpgradeDrainResult> => {\n beginDrain();\n if (leases.size === 0) return { state: currentState, drained: true, pending: 0 };\n if (timeoutMs !== undefined && (!Number.isFinite(timeoutMs) || timeoutMs < 0)) {\n throw new Error(\"升级排空 timeoutMs 必须是非负有限数\");\n }\n let timeout: ReturnType<typeof setTimeout> | undefined;\n let timerResolve: (() => void) | undefined;\n const empty = new Promise<void>((resolve) => {\n emptyWaiters.add(resolve);\n timerResolve = resolve;\n });\n const timeoutPromise = timeoutMs === undefined\n ? undefined\n : new Promise<void>((resolve) => {\n timeout = setTimeout(resolve, timeoutMs);\n });\n if (timeoutPromise) await Promise.race([empty, timeoutPromise]);\n else await empty;\n if (timeout !== undefined) clearTimeout(timeout);\n if (timerResolve) emptyWaiters.delete(timerResolve);\n const pending = leases.size;\n return { state: currentState, drained: pending === 0, pending };\n };\n\n const close = (reason = \"upgrade gate closed\") => {\n if (currentState === \"closed\") return;\n closeReason = reason;\n currentState = \"closed\";\n for (const session of [...sessions]) revokeSession(session, reason);\n for (const lease of [...leases]) revokeLease(lease, reason);\n notifyEmpty();\n };\n\n return {\n get state() { return currentState; },\n mode: options.mode ?? \"cold-switch\",\n authorityInstanceId: options.authorityInstanceId,\n handoverGeneration: options.handoverGeneration,\n handshake,\n assertAccepting,\n admit,\n beginDrain,\n drain,\n close,\n activeIo: () => leases.size,\n };\n}\n","// WebLoom v4 advanced 装配入口。\n// 这些 API 是同一套 Host/transport 实现的显式扩展,不提供旧 API 兼容层。\n\nexport * from \"./host/createPluginHost.js\";\nexport * from \"./host/pluginGraph.js\";\nexport * from \"./host/capabilityRegistry.js\";\nexport * from \"./host/runtimeUnitImplementationRegistry.js\";\nexport * from \"./lifecycle/resourceScope.js\";\nexport * from \"./lifecycle/permissionLease.js\";\nexport * from \"./lifecycle/permissionVerifier.js\";\nexport * from \"./lifecycle/pluginIntentController.js\";\nexport * from \"./lifecycle/taskScheduler.js\";\nexport * from \"./lifecycle/scopedRegistry.js\";\nexport * from \"./lifecycle/upgradeGate.js\";\nexport { createResourceRegistry, registerOwnedResource } from \"./resources/resourceRegistry.js\";\n/** Resource Store 的 advanced 类型出口;显式 alias 可被 dts bundler 保留。 */\nexport type ResourceStoreApi = import(\"./resources/resourceStore.js\").ResourceStoreApi;\nexport * from \"./transport/serviceBridge.js\";\nexport * from \"./transport/messagePortServiceTransport.js\";\nexport * from \"./transport/messagePortServiceProvider.js\";\nexport { createWindowAppFromHost, hostForWindowApp } from \"./runtime/windowRuntime.js\";\nexport { bridgeForRuntimeHandle } from \"./runtime/connectSharedWorker.js\";\nexport type { PeerController, PeerExposureOptions, StartSharedWorkerAppOptions, StartSharedWorkerAppForTestingOptions, SharedWorkerApp } from \"./runtime/sharedWorkerHost.js\";\nexport * from \"./runtime/runtimeProtocol.js\";\n\nimport type { RuntimeHandle, WindowApp } from \"./runtime/runtimeTypes.js\";\nimport type { RuntimePluginDefinition } from \"./runtime/pluginDefinitions.js\";\nimport { materializePluginDefinitions } from \"./runtime/pluginDefinitions.js\";\nimport { hostForWindowApp } from \"./runtime/windowRuntime.js\";\nimport { bridgeForRuntimeHandle } from \"./runtime/connectSharedWorker.js\";\nimport type { CapabilityBridge } from \"./contracts/capability.js\";\n\n/** 分阶段向已经拥有的 App 注册新的 typed plugin definitions。 */\nexport async function registerPlugins(app: WindowApp, definitions: readonly RuntimePluginDefinition[]): Promise<void> {\n const host = hostForWindowApp(app);\n const materialized = materializePluginDefinitions(definitions, app.runtimeKind);\n for (const definition of materialized) host.registerImplementation({ pluginId: definition.manifest.id, unitId: definition.unitId, setup: definition.setup, capabilities: definition.capabilities });\n await host.registerAll(materialized.map((definition) => definition.manifest));\n}\n\n/** 把一个连接绑定到现有 WindowApp;替换时先撤销旧 bridge。 */\nexport async function attachRemote(app: WindowApp, runtime: RuntimeHandle): Promise<() => void> {\n const host = hostForWindowApp(app);\n const bridge: CapabilityBridge = bridgeForRuntimeHandle(runtime);\n host.attachRemote(bridge);\n await host.reconcile();\n return () => host.detachRemote(\"Remote Runtime detached\");\n}\n"]}
|