From d86dc83d656a26806f640e1dd3083c61ed70b963 Mon Sep 17 00:00:00 2001 From: "chendaxin.tk" Date: Sun, 27 Sep 2026 23:29:04 +0800 Subject: [PATCH] fix(core): share generated ids across bundles Co-authored-by: TRAE CLI --- .../__tests__/unit/common/generator.test.ts | 32 +++++++++++++++++++ packages/vrender-core/src/common/generator.ts | 21 ++++++++++-- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/packages/vrender-core/__tests__/unit/common/generator.test.ts b/packages/vrender-core/__tests__/unit/common/generator.test.ts index c00bc5cc4..ae29c647a 100644 --- a/packages/vrender-core/__tests__/unit/common/generator.test.ts +++ b/packages/vrender-core/__tests__/unit/common/generator.test.ts @@ -1,5 +1,11 @@ +/** + * @jest-environment node + */ + import { Generator } from '../../../src/common/generator'; +declare const require: any; + describe('Generator', () => { test('GenAutoIncrementId returns a finite number', () => { const id = Generator.GenAutoIncrementId(); @@ -20,4 +26,30 @@ describe('Generator', () => { expect(ids[i + 1]).toBe(ids[i] + 1); } }); + + test('GenAutoIncrementId shares one sequence across isolated module instances', () => { + jest.resetModules(); + const { Generator: FirstGenerator } = require('../../../src/common/generator'); + const firstId = FirstGenerator.GenAutoIncrementId(); + + jest.resetModules(); + const { Generator: SecondGenerator } = require('../../../src/common/generator'); + const secondId = SecondGenerator.GenAutoIncrementId(); + + expect(secondId).toBe(firstId + 1); + }); + + test('keeps node ids unique across isolated module instances', () => { + jest.resetModules(); + const { Node: ParentNode } = require('../../../src/graphic/node-tree'); + const parent = new ParentNode(); + + jest.resetModules(); + const { Node: ChildNode } = require('../../../src/graphic/node-tree'); + const child = new ChildNode(); + + expect(child._uid).not.toBe(parent._uid); + expect(parent.appendChild(child)).toBe(child); + expect(parent.firstChild).toBe(child); + }); }); diff --git a/packages/vrender-core/src/common/generator.ts b/packages/vrender-core/src/common/generator.ts index 5a252a963..81e6897d1 100644 --- a/packages/vrender-core/src/common/generator.ts +++ b/packages/vrender-core/src/common/generator.ts @@ -1,7 +1,22 @@ -export class Generator { - private static auto_increment_id: number = 0; +interface IGeneratorState { + autoIncrementId: number; +} +const GENERATOR_STATE_SYMBOL = Symbol.for('@visactor/vrender-core/generator-state'); + +function getGeneratorState(): IGeneratorState { + const scope = globalThis as typeof globalThis & { + [GENERATOR_STATE_SYMBOL]?: IGeneratorState; + }; + return scope[GENERATOR_STATE_SYMBOL] || (scope[GENERATOR_STATE_SYMBOL] = { autoIncrementId: 0 }); +} + +// Application and legacy runtime state are shared across bundles. Keep node ids in the same +// global scope so a shared Stage cannot receive a Layer with a colliding id from another bundle. +const generatorState = getGeneratorState(); + +export class Generator { static GenAutoIncrementId(): number { - return Generator.auto_increment_id++; + return generatorState.autoIncrementId++; } }