From 3ccedf5ff797b18df6c62b3822433728858fe459 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Aug 2026 21:54:15 +0000 Subject: [PATCH 1/3] deps: bump @types/node from 26.1.2 to 26.2.0 in the minor group Bumps the minor group with 1 update: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node). Updates `@types/node` from 26.1.2 to 26.2.0 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 26.2.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 10d1dc9..eec2f80 100644 --- a/package-lock.json +++ b/package-lock.json @@ -979,9 +979,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "26.1.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.2.tgz", - "integrity": "sha512-Vu4a5UFA9rIIFJ7rB/Vaafh9lrCQszopTCx6KjFboXTGQbPNasehVR5TEiithSDGyd1DEiUByggTZsg8jukeIg==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.2.0.tgz", + "integrity": "sha512-5IviulTZeRNp2vAJ514cc/HUlY5nZ9fCbq9DMyC52BrhFZACo3nI0R7qBxhQmo/d27NFe96ur/b7Wwxklda+kg==", "dev": true, "license": "MIT", "dependencies": { From cbd9d42c1d458181c183be724853c45db9cce024 Mon Sep 17 00:00:00 2001 From: cldmv-bot <230939188+cldmv-bot@users.noreply.github.com> Date: Wed, 12 Aug 2026 21:56:11 +0000 Subject: [PATCH 2/3] style: apply automated lint/format fixes --- .github/dependabot.yml | 88 +- .github/workflows/branch-retention.yml | 22 +- .github/workflows/cla.yml | 38 +- .github/workflows/codeql.yml | 64 +- .github/workflows/dependabot-auto-merge.yml | 30 +- .github/workflows/dependency-review.yml | 34 +- .github/workflows/feature-pr.yml | 54 +- .github/workflows/hotfix-redirector.yml | 26 +- .github/workflows/hotfixes-release.yml | 52 +- .github/workflows/labeler.yml | 22 +- .github/workflows/master-commit-audit.yml | 76 +- .github/workflows/next-release.yml | 52 +- .github/workflows/next-reset.yml | 24 +- .github/workflows/pr-title-normalizer.yml | 26 +- .github/workflows/release-notify.yml | 16 +- .github/workflows/scorecard.yml | 28 +- .github/workflows/stale.yml | 44 +- .github/workflows/tag-health.yml | 78 +- .github/workflows/v4-bootstrap.yml | 110 +- .github/workflows/welcome.yml | 26 +- types/build.d.mts | 2 +- types/build.d.ts | 2 +- types/devcheck.d.mts | 2 +- types/examples/enhanced-coalescing-test.d.mts | 2 +- .../old/breaking-point-analysis.d.mts | 140 +-- types/examples/old/coalescing-analysis.d.mts | 2 +- .../examples/old/device-control-pattern.d.mts | 76 +- types/examples/old/device-simulation.d.mts | 120 +- types/examples/old/proper-delay-test.d.mts | 100 +- types/examples/old/run-volume-test.d.mts | 2 +- types/examples/old/test-analysis.d.mts | 2 +- types/examples/old/test-breaking-point.d.mts | 2 +- types/examples/old/test-device-control.d.mts | 2 +- .../examples/old/test-device-simulation.d.mts | 2 +- types/examples/old/test-proper-delays.d.mts | 2 +- types/examples/old/test-timing-analysis.d.mts | 2 +- types/examples/old/timing-analysis.d.mts | 58 +- .../examples/old/volume-coalescing-test.d.mts | 138 ++- types/examples/priority-stress-test.d.mts | 109 +- types/examples/run-priority-stress-test.d.mts | 2 +- types/examples/unified-priority-test.d.mts | 2 +- types/index.d.mts | 2 +- types/src/hold-my-task.d.mts | 1098 +++++++++-------- types/src/utils.d.mts | 108 +- 44 files changed, 1457 insertions(+), 1430 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 585ad76..3748ab0 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -32,48 +32,48 @@ version: 2 updates: - # GitHub Actions: keep pinned action SHAs / version tags fresh. - - package-ecosystem: "github-actions" - directory: "/" - target-branch: "next" - schedule: - interval: "weekly" - open-pull-requests-limit: 5 - commit-message: - prefix: "deps" - # Grouped PRs cut noise: one PR per (security | patch | minor) bundle - # per week instead of N separate PRs. Security PRs still get retargeted - # to `hotfixes` by hotfix-redirector.yml when GHSA refs appear in the - # body โ€” bundling N GHSA fixes into one PR is fine, the redirector - # only needs one match to retarget. - groups: - security: - applies-to: security-updates - patterns: ["*"] - patch: - applies-to: version-updates - update-types: ["patch"] - minor: - applies-to: version-updates - update-types: ["minor"] + # GitHub Actions: keep pinned action SHAs / version tags fresh. + - package-ecosystem: "github-actions" + directory: "/" + target-branch: "next" + schedule: + interval: "weekly" + open-pull-requests-limit: 5 + commit-message: + prefix: "deps" + # Grouped PRs cut noise: one PR per (security | patch | minor) bundle + # per week instead of N separate PRs. Security PRs still get retargeted + # to `hotfixes` by hotfix-redirector.yml when GHSA refs appear in the + # body โ€” bundling N GHSA fixes into one PR is fine, the redirector + # only needs one match to retarget. + groups: + security: + applies-to: security-updates + patterns: ["*"] + patch: + applies-to: version-updates + update-types: ["patch"] + minor: + applies-to: version-updates + update-types: ["minor"] - # NPM: package.json + package-lock.json updates. - # Delete this block if your repo isn't a Node project. - - package-ecosystem: "npm" - directory: "/" - target-branch: "next" - schedule: - interval: "weekly" - open-pull-requests-limit: 5 - commit-message: - prefix: "deps" - groups: - security: - applies-to: security-updates - patterns: ["*"] - patch: - applies-to: version-updates - update-types: ["patch"] - minor: - applies-to: version-updates - update-types: ["minor"] + # NPM: package.json + package-lock.json updates. + # Delete this block if your repo isn't a Node project. + - package-ecosystem: "npm" + directory: "/" + target-branch: "next" + schedule: + interval: "weekly" + open-pull-requests-limit: 5 + commit-message: + prefix: "deps" + groups: + security: + applies-to: security-updates + patterns: ["*"] + patch: + applies-to: version-updates + update-types: ["patch"] + minor: + applies-to: version-updates + update-types: ["minor"] diff --git a/.github/workflows/branch-retention.yml b/.github/workflows/branch-retention.yml index c6af9cc..e4181d1 100644 --- a/.github/workflows/branch-retention.yml +++ b/.github/workflows/branch-retention.yml @@ -21,18 +21,18 @@ name: ๐ŸŒฟ Branch Retention on: - pull_request: - types: [closed] - branches: [master, main, next, hotfixes] + pull_request: + types: [closed] + branches: [master, main, next, hotfixes] permissions: - contents: write - pull-requests: read + contents: write + pull-requests: read jobs: - retain: - if: github.event.pull_request.merged == true - uses: CLDMV/.github/.github/workflows/reusable-branch-retention.yml@v4 - secrets: - BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} - BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} + retain: + if: github.event.pull_request.merged == true + uses: CLDMV/.github/.github/workflows/reusable-branch-retention.yml@v4 + secrets: + BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} + BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index ddf2288..3de25c7 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -35,26 +35,26 @@ name: ๐Ÿ“œ CLA on: - pull_request_target: - types: [opened, synchronize, reopened, ready_for_review] - issue_comment: - types: [created] + pull_request_target: + types: [opened, synchronize, reopened, ready_for_review] + issue_comment: + types: [created] permissions: - contents: read - pull-requests: write - statuses: write - issues: write + contents: read + pull-requests: write + statuses: write + issues: write jobs: - cla: - uses: CLDMV/.github/.github/workflows/reusable-cla.yml@v4 - with: - cla_version: "1.0" - secrets: - BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} - BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} - CLA_BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_CLA_BOT_APP_CLIENT_ID }} - CLA_BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_CLA_BOT_APP_PRIVATE_KEY }} - TAGGER_NAME: ${{ secrets.CLDMV_BOT_NAME }} - TAGGER_EMAIL: ${{ secrets.CLDMV_BOT_EMAIL }} + cla: + uses: CLDMV/.github/.github/workflows/reusable-cla.yml@v4 + with: + cla_version: "1.0" + secrets: + BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} + BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} + CLA_BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_CLA_BOT_APP_CLIENT_ID }} + CLA_BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_CLA_BOT_APP_PRIVATE_KEY }} + TAGGER_NAME: ${{ secrets.CLDMV_BOT_NAME }} + TAGGER_EMAIL: ${{ secrets.CLDMV_BOT_EMAIL }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index ed1c04a..a54020c 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -30,41 +30,41 @@ name: ๐Ÿ” CodeQL on: - push: - branches: [master, main] - # Same fork-PR consideration as ci.yml: pull_request fires for forks; SARIF - # upload to base-repo Security tab fails with read-only token. Acceptable โ€” - # push-to-master analysis after merge catches anything missed. DO NOT use - # pull_request_target (runs base-repo workflow with secrets against fork - # code; dangerous). - pull_request: - types: [opened, synchronize, reopened, ready_for_review] - # Include the v4 integration branches (`next`, `hotfixes`) so feature - # and hotfix PRs trigger CodeQL. Without these, branch protection - # rulesets that require the CodeQL check on `next`/`hotfixes` will - # sit on "waiting for results" indefinitely. Branches that don't - # exist in a given repo simply never trigger the workflow โ€” harmless - # for repos that haven't adopted the v4 staging-branch flow. - branches: [master, main, next, hotfixes] - schedule: - - cron: "37 14 * * 1" # weekly Monday 14:37 UTC; GitHub updates queries over time + push: + branches: [master, main] + # Same fork-PR consideration as ci.yml: pull_request fires for forks; SARIF + # upload to base-repo Security tab fails with read-only token. Acceptable โ€” + # push-to-master analysis after merge catches anything missed. DO NOT use + # pull_request_target (runs base-repo workflow with secrets against fork + # code; dangerous). + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + # Include the v4 integration branches (`next`, `hotfixes`) so feature + # and hotfix PRs trigger CodeQL. Without these, branch protection + # rulesets that require the CodeQL check on `next`/`hotfixes` will + # sit on "waiting for results" indefinitely. Branches that don't + # exist in a given repo simply never trigger the workflow โ€” harmless + # for repos that haven't adopted the v4 staging-branch flow. + branches: [master, main, next, hotfixes] + schedule: + - cron: "37 14 * * 1" # weekly Monday 14:37 UTC; GitHub updates queries over time permissions: - security-events: write - contents: read - actions: read + security-events: write + contents: read + actions: read concurrency: - group: codeql-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ github.ref != 'refs/heads/master' && github.ref != 'refs/heads/main' }} + group: codeql-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/master' && github.ref != 'refs/heads/main' }} jobs: - analyze: - uses: CLDMV/.github/.github/workflows/reusable-codeql.yml@v4 - with: - languages: "javascript-typescript" - # Override defaults if needed: - # queries: "security-extended,security-and-quality" - # paths_ignore: "node_modules/,dist/,coverage/,**/test/**" - # config_file: ".github/codeql-config.yml" - # build_mode: "autobuild" + analyze: + uses: CLDMV/.github/.github/workflows/reusable-codeql.yml@v4 + with: + languages: "javascript-typescript" + # Override defaults if needed: + # queries: "security-extended,security-and-quality" + # paths_ignore: "node_modules/,dist/,coverage/,**/test/**" + # config_file: ".github/codeql-config.yml" + # build_mode: "autobuild" diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml index 48cbc52..663f9aa 100644 --- a/.github/workflows/dependabot-auto-merge.yml +++ b/.github/workflows/dependabot-auto-merge.yml @@ -33,22 +33,22 @@ name: ๐Ÿค– Dependabot Auto-Merge on: - pull_request: - types: [opened, reopened, synchronize, ready_for_review] + pull_request: + types: [opened, reopened, synchronize, ready_for_review] permissions: - contents: write - pull-requests: write + contents: write + pull-requests: write jobs: - automerge: - # Pre-filter at workflow level so this doesn't spin up for every PR. - if: github.event.pull_request.user.login == 'dependabot[bot]' - uses: CLDMV/.github/.github/workflows/reusable-dependabot-auto-merge.yml@v4 - with: - bump_types: "patch,minor" - merge_method: "squash" - # also_for_actors: "renovate[bot]" # extend if you adopt Renovate - secrets: - BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} - BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} + automerge: + # Pre-filter at workflow level so this doesn't spin up for every PR. + if: github.event.pull_request.user.login == 'dependabot[bot]' + uses: CLDMV/.github/.github/workflows/reusable-dependabot-auto-merge.yml@v4 + with: + bump_types: "patch,minor" + merge_method: "squash" + # also_for_actors: "renovate[bot]" # extend if you adopt Renovate + secrets: + BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} + BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 78df3f8..69b36ad 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -11,24 +11,24 @@ name: ๐Ÿ”’ Dependency Review on: - pull_request: - types: [opened, synchronize, reopened, ready_for_review] - branches: [master, main] + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + branches: [master, main] permissions: - contents: read - pull-requests: write + contents: read + pull-requests: write jobs: - review: - uses: CLDMV/.github/.github/workflows/reusable-dependency-review.yml@v4 - with: - fail_on_severity: "moderate" - # Per-repo license policy override: - # deny_licenses: "AGPL-3.0,LGPL-3.0" # block copyleft for an Apache-2.0 repo - # Bot App credentials. When set, the dependency-review PR comment is - # posted by the consumer's bot App instead of github-actions[bot]. - # Both lines are optional; remove them to fall back to GITHUB_TOKEN. - secrets: - BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} - BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} + review: + uses: CLDMV/.github/.github/workflows/reusable-dependency-review.yml@v4 + with: + fail_on_severity: "moderate" + # Per-repo license policy override: + # deny_licenses: "AGPL-3.0,LGPL-3.0" # block copyleft for an Apache-2.0 repo + # Bot App credentials. When set, the dependency-review PR comment is + # posted by the consumer's bot App instead of github-actions[bot]. + # Both lines are optional; remove them to fall back to GITHUB_TOKEN. + secrets: + BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} + BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} diff --git a/.github/workflows/feature-pr.yml b/.github/workflows/feature-pr.yml index fcee49e..9ef7b86 100644 --- a/.github/workflows/feature-pr.yml +++ b/.github/workflows/feature-pr.yml @@ -26,34 +26,34 @@ name: ๐Ÿ”€ Feature PR (v4) on: - push: - branches: - # CUSTOMIZE: prune this list to whichever branch prefixes your - # repo uses. Must align with the `case` statement in the reusable. - - 'feat/**' - - 'feature/**' - - 'fix/**' - - 'release/**' - - 'chore/**' - - 'refactor/**' - - 'docs/**' - - 'ci/**' - - 'perf/**' - - 'test/**' - - 'style/**' - - 'hotfix/**' + push: + branches: + # CUSTOMIZE: prune this list to whichever branch prefixes your + # repo uses. Must align with the `case` statement in the reusable. + - "feat/**" + - "feature/**" + - "fix/**" + - "release/**" + - "chore/**" + - "refactor/**" + - "docs/**" + - "ci/**" + - "perf/**" + - "test/**" + - "style/**" + - "hotfix/**" concurrency: - group: feature-pr-${{ github.repository }}-${{ github.ref }} - cancel-in-progress: false + group: feature-pr-${{ github.repository }}-${{ github.ref }} + cancel-in-progress: false jobs: - open-pr: - permissions: - contents: read - pull-requests: write - uses: CLDMV/.github/.github/workflows/workflow-feature-pr.yml@v4 - secrets: - # Map your repo/org secrets to the expected names. - BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} - BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} + open-pr: + permissions: + contents: read + pull-requests: write + uses: CLDMV/.github/.github/workflows/workflow-feature-pr.yml@v4 + secrets: + # Map your repo/org secrets to the expected names. + BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} + BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} diff --git a/.github/workflows/hotfix-redirector.yml b/.github/workflows/hotfix-redirector.yml index 830cad6..8a557bb 100644 --- a/.github/workflows/hotfix-redirector.yml +++ b/.github/workflows/hotfix-redirector.yml @@ -32,20 +32,20 @@ name: ๐Ÿ”€ Hotfix PR Redirector (v4) # `opened` only (NOT `edited`): if a maintainer manually re-targets the PR, we # must not fight them by redirecting again. on: - pull_request_target: - types: [opened] + pull_request_target: + types: [opened] concurrency: - group: hotfix-redirector-${{ github.event.pull_request.number }} - cancel-in-progress: true + group: hotfix-redirector-${{ github.event.pull_request.number }} + cancel-in-progress: true jobs: - redirect: - permissions: - contents: write - pull-requests: write - uses: CLDMV/.github/.github/workflows/workflow-hotfix-redirector.yml@v4 - secrets: - # Map your repo/org secrets to the expected names. - BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} - BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} + redirect: + permissions: + contents: write + pull-requests: write + uses: CLDMV/.github/.github/workflows/workflow-hotfix-redirector.yml@v4 + secrets: + # Map your repo/org secrets to the expected names. + BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} + BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} diff --git a/.github/workflows/hotfixes-release.yml b/.github/workflows/hotfixes-release.yml index 4773269..96ff761 100644 --- a/.github/workflows/hotfixes-release.yml +++ b/.github/workflows/hotfixes-release.yml @@ -23,33 +23,33 @@ name: ๐Ÿš‘ Hotfixes Release (v4) on: - push: - branches: [hotfixes] - workflow_dispatch: # manual kick โ€” e.g. to open/refresh the PR for content already on `hotfixes` + push: + branches: [hotfixes] + workflow_dispatch: # manual kick โ€” e.g. to open/refresh the PR for content already on `hotfixes` concurrency: - group: hotfixes-release-${{ github.repository }} - cancel-in-progress: false + group: hotfixes-release-${{ github.repository }} + cancel-in-progress: false jobs: - release: - permissions: - contents: write - pull-requests: write - uses: CLDMV/.github/.github/workflows/workflow-hotfixes-release.yml@v4 - with: - package_name: "@cldmv/holdmytask" - build_command: "npm run build:ci" - secrets: - # Map your repo/org secrets to the expected names. - BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} - BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} - # Optional release-PR notifier webhooks โ€” each is independently - # opt-in: leave one unset and that channel is silently skipped. - # Delete the lines you don't use. - DISCORD_RELEASE_PR_PUBLIC_WEBHOOK: ${{ secrets.DISCORD_RELEASE_PR_PUBLIC_WEBHOOK }} - DISCORD_RELEASE_PR_PRIVATE_WEBHOOK: ${{ secrets.DISCORD_RELEASE_PR_PRIVATE_WEBHOOK }} - SLACK_RELEASE_PR_PUBLIC_WEBHOOK: ${{ secrets.SLACK_RELEASE_PR_PUBLIC_WEBHOOK }} - SLACK_RELEASE_PR_PRIVATE_WEBHOOK: ${{ secrets.SLACK_RELEASE_PR_PRIVATE_WEBHOOK }} - GENERIC_RELEASE_PR_PUBLIC_WEBHOOK: ${{ secrets.GENERIC_RELEASE_PR_PUBLIC_WEBHOOK }} - GENERIC_RELEASE_PR_PRIVATE_WEBHOOK: ${{ secrets.GENERIC_RELEASE_PR_PRIVATE_WEBHOOK }} + release: + permissions: + contents: write + pull-requests: write + uses: CLDMV/.github/.github/workflows/workflow-hotfixes-release.yml@v4 + with: + package_name: "@cldmv/holdmytask" + build_command: "npm run build:ci" + secrets: + # Map your repo/org secrets to the expected names. + BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} + BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} + # Optional release-PR notifier webhooks โ€” each is independently + # opt-in: leave one unset and that channel is silently skipped. + # Delete the lines you don't use. + DISCORD_RELEASE_PR_PUBLIC_WEBHOOK: ${{ secrets.DISCORD_RELEASE_PR_PUBLIC_WEBHOOK }} + DISCORD_RELEASE_PR_PRIVATE_WEBHOOK: ${{ secrets.DISCORD_RELEASE_PR_PRIVATE_WEBHOOK }} + SLACK_RELEASE_PR_PUBLIC_WEBHOOK: ${{ secrets.SLACK_RELEASE_PR_PUBLIC_WEBHOOK }} + SLACK_RELEASE_PR_PRIVATE_WEBHOOK: ${{ secrets.SLACK_RELEASE_PR_PRIVATE_WEBHOOK }} + GENERIC_RELEASE_PR_PUBLIC_WEBHOOK: ${{ secrets.GENERIC_RELEASE_PR_PUBLIC_WEBHOOK }} + GENERIC_RELEASE_PR_PRIVATE_WEBHOOK: ${{ secrets.GENERIC_RELEASE_PR_PRIVATE_WEBHOOK }} diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index a675a28..d2ff95a 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -27,18 +27,18 @@ name: ๐Ÿท๏ธ PR Labeler # DO NOT add a checkout step or any step that executes PR-supplied content # (build commands, scripts, test runs, etc.) to this workflow. on: - pull_request_target: - types: [opened, synchronize, reopened, ready_for_review] + pull_request_target: + types: [opened, synchronize, reopened, ready_for_review] permissions: - contents: read - pull-requests: write + contents: read + pull-requests: write jobs: - label: - uses: CLDMV/.github/.github/workflows/reusable-pr-labeler.yml@v4 - # Optional. Without these, labels are attributed to github-actions[bot]. - # With these, they're attributed to your CLDMV bot App. - secrets: - BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} - BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} + label: + uses: CLDMV/.github/.github/workflows/reusable-pr-labeler.yml@v4 + # Optional. Without these, labels are attributed to github-actions[bot]. + # With these, they're attributed to your CLDMV bot App. + secrets: + BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} + BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} diff --git a/.github/workflows/master-commit-audit.yml b/.github/workflows/master-commit-audit.yml index 8d89614..3bdfa7a 100644 --- a/.github/workflows/master-commit-audit.yml +++ b/.github/workflows/master-commit-audit.yml @@ -21,46 +21,46 @@ name: ๐Ÿงพ Master Commit Audit on: - push: - branches: [master, main] + push: + branches: [master, main] permissions: - contents: read - issues: write + contents: read + issues: write jobs: - audit: - runs-on: ubuntu-latest - steps: - # Optional. Without these, the audit issue is filed by - # github-actions[bot]. With them, the issue is filed by your bot App. - - name: Create App token (falls back to GITHUB_TOKEN) - id: app-token - uses: CLDMV/.github/.github/actions/github/steps/create-app-token@v4 - with: - client_id: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} - private_key: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} - env: - BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} - BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} + audit: + runs-on: ubuntu-latest + steps: + # Optional. Without these, the audit issue is filed by + # github-actions[bot]. With them, the issue is filed by your bot App. + - name: Create App token (falls back to GITHUB_TOKEN) + id: app-token + uses: CLDMV/.github/.github/actions/github/steps/create-app-token@v4 + with: + client_id: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} + private_key: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} + env: + BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} + BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} - - name: Audit commit subject - uses: CLDMV/.github/.github/actions/git/jobs/audit-commit-subject@v4 - with: - commit_sha: ${{ github.sha }} - # allowed_patterns omitted -> inherit the canonical default from - # audit-commit-subject (release/chore/merge patterns, including - # the "release: vX.Y.Z - " form). Customize only if - # this repo's conventions genuinely differ โ€” a hardcoded copy - # here goes stale the next time the canonical default changes. - # allowed_patterns: | - # ^release: v\d+\.\d+\.\d+( - .+?)?( \(#\d+\))?$ - # ^chore(\([^)]+\))?: .+ - # ^Merge pull request #\d+ from .+ - # ^feat(\([^)]+\))?: .+ - # Canonical label names from CLDMV/.github's data/github-labels.json - # (note the space after each colon). Replace with names that exist - # in your repo's label catalog. - issue_labels: "type: ci,priority: high" - # issue_assignee: "shinrai" # uncomment to auto-assign - github_token: ${{ steps.app-token.outputs.token }} + - name: Audit commit subject + uses: CLDMV/.github/.github/actions/git/jobs/audit-commit-subject@v4 + with: + commit_sha: ${{ github.sha }} + # allowed_patterns omitted -> inherit the canonical default from + # audit-commit-subject (release/chore/merge patterns, including + # the "release: vX.Y.Z - " form). Customize only if + # this repo's conventions genuinely differ โ€” a hardcoded copy + # here goes stale the next time the canonical default changes. + # allowed_patterns: | + # ^release: v\d+\.\d+\.\d+( - .+?)?( \(#\d+\))?$ + # ^chore(\([^)]+\))?: .+ + # ^Merge pull request #\d+ from .+ + # ^feat(\([^)]+\))?: .+ + # Canonical label names from CLDMV/.github's data/github-labels.json + # (note the space after each colon). Replace with names that exist + # in your repo's label catalog. + issue_labels: "type: ci,priority: high" + # issue_assignee: "shinrai" # uncomment to auto-assign + github_token: ${{ steps.app-token.outputs.token }} diff --git a/.github/workflows/next-release.yml b/.github/workflows/next-release.yml index b9c217b..e0b7767 100644 --- a/.github/workflows/next-release.yml +++ b/.github/workflows/next-release.yml @@ -27,35 +27,35 @@ name: ๐Ÿš€ Next Release (v4) on: - push: - branches: [next] - workflow_dispatch: # manual kick โ€” e.g. to open/refresh the PR for content already on `next` + push: + branches: [next] + workflow_dispatch: # manual kick โ€” e.g. to open/refresh the PR for content already on `next` # Serialize: each run re-resolves the current PR state, so queueing (not # cancelling) avoids a create/refresh race when pushes land back-to-back. concurrency: - group: next-release-${{ github.repository }} - cancel-in-progress: false + group: next-release-${{ github.repository }} + cancel-in-progress: false jobs: - release: - permissions: - contents: write - pull-requests: write - uses: CLDMV/.github/.github/workflows/workflow-next-release.yml@v4 - with: - package_name: "@cldmv/holdmytask" - build_command: "npm run build:ci" - secrets: - # Map your repo/org secrets to the expected names. - BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} - BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} - # Optional release-PR notifier webhooks โ€” each is independently - # opt-in: leave one unset and that channel is silently skipped. - # Delete the lines you don't use. - DISCORD_RELEASE_PR_PUBLIC_WEBHOOK: ${{ secrets.DISCORD_RELEASE_PR_PUBLIC_WEBHOOK }} - DISCORD_RELEASE_PR_PRIVATE_WEBHOOK: ${{ secrets.DISCORD_RELEASE_PR_PRIVATE_WEBHOOK }} - SLACK_RELEASE_PR_PUBLIC_WEBHOOK: ${{ secrets.SLACK_RELEASE_PR_PUBLIC_WEBHOOK }} - SLACK_RELEASE_PR_PRIVATE_WEBHOOK: ${{ secrets.SLACK_RELEASE_PR_PRIVATE_WEBHOOK }} - GENERIC_RELEASE_PR_PUBLIC_WEBHOOK: ${{ secrets.GENERIC_RELEASE_PR_PUBLIC_WEBHOOK }} - GENERIC_RELEASE_PR_PRIVATE_WEBHOOK: ${{ secrets.GENERIC_RELEASE_PR_PRIVATE_WEBHOOK }} + release: + permissions: + contents: write + pull-requests: write + uses: CLDMV/.github/.github/workflows/workflow-next-release.yml@v4 + with: + package_name: "@cldmv/holdmytask" + build_command: "npm run build:ci" + secrets: + # Map your repo/org secrets to the expected names. + BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} + BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} + # Optional release-PR notifier webhooks โ€” each is independently + # opt-in: leave one unset and that channel is silently skipped. + # Delete the lines you don't use. + DISCORD_RELEASE_PR_PUBLIC_WEBHOOK: ${{ secrets.DISCORD_RELEASE_PR_PUBLIC_WEBHOOK }} + DISCORD_RELEASE_PR_PRIVATE_WEBHOOK: ${{ secrets.DISCORD_RELEASE_PR_PRIVATE_WEBHOOK }} + SLACK_RELEASE_PR_PUBLIC_WEBHOOK: ${{ secrets.SLACK_RELEASE_PR_PUBLIC_WEBHOOK }} + SLACK_RELEASE_PR_PRIVATE_WEBHOOK: ${{ secrets.SLACK_RELEASE_PR_PRIVATE_WEBHOOK }} + GENERIC_RELEASE_PR_PUBLIC_WEBHOOK: ${{ secrets.GENERIC_RELEASE_PR_PUBLIC_WEBHOOK }} + GENERIC_RELEASE_PR_PRIVATE_WEBHOOK: ${{ secrets.GENERIC_RELEASE_PR_PRIVATE_WEBHOOK }} diff --git a/.github/workflows/next-reset.yml b/.github/workflows/next-reset.yml index 87ba088..6576845 100644 --- a/.github/workflows/next-reset.yml +++ b/.github/workflows/next-reset.yml @@ -25,19 +25,19 @@ name: โ™ป๏ธ Next/Hotfixes Reset (v4) on: - push: - branches: [master, main] + push: + branches: [master, main] concurrency: - group: next-reset-${{ github.repository }} - cancel-in-progress: false + group: next-reset-${{ github.repository }} + cancel-in-progress: false jobs: - sync: - permissions: - contents: write - uses: CLDMV/.github/.github/workflows/workflow-next-reset.yml@v4 - secrets: - # Map your repo/org secrets to the expected names. - BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} - BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} + sync: + permissions: + contents: write + uses: CLDMV/.github/.github/workflows/workflow-next-reset.yml@v4 + secrets: + # Map your repo/org secrets to the expected names. + BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} + BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} diff --git a/.github/workflows/pr-title-normalizer.yml b/.github/workflows/pr-title-normalizer.yml index adba973..0aa8554 100644 --- a/.github/workflows/pr-title-normalizer.yml +++ b/.github/workflows/pr-title-normalizer.yml @@ -26,20 +26,20 @@ name: ๐Ÿท๏ธ PR Title Normalizer # only (NOT edited): a maintainer hand-editing the title must not kick off a # re-normalize loop. on: - pull_request_target: - types: [opened, synchronize] + pull_request_target: + types: [opened, synchronize] concurrency: - group: pr-title-normalizer-${{ github.event.pull_request.number }} - cancel-in-progress: true + group: pr-title-normalizer-${{ github.event.pull_request.number }} + cancel-in-progress: true jobs: - normalize: - permissions: - contents: read - pull-requests: write - uses: CLDMV/.github/.github/workflows/workflow-pr-title-normalizer.yml@v4 - secrets: - # Map your repo/org secrets to the expected names. - BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} - BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} + normalize: + permissions: + contents: read + pull-requests: write + uses: CLDMV/.github/.github/workflows/workflow-pr-title-normalizer.yml@v4 + secrets: + # Map your repo/org secrets to the expected names. + BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} + BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} diff --git a/.github/workflows/release-notify.yml b/.github/workflows/release-notify.yml index b5fde82..7a4090e 100644 --- a/.github/workflows/release-notify.yml +++ b/.github/workflows/release-notify.yml @@ -23,15 +23,15 @@ name: ๐Ÿ“ฃ Release Notify on: - release: - types: [published] + release: + types: [published] permissions: - contents: read + contents: read jobs: - notify: - # Defensive: skip untagged releases (mirrors Batch 1.2's filter) - if: github.event.release.tag_name != '' - uses: CLDMV/.github/.github/workflows/reusable-release-notifier.yml@v4 - secrets: inherit + notify: + # Defensive: skip untagged releases (mirrors Batch 1.2's filter) + if: github.event.release.tag_name != '' + uses: CLDMV/.github/.github/workflows/reusable-release-notifier.yml@v4 + secrets: inherit diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 250a60f..d9a4823 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -22,12 +22,12 @@ name: ๐Ÿ”ฌ OpenSSF Scorecard on: - branch_protection_rule: - schedule: - - cron: "32 7 * * 1" # weekly Monday 07:32 UTC - push: - branches: [master, main] - workflow_dispatch: + branch_protection_rule: + schedule: + - cron: "32 7 * * 1" # weekly Monday 07:32 UTC + push: + branches: [master, main] + workflow_dispatch: # Caller must grant what the reusable needs โ€” notably id-token: write for the # OpenSSF transparency-log publish. @@ -51,11 +51,11 @@ on: # security-events: write back (job-scoped) if publish_results is set to false # instead. jobs: - analyze: - permissions: - id-token: write - contents: read - actions: read - uses: CLDMV/.github/.github/workflows/reusable-scorecard.yml@v4 - with: - publish_results: true # set false for private repos / to skip the public badge + analyze: + permissions: + id-token: write + contents: read + actions: read + uses: CLDMV/.github/.github/workflows/reusable-scorecard.yml@v4 + with: + publish_results: true # set false for private repos / to skip the public badge diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 93cfcf0..1e37db7 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -18,29 +18,29 @@ name: ๐Ÿ‚ Stale Issues & PRs on: - schedule: - - cron: "13 5 * * *" # daily 05:13 UTC (off-the-hour to avoid GH cron stampede) - workflow_dispatch: - inputs: - dry_run: - description: "Preview only โ€” no changes will be made" - type: boolean - default: false + schedule: + - cron: "13 5 * * *" # daily 05:13 UTC (off-the-hour to avoid GH cron stampede) + workflow_dispatch: + inputs: + dry_run: + description: "Preview only โ€” no changes will be made" + type: boolean + default: false permissions: - issues: write - pull-requests: write + issues: write + pull-requests: write jobs: - sweep: - uses: CLDMV/.github/.github/workflows/reusable-stale.yml@v4 - with: - dry_run: ${{ github.event.inputs.dry_run == 'true' }} - # Override timers if needed: - # days_before_issue_stale: 60 - # days_before_issue_close: 14 - # days_before_pr_stale: 30 - # days_before_pr_close: 7 - secrets: - BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} - BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} + sweep: + uses: CLDMV/.github/.github/workflows/reusable-stale.yml@v4 + with: + dry_run: ${{ github.event.inputs.dry_run == 'true' }} + # Override timers if needed: + # days_before_issue_stale: 60 + # days_before_issue_close: 14 + # days_before_pr_stale: 30 + # days_before_pr_close: 7 + secrets: + BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} + BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} diff --git a/.github/workflows/tag-health.yml b/.github/workflows/tag-health.yml index a967861..82d904a 100644 --- a/.github/workflows/tag-health.yml +++ b/.github/workflows/tag-health.yml @@ -19,46 +19,46 @@ name: ๐Ÿฅ Tag Health on: - schedule: - # Weekly Sunday 04:04 UTC. Off-the-hour to dodge the GitHub :00-cron - # stampede; weekly cadence because tag drift accumulates slowly. - - cron: "4 4 * * 0" - workflow_dispatch: - inputs: - debug: - description: "Enable debug logging for troubleshooting" - type: boolean - required: false - default: false - create_documentation: - description: "Update VERSION_TAGS.md if rolling tags moved" - type: boolean - required: false - default: false - use_gpg: - description: "Enable GPG signing for any tags the sweep creates/recreates" - type: boolean - required: false - default: true + schedule: + # Weekly Sunday 04:04 UTC. Off-the-hour to dodge the GitHub :00-cron + # stampede; weekly cadence because tag drift accumulates slowly. + - cron: "4 4 * * 0" + workflow_dispatch: + inputs: + debug: + description: "Enable debug logging for troubleshooting" + type: boolean + required: false + default: false + create_documentation: + description: "Update VERSION_TAGS.md if rolling tags moved" + type: boolean + required: false + default: false + use_gpg: + description: "Enable GPG signing for any tags the sweep creates/recreates" + type: boolean + required: false + default: true permissions: - contents: write + contents: write jobs: - health: - uses: CLDMV/.github/.github/workflows/reusable-tag-health.yml@v4 - with: - debug: ${{ github.event.inputs.debug == 'true' }} - # Full unified sweep: validates, fixes bot signatures, fixes - # unsigned tags, recovers orphaned releases, relocates orphaned - # tags, and updates rolling major/minor refs. - run_unified_tag_health: true - create_documentation: ${{ github.event.inputs.create_documentation == 'true' }} - use_gpg: ${{ github.event.inputs.use_gpg != 'false' }} - secrets: - BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} - BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} - TAGGER_NAME: ${{ secrets.CLDMV_BOT_NAME }} - TAGGER_EMAIL: ${{ secrets.CLDMV_BOT_EMAIL }} - GPG_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_GPG_PRIVATE_KEY }} - GPG_PASSPHRASE: ${{ secrets.CLDMV_BOT_GPG_PASSPHRASE }} + health: + uses: CLDMV/.github/.github/workflows/reusable-tag-health.yml@v4 + with: + debug: ${{ github.event.inputs.debug == 'true' }} + # Full unified sweep: validates, fixes bot signatures, fixes + # unsigned tags, recovers orphaned releases, relocates orphaned + # tags, and updates rolling major/minor refs. + run_unified_tag_health: true + create_documentation: ${{ github.event.inputs.create_documentation == 'true' }} + use_gpg: ${{ github.event.inputs.use_gpg != 'false' }} + secrets: + BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} + BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} + TAGGER_NAME: ${{ secrets.CLDMV_BOT_NAME }} + TAGGER_EMAIL: ${{ secrets.CLDMV_BOT_EMAIL }} + GPG_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_GPG_PRIVATE_KEY }} + GPG_PASSPHRASE: ${{ secrets.CLDMV_BOT_GPG_PASSPHRASE }} diff --git a/.github/workflows/v4-bootstrap.yml b/.github/workflows/v4-bootstrap.yml index 4f8a222..59825b5 100644 --- a/.github/workflows/v4-bootstrap.yml +++ b/.github/workflows/v4-bootstrap.yml @@ -44,63 +44,63 @@ name: ๐Ÿš€ v4 Bootstrap on: - workflow_dispatch: - inputs: - dry_run: - description: "Dry-run: preview every mutation without firing it. Default `true` โ€” set to `false` to actually apply changes." - type: boolean - required: false - default: true - code_security: - description: "Code Security policy. off = disable. public-only = enable only if this repo is public (free). all = enable (paid on private)." - type: choice - required: false - default: "off" - options: - - "off" - - "public-only" - - "all" - secret_protection: - description: "Secret Protection (scanning + push protection) policy. Same shape as code_security." - type: choice - required: false - default: "off" - options: - - "off" - - "public-only" - - "all" - steps: - description: "Subset of phases to run, comma-separated." - required: false - default: "branches,settings,security,rulesets" + workflow_dispatch: + inputs: + dry_run: + description: "Dry-run: preview every mutation without firing it. Default `true` โ€” set to `false` to actually apply changes." + type: boolean + required: false + default: true + code_security: + description: "Code Security policy. off = disable. public-only = enable only if this repo is public (free). all = enable (paid on private)." + type: choice + required: false + default: "off" + options: + - "off" + - "public-only" + - "all" + secret_protection: + description: "Secret Protection (scanning + push protection) policy. Same shape as code_security." + type: choice + required: false + default: "off" + options: + - "off" + - "public-only" + - "all" + steps: + description: "Subset of phases to run, comma-separated." + required: false + default: "branches,settings,security,rulesets" permissions: - contents: read + contents: read jobs: - bootstrap: - name: "๐Ÿš€ Bootstrap v4 (this repo)" - runs-on: ubuntu-latest - steps: - - name: Create App token - id: app-token - # Full-permission App token โ€” bootstrap needs administration:write - # for security toggles + ruleset import, plus contents:write for - # branch creation. - uses: CLDMV/.github/.github/actions/github/steps/create-app-token@v4 - with: - client_id: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} - private_key: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} - env: - BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} - BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} + bootstrap: + name: "๐Ÿš€ Bootstrap v4 (this repo)" + runs-on: ubuntu-latest + steps: + - name: Create App token + id: app-token + # Full-permission App token โ€” bootstrap needs administration:write + # for security toggles + ruleset import, plus contents:write for + # branch creation. + uses: CLDMV/.github/.github/actions/github/steps/create-app-token@v4 + with: + client_id: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} + private_key: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} + env: + BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} + BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} - - name: Bootstrap - uses: CLDMV/.github/.github/actions/github/jobs/org-bootstrap-repo@v4 - with: - # target_repo defaults to GITHUB_REPOSITORY (this repo). - github_token: ${{ steps.app-token.outputs.token }} - dry_run: ${{ github.event.inputs.dry_run }} - steps: ${{ github.event.inputs.steps }} - code_security: ${{ github.event.inputs.code_security }} - secret_protection: ${{ github.event.inputs.secret_protection }} + - name: Bootstrap + uses: CLDMV/.github/.github/actions/github/jobs/org-bootstrap-repo@v4 + with: + # target_repo defaults to GITHUB_REPOSITORY (this repo). + github_token: ${{ steps.app-token.outputs.token }} + dry_run: ${{ github.event.inputs.dry_run }} + steps: ${{ github.event.inputs.steps }} + code_security: ${{ github.event.inputs.code_security }} + secret_protection: ${{ github.event.inputs.secret_protection }} diff --git a/.github/workflows/welcome.yml b/.github/workflows/welcome.yml index babc8b4..55e35d3 100644 --- a/.github/workflows/welcome.yml +++ b/.github/workflows/welcome.yml @@ -19,20 +19,20 @@ name: ๐Ÿ‘‹ Welcome Contributor # - We only call REST APIs to read prior interactions and post a comment # DO NOT add a checkout step or any step that executes PR-supplied content. on: - issues: - types: [opened] - pull_request_target: - types: [opened] + issues: + types: [opened] + pull_request_target: + types: [opened] permissions: - issues: write - pull-requests: write + issues: write + pull-requests: write jobs: - welcome: - uses: CLDMV/.github/.github/workflows/reusable-welcome.yml@v4 - # Optional. Without these, the welcome comment is posted by - # github-actions[bot]. With these, it's posted by your CLDMV bot App. - secrets: - BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} - BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} + welcome: + uses: CLDMV/.github/.github/workflows/reusable-welcome.yml@v4 + # Optional. Without these, the welcome comment is posted by + # github-actions[bot]. With these, it's posted by your CLDMV bot App. + secrets: + BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} + BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} diff --git a/types/build.d.mts b/types/build.d.mts index 212739e..18261d4 100644 --- a/types/build.d.mts +++ b/types/build.d.mts @@ -11,4 +11,4 @@ * @Copyright: Copyright (c) 2013-2025 Catalyzed Motivation Inc. All rights reserved. */ export {}; -//# sourceMappingURL=build.d.mts.map \ No newline at end of file +//# sourceMappingURL=build.d.mts.map diff --git a/types/build.d.ts b/types/build.d.ts index 2e31f76..ab4eabb 100644 --- a/types/build.d.ts +++ b/types/build.d.ts @@ -1,3 +1,3 @@ #!/usr/bin/env node export {}; -//# sourceMappingURL=build.d.ts.map \ No newline at end of file +//# sourceMappingURL=build.d.ts.map diff --git a/types/devcheck.d.mts b/types/devcheck.d.mts index 374d8e2..1b9ecdd 100644 --- a/types/devcheck.d.mts +++ b/types/devcheck.d.mts @@ -11,4 +11,4 @@ * @Copyright: Copyright (c) 2013-2025 Catalyzed Motivation Inc. All rights reserved. */ export {}; -//# sourceMappingURL=devcheck.d.mts.map \ No newline at end of file +//# sourceMappingURL=devcheck.d.mts.map diff --git a/types/examples/enhanced-coalescing-test.d.mts b/types/examples/enhanced-coalescing-test.d.mts index 1101c51..d40d56f 100644 --- a/types/examples/enhanced-coalescing-test.d.mts +++ b/types/examples/enhanced-coalescing-test.d.mts @@ -8,4 +8,4 @@ * - Backward compatibility with legacy options */ export {}; -//# sourceMappingURL=enhanced-coalescing-test.d.mts.map \ No newline at end of file +//# sourceMappingURL=enhanced-coalescing-test.d.mts.map diff --git a/types/examples/old/breaking-point-analysis.d.mts b/types/examples/old/breaking-point-analysis.d.mts index c82d627..b773e3b 100644 --- a/types/examples/old/breaking-point-analysis.d.mts +++ b/types/examples/old/breaking-point-analysis.d.mts @@ -8,82 +8,84 @@ * Device with configurable delays */ declare class ConfigurableDelayDevice { - volume: number; - commandCount: number; - infoRequestCount: number; - commandDelay: number; - infoDelay: number; - constructor(initialVolume?: number, commandDelay?: number, infoDelay?: number); - volumeCommand(change: any): Promise<{ - commandId: number; - oldVolume: number; - newVolume: number; - change: number; - processingTime: number; - }>; - getInfo(): Promise<{ - requestId: number; - volume: number; - timestamp: number; - totalCommands: number; - totalInfoRequests: number; - processingTime: number; - }>; - getStats(): { - currentVolume: number; - totalCommands: number; - totalInfoRequests: number; - }; + volume: number; + commandCount: number; + infoRequestCount: number; + commandDelay: number; + infoDelay: number; + constructor(initialVolume?: number, commandDelay?: number, infoDelay?: number); + volumeCommand(change: any): Promise<{ + commandId: number; + oldVolume: number; + newVolume: number; + change: number; + processingTime: number; + }>; + getInfo(): Promise<{ + requestId: number; + volume: number; + timestamp: number; + totalCommands: number; + totalInfoRequests: number; + processingTime: number; + }>; + getStats(): { + currentVolume: number; + totalCommands: number; + totalInfoRequests: number; + }; } /** * Controller for timing tests */ declare class TimingTestController { - device: any; - coalescingWindowDuration: number; - queue: any; - commandCounter: number; - results: any[]; - constructor(device: any, coalescingWindowDuration?: number); - volumeUp(amount?: number): Promise<{ - commandId: number; - userActionTime: number; - completionTime: number; - totalDuration: number; - volumeResult: any; - infoResult: any; - deviceVolumeAtCompletion: any; - infoReportsVolume: any; - isAccurate: boolean; - timingData: { - volumeQueueDelay: any; - volumeProcessingTime: any; - infoQueueDelay: any; - infoProcessingTime: any; - }; - }>; - getResults(): { - results: any[]; - deviceStats: any; - coalescingWindowDuration: number; - }; - destroy(): void; + device: any; + coalescingWindowDuration: number; + queue: any; + commandCounter: number; + results: any[]; + constructor(device: any, coalescingWindowDuration?: number); + volumeUp(amount?: number): Promise<{ + commandId: number; + userActionTime: number; + completionTime: number; + totalDuration: number; + volumeResult: any; + infoResult: any; + deviceVolumeAtCompletion: any; + infoReportsVolume: any; + isAccurate: boolean; + timingData: { + volumeQueueDelay: any; + volumeProcessingTime: any; + infoQueueDelay: any; + infoProcessingTime: any; + }; + }>; + getResults(): { + results: any[]; + deviceStats: any; + coalescingWindowDuration: number; + }; + destroy(): void; } /** * Test different device delays to find the breaking point */ -declare function findBreakingPoint(): Promise<{ - description: string | number; - commandDelay: string | number; - coalescingWindow: string | number; - accurateCommands: number; - inaccurateCommands: number; - accuracyRate: number; - maxDuration: number; - avgDuration: number; - deviceCommands: any; - deviceInfoRequests: any; - coalescingEfficiency: number; -}[]>; +declare function findBreakingPoint(): Promise< + { + description: string | number; + commandDelay: string | number; + coalescingWindow: string | number; + accurateCommands: number; + inaccurateCommands: number; + accuracyRate: number; + maxDuration: number; + avgDuration: number; + deviceCommands: any; + deviceInfoRequests: any; + coalescingEfficiency: number; + }[] +>; export { ConfigurableDelayDevice, TimingTestController, findBreakingPoint }; -//# sourceMappingURL=breaking-point-analysis.d.mts.map \ No newline at end of file +//# sourceMappingURL=breaking-point-analysis.d.mts.map diff --git a/types/examples/old/coalescing-analysis.d.mts b/types/examples/old/coalescing-analysis.d.mts index 3018862..d19abf3 100644 --- a/types/examples/old/coalescing-analysis.d.mts +++ b/types/examples/old/coalescing-analysis.d.mts @@ -7,4 +7,4 @@ */ declare function analyzeApproaches(): Promise; export { analyzeApproaches }; -//# sourceMappingURL=coalescing-analysis.d.mts.map \ No newline at end of file +//# sourceMappingURL=coalescing-analysis.d.mts.map diff --git a/types/examples/old/device-control-pattern.d.mts b/types/examples/old/device-control-pattern.d.mts index 5d51a0e..56e1620 100644 --- a/types/examples/old/device-control-pattern.d.mts +++ b/types/examples/old/device-control-pattern.d.mts @@ -6,46 +6,46 @@ */ import { EventEmitter } from "events"; declare class DeviceController extends EventEmitter { - queue: any; - deviceState: { - volume: number; - lastUpdated: number; - }; - pendingVolumeChanges: Map; - constructor(); - /** - * User command: Volume Up - * This accumulates changes and triggers coalesced update - */ - volumeUp(amount?: number): Promise; - /** - * The actual device update task that gets executed (coalesced) - * This applies ALL accumulated changes at once - */ - updateDeviceInfo(coalescingKey: any): Promise<{ - volume: number; - lastUpdated: number; - }>; - /** - * Update system state after device change - */ - updateSystemState(): void; - /** - * Emit events for state changes - */ - emitStateChange(oldVolume: any, newVolume: any): void; - /** - * Get current device state - */ - getState(): { - volume: number; - lastUpdated: number; - }; - destroy(): void; + queue: any; + deviceState: { + volume: number; + lastUpdated: number; + }; + pendingVolumeChanges: Map; + constructor(); + /** + * User command: Volume Up + * This accumulates changes and triggers coalesced update + */ + volumeUp(amount?: number): Promise; + /** + * The actual device update task that gets executed (coalesced) + * This applies ALL accumulated changes at once + */ + updateDeviceInfo(coalescingKey: any): Promise<{ + volume: number; + lastUpdated: number; + }>; + /** + * Update system state after device change + */ + updateSystemState(): void; + /** + * Emit events for state changes + */ + emitStateChange(oldVolume: any, newVolume: any): void; + /** + * Get current device state + */ + getState(): { + volume: number; + lastUpdated: number; + }; + destroy(): void; } declare function demonstrateDeviceControl(): Promise; declare class AdvancedDeviceController extends DeviceController { - volumeUp(amount?: number): Promise; + volumeUp(amount?: number): Promise; } export { DeviceController, AdvancedDeviceController, demonstrateDeviceControl }; -//# sourceMappingURL=device-control-pattern.d.mts.map \ No newline at end of file +//# sourceMappingURL=device-control-pattern.d.mts.map diff --git a/types/examples/old/device-simulation.d.mts b/types/examples/old/device-simulation.d.mts index 6b72f3f..881149f 100644 --- a/types/examples/old/device-simulation.d.mts +++ b/types/examples/old/device-simulation.d.mts @@ -12,79 +12,79 @@ import { EventEmitter } from "events"; * Simulated device that tracks its own state */ declare class PseudoDevice { - volume: number; - commandCount: number; - infoRequestCount: number; - constructor(initialVolume?: number); - /** - * Device receives a volume change command - */ - volumeCommand(change: any): Promise<{ - commandId: number; - oldVolume: number; - newVolume: number; - change: number; - }>; - /** - * Device responds to info request - */ - getInfo(): Promise<{ - requestId: number; - volume: number; - timestamp: number; - totalCommands: number; - totalInfoRequests: number; - }>; - /** - * Get device stats - */ - getStats(): { - currentVolume: number; - totalCommands: number; - totalInfoRequests: number; - }; + volume: number; + commandCount: number; + infoRequestCount: number; + constructor(initialVolume?: number); + /** + * Device receives a volume change command + */ + volumeCommand(change: any): Promise<{ + commandId: number; + oldVolume: number; + newVolume: number; + change: number; + }>; + /** + * Device responds to info request + */ + getInfo(): Promise<{ + requestId: number; + volume: number; + timestamp: number; + totalCommands: number; + totalInfoRequests: number; + }>; + /** + * Get device stats + */ + getStats(): { + currentVolume: number; + totalCommands: number; + totalInfoRequests: number; + }; } /** * Controller that uses the queue system to communicate with the device */ declare class DeviceController extends EventEmitter { - device: any; - queue: any; - optimisticVolume: any; - pendingChanges: number; - constructor(device: any, queueOptions?: {}); - /** - * User calls volumeUp - this should update device and then get fresh info - */ - volumeUp(amount?: number): Promise<{ - volumeCommand: any; - deviceInfo: any; - optimisticVolume: any; - pendingChanges: number; - }>; - /** - * Get current state - */ - getState(): { - optimisticVolume: any; - pendingChanges: number; - deviceStats: any; - }; - destroy(): void; + device: any; + queue: any; + optimisticVolume: any; + pendingChanges: number; + constructor(device: any, queueOptions?: {}); + /** + * User calls volumeUp - this should update device and then get fresh info + */ + volumeUp(amount?: number): Promise<{ + volumeCommand: any; + deviceInfo: any; + optimisticVolume: any; + pendingChanges: number; + }>; + /** + * Get current state + */ + getState(): { + optimisticVolume: any; + pendingChanges: number; + deviceStats: any; + }; + destroy(): void; } /** * Test scenario: Rapid volume commands */ declare function testRapidVolumeCommands(): Promise<{ - expectedVolume: number; - actualVolume: number; - totalCommands: number; - totalInfoRequests: number; - success: boolean; + expectedVolume: number; + actualVolume: number; + totalCommands: number; + totalInfoRequests: number; + success: boolean; }>; /** * Test different coalescing configurations */ declare function testCoalescingConfigurations(): Promise; export { PseudoDevice, DeviceController, testRapidVolumeCommands, testCoalescingConfigurations }; -//# sourceMappingURL=device-simulation.d.mts.map \ No newline at end of file +//# sourceMappingURL=device-simulation.d.mts.map diff --git a/types/examples/old/proper-delay-test.d.mts b/types/examples/old/proper-delay-test.d.mts index 0495217..16bb567 100644 --- a/types/examples/old/proper-delay-test.d.mts +++ b/types/examples/old/proper-delay-test.d.mts @@ -7,65 +7,65 @@ * - This should allow 2 volume updates to complete before info request */ declare class SimpleDevice { - volume: number; - commandCount: number; - infoRequestCount: number; - constructor(initialVolume?: number); - volumeCommand(change: any): Promise<{ - commandId: number; - oldVolume: number; - newVolume: number; - change: number; - }>; - getInfo(): Promise<{ - requestId: number; - volume: number; - timestamp: number; - totalCommands: number; - totalInfoRequests: number; - }>; - getStats(): { - currentVolume: number; - totalCommands: number; - totalInfoRequests: number; - }; + volume: number; + commandCount: number; + infoRequestCount: number; + constructor(initialVolume?: number); + volumeCommand(change: any): Promise<{ + commandId: number; + oldVolume: number; + newVolume: number; + change: number; + }>; + getInfo(): Promise<{ + requestId: number; + volume: number; + timestamp: number; + totalCommands: number; + totalInfoRequests: number; + }>; + getStats(): { + currentVolume: number; + totalCommands: number; + totalInfoRequests: number; + }; } /** * Controller using proper queue delays */ declare class ProperDelayController { - device: any; - queue: any; - commandCounter: number; - constructor(device: any); - volumeUp(amount?: number): Promise<{ - commandId: number; - startTime: number; - endTime: number; - duration: number; - volumeResult: any; - infoResult: any; - deviceVolumeAtEnd: any; - infoReportsVolume: any; - isAccurate: boolean; - }>; - getQueueInfo(): { - pendingCount: any; - runningCount: any; - completedCount: any; - }; - destroy(): void; + device: any; + queue: any; + commandCounter: number; + constructor(device: any); + volumeUp(amount?: number): Promise<{ + commandId: number; + startTime: number; + endTime: number; + duration: number; + volumeResult: any; + infoResult: any; + deviceVolumeAtEnd: any; + infoReportsVolume: any; + isAccurate: boolean; + }>; + getQueueInfo(): { + pendingCount: any; + runningCount: any; + completedCount: any; + }; + destroy(): void; } /** * Test the proper delay scenario */ declare function testProperDelays(): Promise<{ - totalAccurate: number; - totalTests: number; - accuracyRate: number; - deviceCommands: number; - deviceInfoRequests: number; - finalVolume: number; + totalAccurate: number; + totalTests: number; + accuracyRate: number; + deviceCommands: number; + deviceInfoRequests: number; + finalVolume: number; }>; export { SimpleDevice, ProperDelayController, testProperDelays }; -//# sourceMappingURL=proper-delay-test.d.mts.map \ No newline at end of file +//# sourceMappingURL=proper-delay-test.d.mts.map diff --git a/types/examples/old/run-volume-test.d.mts b/types/examples/old/run-volume-test.d.mts index 29eeb8b..0f0c03f 100644 --- a/types/examples/old/run-volume-test.d.mts +++ b/types/examples/old/run-volume-test.d.mts @@ -11,4 +11,4 @@ * @Copyright: Copyright (c) 2013-2025 Catalyzed Motivation Inc. All rights reserved. */ export {}; -//# sourceMappingURL=run-volume-test.d.mts.map \ No newline at end of file +//# sourceMappingURL=run-volume-test.d.mts.map diff --git a/types/examples/old/test-analysis.d.mts b/types/examples/old/test-analysis.d.mts index c53ded1..562c48e 100644 --- a/types/examples/old/test-analysis.d.mts +++ b/types/examples/old/test-analysis.d.mts @@ -1,2 +1,2 @@ export {}; -//# sourceMappingURL=test-analysis.d.mts.map \ No newline at end of file +//# sourceMappingURL=test-analysis.d.mts.map diff --git a/types/examples/old/test-breaking-point.d.mts b/types/examples/old/test-breaking-point.d.mts index da1f04b..9207a6a 100644 --- a/types/examples/old/test-breaking-point.d.mts +++ b/types/examples/old/test-breaking-point.d.mts @@ -1,2 +1,2 @@ export {}; -//# sourceMappingURL=test-breaking-point.d.mts.map \ No newline at end of file +//# sourceMappingURL=test-breaking-point.d.mts.map diff --git a/types/examples/old/test-device-control.d.mts b/types/examples/old/test-device-control.d.mts index 5f96050..7c42817 100644 --- a/types/examples/old/test-device-control.d.mts +++ b/types/examples/old/test-device-control.d.mts @@ -2,4 +2,4 @@ * Test the device control pattern */ export {}; -//# sourceMappingURL=test-device-control.d.mts.map \ No newline at end of file +//# sourceMappingURL=test-device-control.d.mts.map diff --git a/types/examples/old/test-device-simulation.d.mts b/types/examples/old/test-device-simulation.d.mts index 6ea80f7..918ad69 100644 --- a/types/examples/old/test-device-simulation.d.mts +++ b/types/examples/old/test-device-simulation.d.mts @@ -1,2 +1,2 @@ export {}; -//# sourceMappingURL=test-device-simulation.d.mts.map \ No newline at end of file +//# sourceMappingURL=test-device-simulation.d.mts.map diff --git a/types/examples/old/test-proper-delays.d.mts b/types/examples/old/test-proper-delays.d.mts index f666b7b..0058d86 100644 --- a/types/examples/old/test-proper-delays.d.mts +++ b/types/examples/old/test-proper-delays.d.mts @@ -1,2 +1,2 @@ export {}; -//# sourceMappingURL=test-proper-delays.d.mts.map \ No newline at end of file +//# sourceMappingURL=test-proper-delays.d.mts.map diff --git a/types/examples/old/test-timing-analysis.d.mts b/types/examples/old/test-timing-analysis.d.mts index 799f837..1fd5d1e 100644 --- a/types/examples/old/test-timing-analysis.d.mts +++ b/types/examples/old/test-timing-analysis.d.mts @@ -1,2 +1,2 @@ export {}; -//# sourceMappingURL=test-timing-analysis.d.mts.map \ No newline at end of file +//# sourceMappingURL=test-timing-analysis.d.mts.map diff --git a/types/examples/old/timing-analysis.d.mts b/types/examples/old/timing-analysis.d.mts index 0e54447..c818e50 100644 --- a/types/examples/old/timing-analysis.d.mts +++ b/types/examples/old/timing-analysis.d.mts @@ -9,40 +9,40 @@ import { DeviceController } from "./device-simulation.mjs"; * Enhanced controller that logs detailed timing information */ declare class TimingAnalysisController extends DeviceController { - commandCounter: number; - timingLog: any[]; - constructor(device: any, queueOptions?: {}); - volumeUp(amount?: number): Promise<{ - commandId: number; - startTime: number; - endTime: number; - totalDuration: number; - volumeCommand: any; - infoResult: any; - expectedVolume: any; - reportedVolume: any; - }>; - getTimingAnalysis(): { - timingLog: any[]; - deviceStats: any; - }; + commandCounter: number; + timingLog: any[]; + constructor(device: any, queueOptions?: {}); + volumeUp(amount?: number): Promise<{ + commandId: number; + startTime: number; + endTime: number; + totalDuration: number; + volumeCommand: any; + infoResult: any; + expectedVolume: any; + reportedVolume: any; + }>; + getTimingAnalysis(): { + timingLog: any[]; + deviceStats: any; + }; } /** * Test with reference counting approach */ declare class ReferenceCountingController extends DeviceController { - pendingVolumeCommands: Map; - commandCounter: number; - constructor(device: any, queueOptions?: {}); - volumeUp(amount?: number): Promise<{ - commandId: number; - volumeResult: any; - infoResult: any; - expectedVolume: any; - reportedVolume: any; - accurate: boolean; - }>; + pendingVolumeCommands: Map; + commandCounter: number; + constructor(device: any, queueOptions?: {}); + volumeUp(amount?: number): Promise<{ + commandId: number; + volumeResult: any; + infoResult: any; + expectedVolume: any; + reportedVolume: any; + accurate: boolean; + }>; } declare function analyzeTimingIssues(): Promise; export { TimingAnalysisController, ReferenceCountingController, analyzeTimingIssues }; -//# sourceMappingURL=timing-analysis.d.mts.map \ No newline at end of file +//# sourceMappingURL=timing-analysis.d.mts.map diff --git a/types/examples/old/volume-coalescing-test.d.mts b/types/examples/old/volume-coalescing-test.d.mts index a9cf911..aa65504 100644 --- a/types/examples/old/volume-coalescing-test.d.mts +++ b/types/examples/old/volume-coalescing-test.d.mts @@ -11,78 +11,86 @@ * Simple volume system that tracks state */ declare class VolumeSystem { - volume: number; - commandCount: number; - updateCount: number; - log: any[]; - constructor(initialVolume?: number); - /** - * Execute a volume command (changes the actual volume) - */ - executeVolumeCommand(change: any, commandId: any): Promise<{ - commandId: any; - oldVolume: number; - newVolume: number; - change: number; - executionTime: number; - }>; - /** - * Execute an update command (reports current state) - */ - executeUpdateCommand(updateId: any): Promise<{ - updateId: any; - volume: number; - timestamp: number; - totalCommands: number; - totalUpdates: number; - }>; - getState(): { - currentVolume: number; - totalCommands: number; - totalUpdates: number; - }; - getLog(): any[]; - clearLog(): void; + volume: number; + commandCount: number; + updateCount: number; + log: any[]; + constructor(initialVolume?: number); + /** + * Execute a volume command (changes the actual volume) + */ + executeVolumeCommand( + change: any, + commandId: any + ): Promise<{ + commandId: any; + oldVolume: number; + newVolume: number; + change: number; + executionTime: number; + }>; + /** + * Execute an update command (reports current state) + */ + executeUpdateCommand(updateId: any): Promise<{ + updateId: any; + volume: number; + timestamp: number; + totalCommands: number; + totalUpdates: number; + }>; + getState(): { + currentVolume: number; + totalCommands: number; + totalUpdates: number; + }; + getLog(): any[]; + clearLog(): void; } /** * Controller that implements volume commands with coalesced updates */ declare class VolumeController { - volumeSystem: any; - queue: any; - commandCounter: number; - constructor(volumeSystem: any, queueOptions?: {}); - /** - * Volume up command with coalesced update - */ - volumeUp(amount?: number, options?: {}): Promise<{ - commandId: number; - userActionTime: number; - endTime: number; - totalDuration: number; - volumeResult: any; - updateResult: any; - systemVolumeAtEnd: any; - updateReportsVolume: any; - isAccurate: boolean; - options: {}; - }>; - destroy(): void; + volumeSystem: any; + queue: any; + commandCounter: number; + constructor(volumeSystem: any, queueOptions?: {}); + /** + * Volume up command with coalesced update + */ + volumeUp( + amount?: number, + options?: {} + ): Promise<{ + commandId: number; + userActionTime: number; + endTime: number; + totalDuration: number; + volumeResult: any; + updateResult: any; + systemVolumeAtEnd: any; + updateReportsVolume: any; + isAccurate: boolean; + options: {}; + }>; + destroy(): void; } /** * Test different timing scenarios */ -declare function testVolumeCoalescing(): Promise<{ - scenario: string; - totalDuration: number; - accurateCommands: number; - totalCommands: number; - accuracyRate: number; - finalVolume: number; - expectedVolume: number; - volumeCommandsExecuted: number; - updateCommandsExecuted: number; - coalescingEfficiency: number; -}[]>; +declare function testVolumeCoalescing(): Promise< + { + scenario: string; + totalDuration: number; + accurateCommands: number; + totalCommands: number; + accuracyRate: number; + finalVolume: number; + expectedVolume: number; + volumeCommandsExecuted: number; + updateCommandsExecuted: number; + coalescingEfficiency: number; + }[] +>; export { VolumeSystem, VolumeController, testVolumeCoalescing }; -//# sourceMappingURL=volume-coalescing-test.d.mts.map \ No newline at end of file +//# sourceMappingURL=volume-coalescing-test.d.mts.map diff --git a/types/examples/priority-stress-test.d.mts b/types/examples/priority-stress-test.d.mts index ae7f36d..e175d11 100644 --- a/types/examples/priority-stress-test.d.mts +++ b/types/examples/priority-stress-test.d.mts @@ -10,65 +10,70 @@ * Volume system with realistic timing */ declare class RealisticVolumeSystem { - volume: number; - commandCount: number; - updateCount: number; - log: any[]; - constructor(initialVolume?: number); - executeVolumeCommand(change: any, commandId: any): Promise<{ - commandId: any; - oldVolume: number; - newVolume: number; - change: number; - executionTime: number; - processingTime: number; - }>; - executeUpdateCommand(updateId: any): Promise<{ - updateId: any; - volume: number; - timestamp: number; - totalCommands: number; - totalUpdates: number; - processingTime: number; - }>; - getState(): { - currentVolume: number; - totalCommands: number; - totalUpdates: number; - }; - getLog(): any[]; - clearLog(): void; + volume: number; + commandCount: number; + updateCount: number; + log: any[]; + constructor(initialVolume?: number); + executeVolumeCommand( + change: any, + commandId: any + ): Promise<{ + commandId: any; + oldVolume: number; + newVolume: number; + change: number; + executionTime: number; + processingTime: number; + }>; + executeUpdateCommand(updateId: any): Promise<{ + updateId: any; + volume: number; + timestamp: number; + totalCommands: number; + totalUpdates: number; + processingTime: number; + }>; + getState(): { + currentVolume: number; + totalCommands: number; + totalUpdates: number; + }; + getLog(): any[]; + clearLog(): void; } /** * Realistic volume controller with proper priorities and delays */ declare class PriorityVolumeController { - volumeSystem: any; - queue: any; - commandCounter: number; - constructor(volumeSystem: any, queueOptions?: {}); - /** - * Volume up with realistic "fire and forget" pattern - * REAL-WORLD PATTERN: Volume task enqueues update task AFTER completing volume change - */ - volumeUp(amount?: number, options?: {}): any; - destroy(): void; + volumeSystem: any; + queue: any; + commandCounter: number; + constructor(volumeSystem: any, queueOptions?: {}); + /** + * Volume up with realistic "fire and forget" pattern + * REAL-WORLD PATTERN: Volume task enqueues update task AFTER completing volume change + */ + volumeUp(amount?: number, options?: {}): any; + destroy(): void; } /** * Stress test scenarios */ -declare function runPriorityStressTests(): Promise<{ - scenario: string; - totalDuration: number; - accurateCommands: any; - totalCommands: number; - accuracyRate: number; - finalVolume: number; - expectedVolume: number; - volumeCommandsExecuted: number; - updateCommandsExecuted: number; - coalescingEfficiency: number; - averageCommandDuration: number; -}[]>; +declare function runPriorityStressTests(): Promise< + { + scenario: string; + totalDuration: number; + accurateCommands: any; + totalCommands: number; + accuracyRate: number; + finalVolume: number; + expectedVolume: number; + volumeCommandsExecuted: number; + updateCommandsExecuted: number; + coalescingEfficiency: number; + averageCommandDuration: number; + }[] +>; export { RealisticVolumeSystem, PriorityVolumeController, runPriorityStressTests }; -//# sourceMappingURL=priority-stress-test.d.mts.map \ No newline at end of file +//# sourceMappingURL=priority-stress-test.d.mts.map diff --git a/types/examples/run-priority-stress-test.d.mts b/types/examples/run-priority-stress-test.d.mts index 3ef6ef6..2f2723e 100644 --- a/types/examples/run-priority-stress-test.d.mts +++ b/types/examples/run-priority-stress-test.d.mts @@ -2,4 +2,4 @@ * Runner for Priority Stress Test */ export {}; -//# sourceMappingURL=run-priority-stress-test.d.mts.map \ No newline at end of file +//# sourceMappingURL=run-priority-stress-test.d.mts.map diff --git a/types/examples/unified-priority-test.d.mts b/types/examples/unified-priority-test.d.mts index 75d1cc3..f2f574c 100644 --- a/types/examples/unified-priority-test.d.mts +++ b/types/examples/unified-priority-test.d.mts @@ -5,4 +5,4 @@ * This example demonstrates the new unified priority system with backward compatibility */ export {}; -//# sourceMappingURL=unified-priority-test.d.mts.map \ No newline at end of file +//# sourceMappingURL=unified-priority-test.d.mts.map diff --git a/types/index.d.mts b/types/index.d.mts index af165b3..b117688 100644 --- a/types/index.d.mts +++ b/types/index.d.mts @@ -43,4 +43,4 @@ export { HoldMyTask as TaskManager }; export { HoldMyTask as TaskQueue }; export { HoldMyTask as QueueManager }; export { HoldMyTask as TaskProcessor }; -//# sourceMappingURL=index.d.mts.map \ No newline at end of file +//# sourceMappingURL=index.d.mts.map diff --git a/types/src/hold-my-task.d.mts b/types/src/hold-my-task.d.mts index efdc97d..8089aee 100644 --- a/types/src/hold-my-task.d.mts +++ b/types/src/hold-my-task.d.mts @@ -19,547 +19,559 @@ import { MinHeap } from "./utils.mjs"; * @extends EventEmitter */ export declare class HoldMyTask extends EventEmitter { - _syncMode: boolean | undefined; - options: { - constructor: Function; - toString(): string; - toLocaleString(): string; - valueOf(): Object; - hasOwnProperty(v: PropertyKey): boolean; - isPrototypeOf(v: Object): boolean; - propertyIsEnumerable(v: PropertyKey): boolean; - concurrency: number; - tick: number; - autoStart: boolean; - defaultPriority: number; - maxQueue: any; - priorities: {}; - smartScheduling: boolean; - healingInterval: number; - coalescing: { - defaults: Object; - keys: {}; - }; - coalescingWindowDuration: any; - coalescingMaxDelay: any; - coalescingMultipleCallbacks: any; - coalescingResolveAllPromises: any; - } | undefined; - pendingHeap: MinHeap | undefined; - readyHeap: MinHeap | undefined; - running: Set | undefined; - runningByPriority: Map | undefined; - tasks: Map | undefined; - nextId: number | undefined; - enqueueSeq: number | undefined; - isActive: boolean | undefined; - destroyed: boolean | undefined; - lastCompletedPriority: any; - nextAvailableTime: any; - schedulerTimeout: number | null | undefined; - healingInterval: number | null | undefined; - lastSchedulerRun: number | undefined; - intervalId: number | null | undefined; - coalescingGroups: Map | undefined; - coalescingRepresentatives: Map | undefined; - nextGroupId: number | undefined; - timeoutId: number | undefined; - constructor(options?: {}); - /** - * Synchronous initialization for backwards compatibility - * @private - * @param {Object} options - Configuration options - */ - private _initializeSync; - /** - * Asynchronous initialization for modern usage - * @private - * @param {Object} options - Configuration options - * @returns {Promise} Promise that resolves to this instance - */ - private _initializeAsync; - /** - * Common initialization logic used by both sync and async modes - * @private - * @param {Object} options - Configuration options - */ - private _initializeCommon; - /** - * Internal convenience method to create a new HoldMyTask instance with async initialization. - * This enables event listeners to be attached before validation errors can occur. - * @param {Object} [options={}] - Configuration options - * @returns {Promise} Promise that resolves to the initialized instance - * @private - * @example - * // Internal usage - prefer new HoldMyTask({ sync: false }) for public API - * const queue = await HoldMyTask._create({ maxQueue: 100 }); - */ - private static _create; - /** - * Adds a task to the queue for execution. Supports both callback and promise-based APIs. - * @param {Function} task - The task function to execute. Can be sync or async. - * @param {Function|Object} [optionsOrCallback] - Either a callback function or options object - * @param {Object} [options={}] - Additional options (if callback was provided as second parameter) - * @param {string|number} [options.id] - Custom task ID for identification and later reference (must be unique) - * @param {number} [options.priority] - Task priority (higher numbers run first) - * @param {number} [options.timestamp] - When the task should be ready to run (milliseconds since epoch) - * @param {number} [options.start] - Milliseconds from now when the task should be ready to run (convenience for timestamp calculation) - * @param {AbortSignal} [options.signal] - AbortSignal to cancel the task - * @param {number} [options.timeout] - Task timeout in milliseconds (for execution time limit) - * @param {number} [options.expire] - Task expiration timestamp or milliseconds from now (for queue waiting time limit) - * @param {number} [options.delay] - DEPRECATED: Use postDelay instead. Delay after task completion before next task of same priority - * @param {boolean} [options.bypassDelay] - If true, skip any active delay period and start immediately - * @param {string} [options.coalescingKey] - Key for task coalescing - tasks with same key will be coalesced within windows - * @param {number} [options.coalescingWindowDuration] - Override coalescing window duration (task-level override of key-level and defaults) - * @param {number} [options.coalescingMaxDelay] - Override coalescing max delay (task-level override of key-level and defaults) - * @param {boolean} [options.coalescingMultipleCallbacks] - Override callback behavior (task-level override of key-level and defaults) - * @param {boolean} [options.coalescingResolveAllPromises] - Override promise resolution behavior (task-level override of key-level and defaults) - * @param {*} [options.metadata] - Arbitrary metadata to attach to the task - * @returns {Promise|Object} Promise (if no callback) or task control object with id, cancel, status methods - * @throws {Error} If queue is destroyed or full - * @example - * // Promise API - * const result = await queue.enqueue(async () => fetchData()); - * - * // Callback API - * queue.enqueue(() => processData(), (err, result) => { - * if (err) console.error(err); - * else console.log(result); - * }); - * - * // With options - * const task = queue.enqueue(myTask, { priority: 5, timeout: 30000, expire: 10000 }); - * - * // Bypass current delay for urgent task - * const urgent = queue.enqueue(urgentTask, { priority: 10, bypassDelay: true }); - * - * // Alternative: use delay: -1 to bypass - * const urgent2 = queue.enqueue(urgentTask, { priority: 10, delay: -1 }); - * - * // Coalescing tasks - multiple device status checks become one - * queue.enqueue(checkDeviceStatus, callback1, { coalescingKey: "device-123", coalescingWindowDuration: 1000 }); - * queue.enqueue(checkDeviceStatus, callback2, { coalescingKey: "device-123" }); // Gets coalesced with first - */ - enqueue(task: Function, optionsOrCallback?: Function | Object, options?: { - id?: string | number; - priority?: number; - timestamp?: number; - start?: number; - signal?: AbortSignal; - timeout?: number; - expire?: number; - delay?: number; - bypassDelay?: boolean; - coalescingKey?: string; - coalescingWindowDuration?: number; - coalescingMaxDelay?: number; - coalescingMultipleCallbacks?: boolean; - coalescingResolveAllPromises?: boolean; - metadata?: any; - }): Promise | Object; - /** - * Cancels a pending task by ID. - * @param {string} id - The task ID to cancel - * @param {string} [reason="Task canceled"] - Reason for cancellation - * @returns {boolean} True if task was found and cancelled, false otherwise - * @example - * const task = queue.enqueue(() => longRunningTask()); - * const cancelled = queue.cancel(task.id, "User requested cancellation"); - */ - cancel(id: string, reason?: string): boolean; - /** - * Alias for cancel() method for backward compatibility. - * @param {string|number} id - The task ID to cancel - * @param {string} [reason="Task canceled"] - Reason for cancellation - * @returns {boolean} True if task was found and cancelled, false otherwise - */ - cancelTask(id: string | number, reason?: string): boolean; - /** - * Pauses the task queue, stopping execution of new tasks. - * Currently running tasks will continue to completion. - * @returns {void} - * @example - * queue.pause(); - * // Queue stops processing new tasks - */ - pause(): void; - /** - * Resumes the task queue after being paused. - * @returns {void} - * @example - * queue.resume(); - * // Queue resumes processing tasks - */ - resume(): void; - /** - * Clears all pending and ready tasks from the queue. - * Currently running tasks will continue to completion. - * @returns {void} - * @example - * queue.clear(); - * // All queued tasks are removed - */ - clear(): void; - /** - * Returns the number of tasks in the queue. - * @returns {number} Number of tasks in the queue - * @example - * const totalTasks = queue.size(); // 5 - */ - size(): number; - /** - * Returns the number of tasks in the queue (alias for size()). - * @returns {number} Number of tasks in the queue - * @example - * const totalTasks = queue.length(); // 5 - */ - length(): number; - /** - * Returns the number of currently running tasks. - * @returns {number} Number of running tasks - * @example - * const runningTasks = queue.inflight(); // 2 - */ - inflight(): number; - /** - * Gets information about a coalescing group by key and group ID. - * @param {string} coalescingKey - The coalescing key - * @param {string} [groupId] - Optional group ID. If omitted, returns all groups for the key - * @returns {Object|Array|null} Group info object, array of groups, or null if not found - * @example - * // Get all groups for a coalescing key - * const groups = queue.getCoalescingGroup('ui.update'); - * - * // Get specific group by ID - * const group = queue.getCoalescingGroup('ui.update', '1'); - * console.log(group.tasks.size); // Number of tasks in group - * - * // Access individual task metadata - * for (const [taskId, task] of group.tasks) { - * console.log(`Task ${taskId}:`, task.metadata); - * } - */ - getCoalescingGroup(coalescingKey: string, groupId?: string): Object | any[] | null; - /** - * Gets metadata for all tasks in a coalescing group. - * @param {string} coalescingKey - The coalescing key - * @param {string} [groupId] - Optional group ID. If omitted, returns metadata from all groups for the key - * @returns {Array} Array of metadata objects with task IDs - * @example - * // Get metadata from all groups for a key - * const allMetadata = queue.getCoalescingGroupMetadata('ui.update'); - * - * // Get metadata from specific group - * const groupMetadata = queue.getCoalescingGroupMetadata('ui.update', '1'); - * - * // Example output: - * // [ - * // { taskId: '123', metadata: { userId: 100, action: 'save' } }, - * // { taskId: '124', metadata: { userId: 200, action: 'delete' } } - * // ] - */ - getCoalescingGroupMetadata(coalescingKey: string, groupId?: string): any[]; - /** - * Gets a summary of all active coalescing groups. - * @returns {Object} Summary object with coalescing key stats - * @example - * const summary = queue.getCoalescingGroupsSummary(); - * console.log(summary); - * // { - * // 'ui.update': { groupCount: 2, totalTasks: 5 }, - * // 'api.batch': { groupCount: 1, totalTasks: 3 } - * // } - */ - getCoalescingGroupsSummary(): Object; - /** - * Finds the coalescing group that contains a specific task ID. - * @param {string|number} taskId - The task ID to search for - * @returns {Object|null} Group information including the task's metadata, or null if not found - * @example - * const groupInfo = queue.findCoalescingGroupByTaskId('123'); - * if (groupInfo) { - * console.log('Task is in group:', groupInfo.groupId); - * console.log('Task metadata:', groupInfo.task.metadata); - * console.log('Other tasks in group:', groupInfo.groupTasks.length); - * } - */ - findCoalescingGroupByTaskId(taskId: string | number): Object | null; - /** - * Destroys the queue, canceling all tasks and stopping the scheduler. - * Once destroyed, the queue cannot be reused. - * @returns {void} - * @example - * queue.destroy(); - * // Queue is permanently shut down - */ - destroy(): void; - /** - * Returns the current timestamp in milliseconds. - * @returns {number} Current timestamp - * @example - * const timestamp = queue.now(); // 1699564800000 - */ - now(): number; - /** - * Main scheduler tick that moves ready tasks and starts execution. - * @returns {void} - * @private - */ - private schedulerTick; - /** - * Checks if a task can start based on both global and per-priority concurrency limits. - * @param {Object} task - The task to check - * @returns {boolean} True if the task can start, false if concurrency limits prevent it - * @private - */ - private _canStartTask; - /** - * Clears all active timers (intervals and timeouts). - * @returns {void} - * @private - */ - private clearTimers; - /** - * Calculates when the next scheduler run should happen and sets appropriate timeout. - * @private - * @returns {void} - * - * @description - * Smart scheduling that calculates the optimal time for the next scheduler run based on: - * - When the next pending task becomes ready - * - When delay periods end - * - Whether there are tasks that can run immediately - * - * Uses setTimeout for precise timing instead of constant polling intervals. - */ - private scheduleSmartTimeout; - /** - * Runs the main scheduler logic and reschedules if needed. - * @private - * @returns {void} - * - * @description - * Executes the scheduler tick logic and then determines if more scheduling is needed. - * Tracks when scheduler last ran for healing mechanism. - */ - private runScheduler; - /** - * Starts the self-healing interval that ensures scheduler continues working. - * @private - * @returns {void} - * - * @description - * Healing mechanism that periodically checks if the scheduler should be running - * but isn't due to timeout failures or other issues. Runs every healingInterval milliseconds. - */ - private startHealingInterval; - /** - * Clears all scheduler-related timers. - * @private - * @returns {void} - * - * @description - * Cleans up both the main scheduler timeout and the healing interval timer. - */ - private clearSchedulerTimers; - /** - * Configure coalescing settings for specific keys dynamically. - * @param {string} coalescingKey - The coalescing key to configure - * @param {Object} config - Configuration for this key - * @param {number} [config.windowDuration] - Window duration in milliseconds for this key - * @param {number} [config.maxDelay] - Maximum delay in milliseconds for this key - * @param {number} [config.postDelay] - Post-completion delay in milliseconds for this key - * @param {number} [config.startDelay] - Pre-execution delay in milliseconds for this key - * @param {number} [config.delay] - DEPRECATED: Use postDelay instead - * @param {number} [config.start] - DEPRECATED: Use startDelay instead - * @param {boolean} [config.multipleCallbacks] - Whether to call multiple callbacks for this key - * @param {boolean} [config.resolveAllPromises] - Whether to resolve all promises for this key - * @returns {void} - * - * @example - * // Configure specific keys after queue creation - * queue.configureCoalescingKey('ui.update', { - * windowDuration: 100, - * maxDelay: 500, - * postDelay: 25, - * startDelay: 0 - * }); - * - * queue.configureCoalescingKey('api.batch', { - * windowDuration: 1000, - * maxDelay: 5000, - * postDelay: 100, - * startDelay: 200, - * resolveAllPromises: false - * }); - */ - configureCoalescingKey(coalescingKey: string, config: { - windowDuration?: number; - maxDelay?: number; - postDelay?: number; - startDelay?: number; - delay?: number; - start?: number; - multipleCallbacks?: boolean; - resolveAllPromises?: boolean; - }): void; - /** - * Get the effective coalescing configuration for a specific key. - * @param {string} coalescingKey - The coalescing key to get configuration for - * @param {Object} [taskOptions={}] - Task-level options that may override key configuration - * @returns {Object} The effective configuration for this key - * - * @example - * // Get effective configuration for a key - * const config = queue.getCoalescingConfig('ui.update'); - * console.log(`UI updates coalesce within ${config.windowDuration}ms with ${config.postDelay}ms post-completion delay`); - * - * // Check with task-level overrides - * const effectiveConfig = queue.getCoalescingConfig('ui.update', { - * coalescingWindowDuration: 50, - * delay: 30 // Still accepts old property names for backwards compatibility - * }); - */ - getCoalescingConfig(coalescingKey: string, taskOptions?: Object): Object; - /** - * Get all configured coalescing keys and their configurations. - * @returns {Object} Map of coalescingKey to configuration - * - * @example - * // See all configured coalescing keys - * const allConfigs = queue.getCoalescingConfigurations(); - * Object.entries(allConfigs).forEach(([key, config]) => { - * console.log(`${key}: ${config.windowDuration}ms window, ${config.maxDelay}ms max delay, ${config.postDelay}ms post-completion delay, ${config.startDelay}ms pre-execution delay`); - * }); - */ - getCoalescingConfigurations(): Object; - /** - * Configure default settings for specific priorities dynamically. - * @param {number} priority - The priority level to configure - * @param {Object} config - Configuration for this priority - * @param {number} [config.postDelay] - Default post-completion delay in milliseconds for this priority - * @param {number} [config.startDelay] - Default pre-execution delay in milliseconds for this priority - * @param {number} [config.delay] - DEPRECATED: Use postDelay instead - * @param {number} [config.start] - DEPRECATED: Use startDelay instead - * @returns {void} - * - * @example - * // Configure priority defaults after queue creation - * queue.configurePriority(1, { - * postDelay: 100, // High priority tasks have 100ms delay after completion - * startDelay: 0 // High priority tasks start immediately - * }); - * - * queue.configurePriority(3, { - * postDelay: 0, // Low priority tasks have no delay after completion - * startDelay: 200 // Low priority tasks wait 200ms before starting - * }); - */ - configurePriority(priority: number, config: { - postDelay?: number; - startDelay?: number; - delay?: number; - start?: number; - }): void; - /** - * Get the effective configuration for a specific priority. - * @param {number} priority - The priority level to get configuration for - * @param {Object} [taskOptions={}] - Task-level options that may override priority configuration - * @returns {Object} The effective configuration for this priority - * - * @example - * // Get effective configuration for a priority - * const config = queue.getPriorityConfig(1); - * console.log(`Priority 1 tasks: ${config.delay}ms delay, ${config.start}ms start delay`); - * - * // Check with task-level overrides - * const effectiveConfig = queue.getPriorityConfig(1, { - * delay: 50, - * start: 10 - * }); - */ - getPriorityConfig(priority: number, taskOptions?: Object): Object; - /** - * Get all configured priorities and their configurations. - * @returns {Object} Map of priority to configuration - * - * @example - * // See all configured priorities - * const allConfigs = queue.getPriorityConfigurations(); - * Object.entries(allConfigs).forEach(([priority, config]) => { - * console.log(`Priority ${priority}: ${config.delay}ms delay, ${config.start}ms start delay`); - * }); - */ - getPriorityConfigurations(): Object; - /** - * Alias for destroy() method for common queue system naming. - * @returns {void} - */ - shutdown(): void; - /** - * Alias for enqueue() method for common queue system naming. - * @param {Function} task - The task function to execute - * @param {Function|Object} optionsOrCallback - Callback function or options object - * @param {Object} options - Task options (if callback provided as second parameter) - * @returns {Promise|TaskHandle} Promise if no callback provided, TaskHandle otherwise - */ - schedule(task: Function, optionsOrCallback: Function | Object, options?: Object): Promise | TaskHandle; - /** - * Alias for enqueue() method for common queue system naming. - * @param {Function} task - The task function to execute - * @param {Function|Object} optionsOrCallback - Callback function or options object - * @param {Object} options - Task options (if callback provided as second parameter) - * @returns {Promise|TaskHandle} Promise if no callback provided, TaskHandle otherwise - */ - add(task: Function, optionsOrCallback: Function | Object, options?: Object): Promise | TaskHandle; - /** - * Find a task by its ID. - * @param {string|number} id - The task ID to find - * @returns {Object|null} Task object if found, null otherwise - */ - get(id: string | number): Object | null; - /** - * Check if a task with the given ID exists. - * @param {string|number} id - The task ID to check - * @returns {boolean} True if task exists, false otherwise - */ - has(id: string | number): boolean; - /** - * Alias for get() method for backward compatibility. - * @param {string|number} id - The task ID to find - * @returns {Object|null} Task object if found, null otherwise - */ - getTask(id: string | number): Object | null; - /** - * Alias for has() method for backward compatibility. - * @param {string|number} id - The task ID to check - * @returns {boolean} True if task exists, false otherwise - */ - hasTask(id: string | number): boolean; - /** - * Get detailed information about the current queue state for debugging. - * @returns {Object} Comprehensive queue state information - */ - inspect(): Object; - /** - * Get information about active timers and scheduler state. - * @returns {Object} Timer and scheduler information - */ - inspectTimers(): Object; - /** - * Get a summary of all queued tasks by status. - * @returns {Object} Task summary by status - */ - inspectTasks(): Object; - /** - * Get detailed information about the scheduler state and timing. - * @returns {Object} Scheduler state information - */ - inspectScheduler(): Object; - /** - * Log comprehensive queue state to console for debugging. - * @param {boolean} [detailed=false] - Whether to include detailed task information - */ - debugLog(detailed?: boolean): void; + _syncMode: boolean | undefined; + options: + | { + constructor: Function; + toString(): string; + toLocaleString(): string; + valueOf(): Object; + hasOwnProperty(v: PropertyKey): boolean; + isPrototypeOf(v: Object): boolean; + propertyIsEnumerable(v: PropertyKey): boolean; + concurrency: number; + tick: number; + autoStart: boolean; + defaultPriority: number; + maxQueue: any; + priorities: {}; + smartScheduling: boolean; + healingInterval: number; + coalescing: { + defaults: Object; + keys: {}; + }; + coalescingWindowDuration: any; + coalescingMaxDelay: any; + coalescingMultipleCallbacks: any; + coalescingResolveAllPromises: any; + } + | undefined; + pendingHeap: MinHeap | undefined; + readyHeap: MinHeap | undefined; + running: Set | undefined; + runningByPriority: Map | undefined; + tasks: Map | undefined; + nextId: number | undefined; + enqueueSeq: number | undefined; + isActive: boolean | undefined; + destroyed: boolean | undefined; + lastCompletedPriority: any; + nextAvailableTime: any; + schedulerTimeout: number | null | undefined; + healingInterval: number | null | undefined; + lastSchedulerRun: number | undefined; + intervalId: number | null | undefined; + coalescingGroups: Map | undefined; + coalescingRepresentatives: Map | undefined; + nextGroupId: number | undefined; + timeoutId: number | undefined; + constructor(options?: {}); + /** + * Synchronous initialization for backwards compatibility + * @private + * @param {Object} options - Configuration options + */ + private _initializeSync; + /** + * Asynchronous initialization for modern usage + * @private + * @param {Object} options - Configuration options + * @returns {Promise} Promise that resolves to this instance + */ + private _initializeAsync; + /** + * Common initialization logic used by both sync and async modes + * @private + * @param {Object} options - Configuration options + */ + private _initializeCommon; + /** + * Internal convenience method to create a new HoldMyTask instance with async initialization. + * This enables event listeners to be attached before validation errors can occur. + * @param {Object} [options={}] - Configuration options + * @returns {Promise} Promise that resolves to the initialized instance + * @private + * @example + * // Internal usage - prefer new HoldMyTask({ sync: false }) for public API + * const queue = await HoldMyTask._create({ maxQueue: 100 }); + */ + private static _create; + /** + * Adds a task to the queue for execution. Supports both callback and promise-based APIs. + * @param {Function} task - The task function to execute. Can be sync or async. + * @param {Function|Object} [optionsOrCallback] - Either a callback function or options object + * @param {Object} [options={}] - Additional options (if callback was provided as second parameter) + * @param {string|number} [options.id] - Custom task ID for identification and later reference (must be unique) + * @param {number} [options.priority] - Task priority (higher numbers run first) + * @param {number} [options.timestamp] - When the task should be ready to run (milliseconds since epoch) + * @param {number} [options.start] - Milliseconds from now when the task should be ready to run (convenience for timestamp calculation) + * @param {AbortSignal} [options.signal] - AbortSignal to cancel the task + * @param {number} [options.timeout] - Task timeout in milliseconds (for execution time limit) + * @param {number} [options.expire] - Task expiration timestamp or milliseconds from now (for queue waiting time limit) + * @param {number} [options.delay] - DEPRECATED: Use postDelay instead. Delay after task completion before next task of same priority + * @param {boolean} [options.bypassDelay] - If true, skip any active delay period and start immediately + * @param {string} [options.coalescingKey] - Key for task coalescing - tasks with same key will be coalesced within windows + * @param {number} [options.coalescingWindowDuration] - Override coalescing window duration (task-level override of key-level and defaults) + * @param {number} [options.coalescingMaxDelay] - Override coalescing max delay (task-level override of key-level and defaults) + * @param {boolean} [options.coalescingMultipleCallbacks] - Override callback behavior (task-level override of key-level and defaults) + * @param {boolean} [options.coalescingResolveAllPromises] - Override promise resolution behavior (task-level override of key-level and defaults) + * @param {*} [options.metadata] - Arbitrary metadata to attach to the task + * @returns {Promise|Object} Promise (if no callback) or task control object with id, cancel, status methods + * @throws {Error} If queue is destroyed or full + * @example + * // Promise API + * const result = await queue.enqueue(async () => fetchData()); + * + * // Callback API + * queue.enqueue(() => processData(), (err, result) => { + * if (err) console.error(err); + * else console.log(result); + * }); + * + * // With options + * const task = queue.enqueue(myTask, { priority: 5, timeout: 30000, expire: 10000 }); + * + * // Bypass current delay for urgent task + * const urgent = queue.enqueue(urgentTask, { priority: 10, bypassDelay: true }); + * + * // Alternative: use delay: -1 to bypass + * const urgent2 = queue.enqueue(urgentTask, { priority: 10, delay: -1 }); + * + * // Coalescing tasks - multiple device status checks become one + * queue.enqueue(checkDeviceStatus, callback1, { coalescingKey: "device-123", coalescingWindowDuration: 1000 }); + * queue.enqueue(checkDeviceStatus, callback2, { coalescingKey: "device-123" }); // Gets coalesced with first + */ + enqueue( + task: Function, + optionsOrCallback?: Function | Object, + options?: { + id?: string | number; + priority?: number; + timestamp?: number; + start?: number; + signal?: AbortSignal; + timeout?: number; + expire?: number; + delay?: number; + bypassDelay?: boolean; + coalescingKey?: string; + coalescingWindowDuration?: number; + coalescingMaxDelay?: number; + coalescingMultipleCallbacks?: boolean; + coalescingResolveAllPromises?: boolean; + metadata?: any; + } + ): Promise | Object; + /** + * Cancels a pending task by ID. + * @param {string} id - The task ID to cancel + * @param {string} [reason="Task canceled"] - Reason for cancellation + * @returns {boolean} True if task was found and cancelled, false otherwise + * @example + * const task = queue.enqueue(() => longRunningTask()); + * const cancelled = queue.cancel(task.id, "User requested cancellation"); + */ + cancel(id: string, reason?: string): boolean; + /** + * Alias for cancel() method for backward compatibility. + * @param {string|number} id - The task ID to cancel + * @param {string} [reason="Task canceled"] - Reason for cancellation + * @returns {boolean} True if task was found and cancelled, false otherwise + */ + cancelTask(id: string | number, reason?: string): boolean; + /** + * Pauses the task queue, stopping execution of new tasks. + * Currently running tasks will continue to completion. + * @returns {void} + * @example + * queue.pause(); + * // Queue stops processing new tasks + */ + pause(): void; + /** + * Resumes the task queue after being paused. + * @returns {void} + * @example + * queue.resume(); + * // Queue resumes processing tasks + */ + resume(): void; + /** + * Clears all pending and ready tasks from the queue. + * Currently running tasks will continue to completion. + * @returns {void} + * @example + * queue.clear(); + * // All queued tasks are removed + */ + clear(): void; + /** + * Returns the number of tasks in the queue. + * @returns {number} Number of tasks in the queue + * @example + * const totalTasks = queue.size(); // 5 + */ + size(): number; + /** + * Returns the number of tasks in the queue (alias for size()). + * @returns {number} Number of tasks in the queue + * @example + * const totalTasks = queue.length(); // 5 + */ + length(): number; + /** + * Returns the number of currently running tasks. + * @returns {number} Number of running tasks + * @example + * const runningTasks = queue.inflight(); // 2 + */ + inflight(): number; + /** + * Gets information about a coalescing group by key and group ID. + * @param {string} coalescingKey - The coalescing key + * @param {string} [groupId] - Optional group ID. If omitted, returns all groups for the key + * @returns {Object|Array|null} Group info object, array of groups, or null if not found + * @example + * // Get all groups for a coalescing key + * const groups = queue.getCoalescingGroup('ui.update'); + * + * // Get specific group by ID + * const group = queue.getCoalescingGroup('ui.update', '1'); + * console.log(group.tasks.size); // Number of tasks in group + * + * // Access individual task metadata + * for (const [taskId, task] of group.tasks) { + * console.log(`Task ${taskId}:`, task.metadata); + * } + */ + getCoalescingGroup(coalescingKey: string, groupId?: string): Object | any[] | null; + /** + * Gets metadata for all tasks in a coalescing group. + * @param {string} coalescingKey - The coalescing key + * @param {string} [groupId] - Optional group ID. If omitted, returns metadata from all groups for the key + * @returns {Array} Array of metadata objects with task IDs + * @example + * // Get metadata from all groups for a key + * const allMetadata = queue.getCoalescingGroupMetadata('ui.update'); + * + * // Get metadata from specific group + * const groupMetadata = queue.getCoalescingGroupMetadata('ui.update', '1'); + * + * // Example output: + * // [ + * // { taskId: '123', metadata: { userId: 100, action: 'save' } }, + * // { taskId: '124', metadata: { userId: 200, action: 'delete' } } + * // ] + */ + getCoalescingGroupMetadata(coalescingKey: string, groupId?: string): any[]; + /** + * Gets a summary of all active coalescing groups. + * @returns {Object} Summary object with coalescing key stats + * @example + * const summary = queue.getCoalescingGroupsSummary(); + * console.log(summary); + * // { + * // 'ui.update': { groupCount: 2, totalTasks: 5 }, + * // 'api.batch': { groupCount: 1, totalTasks: 3 } + * // } + */ + getCoalescingGroupsSummary(): Object; + /** + * Finds the coalescing group that contains a specific task ID. + * @param {string|number} taskId - The task ID to search for + * @returns {Object|null} Group information including the task's metadata, or null if not found + * @example + * const groupInfo = queue.findCoalescingGroupByTaskId('123'); + * if (groupInfo) { + * console.log('Task is in group:', groupInfo.groupId); + * console.log('Task metadata:', groupInfo.task.metadata); + * console.log('Other tasks in group:', groupInfo.groupTasks.length); + * } + */ + findCoalescingGroupByTaskId(taskId: string | number): Object | null; + /** + * Destroys the queue, canceling all tasks and stopping the scheduler. + * Once destroyed, the queue cannot be reused. + * @returns {void} + * @example + * queue.destroy(); + * // Queue is permanently shut down + */ + destroy(): void; + /** + * Returns the current timestamp in milliseconds. + * @returns {number} Current timestamp + * @example + * const timestamp = queue.now(); // 1699564800000 + */ + now(): number; + /** + * Main scheduler tick that moves ready tasks and starts execution. + * @returns {void} + * @private + */ + private schedulerTick; + /** + * Checks if a task can start based on both global and per-priority concurrency limits. + * @param {Object} task - The task to check + * @returns {boolean} True if the task can start, false if concurrency limits prevent it + * @private + */ + private _canStartTask; + /** + * Clears all active timers (intervals and timeouts). + * @returns {void} + * @private + */ + private clearTimers; + /** + * Calculates when the next scheduler run should happen and sets appropriate timeout. + * @private + * @returns {void} + * + * @description + * Smart scheduling that calculates the optimal time for the next scheduler run based on: + * - When the next pending task becomes ready + * - When delay periods end + * - Whether there are tasks that can run immediately + * + * Uses setTimeout for precise timing instead of constant polling intervals. + */ + private scheduleSmartTimeout; + /** + * Runs the main scheduler logic and reschedules if needed. + * @private + * @returns {void} + * + * @description + * Executes the scheduler tick logic and then determines if more scheduling is needed. + * Tracks when scheduler last ran for healing mechanism. + */ + private runScheduler; + /** + * Starts the self-healing interval that ensures scheduler continues working. + * @private + * @returns {void} + * + * @description + * Healing mechanism that periodically checks if the scheduler should be running + * but isn't due to timeout failures or other issues. Runs every healingInterval milliseconds. + */ + private startHealingInterval; + /** + * Clears all scheduler-related timers. + * @private + * @returns {void} + * + * @description + * Cleans up both the main scheduler timeout and the healing interval timer. + */ + private clearSchedulerTimers; + /** + * Configure coalescing settings for specific keys dynamically. + * @param {string} coalescingKey - The coalescing key to configure + * @param {Object} config - Configuration for this key + * @param {number} [config.windowDuration] - Window duration in milliseconds for this key + * @param {number} [config.maxDelay] - Maximum delay in milliseconds for this key + * @param {number} [config.postDelay] - Post-completion delay in milliseconds for this key + * @param {number} [config.startDelay] - Pre-execution delay in milliseconds for this key + * @param {number} [config.delay] - DEPRECATED: Use postDelay instead + * @param {number} [config.start] - DEPRECATED: Use startDelay instead + * @param {boolean} [config.multipleCallbacks] - Whether to call multiple callbacks for this key + * @param {boolean} [config.resolveAllPromises] - Whether to resolve all promises for this key + * @returns {void} + * + * @example + * // Configure specific keys after queue creation + * queue.configureCoalescingKey('ui.update', { + * windowDuration: 100, + * maxDelay: 500, + * postDelay: 25, + * startDelay: 0 + * }); + * + * queue.configureCoalescingKey('api.batch', { + * windowDuration: 1000, + * maxDelay: 5000, + * postDelay: 100, + * startDelay: 200, + * resolveAllPromises: false + * }); + */ + configureCoalescingKey( + coalescingKey: string, + config: { + windowDuration?: number; + maxDelay?: number; + postDelay?: number; + startDelay?: number; + delay?: number; + start?: number; + multipleCallbacks?: boolean; + resolveAllPromises?: boolean; + } + ): void; + /** + * Get the effective coalescing configuration for a specific key. + * @param {string} coalescingKey - The coalescing key to get configuration for + * @param {Object} [taskOptions={}] - Task-level options that may override key configuration + * @returns {Object} The effective configuration for this key + * + * @example + * // Get effective configuration for a key + * const config = queue.getCoalescingConfig('ui.update'); + * console.log(`UI updates coalesce within ${config.windowDuration}ms with ${config.postDelay}ms post-completion delay`); + * + * // Check with task-level overrides + * const effectiveConfig = queue.getCoalescingConfig('ui.update', { + * coalescingWindowDuration: 50, + * delay: 30 // Still accepts old property names for backwards compatibility + * }); + */ + getCoalescingConfig(coalescingKey: string, taskOptions?: Object): Object; + /** + * Get all configured coalescing keys and their configurations. + * @returns {Object} Map of coalescingKey to configuration + * + * @example + * // See all configured coalescing keys + * const allConfigs = queue.getCoalescingConfigurations(); + * Object.entries(allConfigs).forEach(([key, config]) => { + * console.log(`${key}: ${config.windowDuration}ms window, ${config.maxDelay}ms max delay, ${config.postDelay}ms post-completion delay, ${config.startDelay}ms pre-execution delay`); + * }); + */ + getCoalescingConfigurations(): Object; + /** + * Configure default settings for specific priorities dynamically. + * @param {number} priority - The priority level to configure + * @param {Object} config - Configuration for this priority + * @param {number} [config.postDelay] - Default post-completion delay in milliseconds for this priority + * @param {number} [config.startDelay] - Default pre-execution delay in milliseconds for this priority + * @param {number} [config.delay] - DEPRECATED: Use postDelay instead + * @param {number} [config.start] - DEPRECATED: Use startDelay instead + * @returns {void} + * + * @example + * // Configure priority defaults after queue creation + * queue.configurePriority(1, { + * postDelay: 100, // High priority tasks have 100ms delay after completion + * startDelay: 0 // High priority tasks start immediately + * }); + * + * queue.configurePriority(3, { + * postDelay: 0, // Low priority tasks have no delay after completion + * startDelay: 200 // Low priority tasks wait 200ms before starting + * }); + */ + configurePriority( + priority: number, + config: { + postDelay?: number; + startDelay?: number; + delay?: number; + start?: number; + } + ): void; + /** + * Get the effective configuration for a specific priority. + * @param {number} priority - The priority level to get configuration for + * @param {Object} [taskOptions={}] - Task-level options that may override priority configuration + * @returns {Object} The effective configuration for this priority + * + * @example + * // Get effective configuration for a priority + * const config = queue.getPriorityConfig(1); + * console.log(`Priority 1 tasks: ${config.delay}ms delay, ${config.start}ms start delay`); + * + * // Check with task-level overrides + * const effectiveConfig = queue.getPriorityConfig(1, { + * delay: 50, + * start: 10 + * }); + */ + getPriorityConfig(priority: number, taskOptions?: Object): Object; + /** + * Get all configured priorities and their configurations. + * @returns {Object} Map of priority to configuration + * + * @example + * // See all configured priorities + * const allConfigs = queue.getPriorityConfigurations(); + * Object.entries(allConfigs).forEach(([priority, config]) => { + * console.log(`Priority ${priority}: ${config.delay}ms delay, ${config.start}ms start delay`); + * }); + */ + getPriorityConfigurations(): Object; + /** + * Alias for destroy() method for common queue system naming. + * @returns {void} + */ + shutdown(): void; + /** + * Alias for enqueue() method for common queue system naming. + * @param {Function} task - The task function to execute + * @param {Function|Object} optionsOrCallback - Callback function or options object + * @param {Object} options - Task options (if callback provided as second parameter) + * @returns {Promise|TaskHandle} Promise if no callback provided, TaskHandle otherwise + */ + schedule(task: Function, optionsOrCallback: Function | Object, options?: Object): Promise | TaskHandle; + /** + * Alias for enqueue() method for common queue system naming. + * @param {Function} task - The task function to execute + * @param {Function|Object} optionsOrCallback - Callback function or options object + * @param {Object} options - Task options (if callback provided as second parameter) + * @returns {Promise|TaskHandle} Promise if no callback provided, TaskHandle otherwise + */ + add(task: Function, optionsOrCallback: Function | Object, options?: Object): Promise | TaskHandle; + /** + * Find a task by its ID. + * @param {string|number} id - The task ID to find + * @returns {Object|null} Task object if found, null otherwise + */ + get(id: string | number): Object | null; + /** + * Check if a task with the given ID exists. + * @param {string|number} id - The task ID to check + * @returns {boolean} True if task exists, false otherwise + */ + has(id: string | number): boolean; + /** + * Alias for get() method for backward compatibility. + * @param {string|number} id - The task ID to find + * @returns {Object|null} Task object if found, null otherwise + */ + getTask(id: string | number): Object | null; + /** + * Alias for has() method for backward compatibility. + * @param {string|number} id - The task ID to check + * @returns {boolean} True if task exists, false otherwise + */ + hasTask(id: string | number): boolean; + /** + * Get detailed information about the current queue state for debugging. + * @returns {Object} Comprehensive queue state information + */ + inspect(): Object; + /** + * Get information about active timers and scheduler state. + * @returns {Object} Timer and scheduler information + */ + inspectTimers(): Object; + /** + * Get a summary of all queued tasks by status. + * @returns {Object} Task summary by status + */ + inspectTasks(): Object; + /** + * Get detailed information about the scheduler state and timing. + * @returns {Object} Scheduler state information + */ + inspectScheduler(): Object; + /** + * Log comprehensive queue state to console for debugging. + * @param {boolean} [detailed=false] - Whether to include detailed task information + */ + debugLog(detailed?: boolean): void; } -//# sourceMappingURL=hold-my-task.d.mts.map \ No newline at end of file +//# sourceMappingURL=hold-my-task.d.mts.map diff --git a/types/src/utils.d.mts b/types/src/utils.d.mts index 67ee867..8954dd0 100644 --- a/types/src/utils.d.mts +++ b/types/src/utils.d.mts @@ -15,58 +15,58 @@ * Maintains the heap property where parent nodes are smaller than their children. */ export declare class MinHeap { - heap: any[]; - compare: Function; - /** - * Creates a new MinHeap with a custom comparison function. - * @param {Function} compare - Comparison function that returns negative if a < b, positive if a > b, 0 if equal - * @example - * // Priority queue (higher priority = smaller value) - * const heap = new MinHeap((a, b) => a.priority - b.priority); - */ - constructor(compare: Function); - /** - * Adds an item to the heap, maintaining heap property. - * @param {*} item - The item to add to the heap - * @returns {void} - * @example - * heap.push({ value: 5, priority: 1 }); - */ - push(item: any): void; - /** - * Removes and returns the minimum item from the heap. - * @returns {*|undefined} The minimum item, or undefined if heap is empty - * @example - * const min = heap.pop(); // Returns item with smallest comparison value - */ - pop(): any | undefined; - /** - * Returns the minimum item without removing it from the heap. - * @returns {*|undefined} The minimum item, or undefined if heap is empty - * @example - * const min = heap.peek(); // Look at minimum without removing - */ - peek(): any | undefined; - /** - * Returns the number of items in the heap. - * @returns {number} The size of the heap - * @example - * const count = heap.size(); // 5 - */ - size(): number; - /** - * Moves an item up the heap to maintain heap property after insertion. - * @param {number} index - Index of the item to bubble up - * @returns {void} - * @private - */ - private bubbleUp; - /** - * Moves an item down the heap to maintain heap property after removal. - * @param {number} index - Index of the item to sink down - * @returns {void} - * @private - */ - private sinkDown; + heap: any[]; + compare: Function; + /** + * Creates a new MinHeap with a custom comparison function. + * @param {Function} compare - Comparison function that returns negative if a < b, positive if a > b, 0 if equal + * @example + * // Priority queue (higher priority = smaller value) + * const heap = new MinHeap((a, b) => a.priority - b.priority); + */ + constructor(compare: Function); + /** + * Adds an item to the heap, maintaining heap property. + * @param {*} item - The item to add to the heap + * @returns {void} + * @example + * heap.push({ value: 5, priority: 1 }); + */ + push(item: any): void; + /** + * Removes and returns the minimum item from the heap. + * @returns {*|undefined} The minimum item, or undefined if heap is empty + * @example + * const min = heap.pop(); // Returns item with smallest comparison value + */ + pop(): any | undefined; + /** + * Returns the minimum item without removing it from the heap. + * @returns {*|undefined} The minimum item, or undefined if heap is empty + * @example + * const min = heap.peek(); // Look at minimum without removing + */ + peek(): any | undefined; + /** + * Returns the number of items in the heap. + * @returns {number} The size of the heap + * @example + * const count = heap.size(); // 5 + */ + size(): number; + /** + * Moves an item up the heap to maintain heap property after insertion. + * @param {number} index - Index of the item to bubble up + * @returns {void} + * @private + */ + private bubbleUp; + /** + * Moves an item down the heap to maintain heap property after removal. + * @param {number} index - Index of the item to sink down + * @returns {void} + * @private + */ + private sinkDown; } -//# sourceMappingURL=utils.d.mts.map \ No newline at end of file +//# sourceMappingURL=utils.d.mts.map From 192abbd5f9aff79b94bf1e6955b13deac64e0fb9 Mon Sep 17 00:00:00 2001 From: "cldmv-bot[bot]" <230771808+cldmv-bot[bot]@users.noreply.github.com> Date: Wed, 12 Aug 2026 21:57:43 +0000 Subject: [PATCH 3/3] chore: bump version to 2.0.1 --- package-lock.json | 4 +- package.json | 2 +- types/build.d.mts | 2 +- types/devcheck.d.mts | 4 +- types/examples/enhanced-coalescing-test.d.mts | 2 +- .../old/breaking-point-analysis.d.mts | 140 ++- types/examples/old/coalescing-analysis.d.mts | 2 +- .../examples/old/device-control-pattern.d.mts | 76 +- types/examples/old/device-simulation.d.mts | 120 +- types/examples/old/proper-delay-test.d.mts | 100 +- types/examples/old/run-volume-test.d.mts | 2 +- types/examples/old/test-analysis.d.mts | 2 +- types/examples/old/test-breaking-point.d.mts | 2 +- types/examples/old/test-device-control.d.mts | 2 +- .../examples/old/test-device-simulation.d.mts | 2 +- types/examples/old/test-proper-delays.d.mts | 2 +- types/examples/old/test-timing-analysis.d.mts | 2 +- types/examples/old/timing-analysis.d.mts | 58 +- .../examples/old/volume-coalescing-test.d.mts | 138 +-- types/examples/priority-stress-test.d.mts | 109 +- types/examples/run-priority-stress-test.d.mts | 2 +- types/examples/unified-priority-test.d.mts | 2 +- types/index.d.mts | 2 +- types/src/hold-my-task.d.mts | 1098 ++++++++--------- types/src/hold-my-task.d.mts.map | 2 +- types/src/utils.d.mts | 108 +- 26 files changed, 979 insertions(+), 1006 deletions(-) diff --git a/package-lock.json b/package-lock.json index eec2f80..a339b69 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@cldmv/holdmytask", - "version": "2.0.0", + "version": "2.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@cldmv/holdmytask", - "version": "2.0.0", + "version": "2.0.1", "license": "Apache-2.0", "devDependencies": { "@cldmv/vitest-runner": "^1.2.0", diff --git a/package.json b/package.json index d1de1b8..f59951e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cldmv/holdmytask", - "version": "2.0.0", + "version": "2.0.1", "description": "A tiny task queue that waits until your task is ready", "main": "./index.cjs", "module": "./index.mjs", diff --git a/types/build.d.mts b/types/build.d.mts index 18261d4..212739e 100644 --- a/types/build.d.mts +++ b/types/build.d.mts @@ -11,4 +11,4 @@ * @Copyright: Copyright (c) 2013-2025 Catalyzed Motivation Inc. All rights reserved. */ export {}; -//# sourceMappingURL=build.d.mts.map +//# sourceMappingURL=build.d.mts.map \ No newline at end of file diff --git a/types/devcheck.d.mts b/types/devcheck.d.mts index 1b9ecdd..c74b0cc 100644 --- a/types/devcheck.d.mts +++ b/types/devcheck.d.mts @@ -8,7 +8,7 @@ * @Last modified by: Nate Hyson (Shinrai@users.noreply.github.com) * @Last modified time: 2025-11-21 14:51:16 -08:00 (1763765476) * ----- - * @Copyright: Copyright (c) 2013-2025 Catalyzed Motivation Inc. All rights reserved. + * @Copyright: Copyright (c) 2013-2026 Catalyzed Motivation Inc. All rights reserved. */ export {}; -//# sourceMappingURL=devcheck.d.mts.map +//# sourceMappingURL=devcheck.d.mts.map \ No newline at end of file diff --git a/types/examples/enhanced-coalescing-test.d.mts b/types/examples/enhanced-coalescing-test.d.mts index d40d56f..1101c51 100644 --- a/types/examples/enhanced-coalescing-test.d.mts +++ b/types/examples/enhanced-coalescing-test.d.mts @@ -8,4 +8,4 @@ * - Backward compatibility with legacy options */ export {}; -//# sourceMappingURL=enhanced-coalescing-test.d.mts.map +//# sourceMappingURL=enhanced-coalescing-test.d.mts.map \ No newline at end of file diff --git a/types/examples/old/breaking-point-analysis.d.mts b/types/examples/old/breaking-point-analysis.d.mts index b773e3b..c82d627 100644 --- a/types/examples/old/breaking-point-analysis.d.mts +++ b/types/examples/old/breaking-point-analysis.d.mts @@ -8,84 +8,82 @@ * Device with configurable delays */ declare class ConfigurableDelayDevice { - volume: number; - commandCount: number; - infoRequestCount: number; - commandDelay: number; - infoDelay: number; - constructor(initialVolume?: number, commandDelay?: number, infoDelay?: number); - volumeCommand(change: any): Promise<{ - commandId: number; - oldVolume: number; - newVolume: number; - change: number; - processingTime: number; - }>; - getInfo(): Promise<{ - requestId: number; - volume: number; - timestamp: number; - totalCommands: number; - totalInfoRequests: number; - processingTime: number; - }>; - getStats(): { - currentVolume: number; - totalCommands: number; - totalInfoRequests: number; - }; + volume: number; + commandCount: number; + infoRequestCount: number; + commandDelay: number; + infoDelay: number; + constructor(initialVolume?: number, commandDelay?: number, infoDelay?: number); + volumeCommand(change: any): Promise<{ + commandId: number; + oldVolume: number; + newVolume: number; + change: number; + processingTime: number; + }>; + getInfo(): Promise<{ + requestId: number; + volume: number; + timestamp: number; + totalCommands: number; + totalInfoRequests: number; + processingTime: number; + }>; + getStats(): { + currentVolume: number; + totalCommands: number; + totalInfoRequests: number; + }; } /** * Controller for timing tests */ declare class TimingTestController { - device: any; - coalescingWindowDuration: number; - queue: any; - commandCounter: number; - results: any[]; - constructor(device: any, coalescingWindowDuration?: number); - volumeUp(amount?: number): Promise<{ - commandId: number; - userActionTime: number; - completionTime: number; - totalDuration: number; - volumeResult: any; - infoResult: any; - deviceVolumeAtCompletion: any; - infoReportsVolume: any; - isAccurate: boolean; - timingData: { - volumeQueueDelay: any; - volumeProcessingTime: any; - infoQueueDelay: any; - infoProcessingTime: any; - }; - }>; - getResults(): { - results: any[]; - deviceStats: any; - coalescingWindowDuration: number; - }; - destroy(): void; + device: any; + coalescingWindowDuration: number; + queue: any; + commandCounter: number; + results: any[]; + constructor(device: any, coalescingWindowDuration?: number); + volumeUp(amount?: number): Promise<{ + commandId: number; + userActionTime: number; + completionTime: number; + totalDuration: number; + volumeResult: any; + infoResult: any; + deviceVolumeAtCompletion: any; + infoReportsVolume: any; + isAccurate: boolean; + timingData: { + volumeQueueDelay: any; + volumeProcessingTime: any; + infoQueueDelay: any; + infoProcessingTime: any; + }; + }>; + getResults(): { + results: any[]; + deviceStats: any; + coalescingWindowDuration: number; + }; + destroy(): void; } /** * Test different device delays to find the breaking point */ -declare function findBreakingPoint(): Promise< - { - description: string | number; - commandDelay: string | number; - coalescingWindow: string | number; - accurateCommands: number; - inaccurateCommands: number; - accuracyRate: number; - maxDuration: number; - avgDuration: number; - deviceCommands: any; - deviceInfoRequests: any; - coalescingEfficiency: number; - }[] ->; +declare function findBreakingPoint(): Promise<{ + description: string | number; + commandDelay: string | number; + coalescingWindow: string | number; + accurateCommands: number; + inaccurateCommands: number; + accuracyRate: number; + maxDuration: number; + avgDuration: number; + deviceCommands: any; + deviceInfoRequests: any; + coalescingEfficiency: number; +}[]>; export { ConfigurableDelayDevice, TimingTestController, findBreakingPoint }; -//# sourceMappingURL=breaking-point-analysis.d.mts.map +//# sourceMappingURL=breaking-point-analysis.d.mts.map \ No newline at end of file diff --git a/types/examples/old/coalescing-analysis.d.mts b/types/examples/old/coalescing-analysis.d.mts index d19abf3..3018862 100644 --- a/types/examples/old/coalescing-analysis.d.mts +++ b/types/examples/old/coalescing-analysis.d.mts @@ -7,4 +7,4 @@ */ declare function analyzeApproaches(): Promise; export { analyzeApproaches }; -//# sourceMappingURL=coalescing-analysis.d.mts.map +//# sourceMappingURL=coalescing-analysis.d.mts.map \ No newline at end of file diff --git a/types/examples/old/device-control-pattern.d.mts b/types/examples/old/device-control-pattern.d.mts index 56e1620..5d51a0e 100644 --- a/types/examples/old/device-control-pattern.d.mts +++ b/types/examples/old/device-control-pattern.d.mts @@ -6,46 +6,46 @@ */ import { EventEmitter } from "events"; declare class DeviceController extends EventEmitter { - queue: any; - deviceState: { - volume: number; - lastUpdated: number; - }; - pendingVolumeChanges: Map; - constructor(); - /** - * User command: Volume Up - * This accumulates changes and triggers coalesced update - */ - volumeUp(amount?: number): Promise; - /** - * The actual device update task that gets executed (coalesced) - * This applies ALL accumulated changes at once - */ - updateDeviceInfo(coalescingKey: any): Promise<{ - volume: number; - lastUpdated: number; - }>; - /** - * Update system state after device change - */ - updateSystemState(): void; - /** - * Emit events for state changes - */ - emitStateChange(oldVolume: any, newVolume: any): void; - /** - * Get current device state - */ - getState(): { - volume: number; - lastUpdated: number; - }; - destroy(): void; + queue: any; + deviceState: { + volume: number; + lastUpdated: number; + }; + pendingVolumeChanges: Map; + constructor(); + /** + * User command: Volume Up + * This accumulates changes and triggers coalesced update + */ + volumeUp(amount?: number): Promise; + /** + * The actual device update task that gets executed (coalesced) + * This applies ALL accumulated changes at once + */ + updateDeviceInfo(coalescingKey: any): Promise<{ + volume: number; + lastUpdated: number; + }>; + /** + * Update system state after device change + */ + updateSystemState(): void; + /** + * Emit events for state changes + */ + emitStateChange(oldVolume: any, newVolume: any): void; + /** + * Get current device state + */ + getState(): { + volume: number; + lastUpdated: number; + }; + destroy(): void; } declare function demonstrateDeviceControl(): Promise; declare class AdvancedDeviceController extends DeviceController { - volumeUp(amount?: number): Promise; + volumeUp(amount?: number): Promise; } export { DeviceController, AdvancedDeviceController, demonstrateDeviceControl }; -//# sourceMappingURL=device-control-pattern.d.mts.map +//# sourceMappingURL=device-control-pattern.d.mts.map \ No newline at end of file diff --git a/types/examples/old/device-simulation.d.mts b/types/examples/old/device-simulation.d.mts index 881149f..6b72f3f 100644 --- a/types/examples/old/device-simulation.d.mts +++ b/types/examples/old/device-simulation.d.mts @@ -12,79 +12,79 @@ import { EventEmitter } from "events"; * Simulated device that tracks its own state */ declare class PseudoDevice { - volume: number; - commandCount: number; - infoRequestCount: number; - constructor(initialVolume?: number); - /** - * Device receives a volume change command - */ - volumeCommand(change: any): Promise<{ - commandId: number; - oldVolume: number; - newVolume: number; - change: number; - }>; - /** - * Device responds to info request - */ - getInfo(): Promise<{ - requestId: number; - volume: number; - timestamp: number; - totalCommands: number; - totalInfoRequests: number; - }>; - /** - * Get device stats - */ - getStats(): { - currentVolume: number; - totalCommands: number; - totalInfoRequests: number; - }; + volume: number; + commandCount: number; + infoRequestCount: number; + constructor(initialVolume?: number); + /** + * Device receives a volume change command + */ + volumeCommand(change: any): Promise<{ + commandId: number; + oldVolume: number; + newVolume: number; + change: number; + }>; + /** + * Device responds to info request + */ + getInfo(): Promise<{ + requestId: number; + volume: number; + timestamp: number; + totalCommands: number; + totalInfoRequests: number; + }>; + /** + * Get device stats + */ + getStats(): { + currentVolume: number; + totalCommands: number; + totalInfoRequests: number; + }; } /** * Controller that uses the queue system to communicate with the device */ declare class DeviceController extends EventEmitter { - device: any; - queue: any; - optimisticVolume: any; - pendingChanges: number; - constructor(device: any, queueOptions?: {}); - /** - * User calls volumeUp - this should update device and then get fresh info - */ - volumeUp(amount?: number): Promise<{ - volumeCommand: any; - deviceInfo: any; - optimisticVolume: any; - pendingChanges: number; - }>; - /** - * Get current state - */ - getState(): { - optimisticVolume: any; - pendingChanges: number; - deviceStats: any; - }; - destroy(): void; + device: any; + queue: any; + optimisticVolume: any; + pendingChanges: number; + constructor(device: any, queueOptions?: {}); + /** + * User calls volumeUp - this should update device and then get fresh info + */ + volumeUp(amount?: number): Promise<{ + volumeCommand: any; + deviceInfo: any; + optimisticVolume: any; + pendingChanges: number; + }>; + /** + * Get current state + */ + getState(): { + optimisticVolume: any; + pendingChanges: number; + deviceStats: any; + }; + destroy(): void; } /** * Test scenario: Rapid volume commands */ declare function testRapidVolumeCommands(): Promise<{ - expectedVolume: number; - actualVolume: number; - totalCommands: number; - totalInfoRequests: number; - success: boolean; + expectedVolume: number; + actualVolume: number; + totalCommands: number; + totalInfoRequests: number; + success: boolean; }>; /** * Test different coalescing configurations */ declare function testCoalescingConfigurations(): Promise; export { PseudoDevice, DeviceController, testRapidVolumeCommands, testCoalescingConfigurations }; -//# sourceMappingURL=device-simulation.d.mts.map +//# sourceMappingURL=device-simulation.d.mts.map \ No newline at end of file diff --git a/types/examples/old/proper-delay-test.d.mts b/types/examples/old/proper-delay-test.d.mts index 16bb567..0495217 100644 --- a/types/examples/old/proper-delay-test.d.mts +++ b/types/examples/old/proper-delay-test.d.mts @@ -7,65 +7,65 @@ * - This should allow 2 volume updates to complete before info request */ declare class SimpleDevice { - volume: number; - commandCount: number; - infoRequestCount: number; - constructor(initialVolume?: number); - volumeCommand(change: any): Promise<{ - commandId: number; - oldVolume: number; - newVolume: number; - change: number; - }>; - getInfo(): Promise<{ - requestId: number; - volume: number; - timestamp: number; - totalCommands: number; - totalInfoRequests: number; - }>; - getStats(): { - currentVolume: number; - totalCommands: number; - totalInfoRequests: number; - }; + volume: number; + commandCount: number; + infoRequestCount: number; + constructor(initialVolume?: number); + volumeCommand(change: any): Promise<{ + commandId: number; + oldVolume: number; + newVolume: number; + change: number; + }>; + getInfo(): Promise<{ + requestId: number; + volume: number; + timestamp: number; + totalCommands: number; + totalInfoRequests: number; + }>; + getStats(): { + currentVolume: number; + totalCommands: number; + totalInfoRequests: number; + }; } /** * Controller using proper queue delays */ declare class ProperDelayController { - device: any; - queue: any; - commandCounter: number; - constructor(device: any); - volumeUp(amount?: number): Promise<{ - commandId: number; - startTime: number; - endTime: number; - duration: number; - volumeResult: any; - infoResult: any; - deviceVolumeAtEnd: any; - infoReportsVolume: any; - isAccurate: boolean; - }>; - getQueueInfo(): { - pendingCount: any; - runningCount: any; - completedCount: any; - }; - destroy(): void; + device: any; + queue: any; + commandCounter: number; + constructor(device: any); + volumeUp(amount?: number): Promise<{ + commandId: number; + startTime: number; + endTime: number; + duration: number; + volumeResult: any; + infoResult: any; + deviceVolumeAtEnd: any; + infoReportsVolume: any; + isAccurate: boolean; + }>; + getQueueInfo(): { + pendingCount: any; + runningCount: any; + completedCount: any; + }; + destroy(): void; } /** * Test the proper delay scenario */ declare function testProperDelays(): Promise<{ - totalAccurate: number; - totalTests: number; - accuracyRate: number; - deviceCommands: number; - deviceInfoRequests: number; - finalVolume: number; + totalAccurate: number; + totalTests: number; + accuracyRate: number; + deviceCommands: number; + deviceInfoRequests: number; + finalVolume: number; }>; export { SimpleDevice, ProperDelayController, testProperDelays }; -//# sourceMappingURL=proper-delay-test.d.mts.map +//# sourceMappingURL=proper-delay-test.d.mts.map \ No newline at end of file diff --git a/types/examples/old/run-volume-test.d.mts b/types/examples/old/run-volume-test.d.mts index 0f0c03f..29eeb8b 100644 --- a/types/examples/old/run-volume-test.d.mts +++ b/types/examples/old/run-volume-test.d.mts @@ -11,4 +11,4 @@ * @Copyright: Copyright (c) 2013-2025 Catalyzed Motivation Inc. All rights reserved. */ export {}; -//# sourceMappingURL=run-volume-test.d.mts.map +//# sourceMappingURL=run-volume-test.d.mts.map \ No newline at end of file diff --git a/types/examples/old/test-analysis.d.mts b/types/examples/old/test-analysis.d.mts index 562c48e..c53ded1 100644 --- a/types/examples/old/test-analysis.d.mts +++ b/types/examples/old/test-analysis.d.mts @@ -1,2 +1,2 @@ export {}; -//# sourceMappingURL=test-analysis.d.mts.map +//# sourceMappingURL=test-analysis.d.mts.map \ No newline at end of file diff --git a/types/examples/old/test-breaking-point.d.mts b/types/examples/old/test-breaking-point.d.mts index 9207a6a..da1f04b 100644 --- a/types/examples/old/test-breaking-point.d.mts +++ b/types/examples/old/test-breaking-point.d.mts @@ -1,2 +1,2 @@ export {}; -//# sourceMappingURL=test-breaking-point.d.mts.map +//# sourceMappingURL=test-breaking-point.d.mts.map \ No newline at end of file diff --git a/types/examples/old/test-device-control.d.mts b/types/examples/old/test-device-control.d.mts index 7c42817..5f96050 100644 --- a/types/examples/old/test-device-control.d.mts +++ b/types/examples/old/test-device-control.d.mts @@ -2,4 +2,4 @@ * Test the device control pattern */ export {}; -//# sourceMappingURL=test-device-control.d.mts.map +//# sourceMappingURL=test-device-control.d.mts.map \ No newline at end of file diff --git a/types/examples/old/test-device-simulation.d.mts b/types/examples/old/test-device-simulation.d.mts index 918ad69..6ea80f7 100644 --- a/types/examples/old/test-device-simulation.d.mts +++ b/types/examples/old/test-device-simulation.d.mts @@ -1,2 +1,2 @@ export {}; -//# sourceMappingURL=test-device-simulation.d.mts.map +//# sourceMappingURL=test-device-simulation.d.mts.map \ No newline at end of file diff --git a/types/examples/old/test-proper-delays.d.mts b/types/examples/old/test-proper-delays.d.mts index 0058d86..f666b7b 100644 --- a/types/examples/old/test-proper-delays.d.mts +++ b/types/examples/old/test-proper-delays.d.mts @@ -1,2 +1,2 @@ export {}; -//# sourceMappingURL=test-proper-delays.d.mts.map +//# sourceMappingURL=test-proper-delays.d.mts.map \ No newline at end of file diff --git a/types/examples/old/test-timing-analysis.d.mts b/types/examples/old/test-timing-analysis.d.mts index 1fd5d1e..799f837 100644 --- a/types/examples/old/test-timing-analysis.d.mts +++ b/types/examples/old/test-timing-analysis.d.mts @@ -1,2 +1,2 @@ export {}; -//# sourceMappingURL=test-timing-analysis.d.mts.map +//# sourceMappingURL=test-timing-analysis.d.mts.map \ No newline at end of file diff --git a/types/examples/old/timing-analysis.d.mts b/types/examples/old/timing-analysis.d.mts index c818e50..0e54447 100644 --- a/types/examples/old/timing-analysis.d.mts +++ b/types/examples/old/timing-analysis.d.mts @@ -9,40 +9,40 @@ import { DeviceController } from "./device-simulation.mjs"; * Enhanced controller that logs detailed timing information */ declare class TimingAnalysisController extends DeviceController { - commandCounter: number; - timingLog: any[]; - constructor(device: any, queueOptions?: {}); - volumeUp(amount?: number): Promise<{ - commandId: number; - startTime: number; - endTime: number; - totalDuration: number; - volumeCommand: any; - infoResult: any; - expectedVolume: any; - reportedVolume: any; - }>; - getTimingAnalysis(): { - timingLog: any[]; - deviceStats: any; - }; + commandCounter: number; + timingLog: any[]; + constructor(device: any, queueOptions?: {}); + volumeUp(amount?: number): Promise<{ + commandId: number; + startTime: number; + endTime: number; + totalDuration: number; + volumeCommand: any; + infoResult: any; + expectedVolume: any; + reportedVolume: any; + }>; + getTimingAnalysis(): { + timingLog: any[]; + deviceStats: any; + }; } /** * Test with reference counting approach */ declare class ReferenceCountingController extends DeviceController { - pendingVolumeCommands: Map; - commandCounter: number; - constructor(device: any, queueOptions?: {}); - volumeUp(amount?: number): Promise<{ - commandId: number; - volumeResult: any; - infoResult: any; - expectedVolume: any; - reportedVolume: any; - accurate: boolean; - }>; + pendingVolumeCommands: Map; + commandCounter: number; + constructor(device: any, queueOptions?: {}); + volumeUp(amount?: number): Promise<{ + commandId: number; + volumeResult: any; + infoResult: any; + expectedVolume: any; + reportedVolume: any; + accurate: boolean; + }>; } declare function analyzeTimingIssues(): Promise; export { TimingAnalysisController, ReferenceCountingController, analyzeTimingIssues }; -//# sourceMappingURL=timing-analysis.d.mts.map +//# sourceMappingURL=timing-analysis.d.mts.map \ No newline at end of file diff --git a/types/examples/old/volume-coalescing-test.d.mts b/types/examples/old/volume-coalescing-test.d.mts index aa65504..a9cf911 100644 --- a/types/examples/old/volume-coalescing-test.d.mts +++ b/types/examples/old/volume-coalescing-test.d.mts @@ -11,86 +11,78 @@ * Simple volume system that tracks state */ declare class VolumeSystem { - volume: number; - commandCount: number; - updateCount: number; - log: any[]; - constructor(initialVolume?: number); - /** - * Execute a volume command (changes the actual volume) - */ - executeVolumeCommand( - change: any, - commandId: any - ): Promise<{ - commandId: any; - oldVolume: number; - newVolume: number; - change: number; - executionTime: number; - }>; - /** - * Execute an update command (reports current state) - */ - executeUpdateCommand(updateId: any): Promise<{ - updateId: any; - volume: number; - timestamp: number; - totalCommands: number; - totalUpdates: number; - }>; - getState(): { - currentVolume: number; - totalCommands: number; - totalUpdates: number; - }; - getLog(): any[]; - clearLog(): void; + volume: number; + commandCount: number; + updateCount: number; + log: any[]; + constructor(initialVolume?: number); + /** + * Execute a volume command (changes the actual volume) + */ + executeVolumeCommand(change: any, commandId: any): Promise<{ + commandId: any; + oldVolume: number; + newVolume: number; + change: number; + executionTime: number; + }>; + /** + * Execute an update command (reports current state) + */ + executeUpdateCommand(updateId: any): Promise<{ + updateId: any; + volume: number; + timestamp: number; + totalCommands: number; + totalUpdates: number; + }>; + getState(): { + currentVolume: number; + totalCommands: number; + totalUpdates: number; + }; + getLog(): any[]; + clearLog(): void; } /** * Controller that implements volume commands with coalesced updates */ declare class VolumeController { - volumeSystem: any; - queue: any; - commandCounter: number; - constructor(volumeSystem: any, queueOptions?: {}); - /** - * Volume up command with coalesced update - */ - volumeUp( - amount?: number, - options?: {} - ): Promise<{ - commandId: number; - userActionTime: number; - endTime: number; - totalDuration: number; - volumeResult: any; - updateResult: any; - systemVolumeAtEnd: any; - updateReportsVolume: any; - isAccurate: boolean; - options: {}; - }>; - destroy(): void; + volumeSystem: any; + queue: any; + commandCounter: number; + constructor(volumeSystem: any, queueOptions?: {}); + /** + * Volume up command with coalesced update + */ + volumeUp(amount?: number, options?: {}): Promise<{ + commandId: number; + userActionTime: number; + endTime: number; + totalDuration: number; + volumeResult: any; + updateResult: any; + systemVolumeAtEnd: any; + updateReportsVolume: any; + isAccurate: boolean; + options: {}; + }>; + destroy(): void; } /** * Test different timing scenarios */ -declare function testVolumeCoalescing(): Promise< - { - scenario: string; - totalDuration: number; - accurateCommands: number; - totalCommands: number; - accuracyRate: number; - finalVolume: number; - expectedVolume: number; - volumeCommandsExecuted: number; - updateCommandsExecuted: number; - coalescingEfficiency: number; - }[] ->; +declare function testVolumeCoalescing(): Promise<{ + scenario: string; + totalDuration: number; + accurateCommands: number; + totalCommands: number; + accuracyRate: number; + finalVolume: number; + expectedVolume: number; + volumeCommandsExecuted: number; + updateCommandsExecuted: number; + coalescingEfficiency: number; +}[]>; export { VolumeSystem, VolumeController, testVolumeCoalescing }; -//# sourceMappingURL=volume-coalescing-test.d.mts.map +//# sourceMappingURL=volume-coalescing-test.d.mts.map \ No newline at end of file diff --git a/types/examples/priority-stress-test.d.mts b/types/examples/priority-stress-test.d.mts index e175d11..ae7f36d 100644 --- a/types/examples/priority-stress-test.d.mts +++ b/types/examples/priority-stress-test.d.mts @@ -10,70 +10,65 @@ * Volume system with realistic timing */ declare class RealisticVolumeSystem { - volume: number; - commandCount: number; - updateCount: number; - log: any[]; - constructor(initialVolume?: number); - executeVolumeCommand( - change: any, - commandId: any - ): Promise<{ - commandId: any; - oldVolume: number; - newVolume: number; - change: number; - executionTime: number; - processingTime: number; - }>; - executeUpdateCommand(updateId: any): Promise<{ - updateId: any; - volume: number; - timestamp: number; - totalCommands: number; - totalUpdates: number; - processingTime: number; - }>; - getState(): { - currentVolume: number; - totalCommands: number; - totalUpdates: number; - }; - getLog(): any[]; - clearLog(): void; + volume: number; + commandCount: number; + updateCount: number; + log: any[]; + constructor(initialVolume?: number); + executeVolumeCommand(change: any, commandId: any): Promise<{ + commandId: any; + oldVolume: number; + newVolume: number; + change: number; + executionTime: number; + processingTime: number; + }>; + executeUpdateCommand(updateId: any): Promise<{ + updateId: any; + volume: number; + timestamp: number; + totalCommands: number; + totalUpdates: number; + processingTime: number; + }>; + getState(): { + currentVolume: number; + totalCommands: number; + totalUpdates: number; + }; + getLog(): any[]; + clearLog(): void; } /** * Realistic volume controller with proper priorities and delays */ declare class PriorityVolumeController { - volumeSystem: any; - queue: any; - commandCounter: number; - constructor(volumeSystem: any, queueOptions?: {}); - /** - * Volume up with realistic "fire and forget" pattern - * REAL-WORLD PATTERN: Volume task enqueues update task AFTER completing volume change - */ - volumeUp(amount?: number, options?: {}): any; - destroy(): void; + volumeSystem: any; + queue: any; + commandCounter: number; + constructor(volumeSystem: any, queueOptions?: {}); + /** + * Volume up with realistic "fire and forget" pattern + * REAL-WORLD PATTERN: Volume task enqueues update task AFTER completing volume change + */ + volumeUp(amount?: number, options?: {}): any; + destroy(): void; } /** * Stress test scenarios */ -declare function runPriorityStressTests(): Promise< - { - scenario: string; - totalDuration: number; - accurateCommands: any; - totalCommands: number; - accuracyRate: number; - finalVolume: number; - expectedVolume: number; - volumeCommandsExecuted: number; - updateCommandsExecuted: number; - coalescingEfficiency: number; - averageCommandDuration: number; - }[] ->; +declare function runPriorityStressTests(): Promise<{ + scenario: string; + totalDuration: number; + accurateCommands: any; + totalCommands: number; + accuracyRate: number; + finalVolume: number; + expectedVolume: number; + volumeCommandsExecuted: number; + updateCommandsExecuted: number; + coalescingEfficiency: number; + averageCommandDuration: number; +}[]>; export { RealisticVolumeSystem, PriorityVolumeController, runPriorityStressTests }; -//# sourceMappingURL=priority-stress-test.d.mts.map +//# sourceMappingURL=priority-stress-test.d.mts.map \ No newline at end of file diff --git a/types/examples/run-priority-stress-test.d.mts b/types/examples/run-priority-stress-test.d.mts index 2f2723e..3ef6ef6 100644 --- a/types/examples/run-priority-stress-test.d.mts +++ b/types/examples/run-priority-stress-test.d.mts @@ -2,4 +2,4 @@ * Runner for Priority Stress Test */ export {}; -//# sourceMappingURL=run-priority-stress-test.d.mts.map +//# sourceMappingURL=run-priority-stress-test.d.mts.map \ No newline at end of file diff --git a/types/examples/unified-priority-test.d.mts b/types/examples/unified-priority-test.d.mts index f2f574c..75d1cc3 100644 --- a/types/examples/unified-priority-test.d.mts +++ b/types/examples/unified-priority-test.d.mts @@ -5,4 +5,4 @@ * This example demonstrates the new unified priority system with backward compatibility */ export {}; -//# sourceMappingURL=unified-priority-test.d.mts.map +//# sourceMappingURL=unified-priority-test.d.mts.map \ No newline at end of file diff --git a/types/index.d.mts b/types/index.d.mts index b117688..af165b3 100644 --- a/types/index.d.mts +++ b/types/index.d.mts @@ -43,4 +43,4 @@ export { HoldMyTask as TaskManager }; export { HoldMyTask as TaskQueue }; export { HoldMyTask as QueueManager }; export { HoldMyTask as TaskProcessor }; -//# sourceMappingURL=index.d.mts.map +//# sourceMappingURL=index.d.mts.map \ No newline at end of file diff --git a/types/src/hold-my-task.d.mts b/types/src/hold-my-task.d.mts index 8089aee..efdc97d 100644 --- a/types/src/hold-my-task.d.mts +++ b/types/src/hold-my-task.d.mts @@ -19,559 +19,547 @@ import { MinHeap } from "./utils.mjs"; * @extends EventEmitter */ export declare class HoldMyTask extends EventEmitter { - _syncMode: boolean | undefined; - options: - | { - constructor: Function; - toString(): string; - toLocaleString(): string; - valueOf(): Object; - hasOwnProperty(v: PropertyKey): boolean; - isPrototypeOf(v: Object): boolean; - propertyIsEnumerable(v: PropertyKey): boolean; - concurrency: number; - tick: number; - autoStart: boolean; - defaultPriority: number; - maxQueue: any; - priorities: {}; - smartScheduling: boolean; - healingInterval: number; - coalescing: { - defaults: Object; - keys: {}; - }; - coalescingWindowDuration: any; - coalescingMaxDelay: any; - coalescingMultipleCallbacks: any; - coalescingResolveAllPromises: any; - } - | undefined; - pendingHeap: MinHeap | undefined; - readyHeap: MinHeap | undefined; - running: Set | undefined; - runningByPriority: Map | undefined; - tasks: Map | undefined; - nextId: number | undefined; - enqueueSeq: number | undefined; - isActive: boolean | undefined; - destroyed: boolean | undefined; - lastCompletedPriority: any; - nextAvailableTime: any; - schedulerTimeout: number | null | undefined; - healingInterval: number | null | undefined; - lastSchedulerRun: number | undefined; - intervalId: number | null | undefined; - coalescingGroups: Map | undefined; - coalescingRepresentatives: Map | undefined; - nextGroupId: number | undefined; - timeoutId: number | undefined; - constructor(options?: {}); - /** - * Synchronous initialization for backwards compatibility - * @private - * @param {Object} options - Configuration options - */ - private _initializeSync; - /** - * Asynchronous initialization for modern usage - * @private - * @param {Object} options - Configuration options - * @returns {Promise} Promise that resolves to this instance - */ - private _initializeAsync; - /** - * Common initialization logic used by both sync and async modes - * @private - * @param {Object} options - Configuration options - */ - private _initializeCommon; - /** - * Internal convenience method to create a new HoldMyTask instance with async initialization. - * This enables event listeners to be attached before validation errors can occur. - * @param {Object} [options={}] - Configuration options - * @returns {Promise} Promise that resolves to the initialized instance - * @private - * @example - * // Internal usage - prefer new HoldMyTask({ sync: false }) for public API - * const queue = await HoldMyTask._create({ maxQueue: 100 }); - */ - private static _create; - /** - * Adds a task to the queue for execution. Supports both callback and promise-based APIs. - * @param {Function} task - The task function to execute. Can be sync or async. - * @param {Function|Object} [optionsOrCallback] - Either a callback function or options object - * @param {Object} [options={}] - Additional options (if callback was provided as second parameter) - * @param {string|number} [options.id] - Custom task ID for identification and later reference (must be unique) - * @param {number} [options.priority] - Task priority (higher numbers run first) - * @param {number} [options.timestamp] - When the task should be ready to run (milliseconds since epoch) - * @param {number} [options.start] - Milliseconds from now when the task should be ready to run (convenience for timestamp calculation) - * @param {AbortSignal} [options.signal] - AbortSignal to cancel the task - * @param {number} [options.timeout] - Task timeout in milliseconds (for execution time limit) - * @param {number} [options.expire] - Task expiration timestamp or milliseconds from now (for queue waiting time limit) - * @param {number} [options.delay] - DEPRECATED: Use postDelay instead. Delay after task completion before next task of same priority - * @param {boolean} [options.bypassDelay] - If true, skip any active delay period and start immediately - * @param {string} [options.coalescingKey] - Key for task coalescing - tasks with same key will be coalesced within windows - * @param {number} [options.coalescingWindowDuration] - Override coalescing window duration (task-level override of key-level and defaults) - * @param {number} [options.coalescingMaxDelay] - Override coalescing max delay (task-level override of key-level and defaults) - * @param {boolean} [options.coalescingMultipleCallbacks] - Override callback behavior (task-level override of key-level and defaults) - * @param {boolean} [options.coalescingResolveAllPromises] - Override promise resolution behavior (task-level override of key-level and defaults) - * @param {*} [options.metadata] - Arbitrary metadata to attach to the task - * @returns {Promise|Object} Promise (if no callback) or task control object with id, cancel, status methods - * @throws {Error} If queue is destroyed or full - * @example - * // Promise API - * const result = await queue.enqueue(async () => fetchData()); - * - * // Callback API - * queue.enqueue(() => processData(), (err, result) => { - * if (err) console.error(err); - * else console.log(result); - * }); - * - * // With options - * const task = queue.enqueue(myTask, { priority: 5, timeout: 30000, expire: 10000 }); - * - * // Bypass current delay for urgent task - * const urgent = queue.enqueue(urgentTask, { priority: 10, bypassDelay: true }); - * - * // Alternative: use delay: -1 to bypass - * const urgent2 = queue.enqueue(urgentTask, { priority: 10, delay: -1 }); - * - * // Coalescing tasks - multiple device status checks become one - * queue.enqueue(checkDeviceStatus, callback1, { coalescingKey: "device-123", coalescingWindowDuration: 1000 }); - * queue.enqueue(checkDeviceStatus, callback2, { coalescingKey: "device-123" }); // Gets coalesced with first - */ - enqueue( - task: Function, - optionsOrCallback?: Function | Object, - options?: { - id?: string | number; - priority?: number; - timestamp?: number; - start?: number; - signal?: AbortSignal; - timeout?: number; - expire?: number; - delay?: number; - bypassDelay?: boolean; - coalescingKey?: string; - coalescingWindowDuration?: number; - coalescingMaxDelay?: number; - coalescingMultipleCallbacks?: boolean; - coalescingResolveAllPromises?: boolean; - metadata?: any; - } - ): Promise | Object; - /** - * Cancels a pending task by ID. - * @param {string} id - The task ID to cancel - * @param {string} [reason="Task canceled"] - Reason for cancellation - * @returns {boolean} True if task was found and cancelled, false otherwise - * @example - * const task = queue.enqueue(() => longRunningTask()); - * const cancelled = queue.cancel(task.id, "User requested cancellation"); - */ - cancel(id: string, reason?: string): boolean; - /** - * Alias for cancel() method for backward compatibility. - * @param {string|number} id - The task ID to cancel - * @param {string} [reason="Task canceled"] - Reason for cancellation - * @returns {boolean} True if task was found and cancelled, false otherwise - */ - cancelTask(id: string | number, reason?: string): boolean; - /** - * Pauses the task queue, stopping execution of new tasks. - * Currently running tasks will continue to completion. - * @returns {void} - * @example - * queue.pause(); - * // Queue stops processing new tasks - */ - pause(): void; - /** - * Resumes the task queue after being paused. - * @returns {void} - * @example - * queue.resume(); - * // Queue resumes processing tasks - */ - resume(): void; - /** - * Clears all pending and ready tasks from the queue. - * Currently running tasks will continue to completion. - * @returns {void} - * @example - * queue.clear(); - * // All queued tasks are removed - */ - clear(): void; - /** - * Returns the number of tasks in the queue. - * @returns {number} Number of tasks in the queue - * @example - * const totalTasks = queue.size(); // 5 - */ - size(): number; - /** - * Returns the number of tasks in the queue (alias for size()). - * @returns {number} Number of tasks in the queue - * @example - * const totalTasks = queue.length(); // 5 - */ - length(): number; - /** - * Returns the number of currently running tasks. - * @returns {number} Number of running tasks - * @example - * const runningTasks = queue.inflight(); // 2 - */ - inflight(): number; - /** - * Gets information about a coalescing group by key and group ID. - * @param {string} coalescingKey - The coalescing key - * @param {string} [groupId] - Optional group ID. If omitted, returns all groups for the key - * @returns {Object|Array|null} Group info object, array of groups, or null if not found - * @example - * // Get all groups for a coalescing key - * const groups = queue.getCoalescingGroup('ui.update'); - * - * // Get specific group by ID - * const group = queue.getCoalescingGroup('ui.update', '1'); - * console.log(group.tasks.size); // Number of tasks in group - * - * // Access individual task metadata - * for (const [taskId, task] of group.tasks) { - * console.log(`Task ${taskId}:`, task.metadata); - * } - */ - getCoalescingGroup(coalescingKey: string, groupId?: string): Object | any[] | null; - /** - * Gets metadata for all tasks in a coalescing group. - * @param {string} coalescingKey - The coalescing key - * @param {string} [groupId] - Optional group ID. If omitted, returns metadata from all groups for the key - * @returns {Array} Array of metadata objects with task IDs - * @example - * // Get metadata from all groups for a key - * const allMetadata = queue.getCoalescingGroupMetadata('ui.update'); - * - * // Get metadata from specific group - * const groupMetadata = queue.getCoalescingGroupMetadata('ui.update', '1'); - * - * // Example output: - * // [ - * // { taskId: '123', metadata: { userId: 100, action: 'save' } }, - * // { taskId: '124', metadata: { userId: 200, action: 'delete' } } - * // ] - */ - getCoalescingGroupMetadata(coalescingKey: string, groupId?: string): any[]; - /** - * Gets a summary of all active coalescing groups. - * @returns {Object} Summary object with coalescing key stats - * @example - * const summary = queue.getCoalescingGroupsSummary(); - * console.log(summary); - * // { - * // 'ui.update': { groupCount: 2, totalTasks: 5 }, - * // 'api.batch': { groupCount: 1, totalTasks: 3 } - * // } - */ - getCoalescingGroupsSummary(): Object; - /** - * Finds the coalescing group that contains a specific task ID. - * @param {string|number} taskId - The task ID to search for - * @returns {Object|null} Group information including the task's metadata, or null if not found - * @example - * const groupInfo = queue.findCoalescingGroupByTaskId('123'); - * if (groupInfo) { - * console.log('Task is in group:', groupInfo.groupId); - * console.log('Task metadata:', groupInfo.task.metadata); - * console.log('Other tasks in group:', groupInfo.groupTasks.length); - * } - */ - findCoalescingGroupByTaskId(taskId: string | number): Object | null; - /** - * Destroys the queue, canceling all tasks and stopping the scheduler. - * Once destroyed, the queue cannot be reused. - * @returns {void} - * @example - * queue.destroy(); - * // Queue is permanently shut down - */ - destroy(): void; - /** - * Returns the current timestamp in milliseconds. - * @returns {number} Current timestamp - * @example - * const timestamp = queue.now(); // 1699564800000 - */ - now(): number; - /** - * Main scheduler tick that moves ready tasks and starts execution. - * @returns {void} - * @private - */ - private schedulerTick; - /** - * Checks if a task can start based on both global and per-priority concurrency limits. - * @param {Object} task - The task to check - * @returns {boolean} True if the task can start, false if concurrency limits prevent it - * @private - */ - private _canStartTask; - /** - * Clears all active timers (intervals and timeouts). - * @returns {void} - * @private - */ - private clearTimers; - /** - * Calculates when the next scheduler run should happen and sets appropriate timeout. - * @private - * @returns {void} - * - * @description - * Smart scheduling that calculates the optimal time for the next scheduler run based on: - * - When the next pending task becomes ready - * - When delay periods end - * - Whether there are tasks that can run immediately - * - * Uses setTimeout for precise timing instead of constant polling intervals. - */ - private scheduleSmartTimeout; - /** - * Runs the main scheduler logic and reschedules if needed. - * @private - * @returns {void} - * - * @description - * Executes the scheduler tick logic and then determines if more scheduling is needed. - * Tracks when scheduler last ran for healing mechanism. - */ - private runScheduler; - /** - * Starts the self-healing interval that ensures scheduler continues working. - * @private - * @returns {void} - * - * @description - * Healing mechanism that periodically checks if the scheduler should be running - * but isn't due to timeout failures or other issues. Runs every healingInterval milliseconds. - */ - private startHealingInterval; - /** - * Clears all scheduler-related timers. - * @private - * @returns {void} - * - * @description - * Cleans up both the main scheduler timeout and the healing interval timer. - */ - private clearSchedulerTimers; - /** - * Configure coalescing settings for specific keys dynamically. - * @param {string} coalescingKey - The coalescing key to configure - * @param {Object} config - Configuration for this key - * @param {number} [config.windowDuration] - Window duration in milliseconds for this key - * @param {number} [config.maxDelay] - Maximum delay in milliseconds for this key - * @param {number} [config.postDelay] - Post-completion delay in milliseconds for this key - * @param {number} [config.startDelay] - Pre-execution delay in milliseconds for this key - * @param {number} [config.delay] - DEPRECATED: Use postDelay instead - * @param {number} [config.start] - DEPRECATED: Use startDelay instead - * @param {boolean} [config.multipleCallbacks] - Whether to call multiple callbacks for this key - * @param {boolean} [config.resolveAllPromises] - Whether to resolve all promises for this key - * @returns {void} - * - * @example - * // Configure specific keys after queue creation - * queue.configureCoalescingKey('ui.update', { - * windowDuration: 100, - * maxDelay: 500, - * postDelay: 25, - * startDelay: 0 - * }); - * - * queue.configureCoalescingKey('api.batch', { - * windowDuration: 1000, - * maxDelay: 5000, - * postDelay: 100, - * startDelay: 200, - * resolveAllPromises: false - * }); - */ - configureCoalescingKey( - coalescingKey: string, - config: { - windowDuration?: number; - maxDelay?: number; - postDelay?: number; - startDelay?: number; - delay?: number; - start?: number; - multipleCallbacks?: boolean; - resolveAllPromises?: boolean; - } - ): void; - /** - * Get the effective coalescing configuration for a specific key. - * @param {string} coalescingKey - The coalescing key to get configuration for - * @param {Object} [taskOptions={}] - Task-level options that may override key configuration - * @returns {Object} The effective configuration for this key - * - * @example - * // Get effective configuration for a key - * const config = queue.getCoalescingConfig('ui.update'); - * console.log(`UI updates coalesce within ${config.windowDuration}ms with ${config.postDelay}ms post-completion delay`); - * - * // Check with task-level overrides - * const effectiveConfig = queue.getCoalescingConfig('ui.update', { - * coalescingWindowDuration: 50, - * delay: 30 // Still accepts old property names for backwards compatibility - * }); - */ - getCoalescingConfig(coalescingKey: string, taskOptions?: Object): Object; - /** - * Get all configured coalescing keys and their configurations. - * @returns {Object} Map of coalescingKey to configuration - * - * @example - * // See all configured coalescing keys - * const allConfigs = queue.getCoalescingConfigurations(); - * Object.entries(allConfigs).forEach(([key, config]) => { - * console.log(`${key}: ${config.windowDuration}ms window, ${config.maxDelay}ms max delay, ${config.postDelay}ms post-completion delay, ${config.startDelay}ms pre-execution delay`); - * }); - */ - getCoalescingConfigurations(): Object; - /** - * Configure default settings for specific priorities dynamically. - * @param {number} priority - The priority level to configure - * @param {Object} config - Configuration for this priority - * @param {number} [config.postDelay] - Default post-completion delay in milliseconds for this priority - * @param {number} [config.startDelay] - Default pre-execution delay in milliseconds for this priority - * @param {number} [config.delay] - DEPRECATED: Use postDelay instead - * @param {number} [config.start] - DEPRECATED: Use startDelay instead - * @returns {void} - * - * @example - * // Configure priority defaults after queue creation - * queue.configurePriority(1, { - * postDelay: 100, // High priority tasks have 100ms delay after completion - * startDelay: 0 // High priority tasks start immediately - * }); - * - * queue.configurePriority(3, { - * postDelay: 0, // Low priority tasks have no delay after completion - * startDelay: 200 // Low priority tasks wait 200ms before starting - * }); - */ - configurePriority( - priority: number, - config: { - postDelay?: number; - startDelay?: number; - delay?: number; - start?: number; - } - ): void; - /** - * Get the effective configuration for a specific priority. - * @param {number} priority - The priority level to get configuration for - * @param {Object} [taskOptions={}] - Task-level options that may override priority configuration - * @returns {Object} The effective configuration for this priority - * - * @example - * // Get effective configuration for a priority - * const config = queue.getPriorityConfig(1); - * console.log(`Priority 1 tasks: ${config.delay}ms delay, ${config.start}ms start delay`); - * - * // Check with task-level overrides - * const effectiveConfig = queue.getPriorityConfig(1, { - * delay: 50, - * start: 10 - * }); - */ - getPriorityConfig(priority: number, taskOptions?: Object): Object; - /** - * Get all configured priorities and their configurations. - * @returns {Object} Map of priority to configuration - * - * @example - * // See all configured priorities - * const allConfigs = queue.getPriorityConfigurations(); - * Object.entries(allConfigs).forEach(([priority, config]) => { - * console.log(`Priority ${priority}: ${config.delay}ms delay, ${config.start}ms start delay`); - * }); - */ - getPriorityConfigurations(): Object; - /** - * Alias for destroy() method for common queue system naming. - * @returns {void} - */ - shutdown(): void; - /** - * Alias for enqueue() method for common queue system naming. - * @param {Function} task - The task function to execute - * @param {Function|Object} optionsOrCallback - Callback function or options object - * @param {Object} options - Task options (if callback provided as second parameter) - * @returns {Promise|TaskHandle} Promise if no callback provided, TaskHandle otherwise - */ - schedule(task: Function, optionsOrCallback: Function | Object, options?: Object): Promise | TaskHandle; - /** - * Alias for enqueue() method for common queue system naming. - * @param {Function} task - The task function to execute - * @param {Function|Object} optionsOrCallback - Callback function or options object - * @param {Object} options - Task options (if callback provided as second parameter) - * @returns {Promise|TaskHandle} Promise if no callback provided, TaskHandle otherwise - */ - add(task: Function, optionsOrCallback: Function | Object, options?: Object): Promise | TaskHandle; - /** - * Find a task by its ID. - * @param {string|number} id - The task ID to find - * @returns {Object|null} Task object if found, null otherwise - */ - get(id: string | number): Object | null; - /** - * Check if a task with the given ID exists. - * @param {string|number} id - The task ID to check - * @returns {boolean} True if task exists, false otherwise - */ - has(id: string | number): boolean; - /** - * Alias for get() method for backward compatibility. - * @param {string|number} id - The task ID to find - * @returns {Object|null} Task object if found, null otherwise - */ - getTask(id: string | number): Object | null; - /** - * Alias for has() method for backward compatibility. - * @param {string|number} id - The task ID to check - * @returns {boolean} True if task exists, false otherwise - */ - hasTask(id: string | number): boolean; - /** - * Get detailed information about the current queue state for debugging. - * @returns {Object} Comprehensive queue state information - */ - inspect(): Object; - /** - * Get information about active timers and scheduler state. - * @returns {Object} Timer and scheduler information - */ - inspectTimers(): Object; - /** - * Get a summary of all queued tasks by status. - * @returns {Object} Task summary by status - */ - inspectTasks(): Object; - /** - * Get detailed information about the scheduler state and timing. - * @returns {Object} Scheduler state information - */ - inspectScheduler(): Object; - /** - * Log comprehensive queue state to console for debugging. - * @param {boolean} [detailed=false] - Whether to include detailed task information - */ - debugLog(detailed?: boolean): void; + _syncMode: boolean | undefined; + options: { + constructor: Function; + toString(): string; + toLocaleString(): string; + valueOf(): Object; + hasOwnProperty(v: PropertyKey): boolean; + isPrototypeOf(v: Object): boolean; + propertyIsEnumerable(v: PropertyKey): boolean; + concurrency: number; + tick: number; + autoStart: boolean; + defaultPriority: number; + maxQueue: any; + priorities: {}; + smartScheduling: boolean; + healingInterval: number; + coalescing: { + defaults: Object; + keys: {}; + }; + coalescingWindowDuration: any; + coalescingMaxDelay: any; + coalescingMultipleCallbacks: any; + coalescingResolveAllPromises: any; + } | undefined; + pendingHeap: MinHeap | undefined; + readyHeap: MinHeap | undefined; + running: Set | undefined; + runningByPriority: Map | undefined; + tasks: Map | undefined; + nextId: number | undefined; + enqueueSeq: number | undefined; + isActive: boolean | undefined; + destroyed: boolean | undefined; + lastCompletedPriority: any; + nextAvailableTime: any; + schedulerTimeout: number | null | undefined; + healingInterval: number | null | undefined; + lastSchedulerRun: number | undefined; + intervalId: number | null | undefined; + coalescingGroups: Map | undefined; + coalescingRepresentatives: Map | undefined; + nextGroupId: number | undefined; + timeoutId: number | undefined; + constructor(options?: {}); + /** + * Synchronous initialization for backwards compatibility + * @private + * @param {Object} options - Configuration options + */ + private _initializeSync; + /** + * Asynchronous initialization for modern usage + * @private + * @param {Object} options - Configuration options + * @returns {Promise} Promise that resolves to this instance + */ + private _initializeAsync; + /** + * Common initialization logic used by both sync and async modes + * @private + * @param {Object} options - Configuration options + */ + private _initializeCommon; + /** + * Internal convenience method to create a new HoldMyTask instance with async initialization. + * This enables event listeners to be attached before validation errors can occur. + * @param {Object} [options={}] - Configuration options + * @returns {Promise} Promise that resolves to the initialized instance + * @private + * @example + * // Internal usage - prefer new HoldMyTask({ sync: false }) for public API + * const queue = await HoldMyTask._create({ maxQueue: 100 }); + */ + private static _create; + /** + * Adds a task to the queue for execution. Supports both callback and promise-based APIs. + * @param {Function} task - The task function to execute. Can be sync or async. + * @param {Function|Object} [optionsOrCallback] - Either a callback function or options object + * @param {Object} [options={}] - Additional options (if callback was provided as second parameter) + * @param {string|number} [options.id] - Custom task ID for identification and later reference (must be unique) + * @param {number} [options.priority] - Task priority (higher numbers run first) + * @param {number} [options.timestamp] - When the task should be ready to run (milliseconds since epoch) + * @param {number} [options.start] - Milliseconds from now when the task should be ready to run (convenience for timestamp calculation) + * @param {AbortSignal} [options.signal] - AbortSignal to cancel the task + * @param {number} [options.timeout] - Task timeout in milliseconds (for execution time limit) + * @param {number} [options.expire] - Task expiration timestamp or milliseconds from now (for queue waiting time limit) + * @param {number} [options.delay] - DEPRECATED: Use postDelay instead. Delay after task completion before next task of same priority + * @param {boolean} [options.bypassDelay] - If true, skip any active delay period and start immediately + * @param {string} [options.coalescingKey] - Key for task coalescing - tasks with same key will be coalesced within windows + * @param {number} [options.coalescingWindowDuration] - Override coalescing window duration (task-level override of key-level and defaults) + * @param {number} [options.coalescingMaxDelay] - Override coalescing max delay (task-level override of key-level and defaults) + * @param {boolean} [options.coalescingMultipleCallbacks] - Override callback behavior (task-level override of key-level and defaults) + * @param {boolean} [options.coalescingResolveAllPromises] - Override promise resolution behavior (task-level override of key-level and defaults) + * @param {*} [options.metadata] - Arbitrary metadata to attach to the task + * @returns {Promise|Object} Promise (if no callback) or task control object with id, cancel, status methods + * @throws {Error} If queue is destroyed or full + * @example + * // Promise API + * const result = await queue.enqueue(async () => fetchData()); + * + * // Callback API + * queue.enqueue(() => processData(), (err, result) => { + * if (err) console.error(err); + * else console.log(result); + * }); + * + * // With options + * const task = queue.enqueue(myTask, { priority: 5, timeout: 30000, expire: 10000 }); + * + * // Bypass current delay for urgent task + * const urgent = queue.enqueue(urgentTask, { priority: 10, bypassDelay: true }); + * + * // Alternative: use delay: -1 to bypass + * const urgent2 = queue.enqueue(urgentTask, { priority: 10, delay: -1 }); + * + * // Coalescing tasks - multiple device status checks become one + * queue.enqueue(checkDeviceStatus, callback1, { coalescingKey: "device-123", coalescingWindowDuration: 1000 }); + * queue.enqueue(checkDeviceStatus, callback2, { coalescingKey: "device-123" }); // Gets coalesced with first + */ + enqueue(task: Function, optionsOrCallback?: Function | Object, options?: { + id?: string | number; + priority?: number; + timestamp?: number; + start?: number; + signal?: AbortSignal; + timeout?: number; + expire?: number; + delay?: number; + bypassDelay?: boolean; + coalescingKey?: string; + coalescingWindowDuration?: number; + coalescingMaxDelay?: number; + coalescingMultipleCallbacks?: boolean; + coalescingResolveAllPromises?: boolean; + metadata?: any; + }): Promise | Object; + /** + * Cancels a pending task by ID. + * @param {string} id - The task ID to cancel + * @param {string} [reason="Task canceled"] - Reason for cancellation + * @returns {boolean} True if task was found and cancelled, false otherwise + * @example + * const task = queue.enqueue(() => longRunningTask()); + * const cancelled = queue.cancel(task.id, "User requested cancellation"); + */ + cancel(id: string, reason?: string): boolean; + /** + * Alias for cancel() method for backward compatibility. + * @param {string|number} id - The task ID to cancel + * @param {string} [reason="Task canceled"] - Reason for cancellation + * @returns {boolean} True if task was found and cancelled, false otherwise + */ + cancelTask(id: string | number, reason?: string): boolean; + /** + * Pauses the task queue, stopping execution of new tasks. + * Currently running tasks will continue to completion. + * @returns {void} + * @example + * queue.pause(); + * // Queue stops processing new tasks + */ + pause(): void; + /** + * Resumes the task queue after being paused. + * @returns {void} + * @example + * queue.resume(); + * // Queue resumes processing tasks + */ + resume(): void; + /** + * Clears all pending and ready tasks from the queue. + * Currently running tasks will continue to completion. + * @returns {void} + * @example + * queue.clear(); + * // All queued tasks are removed + */ + clear(): void; + /** + * Returns the number of tasks in the queue. + * @returns {number} Number of tasks in the queue + * @example + * const totalTasks = queue.size(); // 5 + */ + size(): number; + /** + * Returns the number of tasks in the queue (alias for size()). + * @returns {number} Number of tasks in the queue + * @example + * const totalTasks = queue.length(); // 5 + */ + length(): number; + /** + * Returns the number of currently running tasks. + * @returns {number} Number of running tasks + * @example + * const runningTasks = queue.inflight(); // 2 + */ + inflight(): number; + /** + * Gets information about a coalescing group by key and group ID. + * @param {string} coalescingKey - The coalescing key + * @param {string} [groupId] - Optional group ID. If omitted, returns all groups for the key + * @returns {Object|Array|null} Group info object, array of groups, or null if not found + * @example + * // Get all groups for a coalescing key + * const groups = queue.getCoalescingGroup('ui.update'); + * + * // Get specific group by ID + * const group = queue.getCoalescingGroup('ui.update', '1'); + * console.log(group.tasks.size); // Number of tasks in group + * + * // Access individual task metadata + * for (const [taskId, task] of group.tasks) { + * console.log(`Task ${taskId}:`, task.metadata); + * } + */ + getCoalescingGroup(coalescingKey: string, groupId?: string): Object | any[] | null; + /** + * Gets metadata for all tasks in a coalescing group. + * @param {string} coalescingKey - The coalescing key + * @param {string} [groupId] - Optional group ID. If omitted, returns metadata from all groups for the key + * @returns {Array} Array of metadata objects with task IDs + * @example + * // Get metadata from all groups for a key + * const allMetadata = queue.getCoalescingGroupMetadata('ui.update'); + * + * // Get metadata from specific group + * const groupMetadata = queue.getCoalescingGroupMetadata('ui.update', '1'); + * + * // Example output: + * // [ + * // { taskId: '123', metadata: { userId: 100, action: 'save' } }, + * // { taskId: '124', metadata: { userId: 200, action: 'delete' } } + * // ] + */ + getCoalescingGroupMetadata(coalescingKey: string, groupId?: string): any[]; + /** + * Gets a summary of all active coalescing groups. + * @returns {Object} Summary object with coalescing key stats + * @example + * const summary = queue.getCoalescingGroupsSummary(); + * console.log(summary); + * // { + * // 'ui.update': { groupCount: 2, totalTasks: 5 }, + * // 'api.batch': { groupCount: 1, totalTasks: 3 } + * // } + */ + getCoalescingGroupsSummary(): Object; + /** + * Finds the coalescing group that contains a specific task ID. + * @param {string|number} taskId - The task ID to search for + * @returns {Object|null} Group information including the task's metadata, or null if not found + * @example + * const groupInfo = queue.findCoalescingGroupByTaskId('123'); + * if (groupInfo) { + * console.log('Task is in group:', groupInfo.groupId); + * console.log('Task metadata:', groupInfo.task.metadata); + * console.log('Other tasks in group:', groupInfo.groupTasks.length); + * } + */ + findCoalescingGroupByTaskId(taskId: string | number): Object | null; + /** + * Destroys the queue, canceling all tasks and stopping the scheduler. + * Once destroyed, the queue cannot be reused. + * @returns {void} + * @example + * queue.destroy(); + * // Queue is permanently shut down + */ + destroy(): void; + /** + * Returns the current timestamp in milliseconds. + * @returns {number} Current timestamp + * @example + * const timestamp = queue.now(); // 1699564800000 + */ + now(): number; + /** + * Main scheduler tick that moves ready tasks and starts execution. + * @returns {void} + * @private + */ + private schedulerTick; + /** + * Checks if a task can start based on both global and per-priority concurrency limits. + * @param {Object} task - The task to check + * @returns {boolean} True if the task can start, false if concurrency limits prevent it + * @private + */ + private _canStartTask; + /** + * Clears all active timers (intervals and timeouts). + * @returns {void} + * @private + */ + private clearTimers; + /** + * Calculates when the next scheduler run should happen and sets appropriate timeout. + * @private + * @returns {void} + * + * @description + * Smart scheduling that calculates the optimal time for the next scheduler run based on: + * - When the next pending task becomes ready + * - When delay periods end + * - Whether there are tasks that can run immediately + * + * Uses setTimeout for precise timing instead of constant polling intervals. + */ + private scheduleSmartTimeout; + /** + * Runs the main scheduler logic and reschedules if needed. + * @private + * @returns {void} + * + * @description + * Executes the scheduler tick logic and then determines if more scheduling is needed. + * Tracks when scheduler last ran for healing mechanism. + */ + private runScheduler; + /** + * Starts the self-healing interval that ensures scheduler continues working. + * @private + * @returns {void} + * + * @description + * Healing mechanism that periodically checks if the scheduler should be running + * but isn't due to timeout failures or other issues. Runs every healingInterval milliseconds. + */ + private startHealingInterval; + /** + * Clears all scheduler-related timers. + * @private + * @returns {void} + * + * @description + * Cleans up both the main scheduler timeout and the healing interval timer. + */ + private clearSchedulerTimers; + /** + * Configure coalescing settings for specific keys dynamically. + * @param {string} coalescingKey - The coalescing key to configure + * @param {Object} config - Configuration for this key + * @param {number} [config.windowDuration] - Window duration in milliseconds for this key + * @param {number} [config.maxDelay] - Maximum delay in milliseconds for this key + * @param {number} [config.postDelay] - Post-completion delay in milliseconds for this key + * @param {number} [config.startDelay] - Pre-execution delay in milliseconds for this key + * @param {number} [config.delay] - DEPRECATED: Use postDelay instead + * @param {number} [config.start] - DEPRECATED: Use startDelay instead + * @param {boolean} [config.multipleCallbacks] - Whether to call multiple callbacks for this key + * @param {boolean} [config.resolveAllPromises] - Whether to resolve all promises for this key + * @returns {void} + * + * @example + * // Configure specific keys after queue creation + * queue.configureCoalescingKey('ui.update', { + * windowDuration: 100, + * maxDelay: 500, + * postDelay: 25, + * startDelay: 0 + * }); + * + * queue.configureCoalescingKey('api.batch', { + * windowDuration: 1000, + * maxDelay: 5000, + * postDelay: 100, + * startDelay: 200, + * resolveAllPromises: false + * }); + */ + configureCoalescingKey(coalescingKey: string, config: { + windowDuration?: number; + maxDelay?: number; + postDelay?: number; + startDelay?: number; + delay?: number; + start?: number; + multipleCallbacks?: boolean; + resolveAllPromises?: boolean; + }): void; + /** + * Get the effective coalescing configuration for a specific key. + * @param {string} coalescingKey - The coalescing key to get configuration for + * @param {Object} [taskOptions={}] - Task-level options that may override key configuration + * @returns {Object} The effective configuration for this key + * + * @example + * // Get effective configuration for a key + * const config = queue.getCoalescingConfig('ui.update'); + * console.log(`UI updates coalesce within ${config.windowDuration}ms with ${config.postDelay}ms post-completion delay`); + * + * // Check with task-level overrides + * const effectiveConfig = queue.getCoalescingConfig('ui.update', { + * coalescingWindowDuration: 50, + * delay: 30 // Still accepts old property names for backwards compatibility + * }); + */ + getCoalescingConfig(coalescingKey: string, taskOptions?: Object): Object; + /** + * Get all configured coalescing keys and their configurations. + * @returns {Object} Map of coalescingKey to configuration + * + * @example + * // See all configured coalescing keys + * const allConfigs = queue.getCoalescingConfigurations(); + * Object.entries(allConfigs).forEach(([key, config]) => { + * console.log(`${key}: ${config.windowDuration}ms window, ${config.maxDelay}ms max delay, ${config.postDelay}ms post-completion delay, ${config.startDelay}ms pre-execution delay`); + * }); + */ + getCoalescingConfigurations(): Object; + /** + * Configure default settings for specific priorities dynamically. + * @param {number} priority - The priority level to configure + * @param {Object} config - Configuration for this priority + * @param {number} [config.postDelay] - Default post-completion delay in milliseconds for this priority + * @param {number} [config.startDelay] - Default pre-execution delay in milliseconds for this priority + * @param {number} [config.delay] - DEPRECATED: Use postDelay instead + * @param {number} [config.start] - DEPRECATED: Use startDelay instead + * @returns {void} + * + * @example + * // Configure priority defaults after queue creation + * queue.configurePriority(1, { + * postDelay: 100, // High priority tasks have 100ms delay after completion + * startDelay: 0 // High priority tasks start immediately + * }); + * + * queue.configurePriority(3, { + * postDelay: 0, // Low priority tasks have no delay after completion + * startDelay: 200 // Low priority tasks wait 200ms before starting + * }); + */ + configurePriority(priority: number, config: { + postDelay?: number; + startDelay?: number; + delay?: number; + start?: number; + }): void; + /** + * Get the effective configuration for a specific priority. + * @param {number} priority - The priority level to get configuration for + * @param {Object} [taskOptions={}] - Task-level options that may override priority configuration + * @returns {Object} The effective configuration for this priority + * + * @example + * // Get effective configuration for a priority + * const config = queue.getPriorityConfig(1); + * console.log(`Priority 1 tasks: ${config.delay}ms delay, ${config.start}ms start delay`); + * + * // Check with task-level overrides + * const effectiveConfig = queue.getPriorityConfig(1, { + * delay: 50, + * start: 10 + * }); + */ + getPriorityConfig(priority: number, taskOptions?: Object): Object; + /** + * Get all configured priorities and their configurations. + * @returns {Object} Map of priority to configuration + * + * @example + * // See all configured priorities + * const allConfigs = queue.getPriorityConfigurations(); + * Object.entries(allConfigs).forEach(([priority, config]) => { + * console.log(`Priority ${priority}: ${config.delay}ms delay, ${config.start}ms start delay`); + * }); + */ + getPriorityConfigurations(): Object; + /** + * Alias for destroy() method for common queue system naming. + * @returns {void} + */ + shutdown(): void; + /** + * Alias for enqueue() method for common queue system naming. + * @param {Function} task - The task function to execute + * @param {Function|Object} optionsOrCallback - Callback function or options object + * @param {Object} options - Task options (if callback provided as second parameter) + * @returns {Promise|TaskHandle} Promise if no callback provided, TaskHandle otherwise + */ + schedule(task: Function, optionsOrCallback: Function | Object, options?: Object): Promise | TaskHandle; + /** + * Alias for enqueue() method for common queue system naming. + * @param {Function} task - The task function to execute + * @param {Function|Object} optionsOrCallback - Callback function or options object + * @param {Object} options - Task options (if callback provided as second parameter) + * @returns {Promise|TaskHandle} Promise if no callback provided, TaskHandle otherwise + */ + add(task: Function, optionsOrCallback: Function | Object, options?: Object): Promise | TaskHandle; + /** + * Find a task by its ID. + * @param {string|number} id - The task ID to find + * @returns {Object|null} Task object if found, null otherwise + */ + get(id: string | number): Object | null; + /** + * Check if a task with the given ID exists. + * @param {string|number} id - The task ID to check + * @returns {boolean} True if task exists, false otherwise + */ + has(id: string | number): boolean; + /** + * Alias for get() method for backward compatibility. + * @param {string|number} id - The task ID to find + * @returns {Object|null} Task object if found, null otherwise + */ + getTask(id: string | number): Object | null; + /** + * Alias for has() method for backward compatibility. + * @param {string|number} id - The task ID to check + * @returns {boolean} True if task exists, false otherwise + */ + hasTask(id: string | number): boolean; + /** + * Get detailed information about the current queue state for debugging. + * @returns {Object} Comprehensive queue state information + */ + inspect(): Object; + /** + * Get information about active timers and scheduler state. + * @returns {Object} Timer and scheduler information + */ + inspectTimers(): Object; + /** + * Get a summary of all queued tasks by status. + * @returns {Object} Task summary by status + */ + inspectTasks(): Object; + /** + * Get detailed information about the scheduler state and timing. + * @returns {Object} Scheduler state information + */ + inspectScheduler(): Object; + /** + * Log comprehensive queue state to console for debugging. + * @param {boolean} [detailed=false] - Whether to include detailed task information + */ + debugLog(detailed?: boolean): void; } -//# sourceMappingURL=hold-my-task.d.mts.map +//# sourceMappingURL=hold-my-task.d.mts.map \ No newline at end of file diff --git a/types/src/hold-my-task.d.mts.map b/types/src/hold-my-task.d.mts.map index a5f0b71..731ac8c 100644 --- a/types/src/hold-my-task.d.mts.map +++ b/types/src/hold-my-task.d.mts.map @@ -1 +1 @@ -{"version":3,"file":"hold-my-task.d.mts","sourceRoot":"","sources":["../../src/hold-my-task.mjs"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"hold-my-task.d.mts","sourceRoot":"","sources":["../../src/hold-my-task.mjs"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/types/src/utils.d.mts b/types/src/utils.d.mts index 8954dd0..67ee867 100644 --- a/types/src/utils.d.mts +++ b/types/src/utils.d.mts @@ -15,58 +15,58 @@ * Maintains the heap property where parent nodes are smaller than their children. */ export declare class MinHeap { - heap: any[]; - compare: Function; - /** - * Creates a new MinHeap with a custom comparison function. - * @param {Function} compare - Comparison function that returns negative if a < b, positive if a > b, 0 if equal - * @example - * // Priority queue (higher priority = smaller value) - * const heap = new MinHeap((a, b) => a.priority - b.priority); - */ - constructor(compare: Function); - /** - * Adds an item to the heap, maintaining heap property. - * @param {*} item - The item to add to the heap - * @returns {void} - * @example - * heap.push({ value: 5, priority: 1 }); - */ - push(item: any): void; - /** - * Removes and returns the minimum item from the heap. - * @returns {*|undefined} The minimum item, or undefined if heap is empty - * @example - * const min = heap.pop(); // Returns item with smallest comparison value - */ - pop(): any | undefined; - /** - * Returns the minimum item without removing it from the heap. - * @returns {*|undefined} The minimum item, or undefined if heap is empty - * @example - * const min = heap.peek(); // Look at minimum without removing - */ - peek(): any | undefined; - /** - * Returns the number of items in the heap. - * @returns {number} The size of the heap - * @example - * const count = heap.size(); // 5 - */ - size(): number; - /** - * Moves an item up the heap to maintain heap property after insertion. - * @param {number} index - Index of the item to bubble up - * @returns {void} - * @private - */ - private bubbleUp; - /** - * Moves an item down the heap to maintain heap property after removal. - * @param {number} index - Index of the item to sink down - * @returns {void} - * @private - */ - private sinkDown; + heap: any[]; + compare: Function; + /** + * Creates a new MinHeap with a custom comparison function. + * @param {Function} compare - Comparison function that returns negative if a < b, positive if a > b, 0 if equal + * @example + * // Priority queue (higher priority = smaller value) + * const heap = new MinHeap((a, b) => a.priority - b.priority); + */ + constructor(compare: Function); + /** + * Adds an item to the heap, maintaining heap property. + * @param {*} item - The item to add to the heap + * @returns {void} + * @example + * heap.push({ value: 5, priority: 1 }); + */ + push(item: any): void; + /** + * Removes and returns the minimum item from the heap. + * @returns {*|undefined} The minimum item, or undefined if heap is empty + * @example + * const min = heap.pop(); // Returns item with smallest comparison value + */ + pop(): any | undefined; + /** + * Returns the minimum item without removing it from the heap. + * @returns {*|undefined} The minimum item, or undefined if heap is empty + * @example + * const min = heap.peek(); // Look at minimum without removing + */ + peek(): any | undefined; + /** + * Returns the number of items in the heap. + * @returns {number} The size of the heap + * @example + * const count = heap.size(); // 5 + */ + size(): number; + /** + * Moves an item up the heap to maintain heap property after insertion. + * @param {number} index - Index of the item to bubble up + * @returns {void} + * @private + */ + private bubbleUp; + /** + * Moves an item down the heap to maintain heap property after removal. + * @param {number} index - Index of the item to sink down + * @returns {void} + * @private + */ + private sinkDown; } -//# sourceMappingURL=utils.d.mts.map +//# sourceMappingURL=utils.d.mts.map \ No newline at end of file