Skip to content

Commit 9e272d3

Browse files
committed
build!: Update build, export real ESM (#100)
BREAKING CHANGE: exports native esm modules and removes the index file in favor of sub imports
1 parent a9613ec commit 9e272d3

File tree

72 files changed

+1745
-2191
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+1745
-2191
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
lib/
2-
esm/
2+
cjs/
33

44
# Logs
55
logs

package.json

+37-32
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,27 @@
11
{
22
"name": "@restart/hooks",
33
"version": "0.5.1",
4-
"main": "lib/cjs/index.js",
5-
"types": "lib/cjs/index.d.ts",
6-
"module": "lib/esm/index.js",
4+
"type": "module",
75
"exports": {
8-
".": {
9-
"types": "./esm/index.d.ts",
10-
"import": "./esm/index.js",
11-
"require": "./cjs/index.js"
12-
},
136
"./*": {
14-
"types": "./esm/*.d.ts",
15-
"import": "./esm/*.js",
16-
"require": "./cjs/*.js"
7+
"require": {
8+
"types": "./cjs/index.d.ts",
9+
"default": "./cjs/index.js"
10+
},
11+
"import": {
12+
"types": "./lib/index.d.ts",
13+
"default": "./lib/index.js"
14+
}
1715
}
1816
},
17+
"files": [
18+
"cjs",
19+
"lib",
20+
"CHANGELOG.md"
21+
],
1922
"repository": {
2023
"type": "git",
21-
"url": "git+https://github.com/jquense/react-common-hooks.git"
24+
"url": "git+https://github.com/react-restart/hooks.git"
2225
},
2326
"author": {
2427
"name": "Jason Quense",
@@ -31,12 +34,16 @@
3134
"homepage": "https://github.com/react-restart/hooks#readme",
3235
"scripts": {
3336
"bootstrap": "yarn && yarn --cwd www",
34-
"test": "jest --coverage",
35-
"tdd": "jest --watch",
36-
"build:pick": "cherry-pick --name=@restart/hooks --cwd=lib --input-dir=../src --cjs-dir=cjs --esm-dir=esm",
37-
"build": "rimraf lib && 4c build src && yarn build:pick",
37+
"test": "vitest run --coverage",
38+
"tdd": "vitest",
39+
"build": "rimraf lib cjs && concurrently --names 'esm,cjs' 'yarn build:esm' 'yarn build:cjs' && concurrently --names 'esm types,cjs types' 'yarn build:esm:types' 'yarn build:cjs:types'",
40+
"build:esm": "babel src --env-name esm --out-dir lib --extensions '.ts' --ignore='**/*.d.ts'",
41+
"build:esm:types": "tsc -p . --emitDeclarationOnly --declaration --outDir lib",
42+
"build:cjs": "babel src --out-dir cjs --extensions '.ts' --ignore='**/*.d.ts' && echo '{\"type\": \"commonjs\"}' > cjs/package.json",
43+
"build:cjs:types": "tsc -p . --emitDeclarationOnly --declaration --outDir cjs --module commonjs --moduleResolution node",
3844
"deploy-docs": "yarn --cwd www build --prefix-paths && gh-pages -d www/public",
3945
"prepublishOnly": "yarn build",
46+
"typecheck": "tsc -p . --noEmit",
4047
"release": "rollout"
4148
},
4249
"jest": {
@@ -52,8 +59,7 @@
5259
"trailingComma": "all"
5360
},
5461
"publishConfig": {
55-
"access": "public",
56-
"directory": "lib"
62+
"access": "public"
5763
},
5864
"release": {
5965
"conventionalCommits": true
@@ -64,33 +70,32 @@
6470
"devDependencies": {
6571
"@4c/babel-preset": "^10.2.1",
6672
"@4c/cli": "^4.0.4",
67-
"@4c/jest-preset": "^1.8.1",
6873
"@4c/rollout": "^4.0.2",
6974
"@4c/tsconfig": "^0.4.1",
70-
"@babel/cli": "^7.22.9",
71-
"@babel/core": "^7.22.9",
72-
"@babel/preset-typescript": "^7.22.5",
73-
"@testing-library/react": "^12.1.5",
74-
"@testing-library/react-hooks": "^7.0.0",
75-
"@types/jest": "^29.5.3",
75+
"@babel/cli": "^7.26.4",
76+
"@babel/core": "^7.26.0",
77+
"@babel/preset-typescript": "^7.26.0",
78+
"@testing-library/dom": "^10.4.0",
79+
"@testing-library/react": "^16.1.0",
7680
"@types/lodash": "^4.14.195",
77-
"@types/react": "^18.2.15",
78-
"babel-jest": "^29.6.1",
81+
"@types/react": "^19.0.2",
82+
"@vitest/coverage-v8": "2.1.8",
7983
"babel-plugin-transform-rename-import": "^2.3.0",
8084
"cherry-pick": "^0.5.0",
8185
"codecov": "^3.8.3",
86+
"concurrently": "^9.1.2",
8287
"eslint": "^8.44.0",
8388
"gh-pages": "^3.1.0",
8489
"husky": "^4.3.6",
85-
"jest": "^29.6.1",
86-
"jest-environment-jsdom": "^29.6.1",
90+
"jsdom": "^25.0.1",
8791
"lint-staged": "^13.2.3",
8892
"mq-polyfill": "^1.1.8",
8993
"prettier": "^3.0.0",
90-
"react": "^16.13.0",
91-
"react-dom": "^16.13.0",
94+
"react": "^19.0.0",
95+
"react-dom": "^19.0.0",
9296
"rimraf": "^5.0.1",
93-
"typescript": "^5.1.6"
97+
"typescript": "^5.1.6",
98+
"vitest": "^2.1.8"
9499
},
95100
"dependencies": {
96101
"dequal": "^2.0.3"

src/index.ts

-29
This file was deleted.

src/useAnimationFrame.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useEffect, useState } from 'react'
2-
import useMounted from './useMounted'
2+
import useMounted from './useMounted.js'
33

44
export interface UseAnimationFrameReturn {
55
cancel(): void

src/useBreakpoint.ts

+13-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import useMediaQuery from './useMediaQuery'
1+
import useMediaQuery from './useMediaQuery.js'
22
import { useMemo } from 'react'
33

44
export type BreakpointDirection = 'up' | 'down' | true
@@ -124,19 +124,18 @@ export function createBreakpointHook<TKey extends string>(
124124

125125
let query = useMemo(
126126
() =>
127-
Object.entries(breakpointMap).reduce(
128-
(query, [key, direction]: [TKey, BreakpointDirection]) => {
129-
if (direction === 'up' || direction === true) {
130-
query = and(query, getMinQuery(key))
131-
}
132-
if (direction === 'down' || direction === true) {
133-
query = and(query, getMaxQuery(key))
134-
}
135-
136-
return query
137-
},
138-
'',
139-
),
127+
Object.entries(breakpointMap).reduce((query, entry) => {
128+
const [key, direction] = entry as [TKey, BreakpointDirection]
129+
130+
if (direction === 'up' || direction === true) {
131+
query = and(query, getMinQuery(key))
132+
}
133+
if (direction === 'down' || direction === true) {
134+
query = and(query, getMaxQuery(key))
135+
}
136+
137+
return query
138+
}, ''),
140139
[JSON.stringify(breakpointMap)],
141140
)
142141

src/useCustomEffect.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
useEffect,
66
useDebugValue,
77
} from 'react'
8-
import useMounted from './useMounted'
8+
import useMounted from './useMounted.js'
99

1010
export type EffectHook = (effect: EffectCallback, deps?: DependencyList) => void
1111

@@ -61,7 +61,7 @@ function useCustomEffect<TDeps extends DependencyList = DependencyList>(
6161
? { isEqual: isEqualOrOptions }
6262
: isEqualOrOptions
6363

64-
const dependenciesRef = useRef<TDeps>()
64+
const dependenciesRef = useRef<TDeps | null>(null)
6565
dependenciesRef.current = dependencies
6666

6767
const cleanupRef = useRef<CleanUp | null>(null)

src/useDebouncedCallback.ts

+16-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useMemo, useRef } from 'react'
2-
import useTimeout from './useTimeout'
3-
import useEventCallback from './useEventCallback'
2+
import useTimeout from './useTimeout.js'
3+
import useEventCallback from './useEventCallback.js'
44

55
export interface UseDebouncedCallbackOptions {
66
wait: number
@@ -14,6 +14,8 @@ export interface UseDebouncedCallbackOptionsLeading
1414
leading: true
1515
}
1616

17+
const EMPTY: unique symbol = Symbol('EMPTY')
18+
1719
/**
1820
* Creates a debounced function that will invoke the input function after the
1921
* specified wait.
@@ -50,7 +52,7 @@ function useDebouncedCallback<TCallback extends (...args: any[]) => any>(
5052
): (...args: Parameters<TCallback>) => ReturnType<TCallback> | undefined {
5153
const lastCallTimeRef = useRef<number | null>(null)
5254
const lastInvokeTimeRef = useRef(0)
53-
const returnValueRef = useRef<ReturnType<TCallback>>()
55+
const returnValueRef = useRef<ReturnType<TCallback> | typeof EMPTY>(EMPTY)
5456

5557
const isTimerSetRef = useRef(false)
5658
const lastArgsRef = useRef<unknown[] | null>(null)
@@ -80,7 +82,9 @@ function useDebouncedCallback<TCallback extends (...args: any[]) => any>(
8082
timeout.set(timerExpired, wait)
8183

8284
if (!leading) {
83-
return returnValueRef.current
85+
return returnValueRef.current === EMPTY
86+
? undefined
87+
: returnValueRef.current
8488
}
8589

8690
return invokeFunc(time)
@@ -96,7 +100,9 @@ function useDebouncedCallback<TCallback extends (...args: any[]) => any>(
96100
}
97101

98102
lastArgsRef.current = null
99-
return returnValueRef.current
103+
return returnValueRef.current === EMPTY
104+
? undefined
105+
: returnValueRef.current
100106
}
101107

102108
function timerExpired() {
@@ -110,6 +116,8 @@ function useDebouncedCallback<TCallback extends (...args: any[]) => any>(
110116
const timeSinceLastInvoke = time - lastInvokeTimeRef.current
111117
const timeWaiting = wait - timeSinceLastCall
112118

119+
// console.log('g', Math.min(timeWaiting, maxWait - timeSinceLastInvoke))
120+
113121
// Restart the timer.
114122
timeout.set(
115123
timerExpired,
@@ -170,7 +178,9 @@ function useDebouncedCallback<TCallback extends (...args: any[]) => any>(
170178
timeout.set(timerExpired, wait)
171179
}
172180

173-
return returnValueRef.current
181+
return returnValueRef.current === EMPTY
182+
? undefined
183+
: returnValueRef.current
174184
}
175185
}, [handleCallback, wait, maxWait, leading, trailing])
176186
}

src/useDebouncedState.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useState, Dispatch, SetStateAction } from 'react'
22
import useDebouncedCallback, {
33
UseDebouncedCallbackOptions,
4-
} from './useDebouncedCallback'
4+
} from './useDebouncedCallback.js'
55

66
/**
77
* Similar to `useState`, except the setter function is debounced by

src/useDebouncedValue.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useEffect, useDebugValue, useRef } from 'react'
2-
import useDebouncedState from './useDebouncedState'
3-
import { UseDebouncedCallbackOptions } from './useDebouncedCallback'
2+
import useDebouncedState from './useDebouncedState.js'
3+
import { UseDebouncedCallbackOptions } from './useDebouncedCallback.js'
44

55
const defaultIsEqual = (a: any, b: any) => a === b
66

src/useEventCallback.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { useEffect, useCallback, useRef } from 'react'
2-
import useCommittedRef from './useCommittedRef'
2+
import useCommittedRef from './useCommittedRef.js'
33

44
export default function useEventCallback<
5-
TCallback extends (...args: any[]) => any
5+
TCallback extends (...args: any[]) => any,
66
>(fn?: TCallback | null): TCallback {
77
const ref = useCommittedRef(fn)
88
return useCallback(
9-
function(...args: any[]) {
9+
function (...args: any[]) {
1010
return ref.current && ref.current(...args)
1111
},
1212
[ref],

src/useEventListener.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useEffect } from 'react'
22

3-
import useEventCallback from './useEventCallback'
3+
import useEventCallback from './useEventCallback.js'
44

55
type EventHandler<T, K extends keyof DocumentEventMap> = (
66
this: T,
@@ -18,14 +18,14 @@ type EventHandler<T, K extends keyof DocumentEventMap> = (
1818
*/
1919
export default function useEventListener<
2020
T extends Element | Document | Window,
21-
K extends keyof DocumentEventMap
21+
K extends keyof DocumentEventMap,
2222
>(
2323
eventTarget: T | (() => T),
2424
event: K,
2525
listener: EventHandler<T, K>,
2626
capture: boolean | AddEventListenerOptions = false,
2727
) {
28-
const handler = useEventCallback(listener)
28+
const handler = useEventCallback(listener) as EventListener
2929

3030
useEffect(() => {
3131
const target =

src/useFocusManager.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useCallback, useMemo, useRef } from 'react'
2-
import useEventCallback from './useEventCallback'
3-
import useMounted from './useMounted'
2+
import useEventCallback from './useEventCallback.js'
3+
import useMounted from './useMounted.js'
44

55
export interface FocusManagerOptions {
66
/**
@@ -59,8 +59,8 @@ export default function useFocusManager(
5959
): FocusController {
6060
const isMounted = useMounted()
6161

62-
const lastFocused = useRef<boolean | undefined>()
63-
const handle = useRef<number | undefined>()
62+
const lastFocused = useRef<boolean | undefined>(undefined)
63+
const handle = useRef<number | undefined>(undefined)
6464

6565
const willHandle = useEventCallback(opts.willHandle)
6666
const didHandle = useEventCallback(opts.didHandle)

src/useGlobalListener.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import useEventListener from './useEventListener'
1+
import useEventListener from './useEventListener.js'
22
import { useCallback } from 'react'
33

44
type DocumentEventHandler<K extends keyof DocumentEventMap> = (

src/useImmediateUpdateEffect.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
import useUpdateImmediateEffect from './useUpdateImmediateEffect'
1+
import useUpdateImmediateEffect from './useUpdateImmediateEffect.js'
22

33
export default useUpdateImmediateEffect

src/useIntersectionObserver.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { useState } from 'react'
22

3-
import useStableMemo from './useStableMemo'
4-
import useEffect from './useIsomorphicEffect'
5-
import useEventCallback from './useEventCallback'
3+
import useStableMemo from './useStableMemo.js'
4+
import useEffect from './useIsomorphicEffect.js'
5+
import useEventCallback from './useEventCallback.js'
66

77
/**
88
* Setup an [`IntersectionObserver`](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver) on

src/useInterval.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useEffect } from 'react'
2-
import useCommittedRef from './useCommittedRef'
2+
import useCommittedRef from './useCommittedRef.js'
33

44
/**
55
* Creates a `setInterval` that is properly cleaned up when a component unmounted

0 commit comments

Comments
 (0)