Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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": [
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin/package.json
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
2 changes: 1 addition & 1 deletion packages/js-toolkit/package.json
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
9 changes: 8 additions & 1 deletion packages/js-toolkit/src/exports.spec.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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<SmoothToRecord<'x' | 'y'>>();
});

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<string, unknown>;
Expand Down
7 changes: 6 additions & 1 deletion packages/js-toolkit/src/utils/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/js-toolkit/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading