Publish numeric on the global object so browsers can use it - #86
Merged
Conversation
numeric.js builds most of its helpers at load time with the `Function`
constructor, and the generated bodies reference a bare `numeric` — for
instance `if(typeof _s === "undefined") _s = numeric.dim(x);`. Functions
made that way are evaluated in global scope, so the reference resolves
only if `numeric` is a property of the global object.
numeric.js puts it there itself, but through a Node-ism:
if (typeof global !== "undefined") { global.numeric = numeric; }
A browser main thread and a web worker both have no `global`, so the
assignment is skipped and every generated helper — `add`, `mul`, `sub`,
`dim`, … — throws `ReferenceError: numeric is not defined` the first
time it is called. `math.dopri` reaches those helpers immediately, so
integrating an ODE fails outright in the browser while passing in Node.
Publish `numeric` from here instead, which covers every runtime.
The assignment is unconditional rather than guarded on
`globalThis.numeric === undefined`: on a page holding an element whose id
is `numeric`, the named-element global makes the slot look occupied while
still being useless to the generated code.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
me.math.doprithrowsReferenceError: numeric is not definedin a browser and in a web worker, while working fine under Node. DoenetML's<odeSystem>integrates with it, so every activity containing an ODE currently dies on load — the worker error surfaces as a red "numeric is not defined" banner in place of the document.Why
numeric.js builds most of its helpers at load time with the
Functionconstructor. The generated bodies reference a barenumeric:Functions made with
Function(...)are evaluated in global scope, so that reference resolves only ifnumericis a property of the global object. numeric.js puts it there itself — but through a Node-ism:A browser main thread and a web worker both have no
global, so the assignment is skipped and every generated helper (add,mul,sub,dim, …) throws the first time it is called.doprireaches those helpers immediately.The change
lib/mathjs.js— the one place that imports numeric — publishes it itself, which covers every runtime.The assignment is unconditional rather than guarded on
globalThis.numeric === undefined. On a page holding an element whose id isnumeric, the named-element global makes the slot look occupied while still being useless to the generated code — which is exactly what happens in DoenetML, whose virtual keyboard has anumericbutton, and it turns the error into the more puzzlingdim is not a function.Test
spec/quick_numeric-global.spec.jsdeletesglobalbefore the first import oflib/mathjs.js, reproducing the shape a browser sees, then integrates x' = x from x(0) = 1 and checks it lands on e. Without the fix it fails with the production error:npm testis green (3580 tests, 19 files). Verified end to end against DoenetML: with the equivalent shim in place, an<odeSystem>document renders its values and plots its solution curve in both the worker and the main-thread renderer.Base branch
Against
2.x, branched fromv2.0.0-alpha94— the published 2.x line that DoenetML consumes.mainno longer containslib/mathjs.js; the Rust port (#77) removed it. A companion PR, #87, restores numeric inpackages/math-expressions-js-compatonmain, whereme.mathcurrently has nodopriat all.A second commit bumps the version to
2.0.0-alpha95, so this can be published as soon as it merges.🤖 Generated with Claude Code