fix: clone settings locale data#96
Conversation
|
Can you describe the use case when this is played? |
There was a problem hiding this comment.
Pull request overview
Fixes settings.getLocaleData() to safely return a detached copy of Dayjs locale data even when the locale object contains function-valued properties (e.g., ordinal), avoiding structuredClone’s DataCloneError in browsers/Node.
Changes:
- Replaced
structuredCloneusage insettings.getLocaleData()with a small recursive clone helper that preserves function references. - Added a unit test asserting locale data is cloned (new references) while function values remain callable.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/settings/settings.ts |
Introduces cloneLocaleData and uses it in getLocaleData() instead of structuredClone. |
src/settings/settings.test.ts |
Adds a test to ensure locale data cloning works when locale objects contain functions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
@korvin89 fyi |
| import {localeLoaders} from './locales'; | ||
| import type {Locale, Parser, PublicSettings, UpdateLocaleConfig} from './types'; | ||
|
|
||
| function cloneLocaleData<T>(value: T): T { |
There was a problem hiding this comment.
Worth a one-line comment that this helper intentionally assumes locale data is function-or-JSON-shaped. Unlike structuredClone, it would stack-overflow on a circular reference and would flatten Date/RegExp/Map/Set to {}. None of those exist in dayjs locale objects today (only strings/numbers/arrays/plain objects/functions), so nothing to fix here — just a note so a future locale field doesn't silently get mangled.
There was a problem hiding this comment.
Fixed in 589af2a: added a one-line note that this helper is specific to Dayjs JSON-like locale data with function fields and is not a general structuredClone replacement.
| expect(settings.getLocale()).toEqual(LOCALE); | ||
| }); | ||
|
|
||
| it('should clone locale data with function values', () => { |
There was a problem hiding this comment.
This test runs against whatever locale the previous test left set (de) rather than a locale it sets itself. It passes regardless since en also has ordinal + formats, but calling settings.setLocale('en') at the start would make it self-contained and order-independent.
There was a problem hiding this comment.
Fixed in 589af2a: added settings.setLocale('en') at the start of this test, so it is self-contained and order-independent.


What changed
settings.getLocaleData()now clones dayjs locale data with a small internal clone helper instead ofstructuredClone.The helper keeps function values intact while still returning a detached copy for plain objects and arrays.
Why
dayjs.Ls[locale]can contain functions, for exampleordinal.structuredClonecannot clone functions and throwsDataCloneErrorin browsers and Node:This surfaced in consumers that render date field/date picker components: date format expansion calls
getLocaleData(), which crashes during render.Tests
npm test -- settingsnpm run typechecknpm run lint(passes with existing warnings)npm testnpm run build