@thi.ng/file-io 1.1.5 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -1
- package/README.md +8 -4
- package/files.js +1 -4
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/internal/ensure.d.ts +6 -0
- package/internal/ensure.js +8 -0
- package/package.json +12 -8
- package/watch.d.ts +41 -0
- package/watch.js +119 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2024-01-
|
|
3
|
+
- **Last updated**: 2024-01-29T20:39:36Z
|
|
4
4
|
- **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
|
|
5
5
|
|
|
6
6
|
All notable changes to this project will be documented in this file.
|
|
@@ -9,6 +9,16 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
|
|
|
9
9
|
**Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
|
|
10
10
|
and/or version bumps of transitive dependencies.
|
|
11
11
|
|
|
12
|
+
## [1.2.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/file-io@1.2.0) (2024-01-26)
|
|
13
|
+
|
|
14
|
+
#### 🚀 Features
|
|
15
|
+
|
|
16
|
+
- add fileWatcher() ([71c1d8f](https://github.com/thi-ng/umbrella/commit/71c1d8f))
|
|
17
|
+
|
|
18
|
+
#### ♻️ Refactoring
|
|
19
|
+
|
|
20
|
+
- migrate internal predicates ([52c985a](https://github.com/thi-ng/umbrella/commit/52c985a))
|
|
21
|
+
|
|
12
22
|
## [1.1.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/file-io@1.1.0) (2023-12-18)
|
|
13
23
|
|
|
14
24
|
#### 🚀 Features
|
package/README.md
CHANGED
|
@@ -7,9 +7,13 @@
|
|
|
7
7
|

|
|
8
8
|
[](https://mastodon.thi.ng/@toxi)
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
> [!NOTE]
|
|
11
|
+
> This is one of 189 standalone projects, maintained as part
|
|
12
|
+
> of the [@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo
|
|
13
|
+
> and anti-framework.
|
|
14
|
+
>
|
|
15
|
+
> 🚀 Help me to work full-time on these projects by [sponsoring me on
|
|
16
|
+
> GitHub](https://github.com/sponsors/postspectacular). Thank you! ❤️
|
|
13
17
|
|
|
14
18
|
- [About](#about)
|
|
15
19
|
- [Status](#status)
|
|
@@ -45,7 +49,7 @@ For Node.js REPL:
|
|
|
45
49
|
const fileIo = await import("@thi.ng/file-io");
|
|
46
50
|
```
|
|
47
51
|
|
|
48
|
-
Package sizes (brotli'd, pre-treeshake): ESM: 1.
|
|
52
|
+
Package sizes (brotli'd, pre-treeshake): ESM: 1.98 KB
|
|
49
53
|
|
|
50
54
|
## Dependencies
|
|
51
55
|
|
package/files.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { isFunction } from "@thi.ng/checks/is-function";
|
|
2
|
-
import { isString } from "@thi.ng/checks/is-string";
|
|
3
1
|
import { readdirSync, statSync } from "fs";
|
|
4
2
|
import { sep } from "path";
|
|
5
3
|
import { isDirectory } from "./dir.js";
|
|
4
|
+
import { __ensurePred } from "./internal/ensure.js";
|
|
6
5
|
const files = (dir, match = "", maxDepth = Infinity, logger) => __files(dir, match, logger, maxDepth, 0);
|
|
7
6
|
function* __files(dir, match = "", logger, maxDepth = Infinity, depth = 0) {
|
|
8
7
|
if (depth >= maxDepth)
|
|
@@ -39,8 +38,6 @@ function* __dirs(dir, match = "", logger, maxDepth = Infinity, depth = 0) {
|
|
|
39
38
|
}
|
|
40
39
|
}
|
|
41
40
|
}
|
|
42
|
-
const __ensureRegEx = (match) => isString(match) ? new RegExp(`${match.replace(/\./g, "\\.")}$`) : match;
|
|
43
|
-
const __ensurePred = (match) => isFunction(match) ? match : (match = __ensureRegEx(match), (x) => match.test(x));
|
|
44
41
|
export {
|
|
45
42
|
dirs,
|
|
46
43
|
files
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Predicate } from "@thi.ng/api";
|
|
2
|
+
/** @internal */
|
|
3
|
+
export declare const __ensureRegEx: (match: string | RegExp | Predicate<string>) => RegExp | Predicate<string>;
|
|
4
|
+
/** @internal */
|
|
5
|
+
export declare const __ensurePred: (match: string | RegExp | Predicate<string>) => Predicate<string>;
|
|
6
|
+
//# sourceMappingURL=ensure.d.ts.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { isFunction } from "@thi.ng/checks/is-function";
|
|
2
|
+
import { isString } from "@thi.ng/checks/is-string";
|
|
3
|
+
const __ensureRegEx = (match) => isString(match) ? new RegExp(`${match.replace(/\./g, "\\.")}$`) : match;
|
|
4
|
+
const __ensurePred = (match) => isFunction(match) ? match : (match = __ensureRegEx(match), (x) => match.test(x));
|
|
5
|
+
export {
|
|
6
|
+
__ensurePred,
|
|
7
|
+
__ensureRegEx
|
|
8
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/file-io",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Assorted file I/O utils (with logging support) for NodeJS",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
"test": "bun test"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@thi.ng/api": "^8.9.
|
|
39
|
-
"@thi.ng/checks": "^3.4.
|
|
40
|
-
"@thi.ng/hex": "^2.3.
|
|
41
|
-
"@thi.ng/logger": "^2.1.
|
|
42
|
-
"@thi.ng/random": "^3.6.
|
|
38
|
+
"@thi.ng/api": "^8.9.19",
|
|
39
|
+
"@thi.ng/checks": "^3.4.19",
|
|
40
|
+
"@thi.ng/hex": "^2.3.31",
|
|
41
|
+
"@thi.ng/logger": "^2.1.5",
|
|
42
|
+
"@thi.ng/random": "^3.6.26"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@microsoft/api-extractor": "^7.39.0",
|
|
@@ -69,7 +69,8 @@
|
|
|
69
69
|
},
|
|
70
70
|
"files": [
|
|
71
71
|
"./*.js",
|
|
72
|
-
"./*.d.ts"
|
|
72
|
+
"./*.d.ts",
|
|
73
|
+
"internal"
|
|
73
74
|
],
|
|
74
75
|
"exports": {
|
|
75
76
|
".": {
|
|
@@ -108,6 +109,9 @@
|
|
|
108
109
|
"./text": {
|
|
109
110
|
"default": "./text.js"
|
|
110
111
|
},
|
|
112
|
+
"./watch": {
|
|
113
|
+
"default": "./watch.js"
|
|
114
|
+
},
|
|
111
115
|
"./write": {
|
|
112
116
|
"default": "./write.js"
|
|
113
117
|
}
|
|
@@ -116,5 +120,5 @@
|
|
|
116
120
|
"status": "stable",
|
|
117
121
|
"year": 2022
|
|
118
122
|
},
|
|
119
|
-
"gitHead": "
|
|
123
|
+
"gitHead": "20909ffc46f23f61ec7647e8d27ed17752ce9828\n"
|
|
120
124
|
}
|
package/watch.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { type Event, type IClear, type INotify, type IObjectOf, type Listener, type Predicate } from "@thi.ng/api";
|
|
3
|
+
import type { ILogger } from "@thi.ng/logger";
|
|
4
|
+
import { type FSWatcher } from "fs";
|
|
5
|
+
export interface WatcherOpts {
|
|
6
|
+
/**
|
|
7
|
+
* Number of milliseconds between observing a file change and notifying
|
|
8
|
+
* attached listeners.
|
|
9
|
+
*
|
|
10
|
+
* @defaultValue 100
|
|
11
|
+
*/
|
|
12
|
+
delay: number;
|
|
13
|
+
/**
|
|
14
|
+
* Logger instance for showing debug info (must have DEBUG level enabled)
|
|
15
|
+
*/
|
|
16
|
+
logger: ILogger;
|
|
17
|
+
}
|
|
18
|
+
export interface PathWatchOpts {
|
|
19
|
+
recursive: boolean;
|
|
20
|
+
ext: string | RegExp | Predicate<string>;
|
|
21
|
+
}
|
|
22
|
+
export declare const EVENT_ADDED = "added";
|
|
23
|
+
export declare const EVENT_CHANGED = "changed";
|
|
24
|
+
export declare const EVENT_REMOVED = "removed";
|
|
25
|
+
export declare class Watcher implements IClear, INotify {
|
|
26
|
+
watchers: IObjectOf<FSWatcher>;
|
|
27
|
+
opts: WatcherOpts;
|
|
28
|
+
protected _signal: boolean;
|
|
29
|
+
constructor(opts?: Partial<WatcherOpts>);
|
|
30
|
+
addAll(paths: (string | [string, Partial<PathWatchOpts>])[]): void;
|
|
31
|
+
add(path: string, opts?: Partial<PathWatchOpts>): boolean;
|
|
32
|
+
remove(path: string): boolean;
|
|
33
|
+
removeAll(paths: Iterable<string>): void;
|
|
34
|
+
clear(): void;
|
|
35
|
+
installSignalHandler(): void;
|
|
36
|
+
addListener(id: string, fn: Listener<string>, scope?: any): boolean;
|
|
37
|
+
removeListener(id: string, fn: Listener<string>, scope?: any): boolean;
|
|
38
|
+
notify(event: Event<string>): boolean;
|
|
39
|
+
}
|
|
40
|
+
export declare const fileWatcher: (opts?: Partial<WatcherOpts>) => Watcher;
|
|
41
|
+
//# sourceMappingURL=watch.d.ts.map
|
package/watch.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result)
|
|
9
|
+
__defProp(target, key, result);
|
|
10
|
+
return result;
|
|
11
|
+
};
|
|
12
|
+
import {
|
|
13
|
+
INotifyMixin
|
|
14
|
+
} from "@thi.ng/api";
|
|
15
|
+
import { isString } from "@thi.ng/checks/is-string";
|
|
16
|
+
import { NULL_LOGGER } from "@thi.ng/logger/null";
|
|
17
|
+
import { watch as $watch, existsSync } from "fs";
|
|
18
|
+
import { join } from "path";
|
|
19
|
+
import { isDirectory } from "./dir.js";
|
|
20
|
+
import { __ensurePred } from "./internal/ensure.js";
|
|
21
|
+
const EVENT_ADDED = "added";
|
|
22
|
+
const EVENT_CHANGED = "changed";
|
|
23
|
+
const EVENT_REMOVED = "removed";
|
|
24
|
+
let Watcher = class {
|
|
25
|
+
watchers = {};
|
|
26
|
+
opts;
|
|
27
|
+
_signal = false;
|
|
28
|
+
constructor(opts) {
|
|
29
|
+
this.opts = {
|
|
30
|
+
logger: NULL_LOGGER,
|
|
31
|
+
delay: 100,
|
|
32
|
+
...opts
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
addAll(paths) {
|
|
36
|
+
for (let p of paths) {
|
|
37
|
+
isString(p) ? this.add(p) : this.add(...p);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
add(path, opts) {
|
|
41
|
+
if (this.watchers[path])
|
|
42
|
+
return false;
|
|
43
|
+
const isDir = isDirectory(path);
|
|
44
|
+
const pred = __ensurePred(opts?.ext || "");
|
|
45
|
+
this.opts.logger.debug(`adding watcher for: ${path}`);
|
|
46
|
+
this.watchers[path] = $watch(
|
|
47
|
+
path,
|
|
48
|
+
{ recursive: opts?.recursive !== false },
|
|
49
|
+
(event, currPath) => {
|
|
50
|
+
if (!currPath)
|
|
51
|
+
return;
|
|
52
|
+
currPath = isDir ? join(path, currPath) : path;
|
|
53
|
+
if (!pred(currPath))
|
|
54
|
+
return;
|
|
55
|
+
setTimeout(() => {
|
|
56
|
+
if (event === "change") {
|
|
57
|
+
this.opts.logger.info(`file changed: ${currPath}`);
|
|
58
|
+
this.notify({
|
|
59
|
+
id: EVENT_CHANGED,
|
|
60
|
+
value: currPath
|
|
61
|
+
});
|
|
62
|
+
} else if (!isDir || path === currPath) {
|
|
63
|
+
this.opts.logger.info(`file removed: ${path}`);
|
|
64
|
+
this.notify({ id: EVENT_REMOVED, value: path });
|
|
65
|
+
this.remove(path);
|
|
66
|
+
} else {
|
|
67
|
+
const id = existsSync(currPath) ? EVENT_ADDED : EVENT_REMOVED;
|
|
68
|
+
this.opts.logger.info(`file ${id}: ${path}`);
|
|
69
|
+
this.notify({ id, value: currPath });
|
|
70
|
+
}
|
|
71
|
+
}, this.opts.delay);
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
remove(path) {
|
|
77
|
+
const watcher = this.watchers[path];
|
|
78
|
+
if (!watcher)
|
|
79
|
+
return false;
|
|
80
|
+
this.opts.logger.debug(`removing watcher for: ${path}`);
|
|
81
|
+
watcher.close();
|
|
82
|
+
delete this.watchers[path];
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
removeAll(paths) {
|
|
86
|
+
for (let p of paths) {
|
|
87
|
+
this.remove(p);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
clear() {
|
|
91
|
+
this.removeAll(Object.keys(this.watchers));
|
|
92
|
+
}
|
|
93
|
+
installSignalHandler() {
|
|
94
|
+
if (!this._signal) {
|
|
95
|
+
process.on("SIGINT", () => this.clear());
|
|
96
|
+
this._signal = true;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// @ts-ignore mixin
|
|
100
|
+
addListener(id, fn, scope) {
|
|
101
|
+
}
|
|
102
|
+
// @ts-ignore mixin
|
|
103
|
+
removeListener(id, fn, scope) {
|
|
104
|
+
}
|
|
105
|
+
// @ts-ignore mixin
|
|
106
|
+
notify(event) {
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
Watcher = __decorateClass([
|
|
110
|
+
INotifyMixin
|
|
111
|
+
], Watcher);
|
|
112
|
+
const fileWatcher = (opts) => new Watcher(opts);
|
|
113
|
+
export {
|
|
114
|
+
EVENT_ADDED,
|
|
115
|
+
EVENT_CHANGED,
|
|
116
|
+
EVENT_REMOVED,
|
|
117
|
+
Watcher,
|
|
118
|
+
fileWatcher
|
|
119
|
+
};
|