@coursebook/change-tracker
Version:
A minimal, type-safe change tracker for JavaScript/TypeScript. You can use it to track changes to files for example.
187 lines (140 loc) • 6 kB
Markdown
# Change Tracker
A minimal, type-safe change tracker for JavaScript/TypeScript. You can use it to track changes to files for example. But it can be used for other things as well, as long as you can represent the data as a collection of types with a `contents: Buffer` property.
**Features:**
- Tracks file changes between builds using MD5 hashes
- Stores change history in a JSON file
- Detects new, modified, unchanged, and untracked files
- Handles deleted files by cleaning up their history
- Provides detailed logging of change tracking operations
- Supports clearing change history
- Written in TypeScript
- Builds to both modern ES modules and CommonJS formats
- Provides TypeScript type definitions
- ESLint for code linting
- Prettier for code formatting
- Vitest for testing
- Tsup for building
- Minimal dependencies
## Installation
This package is published to NPM and you can install it using the following command:
```bash
npm install /change-tracker
```
## Usage
> [!NOTE]
> The type parameter for `ChangeTrackerImpl` and `FileDataCollection` must extend `{ contents: Buffer }`.
### Basic Usage
```typescript
import {
ChangeTrackerImpl,
type FileDataCollection,
} from "@coursebook/change-tracker";
// Define a type for test file data
type TestFileData = { contents: Buffer };
// Create change tracker instance
const changeTracker = new ChangeTrackerImpl<TestFileData>({
historyPath: "./example-history.json",
});
// Track changes in files
// You can change the files object to simulate changes and rerun this script
const files: FileDataCollection<TestFileData> = {
"example.txt": {
contents: Buffer.from("file content!"),
},
};
const states = await changeTracker.trackChanges(files);
// Get state of a specific file
const state = changeTracker.getFileState("example.txt");
console.log(state?.status); // 'new', 'modified', 'unchanged', or 'untracked'
```
### Build Pipeline Example
```typescript
import {
ChangeTrackerImpl,
type FileDataCollection,
} from "@coursebook/change-tracker";
// Define a type for file data
type FileData = { contents: Buffer };
// Initialize components
const changeTracker = new ChangeTrackerImpl<FileData>({
historyPath: ".content-smith/history.json",
});
// During build
async function build() {
// Read files
const files: FileDataCollection<FileData> = await readFiles();
// Track changes
const states = await changeTracker.trackChanges(files);
// Use change states
for (const [filepath, state] of states) {
if (state.status !== "unchanged") {
// Process changed files
await processFile(files[filepath]);
}
}
}
```
## Cloning the Repository
To make your workflow more organized, it's a good idea to clone this repository into a directory named `change-tracker-workspace`. This helps differentiate the workspace from the `change-tracker` located in the `packages` directory.
```bash
git clone https://github.com/proj-coursebook/change-tracker change-tracker-workspace
cd change-tracker-workspace
```
## Repository Structure
- `packages` — Contains the primary package(s) for this repository (e.g., `change-tracker`). Each package is self-contained and can be copied out and used independently.
- `examples` — Contains examples of how to use the packages. Each example is a minimal, standalone project.
- `playgrounds` — Contains demos of the dependencies of the primary package(s). Each playground is a minimal, standalone project.
- `docs` — Contains various documentation for users and developers.
- `.github` — Contains GitHub-specific files, such as workflows and issue templates.
## How to Use This Repo
- To work on a package, go to `packages/<package-name>` and follow its README.
- To try an example, go to `examples/<example-name>` and follow its README.
- To run the playground, go to `playground/<package-name>` and follow its README.
- For documentation, see the `docs` folder.
### Using a VSCode Multi-root Workspace
With Visual Studio Code, you can enhance your development experience by using a multi-root workspace to access packages, examples, and playgrounds simultaneously. This approach is more efficient than opening the root directory, or each package or example separately.
To set up a multi-root workspace:
1. Open Visual Studio Code.
2. Navigate to `File > Open Workspace from File...`.
3. Select the `change-tracker.code-workspace` file located at the root of the repository. This action will open all specified folders in one workspace.
The `change-tracker.code-workspace` file can be customized to include different folders or settings. Here's a typical configuration:
```json
{
"folders": [
{
"path": "packages/change-tracker"
},
{
"path": "examples/simple"
}
],
"settings": {
// Add any workspace-specific settings here, for example:
"git.openRepositoryInParentFolders": "always"
}
}
```
## Developing the Package
Change to the package directory and install dependencies:
```bash
cd packages/change-tracker
npm install
```
- Read the [Project Roadmap](../../docs/ROADMAP.md) for project goals, status, evolution, and development guidelines.
- Read the [Development Guide](../../docs/DEVELOPMENT.md) for detailed information on the package architecture, build configuration, and implementation patterns.
- Follow the [Contributing Guide](../../docs/CONTRIBUTING.md) for contribution guidelines, coding standards, and best practices.
## Package Management
When you are ready to publish your package:
```bash
npm run release
```
This single command will:
- Validate your code with the full validation pipeline
- Analyze commits to determine version bump
- Update package.json version and changelog
- Build the package
- Create and push git tag
- Create GitHub release
- Publish to NPM
> [!TIP]
> For detailed information about package publishing, versioning, and local development workflows, see the [NPM Package Management Guide](../../docs/guides/npm-package.md).