Gathering detailed insights and metrics for jumpgen
Gathering detailed insights and metrics for jumpgen
Gathering detailed insights and metrics for jumpgen
Gathering detailed insights and metrics for jumpgen
Easy, transparent ”watch mode” for filesystem access (powered by Chokidar)
npm install jumpgen
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
8 Stars
112 Commits
1 Watching
5 Branches
1 Contributors
Updated on 26 Nov 2024
TypeScript (100%)
Cumulative downloads
Total Downloads
Last day
500%
18
Compared to previous day
Last week
-87.3%
20
Compared to previous week
Last month
-74.2%
251
Compared to previous month
Last year
0%
1,225
Compared to previous year
4
Easy, transparent ”watch mode” for filesystem access (powered by Chokidar)
The problem: You're writing a script that uses the filesystem as one of its inputs. You want to watch files for changes, so you can rerun your script when they change.
The solution: Use jumpgen
.
Now, your script can use filesystem APIs without worrying about how to watch files for changes, leaving you to focus on the logic of your generator.
task
API. (coming soon)chokidar@4
, picomatch
, tinyglobby
, and fdir
npm packages under the hood for file watching and globbing.See the API Reference for the full documentation.
plop
or yeoman
. But you can absolutely use it to build your own scaffolding tools.chokidar
directly.watchlist
instead.Jumpgen saves the day when your script has complex, configurable logic and/or could benefit from incremental updates. For example, I'm using it to build a type-safe RPC library, alien-rpc
, which is highly configurable and greatly benefits from knowing when certain files change.
1pnpm add jumpgen
Define your generator with a name and a function that receives a Context
object with helper functions for reading, scanning, and writing files. Your generator should avoid using node:fs
APIs directly, or else file-watching will break.
1import { jumpgen } from 'jumpgen' 2 3export default jumpgen( 4 'my-generator', 5 async ({ read, scan, dedent, write }) => { 6 // Find files to use as source modules. If a file matching your globs 7 // is later added or removed, your generator will be rerun (if watch 8 // mode is enabled). 9 const sourceModulePaths = scan(['src/**/*.ts', '!**/*.test.ts'], { 10 absolute: true, 11 }) 12 13 // When you read a file, and you later change or delete it, your generator 14 // will be rerun (if watch mode is enabled). 15 const contents = sourceModulePaths.map(p => read(p)) 16 17 // When you write a file, your generator emits a "write" event. This 18 // is useful for logging, which helps you understand what's happening. 19 contents.forEach((content, i) => { 20 const outPath = sourceModulePaths[i].replace(/\.ts$/, '.js') 21 write(outPath, transform(content)) 22 }) 23 24 // Use the "dedent" function to remove excess indentation from your 25 // template literals. 26 write( 27 'foo.ts', 28 dedent` 29 export const foo = true 30 ` 31 ) 32 } 33)
To run your generator, simply import and call it.
1import myGenerator from './my-generator.js' 2 3// This example uses the default options. 4const runner = myGenerator({ 5 // All file operations are relative to this path. 6 root: process.cwd(), 7 8 // Watch mode must be explicitly enabled. 9 watch: false, 10 11 // You may provide your own EventEmitter, which is mainly useful for 12 // consolidating events across multiple generators. Whether or not you 13 // provide one, you can listen for events on the `runner.events` property. 14 events: undefined, 15}) 16 17// The generator runs immediately. To wait for it to finish, you can 18// await it or call its "then" method. 19await runner 20// or 21runner.then(() => { 22 console.log('done') 23}) 24 25// If the generator is asynchronous and respects the abort signal it's given, 26// you can stop it early with the "stop" method. This also disables file watching. 27await runner.stop() 28 29// Listen to events from the runner. 30runner.events.on('start', generatorName => { 31 console.log(generatorName, 'started') 32}) 33runner.events.on('write', (file, generatorName) => { 34 console.log(generatorName, 'wrote', file) 35}) 36runner.events.on('finish', (result, generatorName) => { 37 console.log(generatorName, 'finished with', result) 38}) 39runner.events.on('error', (error, generatorName) => { 40 console.error(generatorName, 'errored with', error) 41})
The compose
function lets you combine multiple generators into a single generator that runs them all in parallel.
1import { compose } from 'jumpgen' 2 3// The returned generator has the same API as the generators you pass to it, 4// except it resolves with an array containing the results of all the generators. 5const myGenerator = compose(generatorA, generatorB)
See the testing guide for information on how to test your generators.
MIT
No vulnerabilities found.
No security vulnerabilities found.