Skip to content

Commit

Permalink
fix: return a function in onSuccess to do cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
egoist committed Jul 30, 2022
1 parent b595f72 commit 64deb61
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 23 deletions.
25 changes: 23 additions & 2 deletions docs/README.md
Expand Up @@ -331,13 +331,34 @@ tsup src/index.ts --watch --onSuccess "node dist/index.js"
> Warning: You should not use shell scripts, if you need to specify shell scripts you can add it in your "scripts" field and set for example `tsup src/index.ts --watch --onSuccess \"npm run dev\"`

`onSuccess` can also be a `function` that returns `Promise`. For this to work, you need to use `tsup.config.ts` instead of the cli flag:
`onSuccess` can also be a `function` that returns `Promise`. For this to work, you need to use `tsup.config.ts` instead of the cli flag:

```ts
import { defineConfig } from 'tsup'
export default defineConfig({
onSuccess: async () => { ... }
async onSuccess() {
// Start some long running task
// Like a server
},
})
```

You can return a cleanup function in `onSuccess`:

```ts
import { defineConfig } from 'tsup'

export default defineConfig({
async onSuccess() {
const server = http.createServer((req, res) => {
res.end('Hello World!')
})
server.listen(3000)
return () => {
server.close()
}
},
})
```

Expand Down
35 changes: 15 additions & 20 deletions src/index.ts
Expand Up @@ -179,29 +179,24 @@ export async function build(_options: Options) {
}
}

const otherTasks = async () => {
const mainTasks = async () => {
if (!options.dts?.only) {
let existingOnSuccess: ChildProcess | undefined
let existingOnSuccessFnPromise: Promise<any> | undefined
let onSuccessProcess: ChildProcess | undefined
let onSuccessCleanup: (() => any) | undefined | void
/** Files imported by the entry */
const buildDependencies: Set<string> = new Set()

const killPreviousProcessOrPromise = async () => {
if (existingOnSuccess) {
const doOnSuccessCleanup = async () => {
if (onSuccessProcess) {
await killProcess({
pid: existingOnSuccess.pid,
pid: onSuccessProcess.pid,
})
} else if (existingOnSuccessFnPromise) {
await Promise.race([
existingOnSuccessFnPromise,
// cancel existingOnSuccessFnPromise if it is still running,
// using a promise that's been already resolved
Promise.resolve(),
])
} else if (onSuccessCleanup) {
await onSuccessCleanup()
}
// reset them in all occassions anyway
existingOnSuccess = undefined
existingOnSuccessFnPromise = undefined
onSuccessProcess = undefined
onSuccessCleanup = undefined
}

const debouncedBuildAll = debouncePromise(
Expand All @@ -213,7 +208,7 @@ export async function build(_options: Options) {
)

const buildAll = async () => {
const killPromise = killPreviousProcessOrPromise()
await doOnSuccessCleanup()
// Store previous build dependencies in case the build failed
// So we can restore it
const previousBuildDependencies = new Set(buildDependencies)
Expand Down Expand Up @@ -258,12 +253,12 @@ export async function build(_options: Options) {
})
}),
])
await killPromise

if (options.onSuccess) {
if (typeof options.onSuccess === 'function') {
existingOnSuccessFnPromise = options.onSuccess()
onSuccessCleanup = await options.onSuccess()
} else {
existingOnSuccess = execa(options.onSuccess, {
onSuccessProcess = execa(options.onSuccess, {
shell: true,
stdio: 'inherit',
})
Expand Down Expand Up @@ -338,7 +333,7 @@ export async function build(_options: Options) {
}
}

await Promise.all([dtsTask(), otherTasks()])
await Promise.all([dtsTask(), mainTasks()])
}
)
)
Expand Down
4 changes: 3 additions & 1 deletion src/options.ts
Expand Up @@ -72,7 +72,9 @@ export type Options = {
keepNames?: boolean
watch?: boolean | string | (string | boolean)[]
ignoreWatch?: string[] | string
onSuccess?: string | ((...params: any[]) => Promise<any>),
onSuccess?:
| string
| (() => Promise<void | undefined | (() => void | Promise<void>)>)
jsxFactory?: string
jsxFragment?: string
outDir?: string
Expand Down

0 comments on commit 64deb61

Please sign in to comment.