Skip to content

Commit e67b500

Browse files
committed
chore: u
1 parent dc2bd84 commit e67b500

File tree

1 file changed

+54
-21
lines changed

1 file changed

+54
-21
lines changed

src/Instance.ts

Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -129,15 +129,27 @@ export function define<
129129
const { messageBuffer = 20, timeout } = options
130130

131131
let restartResolver = Promise.withResolvers<void>()
132-
let startResolver = Promise.withResolvers<() => void>()
133-
let stopResolver = Promise.withResolvers<void>()
134132

135133
const emitter = new EventEmitter<EventTypes>()
136134

137135
let messages: string[] = []
138136
let status: Instance['status'] = 'idle'
139137
let restarting = false
140138

139+
let currentStart: {
140+
promise: Promise<() => void>
141+
resolve: (fn: () => void) => void
142+
reject: (err: unknown) => void
143+
timer?: NodeJS.Timeout
144+
} | null = null
145+
146+
let currentStop: {
147+
promise: Promise<void>
148+
resolve: () => void
149+
reject: (err: unknown) => void
150+
timer?: NodeJS.Timeout
151+
} | null = null
152+
141153
function onExit() {
142154
status = 'stopped'
143155
}
@@ -167,19 +179,26 @@ export function define<
167179
return status
168180
},
169181
async start() {
170-
if (status === 'starting') return startResolver.promise
182+
if (status === 'starting' && currentStart) return currentStart.promise
171183
if (status !== 'idle' && status !== 'stopped')
172184
throw new Error(
173185
`Instance "${name}" is not in an idle or stopped state. Status: ${status}`,
174186
)
175187

188+
const { promise, resolve, reject } =
189+
Promise.withResolvers<() => void>()
190+
currentStart = { promise, resolve, reject }
191+
176192
if (typeof timeout === 'number') {
177193
const timer = setTimeout(() => {
178-
clearTimeout(timer)
179-
startResolver.reject(
180-
new Error(`Instance "${name}" failed to start in time.`),
181-
)
194+
if (currentStart?.promise === promise) {
195+
currentStart.reject(
196+
new Error(`Instance "${name}" failed to start in time.`),
197+
)
198+
currentStart = null
199+
}
182200
}, timeout)
201+
currentStart.timer = timer
183202
}
184203

185204
emitter.on('message', onMessage)
@@ -199,54 +218,68 @@ export function define<
199218
.then(() => {
200219
status = 'started'
201220

202-
stopResolver = Promise.withResolvers<void>()
203-
startResolver.resolve(this.stop.bind(this))
221+
if (currentStart?.timer) clearTimeout(currentStart.timer)
222+
currentStart?.resolve(this.stop.bind(this))
223+
currentStart = null
204224
})
205225
.catch((error) => {
206226
status = 'idle'
207227
this.messages.clear()
208228
emitter.off('message', onMessage)
209-
startResolver.reject(error)
229+
230+
if (currentStart?.timer) clearTimeout(currentStart.timer)
231+
currentStart?.reject(error)
232+
currentStart = null
210233
})
211234

212-
return startResolver.promise
235+
return promise
213236
},
214237
async stop() {
215-
if (status === 'stopping') return stopResolver.promise
238+
if (status === 'stopping' && currentStop) return currentStop.promise
216239
if (status === 'starting')
217240
throw new Error(`Instance "${name}" is starting.`)
218241

242+
const { promise, resolve, reject } = Promise.withResolvers<void>()
243+
currentStop = { promise, resolve, reject }
244+
219245
if (typeof timeout === 'number') {
220246
const timer = setTimeout(() => {
221-
clearTimeout(timer)
222-
stopResolver.reject(
223-
new Error(`Instance "${name}" failed to stop in time.`),
224-
)
247+
if (currentStop?.promise === promise) {
248+
currentStop.reject(
249+
new Error(`Instance "${name}" failed to stop in time.`),
250+
)
251+
currentStop = null
252+
}
225253
}, timeout)
254+
currentStop.timer = timer
226255
}
227256

228257
status = 'stopping'
229258
stop({
230259
emitter,
231260
status: this.status,
232261
})
233-
.then((...args) => {
262+
.then(() => {
234263
status = 'stopped'
235264
this.messages.clear()
236265

237266
emitter.off('message', onMessage)
238267
emitter.off('listening', onListening)
239268
emitter.off('exit', onExit)
240269

241-
startResolver = Promise.withResolvers<() => void>()
242-
stopResolver.resolve(...args)
270+
if (currentStop?.timer) clearTimeout(currentStop.timer)
271+
currentStop?.resolve()
272+
currentStop = null
243273
})
244274
.catch((error) => {
245275
status = 'started'
246-
stopResolver.reject(error)
276+
277+
if (currentStop?.timer) clearTimeout(currentStop.timer)
278+
currentStop?.reject(error)
279+
currentStop = null
247280
})
248281

249-
return stopResolver.promise
282+
return promise
250283
},
251284
async restart() {
252285
if (restarting) return restartResolver.promise

0 commit comments

Comments
 (0)