mirror of
https://github.com/openclaw/openclaw.git
synced 2026-09-28 05:54:09 +08:00
* chore(deps): refresh dependencies with a seven-day cutoff * fix(deps): preserve Teams and jsdom integration contracts Use the Teams SDK public token and processing APIs while keeping SSO sender checks ahead of native token operations. Remove obsolete ambient declarations and route workarounds, and cover the SDK routing with real processing tests. Adapt the test environment to jsdom private-field bindings, preserve file bytes and registry cleanup, and preload it through native Node and Bun workers. * fix(test): preserve jsdom window and fixture contracts * fix(ci): keep typecheck cache reuse within matching inputs
68 lines
2.8 KiB
TypeScript
68 lines
2.8 KiB
TypeScript
// Jsdom custom elements keeps shared-worker element registrations in step with the module graph.
|
|
//
|
|
// Shared (isolate: false) jsdom lanes re-evaluate the module graph for every test
|
|
// file, so each file gets freshly evaluated component classes. jsdom keeps custom
|
|
// element definitions on the window instead, outside that graph. Every Control UI
|
|
// component registers with `if (!customElements.get(tag))`, so a definition that
|
|
// survives the reset pins the tag to the previous file's class: the next file's
|
|
// `document.createElement(tag)` then builds elements closed over the earlier file's
|
|
// module instances, and its own singletons, module mocks, and spies are never the
|
|
// ones production reaches. Registry lifetime has to match graph lifetime.
|
|
//
|
|
// Only repo-owned tags may be dropped. Dependency packages are externalized, so
|
|
// they evaluate once per worker through native ESM and never re-register; dropping
|
|
// their definitions would leave `wa-*` and friends permanently unupgraded.
|
|
|
|
import {
|
|
jsdomCustomElementDefinitions,
|
|
type JsdomCustomElementDefinition,
|
|
} from "./jsdom-compat.mts";
|
|
|
|
export { jsdomCustomElementDefinitions };
|
|
|
|
export type CustomElementTracking = {
|
|
registry: CustomElementRegistry;
|
|
definitions: JsdomCustomElementDefinition[];
|
|
repoOwnedTags: Set<string>;
|
|
};
|
|
|
|
// Conservative on an unreadable stack: keeping a repo tag costs a stale class in
|
|
// one lane, dropping a dependency tag would leave it unupgraded for the whole run.
|
|
export function isRepoOwnedDefineStack(stack: string | undefined): boolean {
|
|
// [0] "Error", [1] the patched define in this module, [2] the module calling it.
|
|
const callerFrame = (stack ?? "").split("\n")[2] ?? "";
|
|
return callerFrame.trim() !== "" && !/[\\/]node_modules[\\/]/u.test(callerFrame);
|
|
}
|
|
|
|
// Returns undefined for anything that is not a jsdom registry: mixed lanes run
|
|
// `@vitest-environment node` files whose leftover global has no definitions to track.
|
|
export function trackCustomElementRegistry(
|
|
registry: CustomElementRegistry,
|
|
): CustomElementTracking | undefined {
|
|
const definitions = jsdomCustomElementDefinitions(registry);
|
|
if (!definitions) {
|
|
return undefined;
|
|
}
|
|
const tracking: CustomElementTracking = { registry, definitions, repoOwnedTags: new Set() };
|
|
const define = registry.define.bind(registry);
|
|
registry.define = (name, constructor, options) => {
|
|
if (isRepoOwnedDefineStack(new Error().stack)) {
|
|
tracking.repoOwnedTags.add(name);
|
|
}
|
|
define(name, constructor, options);
|
|
};
|
|
return tracking;
|
|
}
|
|
|
|
export function dropRepoOwnedCustomElements(tracking: CustomElementTracking): void {
|
|
if (tracking.repoOwnedTags.size === 0) {
|
|
return;
|
|
}
|
|
const survivors = tracking.definitions.filter(
|
|
(definition) => !tracking.repoOwnedTags.has(definition.name),
|
|
);
|
|
tracking.definitions.length = 0;
|
|
tracking.definitions.push(...survivors);
|
|
tracking.repoOwnedTags.clear();
|
|
}
|