Skip to content

Changelog

What changed in ARDOR, who is affected and what to do about it.

RSS
LatestFeatureuseStoredState can turn its storage off with a null keyA null key makes useStoredState keep its value in memory, like useState, so a component can store state only when a user id or a flag is known.@venizia/ardor-react, @venizia/ardor
90 entries

2026

  1. useStoredState can turn its storage off with a null keyFeature

    A null key makes useStoredState keep its value in memory, like useState, so a component can store state only when a user id or a flag is known.

    @venizia/ardor-react, @venizia/ardor

  2. BrowserStorage.subscribe tells a change of this tab from one of another tabFeature

    The listener of BrowserStorage.subscribe gets { isExternal }, false after a write through BrowserStorage in this tab and true when another tab changed the key.

    @venizia/ardor-kernel, @venizia/ardor

  3. reduxStore is optionalFeature

    ArdorApplication no longer needs a Redux store; without one it mounts no Redux provider.

    @venizia/ardor, @venizia/ardor-admin

  4. The app preset no longer has a vendor chunk that the first screen loadsBehavior

    The app preset keeps only the react group in codeSplitting, because its catch-all vendor group put the libraries of lazy routes into the first screen.

    @venizia/ardor

  5. useIntersection watches several targets, a scroll container and several thresholdsFeature

    useIntersection takes a list of targets and returns one entry for each, takes a root element, and takes a list of thresholds, so a scroll-spy needs no own observer.

    @venizia/ardor-react, @venizia/ardor

  6. Test fakes for the browser APIs the hooks useFeature

    FakeIntersectionObserver, FakeMatchMedia, FakeStorage and FakeClipboard join FakeResizeObserver, which now shows its observers; all in @venizia/ardor/testing.

    @venizia/ardor-kernel, @venizia/ardor

  7. Sign-out removes the stored data and the cached queries of the userBehavior

    When the session ends, by any route, the auth provider removes the keys under @app/store/ and the application empties the query cache.

    @venizia/ardor-admin, @venizia/ardor

  8. The REST data provider sends the record id as one path segmentFix

    getOne, update and delete percent-encode the id, so an id with a slash, a question mark or a hash reaches the server whole; doRequest refuses dot segments.

    @venizia/ardor-admin, @venizia/ardor

  9. The generated app sends a report-only CSP and checks its container inputBehavior

    The app preset sends Content-Security-Policy-Report-Only, hides the nginx version, refuses more secret-looking VITE_ values and checks NGINX_LOCAL_RESOLVERS.

    @venizia/ardor

  10. The codemod never writes through a symlinkFix

    ardor codemod namespace skips a tracked symlink, so --write cannot change a file outside the project that the link points to.

    @venizia/ardor

  11. The codemod writes all files or none, and refuses outside gitFixBehavior

    ardor codemod namespace --write stages every file, names a file it cannot rewrite and writes nothing then, and needs --allow-dirty outside a git repository.

    @venizia/ardor

  12. Client-side roles only show or hide interfaceEnhancement

    The roles ARDOR keeps in the browser, and the permission provider, are not an access check; the docs and the TSDoc now say the backend must check every permission.

    @venizia/ardor-kernel, @venizia/ardor-admin, @venizia/ardor

  13. An application id keeps two applications on one origin apartFeature

    IApplicationInfo.id scopes the session keys and the store prefix in browser storage; without it nothing changes, so a single application per origin needs no migration.

    @venizia/ardor-kernel, @venizia/ardor-admin, @venizia/ardor

  14. Sign-in can stay on the page, and the resolved auth provider can be typed as presentFeature

    paths.afterLogin accepts false so login resolves with redirectTo false; ApplicationProviders.resolve takes isAuthRequired to type the auth provider as present.

    @venizia/ardor-kernel, @venizia/ardor-admin, @venizia/ardor

  15. Everything since ARDOR 0.4.7 in one place, with an upgrade checklistRelease

    A table of every change since 0.4.7 linked to its entry, the IGNIS peer versions, and the ordered checklist an application follows to move to ARDOR 0.4.8.

    @venizia/ardor-kernel, @venizia/ardor-react, @venizia/ardor-admin, @venizia/ardor · 0.4.7

  16. ISendResponse and IListFilter.offset are removedBreaking

    ISendResponse was a second name for INetworkResponse, and IListFilter.offset an alias of skip; both are removed, and the codemod renames or lists them.

    @venizia/ardor-kernel, @venizia/ardor-admin, @venizia/ardor

  17. useUntypedTranslate translates a key that exists only at run timeFeature

    useUntypedTranslate takes a plain string key, so a server error code or a data label needs no cast, while useTranslate keeps its compile-time key check.

    @venizia/ardor-admin, @venizia/ardor

  18. useStoredState writeDelayMs writes the storage once after a burst of changesFeature

    useStoredState writeDelayMs updates the UI at once and writes localStorage once after the delay, for a value that changes many times a second.

    @venizia/ardor-react, @venizia/ardor

  19. useStoredState updaters compose, and the sign-out order is documentedFix

    setValue(updater) of useStoredState runs against the value at the call, so two updaters in one tick both apply; the reference covers sign-out.

    @venizia/ardor-react, @venizia/ardor

  20. StorageCodecs.text reads and writes a bare stringFeature

    StorageCodecs.text() stores a string as it is, with an optional list of allowed values; useStoredState and BrowserStorage take it as a codec.

    @venizia/ardor-kernel, @venizia/ardor-react, @venizia/ardor

  21. useResizeEffect runs one callback when any of several elements resizesFeature

    useResizeEffect observes several elements, and with children their direct children, and calls onResize once per animation frame or before paint.

    @venizia/ardor-react, @venizia/ardor

  22. useSizer is removed, use useElementSizeBreaking

    useSizer measured the element with a given id; useElementSize measures an element or a ref with more options, so useSizer is removed with no alias.

    @venizia/ardor-react, @venizia/ardor

  23. useIntersection tells whether an element is in viewFeature

    useIntersection returns the latest IntersectionObserverEntry of an element, so lazy content or a load-more sentinel needs no own observer.

    @venizia/ardor-react, @venizia/ardor

  24. ardor-react and ardor-admin no longer depend on lodashEnhancement

    Six lodash calls are replaced by destructuring, an existing check and two small helpers, about 10 KB less in an app bundle.

    @venizia/ardor-react, @venizia/ardor-admin

  25. A refreshTokenPath now refreshes the token without a subclassBehavior

    With authRecovery.refreshTokenPath set, the default refreshToken posts to it and saves the new token, so a 401 recovers with no subclass.

    @venizia/ardor-kernel, @venizia/ardor-admin, @venizia/ardor

  26. useCopyToClipboard returns isCopied, with a resetMs optionFeature

    useCopyToClipboard returns { copy, isCopied }, and resetMs sets isCopied back to false after a delay, so a "Copied" button needs no state or timer of its own.

    @venizia/ardor-react, @venizia/ardor

  27. BrowserClipboard writes and reads the clipboard outside ReactFeature

    BrowserClipboard.writeText and readText answer false or undefined on every refusal; useCopyToClipboard calls it and no longer throws on a server.

    @venizia/ardor-kernel, @venizia/ardor-react, @venizia/ardor

  28. BrowserStorage.keys and removeWhere list and sweep keys by prefixFeature

    BrowserStorage.keys lists the keys of a storage area and removeWhere removes those with a prefix, without throwing.

    @venizia/ardor-kernel, @venizia/ardor

  29. useMediaQuery, useDocumentVisibility and useOnlineStatus read browser stateFeature

    Three SSR-safe hooks over useSyncExternalStore for a media query, tab visibility and online status, with no hand-written subscribe.

    @venizia/ardor-react, @venizia/ardor

  30. useInjectableContainer is now useApplicationContainerBreaking

    The hook that returns the application's container is renamed to say what it returns; there is no alias, and the upgrade is a find and replace.

    @venizia/ardor-react, @venizia/ardor

  31. RequestBodyEncoder types its body, and ResponseReader reads a file nameFeatureEnhancement

    encode returns a FormData, a URLSearchParams or the body you passed, and readFilename returns the name in a Content-Disposition header.

    @venizia/ardor-kernel, @venizia/ardor

  32. Session hooks see every token change, and the unauthenticated rejection is configurableFeatureEnhancement

    DefaultAuthService.subscribe tells the provider about every saved or cleared session, so onSessionStarted fires for a refresh by the network service, and unauthenticatedRejection sets what checkAuth and a 401 reject with.

    @venizia/ardor-kernel, @venizia/ardor-admin, @venizia/ardor

  33. DefaultAuthProvider has session hooksFeature

    onSessionStarted and onSessionCleared tell a subclass when the session starts, changes its token or ends, so a socket or a per-user cache stays in step without overriding checkAuth.

    @venizia/ardor-admin, @venizia/ardor

  34. useElementSize no longer throws where there is no ResizeObserverFix

    useElementSize stays at 0 by 0 and observes nothing on a host without ResizeObserver, instead of throwing in its effect.

    @venizia/ardor-react, @venizia/ardor

  35. useElementSize follows any element, rounds and says when it measured, and FakeResizeObserver tests itFeature

    useElementSize returns a callback ref when you pass none, takes round, returns measured, and @venizia/ardor/testing has FakeResizeObserver for hosts whose ResizeObserver does nothing.

    @venizia/ardor-react, @venizia/ardor

  36. Typed browser storage and useElementSizeFeature

    BrowserStorage reads and writes localStorage and sessionStorage without throwing, useStoredState keeps a value in step across hooks and tabs, and useElementSize measures a ref.

    @venizia/ardor-kernel, @venizia/ardor-react, @venizia/ardor

  37. Everything since ARDOR 0.4.6 in one place, with an upgrade checklistRelease

    A table of every change since 0.4.6 linked to its entry, the peer versions, and the ordered checklist an application follows to move to ARDOR 0.4.7.

    @venizia/ardor-kernel, @venizia/ardor-react, @venizia/ardor-admin, @venizia/ardor · 0.4.6

  38. Sign-out clears only keys under @app/auth/, not @app/oauth2/Breaking

    DefaultAuthService.cleanUp no longer removes keys under @app/oauth2/, and LocalStorageKeys.PREFIX_OAUTH2 is removed.

    @venizia/ardor-kernel, @venizia/ardor-admin, @venizia/ardor

  39. The i18n provider takes lazy sources, so a catalogue stays out of the boot bundleFeature

    An entry of i18nSources can be a loader such as () => import('./vi'), called the first time its locale is used; a loader that fails leaves the locale on English.

    @venizia/ardor-admin, @venizia/ardor

  40. Utilities move to classes, hooks to Ardor, logger to IGNIS, and old names are removedBreakingEnhancementCheck this

    Utilities and helpers are now on classes, Ardor holds all hooks, the logger comes from IGNIS, and a tool updates your code.

    @venizia/ardor, @venizia/ardor-kernel, @venizia/ardor-react, @venizia/ardor-admin

  41. Everything since ARDOR 0.4.4 in one place, with an upgrade checklistRelease

    A table of every change since 0.4.4 linked to its entry, and the checklist an application follows to move to ARDOR 0.4.5.

    @venizia/ardor-kernel, @venizia/ardor-react, @venizia/ardor-admin, @venizia/ardor · 0.4.4

  42. useDocumentTitle takes fallback, a base title screens overrideFeature

    useDocumentTitle gains an optional fallback flag; a fallback call shows its title only while no other call is mounted.

    @venizia/ardor-admin, @venizia/ardor

  43. assertArdorApplicationBoots proves an application boots in a unit testFeature

    The new entry @venizia/ardor/testing exports assertArdorApplicationBoots, which proves an application boots in a unit test, with no browser and no network.

    @venizia/ardor, @venizia/ardor-admin

  44. ArdorApplication takes a features prop, so a shell mounts a filtered listFeature

    ArdorApplication has a new optional features prop, the list of features to mount, so a shell can mount a filtered list.

    @venizia/ardor, @venizia/ardor-admin

  45. Everything since ARDOR 0.4.3 in one place, with an upgrade checklistRelease

    A table of every change since 0.4.3 grouped by kind and linked to its entry, and the checklist an application follows to move to ARDOR 0.4.4.

    @venizia/ardor-kernel, @venizia/ardor-react, @venizia/ardor-admin, @venizia/ardor · 0.4.3

  46. Chunks keep import order, and buildInfoFile writes build-info.jsonFeatureBehavior

    The preset turns on output.strictExecutionOrder so chunks keep import order, and @venizia/ardor/vite adds buildInfoFile for an About page.

    @venizia/ardor, @venizia/ardor-kernel

  47. The repository sub-path exports HttpReadShapesEnhancement

    The repository sub-path re-exports the HTTP module of IGNIS, so HttpReadShapes and THttpReadShape from IGNIS 0.4.3 are importable from ARDOR.

    @venizia/ardor-kernel, @venizia/ardor

  48. Everything since ARDOR 0.4.1 in one place, with an upgrade checklistRelease

    A table of every change since 0.4.1 linked to its entry, and the checklist an application follows to move to ARDOR 0.4.3.

    @venizia/ardor-kernel, @venizia/ardor-react, @venizia/ardor-admin, @venizia/ardor · 0.4.1

  49. getRuntimeConfig can require a valueFeatureEnhancement

    Passing required to getRuntimeConfig makes it return a string and throw, naming the key, when no value is set; the error carries a code and the key.

    @venizia/ardor-kernel, @venizia/ardor

  50. The preset image compresses, answers /health and sends security headersSecurityFeatureEnhancementBehavior

    The preset image gzips text, answers /health, sends three security headers on every response, and writes the /api proxy only when API_UPSTREAM is set.

    @venizia/ardor

  51. The network service is split into small parts, and its types are closedBreaking

    DefaultNetworkRequestService stays the class you extend, its request types are closed, and the fetcher and socket client now come from IGNIS.

    @venizia/ardor-kernel, @venizia/ardor-admin, @venizia/ardor

  52. Correctness fixes in the kernel, the admin and the hooksFix

    A series of fixes in the data providers, the network service, the auth service and the React hooks where the code did not do what its documentation said.

    @venizia/ardor-kernel, @venizia/ardor-react, @venizia/ardor-admin, @venizia/ardor

  53. ARDOR 0.4.1 follows IGNIS 0.4.1Breaking

    The four ARDOR packages move to 0.4.1 and peer on IGNIS 0.4.1; the node fetcher no longer logs the Authorization header or the sign-in password.

    @venizia/ardor-kernel, @venizia/ardor-react, @venizia/ardor-admin, @venizia/ardor · 0.4.1

  54. The fetcher no longer logs secrets, and four request bugs are fixedSecurityFix

    NodeFetcher stops logging request headers and bodies, keeps your abort signal with a timeout, sends bodies as they are, and joins params to a url with a query.

    @venizia/ardor-kernel, @venizia/ardor

  55. ARDOR 0.4.0 follows IGNIS 0.4.0Breaking

    The four ARDOR packages move to 0.4.0 and peer on IGNIS 0.4.0; the app preset gets required runtime variables and no formatter config.

    @venizia/ardor-kernel, @venizia/ardor-react, @venizia/ardor-admin, @venizia/ardor · 0.4.0

  56. Runtime config in the app preset, one image for every environmentFeature

    The app preset writes config.js from VITE_ variables at container start, getRuntimeConfig reads it, and APP_REQUIRED_ENV stops a container early.

    @venizia/ardor-kernel, @venizia/ardor

  57. A feature library presetFeature

    vulcan add --preset ardor --lib <name> adds an ARDOR feature package to a monorepo, with a sample feature and a test that mounts it.

    @venizia/ardor

  58. ARDOR ships a VULCAN presetFeature

    Create a monorepo with an ARDOR admin, or add an admin to an existing monorepo, with the ARDOR preset for VULCAN 0.3.0 or newer.

    @venizia/ardor

  59. ARDOR 0.3.0 Is StableEnhancement

    The four ARDOR packages are published at 0.3.0 on the latest tag, on IGNIS 0.3.0. ARDOR and IGNIS now share a minor version.

    @venizia/ardor-kernel, @venizia/ardor-react, @venizia/ardor-admin, @venizia/ardor · 0.3.0

  60. Every app has the same scriptsBreaking

    The generated admin and the examples use one set of script names (server:dev, compile, typecheck, lint, test, clean). The names dev and build are gone.

    @venizia/ardor

  61. toDataUrl no longer needs Promise.withResolversFix

    toDataUrl builds its promise with new Promise, so it runs on a Chrome older than 119.

    @venizia/ardor-kernel

  62. Augment @venizia/ardor, not the declaring packagesFix

    Augment IUseInjectableKeysOverrides and IUseTranslateKeysOverrides on @venizia/ardor; a block on -react or -admin fails under a non-hoisting linker.

    @venizia/ardor

  63. TPaths stops at a Date, a Set, a function and an any fieldFix

    TPaths no longer names the members of a Date, RegExp, Set, Map, Promise, function or any field as paths, so createdAt.getTime is not a state path.

    @venizia/ardor-kernel

  64. ARDOR 0.1.4 on stable IGNIS 0.2.2Behavior

    The IGNIS peers of the four packages are the stable ^0.2.2 range instead of 0.2.2-N prerelease floors. ARDOR 0.1.4 is the first stable line on them.

    @venizia/ardor-kernel, @venizia/ardor-react, @venizia/ardor-admin, @venizia/ardor · 0.1.4

  65. login stores roles, and the sign-in extension points are protected hooksEnhancementBehavior

    DefaultAuthProvider.login saves the roles of the sign-in response where getRoles reads them. The four sign-in options of 0.1.4-4 become protected hooks.

    @venizia/ardor-kernel, @venizia/ardor-admin

  66. One copy of each package that carries identity, owned by the applicationBehavior

    ra-i18n-polyglot is a peer of ardor-admin and ardor, so an application needs no resolve.dedupe list.

    @venizia/ardor-react, @venizia/ardor-admin, @venizia/ardor

  67. Types, hooks and utilities follow IGNIS house styleBehavior

    Kernel utilities take one options object, React hooks take opts with an enabled flag, and features are defined through Features.

    @venizia/ardor-kernel, @venizia/ardor-react, @venizia/ardor-admin

  68. Options hold data, behaviour lives in protected hooksBehavior

    Callbacks, flags and setters on the network service, providers and fetchers become protected hooks; an old-to-new table lists every renamed name.

    @venizia/ardor-kernel, @venizia/ardor-admin

  69. A Vite application autoloads its classes with IgnisArtifactsVitePluginBehavior

    A Vite application registers its decorated classes with IgnisArtifactsVitePlugin and AutoArtifacts instead of listing them; the IGNIS peer floors move.

    @venizia/ardor-kernel, @venizia/ardor-react, @venizia/ardor-admin, @venizia/ardor

  70. A package depends on its siblings at the exact version released with itFix

    ardor, ardor-admin and ardor-react name the other ARDOR packages at the exact version released with them, so a fresh install cannot pull a newer sibling.

    @venizia/ardor-react, @venizia/ardor-admin, @venizia/ardor

  71. IGNIS's sign-in is the default, and an application can run with no sign-inBehavior

    DefaultAuthProvider signs in the way IGNIS's auth controller expects, and ArdorApplication runs with no auth provider; the old path and body stay expressible.

    @venizia/ardor-kernel, @venizia/ardor-admin

  72. start() names a module cycle in the artifact indexFix

    An artifact index that lists undefined or a non-class, as a module cycle leaves behind, makes start() throw an error that names the position and the cause.

    @venizia/ardor-kernel

  73. PATCH in upper case, log levels, no pagination, no NaN countFix

    Four fixes: upper-case fetcher methods, one console method per log level, getManyReference without pagination, no NaN count.

    @venizia/ardor-admin, @venizia/ardor-kernel

  74. A generated artifact index for the applicationFeature

    artifacts() takes the index ignis-artifacts generate emits, so a bundler keeps every stereotyped class and start() fails on a class that was never discovered.

    @venizia/ardor-kernel

  75. canAccess reaches an AuthProvider subclass without a fourth super argumentFix

    DefaultAuthProvider reads the bound permission provider from the container itself, so a subclass with its own constructor gets canAccess without forwarding it.

    @venizia/ardor-admin

  76. The data provider throws an ApplicationError and reads Content-RangeBreakingBehavior

    A failed request through the REST data providers rejects with an ApplicationError, and a malformed Content-Range falls back to the row count.

    @venizia/ardor-kernel

  77. checkError redirects on a 401 or 403 from the data providerFix

    DefaultAuthProvider.checkError falls back to statusCode, so an ApplicationError thrown by the data provider now reaches its 401 and 403 branches.

    @venizia/ardor-admin

  78. useDocumentTitle and useHtmlLangFeature

    Two admin hooks - one sets the browser tab title per screen and restores it on unmount, the other keeps the html lang attribute on the UI locale.

    @venizia/ardor-admin

  79. Const-value types keep their literals when copiedBreakingBehavior

    TConstValue, TStringConstValue, TNumberConstValue and TStatusFromClass keep their literals when copied into an object literal or a let.

    @venizia/ardor-kernel

  80. List extras on the data provider and the repositoryFeature

    ARDOR adopts IGNIS list extras - getList asks with meta.extra and answers meta.extra, and reads a route's default extras unasked.

    @venizia/ardor-kernel, @venizia/ardor-admin

  81. Feature modules and permissionsFeature

    An application mounts feature packages - resources, routes, bindings, messages - from features(), and answers react-admin's canAccess from its own provider.

    @venizia/ardor-admin, @venizia/ardor-kernel

  82. Class identity survives a minifierBehavior

    A pinned datasource resolves in a minified build, and start() refuses two classes that derive one binding key. The IGNIS peer floors rise with it.

    @venizia/ardor

  83. A repository sends what the data provider sendsBehavior

    getDataSourceAuth() fills IGNIS 0.2.1-4's per-send hooks - session headers, timezone, channel, no token on no-auth paths, the server's error code.

    @venizia/ardor

  84. HttpRepository writes and shares the data provider auth; BaseCrudService goesBreaking

    HttpRepository writes on IGNIS 0.2.1, shares the data provider's token and one 401 refresh, and replaces BaseCrudService. Providers bind as singletons.

    @venizia/ardor

  85. Repositories by discovery, a relative baseUrl, and IGNIS 0.2.0 stableFeatureEnhancement

    Declare an HttpRepository with @repository({ type: RepositoryTypes.REMOTE }), point a datasource at '/api', and raise the IGNIS peers together.

    @venizia/ardor-kernel · 0.2.0

  86. Registration by hand, useRepository, and installs that loadBreakingFeatureFix

    Register artifacts by stereotype or by hand as in IGNIS, resolve repositories by class, BaseApiService removed, packages load under Node ESM.

    @venizia/ardor-kernel, @venizia/ardor-react

  87. IGNIS stereotypes and repositories, bulk writes in the body, safer headersBreakingFeatureFix

    Classes register by stereotype, HTTP repositories come from IGNIS, bulk writes send their selector in the body, and requests work on plain-http origins.

    @venizia/ardor-admin, @venizia/ardor-kernel, @venizia/ardor-react

  88. The network layer is fetch only, and axios is goneBreakingEnhancement

    ARDOR drops its axios transport and moves the socket client behind a sub-path, so importing the framework pulls no HTTP client and no optional peer.

    @venizia/ardor-kernel

  89. One logger per scope, singleton services, and a kernel that owns its headersEnhancement

    One logger per scope, singleton services, an application that binds itself, and per-call headers and form-encoded bodies honoured.

    @venizia/ardor-kernel

  90. ARDOR Replaces @minimaltech/ra-core-infraBreakingFeature

    The frontend framework splits into four ARDOR packages behind an umbrella import, with four symbol renames and updated dependency requirements.

    @venizia/ardor-admin, @venizia/ardor, @venizia/ardor-kernel, @venizia/ardor-react