{"_id":"@andrew24601/reckon","_rev":"3-ad97422897a2b37725a6f6f8ee3a33f9","name":"@andrew24601/reckon","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@andrew24601/reckon","version":"0.1.0","keywords":["build","incremental","task-runner","node","typescript"],"license":"MIT","_id":"@andrew24601/reckon@0.1.0","maintainers":[{"name":"andrew24601","email":"extremebasic@gmail.com"}],"dist":{"shasum":"c3430ab222adb38d3faf8c2446376434d8840133","tarball":"https://registry.npmjs.org/@andrew24601/reckon/-/reckon-0.1.0.tgz","fileCount":20,"integrity":"sha512-EDKF5p4rAMBCpS1OdwjKSKVId4uvADpNUil36dt5OUMOXwbWMJUAlxNLDCLfrFyx/jl9DQwCeDAYX5IFxGpTSQ==","signatures":[{"sig":"MEMCIA+q40WNu/clvY2FX/PQtGEBySrBbK8maWaJc0N2VLZwAh8ynEGS4B0TKOJUIBRNFbLDaHWhrvPxt5rVp0KCrFgh","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":61839},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"dc8b871fa7bfc2058565d901370e728cbdbd9d49","scripts":{"test":"node --import tsx --test test/**/*.test.ts","build":"node --input-type=module -e \"import { rm } from 'node:fs/promises'; await rm('dist', { recursive: true, force: true });\" && tsc -p tsconfig.build.json","check":"tsc --noEmit -p tsconfig.json","prepack":"npm run build","pack:dry-run":"npm pack --dry-run","release:check":"npm run check && npm test && npm run build && npm pack --dry-run","prepublishOnly":"npm run check && npm test"},"_npmUser":{"name":"andrew24601","email":"extremebasic@gmail.com"},"_npmVersion":"11.13.0","description":"Incremental Node.js build graph runner","directories":{},"sideEffects":false,"_nodeVersion":"22.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.3","typescript":"^5.8.3","@types/node":"^22.15.18"},"_npmOperationalInternal":{"tmp":"tmp/reckon_0.1.0_1778578853890_0.47890654842704494","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@andrew24601/reckon","version":"0.1.1","keywords":["build","incremental","task-runner","node","typescript"],"license":"MIT","_id":"@andrew24601/reckon@0.1.1","maintainers":[{"name":"andrew24601","email":"extremebasic@gmail.com"}],"dist":{"shasum":"9085418e41b3b6f1aa90a294546f2c6d03518a2f","tarball":"https://registry.npmjs.org/@andrew24601/reckon/-/reckon-0.1.1.tgz","fileCount":20,"integrity":"sha512-jicSrG0RtLn8yI4eOl2AdT/5qghl1QS6VR/AnBlAnvWkXXxAkQSW4mGXdhHOS6FIa7AOZnvW+otNFIjyPFvTtQ==","signatures":[{"sig":"MEYCIQD64A3jM+cr+ZOofklBZ3PZIFlyK3OQlgh6Gaft8LDqNAIhALgVmkNJcKBDLOlW5anjWPoilTCFIYrexo5PkoF4o7Ka","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":62972},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"d3e1ccec926b82e7d53907fddca17311eb4ba262","scripts":{"test":"node --import tsx --test test/**/*.test.ts","build":"node --input-type=module -e \"import { rm } from 'node:fs/promises'; await rm('dist', { recursive: true, force: true });\" && tsc -p tsconfig.build.json","check":"tsc --noEmit -p tsconfig.json","prepack":"npm run build","pack:dry-run":"npm pack --dry-run","release:check":"npm run check && npm test && npm run build && npm pack --dry-run","prepublishOnly":"npm run check && npm test"},"_npmUser":{"name":"andrew24601","email":"extremebasic@gmail.com"},"_npmVersion":"11.13.0","description":"Incremental Node.js build graph runner","directories":{},"sideEffects":false,"_nodeVersion":"22.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.3","typescript":"^5.8.3","@types/node":"^22.15.18"},"_npmOperationalInternal":{"tmp":"tmp/reckon_0.1.1_1778666079993_0.7661688383452105","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@andrew24601/reckon","version":"0.1.2","description":"Incremental Node.js build graph runner","license":"MIT","type":"module","sideEffects":false,"engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"main":"dist/index.js","types":"dist/index.d.ts","keywords":["build","incremental","task-runner","node","typescript"],"publishConfig":{"access":"public"},"scripts":{"build":"node --input-type=module -e \"import { rm } from 'node:fs/promises'; await rm('dist', { recursive: true, force: true });\" && tsc -p tsconfig.build.json","check":"tsc --noEmit -p tsconfig.json","test":"node --import tsx --test test/**/*.test.ts","prepack":"npm run build","prepublishOnly":"npm run check && npm test","pack:dry-run":"npm pack --dry-run","release:check":"npm run check && npm test && npm run build && npm pack --dry-run"},"devDependencies":{"@types/node":"^22.15.18","tsx":"^4.19.3","typescript":"^5.8.3"},"gitHead":"0d1b32c99b94312981057f4994395748b589a399","_id":"@andrew24601/reckon@0.1.2","_nodeVersion":"22.14.0","_npmVersion":"11.13.0","dist":{"integrity":"sha512-6SG0oEO6BGWqIjFJDeQAeEwTFnPTOurQJu6XCCD0TIdFxgi2CfwIIS+nObaiIea3a4Ui5ZpNfj/onpF9hcDPAw==","shasum":"5814d4e69d91cdb47e94bcf73d4f9ac13cbceda2","tarball":"https://registry.npmjs.org/@andrew24601/reckon/-/reckon-0.1.2.tgz","fileCount":20,"unpackedSize":68332,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIFMnm7sxR7KfK/1XSZILfl3SZejUvLwNf3QP8mUgRfUUAiEAn48Tl4iLHwdf0PbLmSGL0YV60v6uufVmcf63kKQgawY="}]},"_npmUser":{"name":"andrew24601","email":"extremebasic@gmail.com"},"directories":{},"maintainers":[{"name":"andrew24601","email":"extremebasic@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/reckon_0.1.2_1778749662385_0.12416466920816815"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-12T09:40:53.815Z","modified":"2026-05-14T09:07:42.634Z","0.1.0":"2026-05-12T09:40:54.020Z","0.1.1":"2026-05-13T09:54:40.166Z","0.1.2":"2026-05-14T09:07:42.530Z"},"license":"MIT","keywords":["build","incremental","task-runner","node","typescript"],"description":"Incremental Node.js build graph runner","maintainers":[{"name":"andrew24601","email":"extremebasic@gmail.com"}],"readme":"# Reckon\n\nReckon is a library-first incremental build system for Node.js. You describe a build as a graph of tasks in JavaScript or TypeScript, then run that graph with `reckon(...)`. Reckon persists task state under `.reckon/state.json`, skips work when inputs and outputs are unchanged, and executes independent tasks in parallel.\n\nThe package is published as ESM. For most projects, use a plain `build.mjs` file and run it with Node. TypeScript build files work well too, but they require a runner such as `tsx`.\n\n## Install\n\n```bash\nnpm install --save-dev reckon\n```\n\n## Quick Start\n\nCreate `build.mjs`:\n\n```js\nimport { clangTree, executable, reckon } from \"reckon\";\n\nconst objects = clangTree(\"src\");\nconst app = executable(\"build/hello\", objects);\n\nawait reckon(app, {\n  verbose: true,\n  clang: {\n    includes: [\"src\"],\n  },\n});\n```\n\nThen run:\n\n```bash\nnode build.mjs\n```\n\n`build.mjs` is the recommended default name because Reckon is a library, not a CLI with a special config-file convention. If you prefer TypeScript, `build.ts` is also sensible:\n\n```bash\nnpm install --save-dev tsx\nnpx tsx build.ts\n```\n\n## What It Does\n\n- Runs task graphs through the `reckon(...)` library API\n- Stores incremental state in `.reckon/state.json`\n- Skips tasks when fingerprints, declared inputs, discovered dependencies, and outputs are unchanged\n- Schedules independent tasks in parallel\n- Provides filesystem helpers: `mkdir`, `writeFile`, `copy`, and `command`\n- Provides C-family helpers: `clang`, `clangTree`, and `executable`\n- Provides unsigned macOS app bundle helpers: `macOSApp`, `appBundle`, and `pngIcon`\n\n## Command Tasks\n\nUse `command(...)` for external tools that are not covered by a built-in helper. Declare outputs explicitly, and list any source files or config files in `fileDependencies`:\n\n```js\nimport { command, reckon } from \"reckon\";\n\nconst webBundle = command(\"npm\", [\"run\", \"build\"], {\n  cwd: \"web\",\n  outputs: [\"web/dist/app.bundle.js\"],\n  fileDependencies: [\"web/build.mjs\", \"web/package.json\", \"web/src/*.js\"],\n});\n\nawait reckon(webBundle);\n```\n\n`fileDependencies` supports `*`, `?`, and `**` wildcards. Reckon expands those patterns to concrete files when checking whether the task is dirty, so matching file additions, removals, and edits trigger a rebuild. Outputs remain explicit paths.\n\n## C Builds\n\n```js\nimport { clangTree, executable, reckon } from \"reckon\";\n\nconst objects = clangTree(\"src\", {\n  flags: [\"-Wall\"],\n});\n\nconst binary = executable(\"build/tool\", objects);\n\nawait reckon(binary, {\n  concurrency: 4,\n  verbose: true,\n  clang: {\n    includes: [\"src\"],\n  },\n});\n```\n\n`clangTree(...)` recursively discovers common C-family source extensions including `.c`, `.cc`, `.cpp`, `.cxx`, `.m`, and `.mm`. `clang(...)` emits compiler dependency files so header changes invalidate the right objects. Object outputs default to `build/obj`; sources under `src/` infer a sibling `build/obj` directory while preserving nested subpaths.\n\n`executable(...)` links object tasks into a binary and automatically switches to `clang++` when upstream objects come from C++ or Objective-C++ sources, unless you override the compiler explicitly.\n\n## macOS App Bundles\n\n```js\nimport { clangTree, executable, macOSApp, pngIcon, reckon } from \"reckon\";\n\nconst objects = clangTree(\"src\", {\n  flags: [\"-fobjc-arc\"],\n});\n\nconst binary = executable(\"build/Hello\", objects, {\n  frameworks: [\"Cocoa\"],\n});\n\nconst icon = pngIcon(\"resources/AppIcon.png\");\n\nconst app = macOSApp(\"build/Hello.app\", binary, {\n  bundleIdentifier: \"dev.example.hello\",\n  icon,\n  resources: [\n    { source: \"resources/README.txt\" },\n  ],\n});\n\nawait reckon(app);\n```\n\n`macOSApp(...)` assembles an unsigned `.app` bundle with `Contents/MacOS`, `Contents/Resources`, and `Contents/Info.plist`. It does not sign, notarize, provision, or create a DMG. `pngIcon(...)` accepts PNG input only and relies on the macOS `sips` and `iconutil` tools to produce `.icns` files.\n\n## Development\n\n```bash\nnpm install\nnpm run check\nnpm test\nnpm run build\n```\n\nBefore publishing:\n\n```bash\nnpm run release:check\nnpm publish --provenance\n```\n\n`npm run pack:dry-run` shows the files that would be included in the published tarball. The package exports only the ESM entry point at `dist/index.js` plus generated TypeScript declarations.\n\n## Current Scope\n\nReckon is intentionally small. It currently does not include a standalone CLI, watch mode, iOS packaging, code signing, notarization, provisioning profile support, DMG creation, or SVG icon conversion.\n","readmeFilename":"README.md"}