Importing the library must not mutate global built-ins
Cluster: browser
Reported as "Angular Material crashes".
Desired behavior
Importing the library, in any environment and via any published entrypoint, MUST NOT mutate global built-ins (Promise, Array.prototype, Object.assign, Symbol, and the rest). Loading the package is a side-effect-free operation with respect to the global scope.
Rationale: a spreadsheet library is a leaf dependency. Host applications and frameworks legitimately replace or instrument global built-ins, and Angular with Zone.js swaps in an instrumented Promise to drive change detection while other frameworks patch scheduling primitives. A library that ships eagerly-applied core-js polyfills in its browser bundle silently overwrites those, producing action-at-a-distance breakage that is nearly impossible for consumers to attribute back to the library.
Prior art (what went wrong upstream)
- The legacy browser bundle was produced by Babel plus core-js and executed
require('core-js/modules/es.promise')at module-load time, unconditionally assigningglobalThis.Promise. - Under Angular this overwrote Zone.js's
ZoneAwarePromise, so promise settlement stopped notifying the framework: double-click-to-act, stuck spinners, phantom route changes, and a console errorZoneAwarePromise (window|global).Promise has been overwritten. - A
bareandbare.minbundle without the polyfill existed but was not the default entrypoint, forcing consumers to hand-edit resolution and then re-supply the polyfills the Babel output assumed. This is exactly the packaging shape we are forking away from. - The symptom eventually disappeared for some users across later builds purely as a side effect of build-config drift, not an intentional guarantee, meaning it could regress at any time without a durable rule.
Requirements for this fork
- Ship modern ESM targeting current runtimes; assume the consumer's toolchain, or a runtime baseline, provides
Promise, async iterators and the rest. Do not down-compile to ES5. - Zero global mutation at import. No core-js entry modules, no polyfill side-effects, no assignment to
globalThis.*on load. If a runtime lacks a needed built-in, that is the consumer's polyfill decision, made before our code runs, not ours. - If any optional runtime-feature shim is ever offered, it must be an explicit, opt-in, separate import that the consumer chooses, never bundled into the default entrypoint.
- A CI guard should assert the built package produces no global side-effects on import, for example by snapshotting key global identities before and after importing the entrypoint and asserting they are unchanged.
Open questions
- What is the minimum runtime baseline we commit to (Node LTS plus evergreen browsers)? That baseline determines which built-ins we may freely assume without any shim.
- Do we ship a single ESM entrypoint for all environments, or distinct Node and browser conditional exports? Either is fine provided neither mutates globals.