Status: implemented in Rollup plugin (UMD path).
Completed:
globalThis.__tsParticlesInternals.tsparticles, tsparticles-*, @tsparticles/* to internals paths.Notes:
__tsParticlesInternals remains internal and non-semver-stable.This document defines the implementation details for the UMD global namespace policy.
window clean and predictable.@tsparticles/pjs behavior in this phase.window: tsParticleswindow: all other engine exports__tsParticlesInternals.engine.*window: only their own load* functions (including multiple load* exports if present)globalThis/window.window: all non-load* exports__tsParticlesInternalsfull, slim, basic, all)window: only their own load* functionswindow: all non-load* exports__tsParticlesInternals.bundles.<bundleName>.*@tsparticles/pjswindow: only initPjsinitPjs stay unchanged:
globalThis.particlesJSglobalThis.ParticlesglobalThis.pJSDom__tsParticlesInternals.bundles.pjs.*confetti, fireworkswindow:
confetti bundle: only confettifireworks bundle: only fireworkswindow.tsParticles is not part of their public API in this policyUse a global shared object:
globalThis.__tsParticlesInternalsCharacteristics:
isNull, PerlinNoise, ensureInteractivityPluginLoaded)bundlespluginsinteractionseffectspathsshapesupdaterspalettespresetsutilsengine (intentional singular exception)For package @tsparticles/<name>:
emittersShapes intermediate segment to avoid collisions with plugins.emitters.*.Examples:
@tsparticles/path-perlin-noise -> __tsParticlesInternals.paths.perlinNoise@tsparticles/plugin-interactivity -> __tsParticlesInternals.plugins.interactivity@tsparticles/updater-out-modes -> __tsParticlesInternals.updaters.outModes@tsparticles/plugin-emitters -> __tsParticlesInternals.plugins.emitters@tsparticles/plugin-emitters-shape-canvas -> __tsParticlesInternals.plugins.emittersShapes.canvastsparticles (full bundle) -> __tsParticlesInternals.bundles.full@tsparticles/slim -> __tsParticlesInternals.bundles.slim@tsparticles/basic -> __tsParticlesInternals.bundles.basic@tsparticles/all -> __tsParticlesInternals.bundles.all@tsparticles/pjs -> __tsParticlesInternals.bundles.pjs@tsparticles/confetti -> __tsParticlesInternals.bundles.confetti@tsparticles/fireworks -> __tsParticlesInternals.bundles.fireworks@tsparticles/engine -> __tsParticlesInternals.engineIf category inference is ambiguous, fallback to package name path segments without blocking build.
Primary implementation files:
cli/utils/rollup-plugin/src/config/createSingleConfig.tscli/utils/rollup-plugin/src/config/externals.tscli/utils/rollup-plugin/src/types.tscli/utils/rollup-plugin/src/createParticlesBuild.tscli/utils/rollup-plugin/src/config/entry.ts (if needed for stable scope computation)At UMD render stage, split entry exports into:
publicExports: eligible for window top-levelinternalExports: written to __tsParticlesInternals.<scope>engine: allow only tsParticlespjs: allow only initPjsconfetti: allow only confettifireworks: allow only fireworks^load[A-Z]For each internal export symbol X in a package scope:
__tsParticlesInternalsscope.X = XUpdate UMD externals mapping so tsparticles package references resolve through internals namespace instead of top-level window:
tsparticles, tsparticles-*, @tsparticles/* -> __tsParticlesInternals... pathsThis is a required compatibility point. Symbols imported across packages must be found and callable from internals, including but not limited to:
__tsParticlesInternals.engine.isNull__tsParticlesInternals.paths.perlinNoise.PerlinNoise__tsParticlesInternals.plugins.interactivity.ensureInteractivityPluginLoadedEvery UMD chunk that writes internals must bootstrap safely:
globalThis.__tsParticlesInternals if absentThis allows loading plugin script before engine script without immediate failures due to missing internal root object.
src/index.ts files for this phase.initPjs side-effects.window only contains expected public symbols per matrix.globalThis.__tsParticlesInternals in correct scope.confetti and fireworks expose only their public callable globals.@tsparticles/pjs exposes only initPjs automatically; legacy globals appear only after calling it.isNull, PerlinNoise, ensureInteractivityPluginLoaded, etc.).load* APIs are always available on globalThis/window as defined by the matrix.plugin-interactivity)path-perlin-noise)full)__tsParticlesInternals.engine.isNull__tsParticlesInternals.paths.perlinNoise.PerlinNoise__tsParticlesInternals.plugins.interactivity.ensureInteractivityPluginLoadedUpdate docs to state:
__tsParticlesInternals is implementation/internal support for UMD package interoperability.