Compare commits
41 Commits
Author | SHA1 | Date | |
---|---|---|---|
21827f06e9 | |||
b5133c2a9c | |||
294420e0b2 | |||
d7a05abfa2 | |||
3444b7c74d | |||
bf76b225c6 | |||
3bad722c25 | |||
28ba176b62 | |||
da500d7fd4 | |||
6aaf66ac5c | |||
34ba87a1fb | |||
8cd846e8bf | |||
d98c54fba9 | |||
50b0fd357a | |||
42976a32d7 | |||
b214de9370 | |||
3d98c2ba6f | |||
e4a349c85e | |||
2abfa7c47a | |||
50aa0a136a | |||
b98a9be2b7 | |||
3314928c5f | |||
0b7c29eae7 | |||
779e495941 | |||
8402deeccb | |||
7c4324b3ad | |||
268201727c | |||
12ae27b2ff | |||
3bb9b2229d | |||
e17e4c376e | |||
d5f2427aad | |||
5715c6fe67 | |||
9628e914b5 | |||
55746f5d92 | |||
90ae869686 | |||
771c454411 | |||
99395794d8 | |||
1763ede6df | |||
102b6ac9ae | |||
cd9ca458f6 | |||
2c4fc8b212 |
66
.gitea/workflows/default_nottags.yaml
Normal file
66
.gitea/workflows/default_nottags.yaml
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
name: Default (not tags)
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags-ignore:
|
||||||
|
- '**'
|
||||||
|
|
||||||
|
env:
|
||||||
|
IMAGE: registry.gitlab.com/hosttoday/ht-docker-node:npmci
|
||||||
|
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@gitea.lossless.digital/${{gitea.repository}}.git
|
||||||
|
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
|
||||||
|
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
|
||||||
|
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
|
||||||
|
NPMCI_URL_CLOUDLY: ${{secrets.NPMCI_URL_CLOUDLY}}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
security:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
continue-on-error: true
|
||||||
|
container:
|
||||||
|
image: ${{ env.IMAGE }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install pnpm and npmci
|
||||||
|
run: |
|
||||||
|
pnpm install -g pnpm
|
||||||
|
pnpm install -g @shipzone/npmci
|
||||||
|
|
||||||
|
- name: Run npm prepare
|
||||||
|
run: npmci npm prepare
|
||||||
|
|
||||||
|
- name: Audit production dependencies
|
||||||
|
run: |
|
||||||
|
npmci command npm config set registry https://registry.npmjs.org
|
||||||
|
npmci command pnpm audit --audit-level=high --prod
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
- name: Audit development dependencies
|
||||||
|
run: |
|
||||||
|
npmci command npm config set registry https://registry.npmjs.org
|
||||||
|
npmci command pnpm audit --audit-level=high --dev
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
test:
|
||||||
|
if: ${{ always() }}
|
||||||
|
needs: security
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: ${{ env.IMAGE }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Test stable
|
||||||
|
run: |
|
||||||
|
npmci node install stable
|
||||||
|
npmci npm install
|
||||||
|
npmci npm test
|
||||||
|
|
||||||
|
- name: Test build
|
||||||
|
run: |
|
||||||
|
npmci node install stable
|
||||||
|
npmci npm install
|
||||||
|
npmci npm build
|
124
.gitea/workflows/default_tags.yaml
Normal file
124
.gitea/workflows/default_tags.yaml
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
name: Default (tags)
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
|
||||||
|
env:
|
||||||
|
IMAGE: registry.gitlab.com/hosttoday/ht-docker-node:npmci
|
||||||
|
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@gitea.lossless.digital/${{gitea.repository}}.git
|
||||||
|
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
|
||||||
|
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
|
||||||
|
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
|
||||||
|
NPMCI_URL_CLOUDLY: ${{secrets.NPMCI_URL_CLOUDLY}}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
security:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
continue-on-error: true
|
||||||
|
container:
|
||||||
|
image: ${{ env.IMAGE }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Prepare
|
||||||
|
run: |
|
||||||
|
pnpm install -g pnpm
|
||||||
|
pnpm install -g @shipzone/npmci
|
||||||
|
npmci npm prepare
|
||||||
|
|
||||||
|
- name: Audit production dependencies
|
||||||
|
run: |
|
||||||
|
npmci command npm config set registry https://registry.npmjs.org
|
||||||
|
npmci command pnpm audit --audit-level=high --prod
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
- name: Audit development dependencies
|
||||||
|
run: |
|
||||||
|
npmci command npm config set registry https://registry.npmjs.org
|
||||||
|
npmci command pnpm audit --audit-level=high --dev
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
test:
|
||||||
|
if: ${{ always() }}
|
||||||
|
needs: security
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: ${{ env.IMAGE }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Prepare
|
||||||
|
run: |
|
||||||
|
pnpm install -g pnpm
|
||||||
|
pnpm install -g @shipzone/npmci
|
||||||
|
npmci npm prepare
|
||||||
|
|
||||||
|
- name: Test stable
|
||||||
|
run: |
|
||||||
|
npmci node install stable
|
||||||
|
npmci npm install
|
||||||
|
npmci npm test
|
||||||
|
|
||||||
|
- name: Test build
|
||||||
|
run: |
|
||||||
|
npmci node install stable
|
||||||
|
npmci npm install
|
||||||
|
npmci npm build
|
||||||
|
|
||||||
|
release:
|
||||||
|
needs: test
|
||||||
|
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: ${{ env.IMAGE }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Prepare
|
||||||
|
run: |
|
||||||
|
pnpm install -g pnpm
|
||||||
|
pnpm install -g @shipzone/npmci
|
||||||
|
npmci npm prepare
|
||||||
|
|
||||||
|
- name: Release
|
||||||
|
run: |
|
||||||
|
npmci node install stable
|
||||||
|
npmci npm publish
|
||||||
|
|
||||||
|
metadata:
|
||||||
|
needs: test
|
||||||
|
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: ${{ env.IMAGE }}
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Prepare
|
||||||
|
run: |
|
||||||
|
pnpm install -g pnpm
|
||||||
|
pnpm install -g @shipzone/npmci
|
||||||
|
npmci npm prepare
|
||||||
|
|
||||||
|
- name: Code quality
|
||||||
|
run: |
|
||||||
|
npmci command npm install -g typescript
|
||||||
|
npmci npm install
|
||||||
|
|
||||||
|
- name: Trigger
|
||||||
|
run: npmci trigger
|
||||||
|
|
||||||
|
- name: Build docs and upload artifacts
|
||||||
|
run: |
|
||||||
|
npmci node install stable
|
||||||
|
npmci npm install
|
||||||
|
pnpm install -g @git.zone/tsdoc
|
||||||
|
npmci command tsdoc
|
||||||
|
continue-on-error: true
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -15,8 +15,6 @@ node_modules/
|
|||||||
|
|
||||||
# builds
|
# builds
|
||||||
dist/
|
dist/
|
||||||
dist_web/
|
dist_*/
|
||||||
dist_serve/
|
|
||||||
dist_ts_web/
|
|
||||||
|
|
||||||
# custom
|
# custom
|
117
.gitlab-ci.yml
117
.gitlab-ci.yml
@ -1,117 +0,0 @@
|
|||||||
# gitzone ci_default
|
|
||||||
image: hosttoday/ht-docker-node:npmci
|
|
||||||
|
|
||||||
cache:
|
|
||||||
paths:
|
|
||||||
- .npmci_cache/
|
|
||||||
key: "$CI_BUILD_STAGE"
|
|
||||||
|
|
||||||
stages:
|
|
||||||
- security
|
|
||||||
- test
|
|
||||||
- release
|
|
||||||
- metadata
|
|
||||||
|
|
||||||
# ====================
|
|
||||||
# security stage
|
|
||||||
# ====================
|
|
||||||
mirror:
|
|
||||||
stage: security
|
|
||||||
script:
|
|
||||||
- npmci git mirror
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
|
|
||||||
snyk:
|
|
||||||
stage: security
|
|
||||||
script:
|
|
||||||
- npmci npm prepare
|
|
||||||
- npmci command npm install -g snyk
|
|
||||||
- npmci command npm install --ignore-scripts
|
|
||||||
- npmci command snyk test
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
|
|
||||||
# ====================
|
|
||||||
# test stage
|
|
||||||
# ====================
|
|
||||||
|
|
||||||
testLTS:
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
- npmci npm prepare
|
|
||||||
- npmci node install lts
|
|
||||||
- npmci npm install
|
|
||||||
- npmci npm test
|
|
||||||
coverage: /\d+.?\d+?\%\s*coverage/
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
|
|
||||||
testSTABLE:
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
- npmci npm prepare
|
|
||||||
- npmci node install stable
|
|
||||||
- npmci npm install
|
|
||||||
- npmci npm test
|
|
||||||
coverage: /\d+.?\d+?\%\s*coverage/
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
|
|
||||||
release:
|
|
||||||
stage: release
|
|
||||||
script:
|
|
||||||
- npmci node install stable
|
|
||||||
- npmci npm publish
|
|
||||||
only:
|
|
||||||
- tags
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
|
|
||||||
# ====================
|
|
||||||
# metadata stage
|
|
||||||
# ====================
|
|
||||||
codequality:
|
|
||||||
stage: metadata
|
|
||||||
allow_failure: true
|
|
||||||
script:
|
|
||||||
- npmci command npm install -g tslint typescript
|
|
||||||
- npmci npm install
|
|
||||||
- npmci command tslint -c tslint.json ./ts/**/*.ts
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- priv
|
|
||||||
|
|
||||||
trigger:
|
|
||||||
stage: metadata
|
|
||||||
script:
|
|
||||||
- npmci trigger
|
|
||||||
only:
|
|
||||||
- tags
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
|
|
||||||
pages:
|
|
||||||
image: hosttoday/ht-docker-node:npmci
|
|
||||||
stage: metadata
|
|
||||||
script:
|
|
||||||
- npmci command npm install -g @gitzone/tsdoc
|
|
||||||
- npmci npm prepare
|
|
||||||
- npmci npm install
|
|
||||||
- npmci command tsdoc
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
only:
|
|
||||||
- tags
|
|
||||||
artifacts:
|
|
||||||
expire_in: 1 week
|
|
||||||
paths:
|
|
||||||
- public
|
|
||||||
allow_failure: true
|
|
9
.snyk
9
.snyk
@ -1,9 +0,0 @@
|
|||||||
# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
|
|
||||||
version: v1.12.0
|
|
||||||
# ignores vulnerabilities until expiry date; change duration by modifying expiry date
|
|
||||||
ignore:
|
|
||||||
'npm:chownr:20180731':
|
|
||||||
- chokidar > fsevents > node-pre-gyp > tar > chownr:
|
|
||||||
reason: None given
|
|
||||||
expires: '2018-11-09T15:06:03.003Z'
|
|
||||||
patch: {}
|
|
11
.vscode/launch.json
vendored
Normal file
11
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"command": "npm test",
|
||||||
|
"name": "Run npm test",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "node-terminal"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
26
.vscode/settings.json
vendored
Normal file
26
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"json.schemas": [
|
||||||
|
{
|
||||||
|
"fileMatch": ["/npmextra.json"],
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"npmci": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "settings for npmci"
|
||||||
|
},
|
||||||
|
"gitzone": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "settings for gitzone",
|
||||||
|
"properties": {
|
||||||
|
"projectType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["website", "element", "service", "npm", "wcc"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
51
README.md
51
README.md
@ -1,51 +0,0 @@
|
|||||||
# @pushrocks/smartchok
|
|
||||||
smart wrapper for chokidar
|
|
||||||
|
|
||||||
## Availabililty and Links
|
|
||||||
* [npmjs.org (npm package)](https://www.npmjs.com/package/@pushrocks/smartchokidar)
|
|
||||||
* [gitlab.com (source)](https://gitlab.com/pushrocks/smartchok)
|
|
||||||
* [github.com (source mirror)](https://github.com/pushrocks/smartchok)
|
|
||||||
* [docs (typedoc)](https://pushrocks.gitlab.io/smartchok/)
|
|
||||||
|
|
||||||
## Status for master
|
|
||||||
[](https://gitlab.com/pushrocks/smartchok/commits/master)
|
|
||||||
[](https://gitlab.com/pushrocks/smartchok/commits/master)
|
|
||||||
[](https://www.npmjs.com/package/@pushrocks/smartchokidar)
|
|
||||||
[](https://snyk.io/test/npm/@pushrocks/smartchokidar)
|
|
||||||
[](https://nodejs.org/dist/latest-v10.x/docs/api/)
|
|
||||||
[](https://nodejs.org/dist/latest-v10.x/docs/api/)
|
|
||||||
[](https://prettier.io/)
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Use TypeScript for best in class instellisense.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
import { Smartchok } from 'smartchok';
|
|
||||||
|
|
||||||
let mySmartChok = new Smartchok(['some/path/**/*.any', '/absolute/*.js'], chokidarOptions);
|
|
||||||
|
|
||||||
mySmartChok.add(['/some/**/*.any']); // add files
|
|
||||||
|
|
||||||
mySmartChok.remove('some/**/*.js');
|
|
||||||
|
|
||||||
mySmartChok.start(); // starts the watch process
|
|
||||||
|
|
||||||
mySmartChok.getObservableFor('change').then(observableArg => {
|
|
||||||
observableArg.subscribe(x => {
|
|
||||||
// do something here when a change is detected
|
|
||||||
// possible events are 'add' | 'addDir' | 'change' | 'error' | 'unlink' | 'unlinkDir' | 'ready' | 'raw'
|
|
||||||
// note that the observable is only created once you call .start() on the Smartchok instance
|
|
||||||
// hence the promise construction
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
mySmartChok.stop();
|
|
||||||
```
|
|
||||||
|
|
||||||
For further information read the linked docs at the top of this readme.
|
|
||||||
|
|
||||||
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
|
|
||||||
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy.html)
|
|
||||||
|
|
||||||
[](https://maintainedby.lossless.com)
|
|
90
changelog.md
Normal file
90
changelog.md
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
## 2025-06-26 - 1.1.1 - fix(package.json)
|
||||||
|
Add packageManager field to package.json for pnpm configuration
|
||||||
|
|
||||||
|
- Added "packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977" to package.json
|
||||||
|
|
||||||
|
## 2025-06-26 - 1.1.0 - feat(Smartchok)
|
||||||
|
Migrate to chokidar 4.x with picomatch glob support, update documentation and tests
|
||||||
|
|
||||||
|
- Removed deprecated @tempfix/watcher and added chokidar and picomatch as dependencies in package.json
|
||||||
|
- Updated Smartchok class to extract base paths and apply custom glob filtering using picomatch
|
||||||
|
- Revised readme and technical hints to reflect migration to chokidar 4.x and clarify glob pattern support
|
||||||
|
- Adjusted tests and commit info to align with the updated code structure
|
||||||
|
|
||||||
|
## 2024-05-29 – 1.0.34 – general
|
||||||
|
This release improves the project description.
|
||||||
|
- update description
|
||||||
|
|
||||||
|
## 2024-05-06 – 1.0.33 – core
|
||||||
|
This release includes a mix of bug fixes and configuration updates.
|
||||||
|
- fix(core): update
|
||||||
|
- update tsconfig
|
||||||
|
- update npmextra.json: githost (recorded multiple times)
|
||||||
|
|
||||||
|
## 2024-02-29 – 1.0.32 to 1.0.28 – core fixes
|
||||||
|
Releases 1.0.32 through 1.0.28 were dedicated to routine core fixes.
|
||||||
|
(This range covers versions that only included “fix(core): update” changes.)
|
||||||
|
|
||||||
|
## 2024-01-28 – 1.0.27 – core
|
||||||
|
This release not only fixed core issues but also adjusted the organization scheme.
|
||||||
|
- fix(core): update
|
||||||
|
- switch to new org scheme (recorded twice)
|
||||||
|
|
||||||
|
## 2021-12-01 – 1.0.26 to 1.0.14 – core fixes
|
||||||
|
Releases 1.0.26 through 1.0.14 were devoted to routine core fixes.
|
||||||
|
(No additional details beyond the core update were recorded.)
|
||||||
|
|
||||||
|
## 2018-02-28 – 1.0.13 to 1.0.11 – ci updates
|
||||||
|
Releases 1.0.13 through 1.0.11 focused on updating the continuous integration configuration.
|
||||||
|
- update ci
|
||||||
|
|
||||||
|
## 2017-06-30 – 1.0.10 – general
|
||||||
|
This release delivered several improvements beyond a simple version bump.
|
||||||
|
- fix Promise issues
|
||||||
|
- update test
|
||||||
|
- update
|
||||||
|
|
||||||
|
## 2017-06-30 – 1.0.9 – general
|
||||||
|
This release addressed module loading and code hygiene.
|
||||||
|
- fix loading of rxjs
|
||||||
|
- clean up code
|
||||||
|
|
||||||
|
## 2017-06-30 – 1.0.8 – general
|
||||||
|
A targeted update to align output with expectations.
|
||||||
|
- update to wirj like expected
|
||||||
|
|
||||||
|
## 2017-04-09 – 1.0.7 – ci
|
||||||
|
An update to the continuous integration configuration.
|
||||||
|
- update ci
|
||||||
|
|
||||||
|
## 2017-04-09 – 1.0.6 – npm
|
||||||
|
This release updated extra npm configuration.
|
||||||
|
- update npmextra.json
|
||||||
|
|
||||||
|
## 2017-02-15 – 1.0.5 – general
|
||||||
|
Standardization work was undertaken with new organizational practices.
|
||||||
|
- update to new gitzone standard
|
||||||
|
|
||||||
|
## 2016-11-18 – 1.0.4 – general
|
||||||
|
This release refreshed dependency settings.
|
||||||
|
- update dependencies
|
||||||
|
|
||||||
|
## 2016-11-18 – 1.0.3 – general
|
||||||
|
Readability and developer guidance were improved.
|
||||||
|
- improve README
|
||||||
|
|
||||||
|
## 2016-11-18 – 1.0.2 – general
|
||||||
|
Minor documentation and CI configuration enhancements were added.
|
||||||
|
- add README
|
||||||
|
- Update .gitlab-ci.yml
|
||||||
|
|
||||||
|
## 2016-09-22 – 1.0.1 – general
|
||||||
|
A fix was applied to ensure the process exits correctly.
|
||||||
|
- fix process not exiting problem
|
||||||
|
|
||||||
|
## 2016-09-22 – 1.0.0 – general
|
||||||
|
The project’s initial setup was established along with CI configuration.
|
||||||
|
- add gitlab-ci
|
||||||
|
- initial
|
@ -4,13 +4,29 @@
|
|||||||
"npmAccessLevel": "public"
|
"npmAccessLevel": "public"
|
||||||
},
|
},
|
||||||
"gitzone": {
|
"gitzone": {
|
||||||
|
"projectType": "npm",
|
||||||
"module": {
|
"module": {
|
||||||
"githost": "gitlab.com",
|
"githost": "code.foss.global",
|
||||||
"gitscope": "pushrocks",
|
"gitscope": "push.rocks",
|
||||||
"gitrepo": "smartchok",
|
"gitrepo": "smartchok",
|
||||||
"shortDescription": "smart wrapper for chokidar",
|
"description": "A smart wrapper for chokidar to facilitate file watching with enhanced features.",
|
||||||
"npmPackagename": "@pushrocks/smartchokidar",
|
"npmPackagename": "@push.rocks/smartchokidar",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"file watching",
|
||||||
|
"chokidar",
|
||||||
|
"filesystem",
|
||||||
|
"observable",
|
||||||
|
"typescript",
|
||||||
|
"node.js",
|
||||||
|
"development tool",
|
||||||
|
"file system events",
|
||||||
|
"real-time",
|
||||||
|
"watch files"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"tsdoc": {
|
||||||
|
"legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n"
|
||||||
}
|
}
|
||||||
}
|
}
|
1892
package-lock.json
generated
1892
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
73
package.json
73
package.json
@ -1,49 +1,68 @@
|
|||||||
{
|
{
|
||||||
"name": "@pushrocks/smartchok",
|
"name": "@push.rocks/smartchok",
|
||||||
"version": "1.0.19",
|
"version": "1.1.1",
|
||||||
"private": false,
|
"private": false,
|
||||||
"description": "smart wrapper for chokidar",
|
"description": "A smart wrapper for chokidar 4.x with glob pattern support and enhanced features.",
|
||||||
"main": "dist/index.js",
|
"main": "dist_ts/index.js",
|
||||||
"typings": "dist/index.d.ts",
|
"typings": "dist_ts/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "(npm run prepareTest && tstest test/)",
|
"test": "(npm run prepareTest && tstest test/)",
|
||||||
"prepareTest": "(rm -f ./test/assets/hi.txt)",
|
"prepareTest": "(rm -f ./test/assets/hi.txt)",
|
||||||
"build": "tsbuild"
|
"build": "tsbuild",
|
||||||
|
"buildDocs": "tsdoc"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+ssh://git@gitlab.com/pushrocks/smartchok.git"
|
"url": "https://code.foss.global/push.rocks/smartchok.git"
|
||||||
},
|
},
|
||||||
"author": "Lossless GmbH",
|
"author": "Lossless GmbH",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://gitlab.com/pushrocks/smartchok/issues"
|
"url": "https://gitlab.com/push.rocks/smartchok/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://gitlab.com/pushrocks/smartchok#README",
|
"homepage": "https://code.foss.global/push.rocks/smartchok",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@pushrocks/lik": "^3.0.5",
|
"@push.rocks/lik": "^6.0.2",
|
||||||
"@pushrocks/smartpromise": "^3.0.2",
|
"@push.rocks/smartpromise": "^4.0.2",
|
||||||
"@pushrocks/smartrx": "^2.0.3",
|
"@push.rocks/smartrx": "^3.0.2",
|
||||||
"@pushrocks/smartspawn": "^2.0.4",
|
"chokidar": "^4.0.3",
|
||||||
"@types/chokidar": "^2.1.3",
|
"picomatch": "^4.0.2"
|
||||||
"chokidar": "^3.0.1"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@gitzone/tsbuild": "^2.1.11",
|
"@git.zone/tsbuild": "^2.1.66",
|
||||||
"@gitzone/tsrun": "^1.2.6",
|
"@git.zone/tsrun": "^1.2.44",
|
||||||
"@gitzone/tstest": "^1.0.24",
|
"@git.zone/tstest": "^1.0.77",
|
||||||
"@pushrocks/smartfile": "^7.0.2",
|
"@push.rocks/smartfile": "^11.0.4",
|
||||||
"@pushrocks/tapbundle": "^3.0.9",
|
"@push.rocks/tapbundle": "^5.0.8",
|
||||||
"@types/node": "^12.0.4"
|
"@types/node": "^20.11.8"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"ts/*",
|
"ts/**/*",
|
||||||
"ts_web/*",
|
"ts_web/**/*",
|
||||||
"dist/*",
|
"dist/**/*",
|
||||||
"dist_web/*",
|
"dist_*/**/*",
|
||||||
"assets/*",
|
"dist_ts/**/*",
|
||||||
|
"dist_ts_web/**/*",
|
||||||
|
"assets/**/*",
|
||||||
"cli.js",
|
"cli.js",
|
||||||
"npmextra.json",
|
"npmextra.json",
|
||||||
"readme.md"
|
"readme.md"
|
||||||
]
|
],
|
||||||
|
"browserslist": [
|
||||||
|
"last 1 chrome versions"
|
||||||
|
],
|
||||||
|
"type": "module",
|
||||||
|
"keywords": [
|
||||||
|
"file watching",
|
||||||
|
"chokidar",
|
||||||
|
"filesystem",
|
||||||
|
"observable",
|
||||||
|
"typescript",
|
||||||
|
"node.js",
|
||||||
|
"development tool",
|
||||||
|
"file system events",
|
||||||
|
"real-time",
|
||||||
|
"watch files"
|
||||||
|
],
|
||||||
|
"packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977"
|
||||||
}
|
}
|
||||||
|
10026
pnpm-lock.yaml
generated
Normal file
10026
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
29
readme.hints.md
Normal file
29
readme.hints.md
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# smartchok - Technical Hints
|
||||||
|
|
||||||
|
## Chokidar 4.x Migration (2024)
|
||||||
|
|
||||||
|
The module has been migrated from `@tempfix/watcher` to `chokidar` 4.x. Key changes:
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
- **Removed**: `@tempfix/watcher` (a fork of fabiospampinato/watcher)
|
||||||
|
- **Added**: `chokidar` 4.x and `picomatch`
|
||||||
|
|
||||||
|
### Why picomatch?
|
||||||
|
Chokidar 4.x removed built-in glob pattern support. We use `picomatch` to maintain backward compatibility and provide glob pattern matching functionality.
|
||||||
|
|
||||||
|
### Implementation Details
|
||||||
|
1. **Glob pattern extraction**: The `getGlobBase()` method extracts base directories from glob patterns
|
||||||
|
2. **Pattern matching**: Each glob pattern is compiled to a picomatch matcher function
|
||||||
|
3. **Event filtering**: File system events are filtered based on glob patterns before being emitted
|
||||||
|
4. **Path normalization**: Paths are normalized to handle different formats (with/without leading ./)
|
||||||
|
|
||||||
|
### Event Handling
|
||||||
|
Chokidar 4.x events are mapped 1:1 with smartchok events:
|
||||||
|
- `add`, `change`, `unlink`: File events
|
||||||
|
- `addDir`, `unlinkDir`: Directory events
|
||||||
|
- `error`: Error events
|
||||||
|
- `raw`: Raw events from underlying watchers
|
||||||
|
- `ready`: Emitted when initial scan is complete
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
All existing tests pass without modification, confirming backward compatibility is maintained.
|
133
readme.md
Normal file
133
readme.md
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
# @push.rocks/smartchok
|
||||||
|
smart wrapper for chokidar
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
Install the package by running the following command in your terminal:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install @push.rocks/smartchok --save
|
||||||
|
```
|
||||||
|
|
||||||
|
This command adds `@push.rocks/smartchok` to your project's dependencies, ensuring that your project can use its functionality and that it will be installed when running `npm install` in your project root.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
The `@push.rocks/smartchok` package provides a convenient and smart wrapper around the popular `chokidar` library (v4.x) for file watching with enhanced features such as observable support for filesystem events and glob pattern matching support. This guide will introduce you to the usage of `@push.rocks/smartchok`, leveraging TypeScript for type safety and better developer experience.
|
||||||
|
|
||||||
|
### Setting Up Your Project
|
||||||
|
|
||||||
|
To use `@push.rocks/smartchok`, ensure your project is set up to use TypeScript and ECMAScript modules (ESM). You need to have a `tsconfig.json` file at the root of your project with the following minimum settings:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "esnext",
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"declaration": true,
|
||||||
|
"outDir": "./dist",
|
||||||
|
"strict": true
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This configuration enables TypeScript compilation targeting the latest ECMAScript standards and includes all TypeScript files (`*.ts`) in your `src` directory.
|
||||||
|
|
||||||
|
### Basic Setup
|
||||||
|
|
||||||
|
To start using `smartchok`, first import it into your TypeScript file:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { Smartchok } from '@push.rocks/smartchok';
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Initializing Smartchok
|
||||||
|
|
||||||
|
Create an instance of `Smartchok` by specifying an array of glob patterns to watch:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const smartchokInstance = new Smartchok([
|
||||||
|
'./src/**/*.ts', // Watch all TypeScript files in the src directory
|
||||||
|
'./public/assets/**/*' // Watch all files in the public/assets directory
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Adding and Removing Files Dynamically
|
||||||
|
|
||||||
|
You can dynamically add and remove paths from being watched by using the `add` and `remove` methods:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Add additional files or patterns
|
||||||
|
smartchokInstance.add(['./tests/**/*.spec.ts']);
|
||||||
|
|
||||||
|
// Remove specific patterns from watch
|
||||||
|
smartchokInstance.remove('./src/**/*.test.ts');
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Handling Filesystem Events
|
||||||
|
|
||||||
|
`smartchok` leverages RxJS observables to notify about filesystem events. This allows you to respond to various events such as file additions, changes, and deletions with ease.
|
||||||
|
|
||||||
|
First, start the watcher:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
await smartchokInstance.start();
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, subscribe to an event:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const changeObservable = await smartchokInstance.getObservableFor('change');
|
||||||
|
|
||||||
|
changeObservable.subscribe({
|
||||||
|
next: ([path, stats]) => {
|
||||||
|
console.log(`File changed: ${path}`);
|
||||||
|
},
|
||||||
|
error: (err) => {
|
||||||
|
console.error(`An error occurred: ${err}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Supported events include 'add', 'change', 'unlink' (for deletions), 'addDir', 'unlinkDir', 'error', 'ready', and 'raw'. Since chokidar 4.x no longer supports glob patterns natively, smartchok handles glob pattern matching internally using picomatch.
|
||||||
|
|
||||||
|
#### Stopping the Watcher
|
||||||
|
|
||||||
|
To stop watching for file changes, simply call:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
await smartchokInstance.stop();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Advanced Usage
|
||||||
|
|
||||||
|
Beyond the basics, `smartchok` allows for more complex monitoring scenarios, such as debounced notifications for rapid changes, filtering events, and integrating with other observables for complex asynchronous workflows.
|
||||||
|
|
||||||
|
### Conclusion
|
||||||
|
|
||||||
|
`@push.rocks/smartchok` provides a robust, observable-based wrapper around `chokidar` 4.x, making it an excellent choice for projects requiring efficient and flexible file monitoring. Its integration with RxJS opens up a wide array of possibilities for handling file system events in a reactive manner, making your code more concise, readable, and maintainable. The package maintains backward compatibility by implementing glob pattern support that was removed in chokidar 4.x.
|
||||||
|
|
||||||
|
By following the guidelines provided in this document, you should now be equipped to integrate `@push.rocks/smartchok` into your TypeScript project, enhancing its capabilities with efficient file system monitoring.
|
||||||
|
|
||||||
|
## License and Legal Information
|
||||||
|
|
||||||
|
This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
|
||||||
|
|
||||||
|
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
### Trademarks
|
||||||
|
|
||||||
|
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.
|
||||||
|
|
||||||
|
### Company Information
|
||||||
|
|
||||||
|
Task Venture Capital GmbH
|
||||||
|
Registered at District court Bremen HRB 35230 HB, Germany
|
||||||
|
|
||||||
|
For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
|
||||||
|
|
||||||
|
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
|
70
readme.plan.md
Normal file
70
readme.plan.md
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
# Migration Plan: smartchok to Chokidar 4.x
|
||||||
|
|
||||||
|
Command to reread CLAUDE.md: `cat /home/philkunz/.claude/CLAUDE.md`
|
||||||
|
|
||||||
|
## MIGRATION COMPLETED ✅
|
||||||
|
|
||||||
|
All phases of the migration have been successfully completed:
|
||||||
|
|
||||||
|
## Current State Analysis
|
||||||
|
|
||||||
|
- **Current dependency**: `@tempfix/watcher` v2.3.0 (a fork of fabiospampinato/watcher)
|
||||||
|
- **Target**: Chokidar v4.0.3
|
||||||
|
- **Major challenge**: Chokidar 4.x removed glob support, but smartchok heavily uses glob patterns
|
||||||
|
|
||||||
|
## Migration Plan
|
||||||
|
|
||||||
|
### Phase 1: Preparation
|
||||||
|
1. Install chokidar 4.x and glob library for pattern matching
|
||||||
|
- `pnpm install chokidar@^4.0.3`
|
||||||
|
- `pnpm install picomatch` (for glob pattern matching)
|
||||||
|
- `pnpm uninstall @tempfix/watcher`
|
||||||
|
|
||||||
|
### Phase 2: Code Changes
|
||||||
|
|
||||||
|
#### 2.1 Update Plugin Imports (ts/smartchok.plugins.ts)
|
||||||
|
- Remove `@tempfix/watcher` import
|
||||||
|
- Add `chokidar` import
|
||||||
|
- Add `picomatch` for glob pattern matching
|
||||||
|
|
||||||
|
#### 2.2 Update Smartchok Class (ts/smartchok.classes.smartchok.ts)
|
||||||
|
- Replace watcher initialization with chokidar
|
||||||
|
- Implement custom glob filtering using picomatch
|
||||||
|
- Update event mapping to match chokidar's event names
|
||||||
|
- Adjust watcher options to match chokidar's API
|
||||||
|
|
||||||
|
#### 2.3 Handle Glob Patterns
|
||||||
|
Since chokidar 4.x removed glob support, we need to:
|
||||||
|
- Parse glob patterns to extract base directories
|
||||||
|
- Use chokidar to watch base directories
|
||||||
|
- Use picomatch to filter events based on glob patterns
|
||||||
|
- Ensure backward compatibility with existing API
|
||||||
|
|
||||||
|
#### 2.4 Event Mapping
|
||||||
|
Map chokidar events to existing smartchok events:
|
||||||
|
- Keep existing event names for backward compatibility
|
||||||
|
- Ensure all current functionality is preserved
|
||||||
|
|
||||||
|
### Phase 3: Testing
|
||||||
|
1. Run existing tests to ensure backward compatibility
|
||||||
|
2. Add new tests for glob pattern handling
|
||||||
|
3. Test edge cases with complex glob patterns
|
||||||
|
4. Verify performance with large file sets
|
||||||
|
|
||||||
|
### Phase 4: Documentation
|
||||||
|
1. Update readme.md to reflect the change to chokidar 4.x
|
||||||
|
2. Document any API changes (if any)
|
||||||
|
3. Update version number in package.json
|
||||||
|
|
||||||
|
## Technical Details
|
||||||
|
|
||||||
|
### Key Differences to Handle:
|
||||||
|
1. **Glob Support**: Implement custom glob filtering layer
|
||||||
|
2. **API Changes**: Adapt initialization and option passing
|
||||||
|
3. **Event Names**: Map between different event naming conventions
|
||||||
|
4. **Minimum Node Version**: Ensure compatibility with Node 14+
|
||||||
|
|
||||||
|
### Risk Mitigation:
|
||||||
|
- Maintain backward compatibility with existing API
|
||||||
|
- Extensive testing with current test suite
|
||||||
|
- Consider keeping a legacy branch if breaking changes are unavoidable
|
36
test/test.ts
36
test/test.ts
@ -1,8 +1,10 @@
|
|||||||
import { tap, expect } from '@pushrocks/tapbundle';
|
import { tap, expect } from '@push.rocks/tapbundle';
|
||||||
import * as smartchok from '../ts/index';
|
import * as smartchok from '../ts/index.js';
|
||||||
import * as smartfile from '@pushrocks/smartfile';
|
import * as smartfile from '@push.rocks/smartfile';
|
||||||
import * as smartpromise from '@pushrocks/smartpromise';
|
import * as smartpromise from '@push.rocks/smartpromise';
|
||||||
import * as smartrx from '@pushrocks/smartrx';
|
import * as smartrx from '@push.rocks/smartrx';
|
||||||
|
|
||||||
|
import * as fs from 'fs';
|
||||||
|
|
||||||
// the module to test
|
// the module to test
|
||||||
if (process.env.CI) {
|
if (process.env.CI) {
|
||||||
@ -10,38 +12,38 @@ if (process.env.CI) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let testSmartchok: smartchok.Smartchok;
|
let testSmartchok: smartchok.Smartchok;
|
||||||
let testAddObservable: smartrx.rxjs.Observable<any>;
|
let testAddObservable: smartrx.rxjs.Observable<[string, fs.Stats]>;
|
||||||
let testSubscription: smartrx.rxjs.Subscription;
|
let testSubscription: smartrx.rxjs.Subscription;
|
||||||
tap.test('should create a new instance', async () => {
|
tap.test('should create a new instance', async () => {
|
||||||
testSmartchok = new smartchok.Smartchok([]);
|
testSmartchok = new smartchok.Smartchok([]);
|
||||||
expect(testSmartchok).to.be.instanceof(smartchok.Smartchok);
|
expect(testSmartchok).toBeInstanceOf(smartchok.Smartchok);
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should add some files to watch and start', async () => {
|
tap.test('should add some files to watch and start', async () => {
|
||||||
testSmartchok.add(['./test/assets/**/*.txt']);
|
testSmartchok.add(['./test/**/*.txt']);
|
||||||
let localPromise = testSmartchok.start().then(async () => {
|
await testSmartchok.start()
|
||||||
testSmartchok.add(['./test/assets/**/*.md']);
|
testSmartchok.add(['./test/**/*.md']);
|
||||||
});
|
|
||||||
await expect(localPromise).to.eventually.be.fulfilled;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should get an observable for a certain event', async () => {
|
tap.test('should get an observable for a certain event', async () => {
|
||||||
let localPromise = testSmartchok.getObservableFor('add').then(async observableArg => {
|
await testSmartchok.getObservableFor('add').then(async (observableArg) => {
|
||||||
testAddObservable = observableArg;
|
testAddObservable = observableArg;
|
||||||
});
|
});
|
||||||
await expect(localPromise).to.eventually.be.fulfilled;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should register an add operation', async () => {
|
tap.test('should register an add operation', async () => {
|
||||||
let testDeferred = smartpromise.defer();
|
let testDeferred = smartpromise.defer();
|
||||||
testSubscription = testAddObservable.subscribe(x => {
|
testSubscription = testAddObservable.subscribe(pathArg => {
|
||||||
|
const pathResult = pathArg[0];
|
||||||
|
console.log(pathResult);
|
||||||
testDeferred.resolve();
|
testDeferred.resolve();
|
||||||
});
|
});
|
||||||
smartfile.memory.toFs('HI', './test/assets/hi.txt');
|
smartfile.memory.toFs('HI', './test/assets/hi.txt');
|
||||||
await expect(testDeferred.promise).to.eventually.be.fulfilled;
|
await testDeferred.promise;
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should stop the watch process', async () => {
|
tap.test('should stop the watch process', async (tools) => {
|
||||||
|
await tools.delayFor(10000);
|
||||||
testSmartchok.stop();
|
testSmartchok.stop();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
8
ts/00_commitinfo_data.ts
Normal file
8
ts/00_commitinfo_data.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/**
|
||||||
|
* autocreated commitinfo by @push.rocks/commitinfo
|
||||||
|
*/
|
||||||
|
export const commitinfo = {
|
||||||
|
name: '@push.rocks/smartchok',
|
||||||
|
version: '1.1.1',
|
||||||
|
description: 'A smart wrapper for chokidar 4.x with glob pattern support and enhanced features.'
|
||||||
|
}
|
@ -1 +1 @@
|
|||||||
export * from './smartchok.classes.smartchok';
|
export * from './smartchok.classes.smartchok.js';
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import * as plugins from './smartchok.plugins';
|
import * as plugins from './smartchok.plugins.js';
|
||||||
import { Stringmap } from '@pushrocks/lik';
|
import { Stringmap } from '@push.rocks/lik';
|
||||||
import { Observablemap } from '@pushrocks/smartrx';
|
|
||||||
|
|
||||||
export type TSmartchokStatus = 'idle' | 'starting' | 'watching';
|
export type TSmartchokStatus = 'idle' | 'starting' | 'watching';
|
||||||
export type TFsEvent =
|
export type TFsEvent =
|
||||||
@ -17,42 +16,71 @@ export type TFsEvent =
|
|||||||
* Smartchok allows easy wathcing of files
|
* Smartchok allows easy wathcing of files
|
||||||
*/
|
*/
|
||||||
export class Smartchok {
|
export class Smartchok {
|
||||||
watchStringmap = new Stringmap();
|
public watchStringmap = new Stringmap();
|
||||||
chokidarOptions: plugins.chokidar.WatchOptions;
|
public status: TSmartchokStatus = 'idle';
|
||||||
status: TSmartchokStatus = 'idle';
|
|
||||||
private watcher: plugins.chokidar.FSWatcher;
|
private watcher: plugins.chokidar.FSWatcher;
|
||||||
|
private globPatterns: string[] = [];
|
||||||
|
private globMatchers: Map<string, (path: string) => boolean> = new Map();
|
||||||
private watchingDeferred = plugins.smartpromise.defer<void>(); // used to run things when watcher is initialized
|
private watchingDeferred = plugins.smartpromise.defer<void>(); // used to run things when watcher is initialized
|
||||||
private eventObservablemap = new plugins.smartrx.Observablemap(); // register one observable per event
|
private eventObservablemap = new plugins.smartrx.Observablemap(); // register one observable per event
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* constructor of class smartchok
|
* constructor of class smartchok
|
||||||
*/
|
*/
|
||||||
constructor(watchArrayArg: string[], optionsArg: plugins.chokidar.WatchOptions = {}) {
|
constructor(watchArrayArg: string[]) {
|
||||||
this.watchStringmap.addStringArray(watchArrayArg);
|
this.watchStringmap.addStringArray(watchArrayArg);
|
||||||
this.chokidarOptions = optionsArg;
|
}
|
||||||
|
|
||||||
|
private getGlobBase(globPattern: string) {
|
||||||
|
// Characters that mark the beginning of a glob pattern
|
||||||
|
const globChars = ['*', '?', '[', ']', '{', '}'];
|
||||||
|
|
||||||
|
// Find the index of the first glob character
|
||||||
|
const firstGlobCharIndex = globPattern.split('').findIndex((char) => globChars.includes(char));
|
||||||
|
|
||||||
|
// If no glob characters are found, return the entire string
|
||||||
|
if (firstGlobCharIndex === -1) {
|
||||||
|
return globPattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the substring up to the first glob character
|
||||||
|
const basePathPortion = globPattern.substring(0, firstGlobCharIndex);
|
||||||
|
|
||||||
|
// Find the last slash before the glob pattern starts
|
||||||
|
const lastSlashIndex = basePathPortion.lastIndexOf('/');
|
||||||
|
|
||||||
|
// If there is no slash, return the basePathPortion as is
|
||||||
|
if (lastSlashIndex === -1) {
|
||||||
|
return basePathPortion;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the base path up to and including the last slash
|
||||||
|
return basePathPortion.substring(0, lastSlashIndex + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* adds files to the list of watched files
|
* adds files to the list of watched files
|
||||||
*/
|
*/
|
||||||
add(pathArrayArg: string[]) {
|
public add(pathArrayArg: string[]) {
|
||||||
this.watchStringmap.addStringArray(pathArrayArg);
|
this.watchStringmap.addStringArray(pathArrayArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* removes files from the list of watched files
|
* removes files from the list of watched files
|
||||||
*/
|
*/
|
||||||
remove(pathArg: string) {
|
public remove(pathArg: string) {
|
||||||
this.watchStringmap.removeString(pathArg);
|
this.watchStringmap.removeString(pathArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gets an observable for a certain event
|
* gets an observable for a certain event
|
||||||
*/
|
*/
|
||||||
getObservableFor(fsEvent: TFsEvent): Promise<plugins.smartrx.rxjs.Observable<any>> {
|
public getObservableFor(
|
||||||
let done = plugins.smartpromise.defer<plugins.smartrx.rxjs.Observable<any>>();
|
fsEvent: TFsEvent
|
||||||
|
): Promise<plugins.smartrx.rxjs.Observable<[string, plugins.fs.Stats]>> {
|
||||||
|
const done = plugins.smartpromise.defer<plugins.smartrx.rxjs.Observable<any>>();
|
||||||
this.watchingDeferred.promise.then(() => {
|
this.watchingDeferred.promise.then(() => {
|
||||||
let eventObservable = this.eventObservablemap.getObservableForEmitterEvent(
|
const eventObservable = this.eventObservablemap.getSubjectForEmitterEvent(
|
||||||
this.watcher,
|
this.watcher,
|
||||||
fsEvent
|
fsEvent
|
||||||
);
|
);
|
||||||
@ -65,13 +93,75 @@ export class Smartchok {
|
|||||||
* starts the watcher
|
* starts the watcher
|
||||||
* @returns Promise<void>
|
* @returns Promise<void>
|
||||||
*/
|
*/
|
||||||
start(): Promise<void> {
|
public start(): Promise<void> {
|
||||||
let done = plugins.smartpromise.defer<void>();
|
const done = plugins.smartpromise.defer<void>();
|
||||||
this.status = 'starting';
|
this.status = 'starting';
|
||||||
this.watcher = plugins.chokidar.watch(
|
|
||||||
this.watchStringmap.getStringArray(),
|
// Store original glob patterns and create matchers
|
||||||
this.chokidarOptions
|
this.globPatterns = this.watchStringmap.getStringArray();
|
||||||
);
|
const basePaths = new Set<string>();
|
||||||
|
|
||||||
|
this.globPatterns.forEach((pattern) => {
|
||||||
|
const basePath = this.getGlobBase(pattern);
|
||||||
|
basePaths.add(basePath);
|
||||||
|
|
||||||
|
// Create a picomatch matcher for each glob pattern
|
||||||
|
const matcher = plugins.picomatch(pattern, {
|
||||||
|
dot: true,
|
||||||
|
basename: false
|
||||||
|
});
|
||||||
|
this.globMatchers.set(pattern, matcher);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Convert Set to Array for chokidar
|
||||||
|
const watchPaths = Array.from(basePaths);
|
||||||
|
console.log('Base paths to watch:', watchPaths);
|
||||||
|
|
||||||
|
this.watcher = plugins.chokidar.watch(watchPaths, {
|
||||||
|
persistent: true,
|
||||||
|
ignoreInitial: false,
|
||||||
|
followSymlinks: false,
|
||||||
|
depth: 4,
|
||||||
|
awaitWriteFinish: {
|
||||||
|
stabilityThreshold: 300,
|
||||||
|
pollInterval: 100
|
||||||
|
},
|
||||||
|
ignored: (path: string, stats?: plugins.fs.Stats) => {
|
||||||
|
// Don't filter during initialization - let chokidar watch everything
|
||||||
|
// We'll filter events as they come in
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set up event handlers with glob filtering
|
||||||
|
const fileEvents: Array<'add' | 'change' | 'unlink' | 'addDir' | 'unlinkDir'> =
|
||||||
|
['add', 'addDir', 'change', 'unlink', 'unlinkDir'];
|
||||||
|
|
||||||
|
// Handle file events
|
||||||
|
fileEvents.forEach(eventName => {
|
||||||
|
this.watcher.on(eventName, (path: string, stats?: plugins.fs.Stats) => {
|
||||||
|
// Only emit event if the path matches our glob patterns
|
||||||
|
if (this.shouldWatchPath(path)) {
|
||||||
|
this.eventObservablemap.getSubjectForEmitterEvent(this.watcher, eventName)
|
||||||
|
.next([path, stats]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle error events
|
||||||
|
this.watcher.on('error', (error: Error) => {
|
||||||
|
this.eventObservablemap.getSubjectForEmitterEvent(this.watcher, 'error')
|
||||||
|
.next([error, undefined]);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle raw events
|
||||||
|
this.watcher.on('raw', (eventType: string, path: string, details: any) => {
|
||||||
|
if (this.shouldWatchPath(path)) {
|
||||||
|
this.eventObservablemap.getSubjectForEmitterEvent(this.watcher, 'raw')
|
||||||
|
.next([path, undefined]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.watcher.on('ready', () => {
|
this.watcher.on('ready', () => {
|
||||||
this.status = 'watching';
|
this.status = 'watching';
|
||||||
this.watchingDeferred.resolve();
|
this.watchingDeferred.resolve();
|
||||||
@ -83,17 +173,48 @@ export class Smartchok {
|
|||||||
/**
|
/**
|
||||||
* stop the watcher process if watching
|
* stop the watcher process if watching
|
||||||
*/
|
*/
|
||||||
stop() {
|
public async stop() {
|
||||||
let closeWatcher = () => {
|
const closeWatcher = async () => {
|
||||||
this.watcher.close();
|
await this.watcher.close();
|
||||||
};
|
};
|
||||||
if (this.status === 'watching') {
|
if (this.status === 'watching') {
|
||||||
console.log('closing while watching');
|
console.log('closing while watching');
|
||||||
closeWatcher();
|
await closeWatcher();
|
||||||
} else if (this.status === 'starting') {
|
} else if (this.status === 'starting') {
|
||||||
this.watchingDeferred.promise.then(() => {
|
await this.watchingDeferred.promise;
|
||||||
closeWatcher();
|
await closeWatcher();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a path should be watched based on glob patterns
|
||||||
|
*/
|
||||||
|
private shouldWatchPath(filePath: string): boolean {
|
||||||
|
// Normalize the path - remove leading ./ if present
|
||||||
|
let normalizedPath = filePath.replace(/\\/g, '/');
|
||||||
|
if (normalizedPath.startsWith('./')) {
|
||||||
|
normalizedPath = normalizedPath.substring(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the path matches any of our glob patterns
|
||||||
|
for (const [pattern, matcher] of this.globMatchers) {
|
||||||
|
// Also normalize the pattern for comparison
|
||||||
|
let normalizedPattern = pattern;
|
||||||
|
if (normalizedPattern.startsWith('./')) {
|
||||||
|
normalizedPattern = normalizedPattern.substring(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try matching with both the original pattern and normalized
|
||||||
|
if (matcher(normalizedPath) || matcher(filePath)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also try matching without the leading path
|
||||||
|
const withoutLeading = 'test/' + normalizedPath.split('test/').slice(1).join('test/');
|
||||||
|
if (matcher(withoutLeading)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,28 @@
|
|||||||
export import lik = require('@pushrocks/lik');
|
// node native
|
||||||
export import chokidar = require('chokidar');
|
import * as fs from 'fs';
|
||||||
export import path = require('path');
|
import * as path from 'path';
|
||||||
export import smartpromise = require('@pushrocks/smartpromise');
|
|
||||||
export import smartrx = require('@pushrocks/smartrx');
|
export {
|
||||||
|
fs,
|
||||||
|
path
|
||||||
|
}
|
||||||
|
|
||||||
|
// @pushrocks scope
|
||||||
|
import * as lik from '@push.rocks/lik';
|
||||||
|
import * as smartpromise from '@push.rocks/smartpromise';
|
||||||
|
import * as smartrx from '@push.rocks/smartrx';
|
||||||
|
|
||||||
|
export {
|
||||||
|
lik,
|
||||||
|
smartpromise,
|
||||||
|
smartrx
|
||||||
|
}
|
||||||
|
|
||||||
|
// thirdparty scope
|
||||||
|
import * as chokidar from 'chokidar';
|
||||||
|
import picomatch from 'picomatch';
|
||||||
|
|
||||||
|
export {
|
||||||
|
chokidar,
|
||||||
|
picomatch,
|
||||||
|
}
|
||||||
|
14
tsconfig.json
Normal file
14
tsconfig.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"useDefineForClassFields": false,
|
||||||
|
"target": "ES2022",
|
||||||
|
"module": "NodeNext",
|
||||||
|
"moduleResolution": "NodeNext",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"verbatimModuleSyntax": true
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"dist_*/**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
17
tslint.json
17
tslint.json
@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": ["tslint:latest", "tslint-config-prettier"],
|
|
||||||
"rules": {
|
|
||||||
"semicolon": [true, "always"],
|
|
||||||
"no-console": false,
|
|
||||||
"ordered-imports": false,
|
|
||||||
"object-literal-sort-keys": false,
|
|
||||||
"member-ordering": {
|
|
||||||
"options":{
|
|
||||||
"order": [
|
|
||||||
"static-method"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"defaultSeverity": "warning"
|
|
||||||
}
|
|
Reference in New Issue
Block a user