Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
insidewhy committed Oct 16, 2020
0 parents commit 251d1fd
Show file tree
Hide file tree
Showing 13 changed files with 1,537 additions and 0 deletions.
32 changes: 32 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
version: 2
jobs:
test:
docker:
- image: circleci/node:10
working_directory: ~/repo
steps:
- run:
name: install watchman
command: |
echo "deb http://http.us.debian.org/debian testing main non-free contrib" | sudo tee -a /etc/apt/sources.list
sudo apt-get update
sudo apt-get install watchman
- checkout
- restore_cache:
keys:
- v1-dependencies-{{ checksum "yarn.lock" }}
- v1-dependencies-
- run: yarn install --frozen-lockfile
- save_cache:
paths:
- node_modules
key: v1-dependencies-{{ checksum "yarn.lock" }}
- run: yarn build
- run: yarn test
- run: yarn lint
- run: yarn validate-prettiness
workflows:
version: 2
test:
jobs:
- test
15 changes: 15 additions & 0 deletions .eslintrc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
parser: "@typescript-eslint/parser"
plugins:
- "@typescript-eslint"
extends:
- "plugin:@typescript-eslint/recommended"
- eslint-config-prettier
rules:
no-unused-vars:
- warn
"@typescript-eslint/member-delimiter-style":
- warn
-
multiline:
delimiter: none
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/dist
/node_modules
/test/dist
/test/src
1 change: 1 addition & 0 deletions .huskyrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
precommit: pretty-quick --staged
4 changes: 4 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
semi: false
printWidth: 98
singleQuote: true
trailingComma: all
5 changes: 5 additions & 0 deletions .renovaterc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extends": [
"config:base"
]
}
3 changes: 3 additions & 0 deletions bin/ts-lube
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env node

require('../dist/command.js').main()
47 changes: 47 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "ts-lube",
"version": "0.0.1",
"description": "run tsc incremental watch and restart process when updates are detected",
"author": "insidewhy <github@chilon.net>",
"license": "ISC",
"keywords": [
"typescript",
"tsc"
],
"repository": {
"type": "git",
"url": "git://github.com/insidewhy/ts-lube.git"
},
"main": "dist/index.js",
"typings": "dist/index",
"bin": {
"ts-lube": "./bin/ts-lube"
},
"sideEffects": false,
"scripts": {
"prepublishOnly": "yarn build",
"test": "echo TODO",
"build": "tsc -p src",
"watch": "yarn build -w",
"clean": "rimraf dist",
"lint": "eslint 'src/*.ts'",
"lint-fix": "yarn lint --fix",
"run-prettier": "prettier 'src/*.ts' '*.md'",
"validate-prettiness": "yarn run-prettier -c",
"make-prettier": "yarn run-prettier --write",
"validate": "yarn test && yarn lint && yarn validate-prettiness"
},
"dependencies": {},
"devDependencies": {
"@types/node": "12.12.37",
"@typescript-eslint/eslint-plugin": "2.34.0",
"@typescript-eslint/parser": "2.34.0",
"eslint": "7.1.0",
"eslint-config-prettier": "6.11.0",
"husky": "4.2.5",
"prettier": "2.0.5",
"pretty-quick": "2.0.1",
"rimraf": "3.0.2",
"typescript": "3.9.3"
}
}
18 changes: 18 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# ts-lube

[![Known Vulnerabilities](https://snyk.io/test/github/insidewhy/ts-lube/badge.svg)](https://snyk.io/test/github/insidewhy/ts-lube)
[![Renovate](https://img.shields.io/badge/renovate-enabled-brightgreen.svg)](https://renovatebot.com)

## Usage

```bash
ts-lube dist
```

Runs `npx tsc --incremental --watch` and runs `node dist` after the first compilation finishes and then restarts it whenever changes are detected (debouncing updates by 300ms).

```bash
ts-lube -y -d 500 dist/kittens.js
```

Runs `yarn tsc --incremental --watch` and runs `node dist/kittens.js` after the first compilation finishes and then restarts it whenever changes are detected (debouncing updates by 500ms).
33 changes: 33 additions & 0 deletions src/command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { tsLube, TsLubeOptions } from '.'

async function doMain(): Promise<void> {
const args = process.argv
const opts: TsLubeOptions = {}

let i = 2
for (; i < args.length; ++i) {
const arg = args[i]
if (arg === '-d' || arg === '--debounce') {
opts.debounce = parseInt(args[++i])
} else if (arg === '-y' || arg === '--yarn') {
opts.yarn = true
} else if (arg === '-v' || arg === '--verbose') {
opts.verbose = true
} else {
break
}
}
const spawnArgs = args.slice(i)

await tsLube(spawnArgs, opts)
}

export async function main(): Promise<void> {
try {
// await to ensure exceptions are propagated
await doMain()
} catch (e) {
console.error(typeof e === 'string' ? e : e.message)
process.exit(1)
}
}
87 changes: 87 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { spawn, ChildProcess } from 'child_process'

export interface TsLubeOptions {
debounce?: number
yarn?: boolean
verbose?: boolean
}

function debounceFunction(cmd: () => void, interval: number): () => void {
let timeout: NodeJS.Timeout | undefined

return (): void => {
if (timeout !== undefined) {
clearTimeout(timeout)
timeout = undefined
}

setTimeout(() => {
timeout = undefined
cmd()
}, interval)
}
}

export async function tsLube(
spawnArgs: string[],
{ debounce = 300, yarn = false, verbose = false }: TsLubeOptions,
): Promise<void> {
let proc: ChildProcess | undefined

const tsc = spawn(yarn ? 'yarn' : 'npx', ['tsc', '--incremental', '--watch'], {
stdio: ['ignore', 'pipe', 'pipe'],
})

const onProcessExit = (): void => {
console.warn('process exited unexpectedly')
proc = undefined
}

const spawnProcess = (): void => {
proc = spawn('node', spawnArgs, { stdio: 'inherit' })

proc.on('exit', onProcessExit)
}

const restartProcess = debounceFunction(() => {
if (proc) {
proc.off('exit', onProcessExit)

proc.on('exit', () => {
proc = undefined
if (verbose) {
console.log('process exited')
}
spawnProcess()
})
proc.kill()
} else {
spawnProcess()
}
}, debounce)

tsc.stdout.on('data', (lineBuffer: Buffer) => {
const line = lineBuffer.toString()
if (verbose) {
console.log('tsc:', line.trim())
}

if (line.includes('Found 0 errors.')) {
if (!proc) {
if (verbose) {
console.log(`starting process`)
}
spawnProcess()
} else {
if (verbose) {
console.log(`restarting process`)
}
restartProcess()
}
}
})

tsc.stderr.on('data', (line) => {
console.warn('tsc:', line.toString().trim())
})
}
14 changes: 14 additions & 0 deletions src/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"compilerOptions": {
"declaration": true,
"strict": true,
"lib": ["es6"],
"module": "commonjs",
"moduleResolution": "node",
"outDir": "../dist",
"sourceMap": true,
"target": "es2017",
"preserveWatchOutput": true
},
"include": ["."]
}
Loading

0 comments on commit 251d1fd

Please sign in to comment.