diff --git a/CHANGELOG.md b/CHANGELOG.md index c6451c79..45720956 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format ## [Unreleased] +## [4.0.0-alpha.1](https://github.com/studiometa/js-toolkit/compare/4.0.0-alpha.0..4.0.0-alpha.1) (2026-08-27) + +### Fixed + +- Export `SmoothToRecord` from `@studiometa/js-toolkit/utils`. It is the return type of the record overload of `smoothTo()`, so it is part of the public signature, but the barrel named only `SmoothTo` and `SmoothToOptions` and the type never reached `dist` — a consumer holding the record in a field or a signature could not write its type. Found by the `@studiometa/ui` v2 port, which had to copy the interface into its own source ([#873](https://github.com/studiometa/js-toolkit/pull/873)) + ## [4.0.0-alpha.0](https://github.com/studiometa/js-toolkit/compare/3.9.0..4.0.0-alpha.0) (2026-08-26) **4.0 is a rewrite, and this is its first published release.** It goes to the `next` dist-tag, so `latest` still installs 3.x. The API is stable and documented; the alpha label says it has not yet run on a production project. diff --git a/package-lock.json b/package-lock.json index ed124d66..e4c1466d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@studiometa/js-toolkit-workspace", - "version": "4.0.0-alpha.0", + "version": "4.0.0-alpha.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@studiometa/js-toolkit-workspace", - "version": "4.0.0-alpha.0", + "version": "4.0.0-alpha.1", "hasInstallScript": true, "workspaces": [ "packages/*" @@ -9604,7 +9604,7 @@ }, "packages/eslint-plugin": { "name": "@studiometa/eslint-plugin-js-toolkit", - "version": "4.0.0-alpha.0", + "version": "4.0.0-alpha.1", "license": "MIT", "dependencies": { "@oxlint/plugins": "1.77.0" @@ -9619,7 +9619,7 @@ }, "packages/js-toolkit": { "name": "@studiometa/js-toolkit", - "version": "4.0.0-alpha.0", + "version": "4.0.0-alpha.1", "license": "MIT", "dependencies": { "morphdom": "^2.7.8" diff --git a/package.json b/package.json index b70cc434..fb33fed2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@studiometa/js-toolkit-workspace", - "version": "4.0.0-alpha.0", + "version": "4.0.0-alpha.1", "private": true, "type": "module", "workspaces": [ diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 0f19f85a..5066a269 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@studiometa/eslint-plugin-js-toolkit", - "version": "4.0.0-alpha.0", + "version": "4.0.0-alpha.1", "description": "Oxlint/ESLint plugin for @studiometa/js-toolkit best practices", "publishConfig": { "access": "public" diff --git a/packages/js-toolkit/package.json b/packages/js-toolkit/package.json index 2d47f9b6..d4d08beb 100644 --- a/packages/js-toolkit/package.json +++ b/packages/js-toolkit/package.json @@ -1,6 +1,6 @@ { "name": "@studiometa/js-toolkit", - "version": "4.0.0-alpha.0", + "version": "4.0.0-alpha.1", "type": "module", "sideEffects": [ "./dist/responsive-options.js" diff --git a/packages/js-toolkit/src/exports.spec.ts b/packages/js-toolkit/src/exports.spec.ts index 21690619..2be5cad6 100644 --- a/packages/js-toolkit/src/exports.spec.ts +++ b/packages/js-toolkit/src/exports.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, expectTypeOf, it } from 'vitest'; import packageManifest from '../package.json' with { type: 'json' }; -import { clamp, smoothTo } from '@studiometa/js-toolkit/utils'; +import { clamp, smoothTo, type SmoothToRecord } from '@studiometa/js-toolkit/utils'; import { Base, DIAGNOSTICS, @@ -173,6 +173,13 @@ describe('the package entry points', () => { x.destroy(); }); + it('names the return type of the record overload of smoothTo', () => { + // The overload is public, so what it returns has to be nameable from the + // entry point — a consumer holding the record in a field or a signature + // cannot write its type otherwise. + expectTypeOf(smoothTo({ x: 0, y: 0 })).toEqualTypeOf>(); + }); + it('keeps the framework on the root entry, without the utils or removed exports', async () => { expect(typeof Base).toBe('function'); const root = (await import('@studiometa/js-toolkit')) as Record; diff --git a/packages/js-toolkit/src/utils/index.spec.ts b/packages/js-toolkit/src/utils/index.spec.ts index 9d997812..7ad3bc2e 100644 --- a/packages/js-toolkit/src/utils/index.spec.ts +++ b/packages/js-toolkit/src/utils/index.spec.ts @@ -19,7 +19,7 @@ import * as strings from './strings.js'; import * as timing from './timing.js'; import * as transformModule from './transform.js'; import * as transitionModule from './transition.js'; -import type { Memo, SmoothTo, SmoothToOptions, SpringOptions } from './index.js'; +import type { Memo, SmoothTo, SmoothToOptions, SmoothToRecord, SpringOptions } from './index.js'; describe('the utils barrel', () => { it('names every runtime export of every module it fronts', () => { @@ -52,11 +52,16 @@ describe('the utils barrel', () => { const spring: SpringOptions = { stiffness: 0.2, damping: 0.6, mass: 1 }; const options: SmoothToOptions = { ...spring, spring: true, precision: 0.01 }; const value: SmoothTo = barrel.smoothTo(0, options); + // The record overload returns a type of its own, so a consumer holding what + // it returns has to be able to name it from the barrel. + const record: SmoothToRecord<'x' | 'y'> = barrel.smoothTo({ x: 0, y: 0 }, options); const upper: Memo<[key: string], string> = barrel.memo((key: string) => key.toUpperCase()); expect(upper('a')).toBe('A'); expect(value()).toBe(0); + expect(record()).toEqual({ x: 0, y: 0 }); value.destroy(); + record.destroy(); }); it('exports nothing the framework barrel also exports', () => { diff --git a/packages/js-toolkit/src/utils/index.ts b/packages/js-toolkit/src/utils/index.ts index f4b32872..fa9a3d9f 100644 --- a/packages/js-toolkit/src/utils/index.ts +++ b/packages/js-toolkit/src/utils/index.ts @@ -85,7 +85,7 @@ export { } from './scrollTo.js'; export { lockScroll } from './scroll-lock.js'; export { selectorFor } from './selectors.js'; -export { smoothTo, type SmoothTo, type SmoothToOptions } from './smoothTo.js'; +export { smoothTo, type SmoothTo, type SmoothToOptions, type SmoothToRecord } from './smoothTo.js'; export { camelCase, capitalize,