Skip to content

Commit

Permalink
chore: help esbuild tree-shake with pure annotations
Browse files Browse the repository at this point in the history
Ideally, we could remove all of these in the future.
  • Loading branch information
aleclarson committed Aug 4, 2024
1 parent 986d9e0 commit 7d27b63
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 44 deletions.
27 changes: 14 additions & 13 deletions src/async/AggregateError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,20 @@
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError
*/
const AggregateErrorOrPolyfill: AggregateErrorConstructor =
// eslint-disable-next-line compat/compat
globalThis.AggregateError ??
(class AggregateError extends Error {
errors: Error[]
constructor(errors: Error[] = []) {
super()
const name = errors.find(e => e.name)?.name ?? ''
this.name = `AggregateError(${name}...)`
this.message = `AggregateError with ${errors.length} errors`
this.stack = errors.find(e => e.stack)?.stack ?? this.stack
this.errors = errors
}
} as unknown as AggregateErrorConstructor)
/* @__PURE__ */ (() =>
// eslint-disable-next-line compat/compat
globalThis.AggregateError ??
(class AggregateError extends Error {
errors: Error[]
constructor(errors: Error[] = []) {
super()
const name = errors.find(e => e.name)?.name ?? ''
this.name = `AggregateError(${name}...)`
this.message = `AggregateError with ${errors.length} errors`
this.stack = errors.find(e => e.stack)?.stack ?? this.stack
this.errors = errors
}
} as unknown as AggregateErrorConstructor))()

// Do not export directly, so the polyfill isn't renamed to
// `AggregateError2` at build time (which ESBuild does to prevent
Expand Down
63 changes: 34 additions & 29 deletions src/curry/once.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,7 @@ export interface OnceFunction<
[onceSymbol]?: Return | typeof onceSymbol
}

/**
* Create a function that runs at most once, no matter how many times
* it's called. If it was already called before, returns the result
* from the first call. This is a lighter version of `memo()`.
*
* To allow your `once`-wrapped function to be called again, see the
* `once.reset` function.
*
* @see https://radashi-org.github.io/reference/curry/once
* @example
* ```ts
* const fn = once(() => Math.random())
* fn() // 0.5
* fn() // 0.5
* ```
*/
export const once: {
type OnceImplementation = {
<Args extends unknown[], Return, This = unknown>(
fn: (this: This, ...args: Args) => Return,
): (this: This, ...args: Args) => Return
Expand All @@ -47,17 +31,38 @@ export const once: {
* ```
*/
reset(fn: OnceFunction): void
} = fn => {
const onceFn = function (...args: any) {
if (onceFn[onceSymbol] === onceSymbol) {
onceFn[onceSymbol] = fn.apply(this as any, args)
}
return onceFn[onceSymbol]
} as OnceFunction
onceFn[onceSymbol] = onceSymbol
return onceFn as typeof fn
}

once.reset = (fn: OnceFunction): void => {
fn[onceSymbol] = onceSymbol
}
/**
* Create a function that runs at most once, no matter how many times
* it's called. If it was already called before, returns the result
* from the first call. This is a lighter version of `memo()`.
*
* To allow your `once`-wrapped function to be called again, see the
* `once.reset` function.
*
* @see https://radashi-org.github.io/reference/curry/once
* @example
* ```ts
* const fn = once(() => Math.random())
* fn() // 0.5
* fn() // 0.5
* ```
*/
export const once: OnceImplementation = /* @__PURE__ */ (() => {
const once: OnceImplementation = fn => {
const onceFn = function (...args: any) {
if (onceFn[onceSymbol] === onceSymbol) {
onceFn[onceSymbol] = fn.apply(this as any, args)
}
return onceFn[onceSymbol]
} as OnceFunction

onceFn[onceSymbol] = onceSymbol
return onceFn as typeof fn
}
once.reset = (fn: OnceFunction): void => {
fn[onceSymbol] = onceSymbol
}
return once
})()
2 changes: 1 addition & 1 deletion src/typed/isArray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type { StrictExtract } from 'radashi'
* isArray('hello') // => false
* ```
*/
export const isArray = Array.isArray as <Input>(
export const isArray = /* @__PURE__ */ (() => Array.isArray)() as <Input>(
value: Input,
) => value is ExtractArray<Input>

Expand Down
4 changes: 3 additions & 1 deletion src/typed/isInt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@
* isInt(0.1) // => false
* ```
*/
export const isInt = Number.isInteger as (value: unknown) => value is number
export const isInt = /* @__PURE__ */ (() => Number.isInteger)() as (
value: unknown,
) => value is number
5 changes: 5 additions & 0 deletions tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,9 @@ export default defineConfig({
format: ['cjs', 'esm'],
dts: true,
target: 'node16',
treeshake: {
preset: 'smallest',
propertyReadSideEffects: false,
moduleSideEffects: false,
},
})

0 comments on commit 7d27b63

Please sign in to comment.