Skip to content

Instantly share code, notes, and snippets.

@souporserious
Created July 17, 2024 22:36
Show Gist options
  • Save souporserious/719cc6e09393e587a277b1e7695752bf to your computer and use it in GitHub Desktop.
Save souporserious/719cc6e09393e587a277b1e7695752bf to your computer and use it in GitHub Desktop.
Execute a callback once for the lifetime of the process.
import {
existsSync,
mkdirSync,
readFileSync,
writeFileSync,
unlinkSync,
} from 'node:fs'
import { resolve } from 'node:path'
import { homedir } from 'node:os'
const cacheDirectory = resolve(homedir(), '.config', 'mdxts')
const cacheFilePath = resolve(cacheDirectory, 'updated.txt')
let callbackCleanup: (() => void) | undefined
if (!existsSync(cacheDirectory)) {
mkdirSync(cacheDirectory, { recursive: true })
}
/**
* Execute a callback once for the lifetime of the process that calls this function.
* If the process is stale for more than an hour, the callback will be called again.
*/
export async function initializeOnce(callback: () => Promise<() => void>) {
const now = Date.now()
if (existsSync(cacheFilePath)) {
const lastRunTimestamp = parseInt(readFileSync(cacheFilePath, 'utf-8'), 10)
const difference = now - lastRunTimestamp
const oneHour = 60 * 60 * 1000
if (difference < oneHour) {
return
} else {
callbackCleanup?.()
}
}
let cleanupCalled = false
callbackCleanup = await callback()
const cleanup = () => {
if (cleanupCalled) {
return
}
cleanupCalled = true
callbackCleanup?.()
if (existsSync(cacheFilePath)) {
unlinkSync(cacheFilePath)
}
}
writeFileSync(cacheFilePath, now.toString())
process.on('exit', cleanup)
process.on('SIGINT', cleanup)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment