@zthun/crumbtrail-fs 2.3.2 → 2.3.4
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/dist/index.cjs +106 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +1 -0
- package/dist/index.js +109 -63
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/dist/index.cjs
CHANGED
|
@@ -16,6 +16,19 @@ const node_url = require('node:url');
|
|
|
16
16
|
const path = require('path');
|
|
17
17
|
const promises$1 = require('fs/promises');
|
|
18
18
|
|
|
19
|
+
function _define_property$3(obj, key, value) {
|
|
20
|
+
if (key in obj) {
|
|
21
|
+
Object.defineProperty(obj, key, {
|
|
22
|
+
value: value,
|
|
23
|
+
enumerable: true,
|
|
24
|
+
configurable: true,
|
|
25
|
+
writable: true
|
|
26
|
+
});
|
|
27
|
+
} else {
|
|
28
|
+
obj[key] = value;
|
|
29
|
+
}
|
|
30
|
+
return obj;
|
|
31
|
+
}
|
|
19
32
|
/**
|
|
20
33
|
* Represents a type of a file system node.
|
|
21
34
|
*/ var ZFileSystemNodeType = /*#__PURE__*/ function(ZFileSystemNodeType) {
|
|
@@ -26,13 +39,6 @@ const promises$1 = require('fs/promises');
|
|
|
26
39
|
/**
|
|
27
40
|
* Represents a builder for a file system node.
|
|
28
41
|
*/ class ZFileSystemNodeBuilder {
|
|
29
|
-
_node;
|
|
30
|
-
constructor(){
|
|
31
|
-
this._node = {
|
|
32
|
-
path: "/",
|
|
33
|
-
type: "folder"
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
42
|
created(at) {
|
|
37
43
|
this._node.created = at instanceof Date ? at.toJSON() : at;
|
|
38
44
|
return this;
|
|
@@ -53,8 +59,6 @@ const promises$1 = require('fs/promises');
|
|
|
53
59
|
this._node.type = type;
|
|
54
60
|
return this;
|
|
55
61
|
}
|
|
56
|
-
file = this.type.bind(this, "file");
|
|
57
|
-
folder = this.type.bind(this, "folder");
|
|
58
62
|
stats(s) {
|
|
59
63
|
const builder = this.size(s.size).created(s.birthtime).updated(s.mtime);
|
|
60
64
|
return s.isFile() ? builder.file() : builder.folder();
|
|
@@ -63,6 +67,15 @@ const promises$1 = require('fs/promises');
|
|
|
63
67
|
const clone = structuredClone(this._node);
|
|
64
68
|
return lodashEs.omitBy(clone, lodashEs.isUndefined);
|
|
65
69
|
}
|
|
70
|
+
constructor(){
|
|
71
|
+
_define_property$3(this, "_node", void 0);
|
|
72
|
+
_define_property$3(this, "file", this.type.bind(this, "file"));
|
|
73
|
+
_define_property$3(this, "folder", this.type.bind(this, "folder"));
|
|
74
|
+
this._node = {
|
|
75
|
+
path: "/",
|
|
76
|
+
type: "folder"
|
|
77
|
+
};
|
|
78
|
+
}
|
|
66
79
|
}
|
|
67
80
|
|
|
68
81
|
/**
|
|
@@ -114,22 +127,22 @@ const promises$1 = require('fs/promises');
|
|
|
114
127
|
}
|
|
115
128
|
}
|
|
116
129
|
|
|
130
|
+
function _define_property$2(obj, key, value) {
|
|
131
|
+
if (key in obj) {
|
|
132
|
+
Object.defineProperty(obj, key, {
|
|
133
|
+
value: value,
|
|
134
|
+
enumerable: true,
|
|
135
|
+
configurable: true,
|
|
136
|
+
writable: true
|
|
137
|
+
});
|
|
138
|
+
} else {
|
|
139
|
+
obj[key] = value;
|
|
140
|
+
}
|
|
141
|
+
return obj;
|
|
142
|
+
}
|
|
117
143
|
/**
|
|
118
144
|
* An implementation of the IZFileWatch.
|
|
119
145
|
*/ class ZFileWatch {
|
|
120
|
-
path;
|
|
121
|
-
_add = new rxjs.Subject();
|
|
122
|
-
_update = new rxjs.Subject();
|
|
123
|
-
_remove = new rxjs.Subject();
|
|
124
|
-
_watcher;
|
|
125
|
-
/**
|
|
126
|
-
* Initializes a new instance of this object.
|
|
127
|
-
*
|
|
128
|
-
* @param path -
|
|
129
|
-
* The path to watch.
|
|
130
|
-
*/ constructor(path){
|
|
131
|
-
this.path = path;
|
|
132
|
-
}
|
|
133
146
|
async start() {
|
|
134
147
|
await this.stop();
|
|
135
148
|
this._watcher = chokidar.watch(this.path, {
|
|
@@ -162,8 +175,37 @@ const promises$1 = require('fs/promises');
|
|
|
162
175
|
remove() {
|
|
163
176
|
return this._remove.asObservable();
|
|
164
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* Initializes a new instance of this object.
|
|
180
|
+
*
|
|
181
|
+
* @param path -
|
|
182
|
+
* The path to watch.
|
|
183
|
+
*/ constructor(path){
|
|
184
|
+
_define_property$2(this, "path", void 0);
|
|
185
|
+
_define_property$2(this, "_add", void 0);
|
|
186
|
+
_define_property$2(this, "_update", void 0);
|
|
187
|
+
_define_property$2(this, "_remove", void 0);
|
|
188
|
+
_define_property$2(this, "_watcher", void 0);
|
|
189
|
+
this.path = path;
|
|
190
|
+
this._add = new rxjs.Subject();
|
|
191
|
+
this._update = new rxjs.Subject();
|
|
192
|
+
this._remove = new rxjs.Subject();
|
|
193
|
+
}
|
|
165
194
|
}
|
|
166
195
|
|
|
196
|
+
function _define_property$1(obj, key, value) {
|
|
197
|
+
if (key in obj) {
|
|
198
|
+
Object.defineProperty(obj, key, {
|
|
199
|
+
value: value,
|
|
200
|
+
enumerable: true,
|
|
201
|
+
configurable: true,
|
|
202
|
+
writable: true
|
|
203
|
+
});
|
|
204
|
+
} else {
|
|
205
|
+
obj[key] = value;
|
|
206
|
+
}
|
|
207
|
+
return obj;
|
|
208
|
+
}
|
|
167
209
|
/**
|
|
168
210
|
* Represents an implementation of a ZFileRepository that watches
|
|
169
211
|
* a given path scope.
|
|
@@ -171,16 +213,6 @@ const promises$1 = require('fs/promises');
|
|
|
171
213
|
* This repository is only concerned about files. Folders
|
|
172
214
|
* will not be retrieved from this repository.
|
|
173
215
|
*/ class ZFileRepository {
|
|
174
|
-
_service = new ZFileSystemService();
|
|
175
|
-
_watcher;
|
|
176
|
-
_nodes = Promise.resolve(new helpfulQuery.ZDataSourceStatic([]));
|
|
177
|
-
_globs = [
|
|
178
|
-
"**"
|
|
179
|
-
];
|
|
180
|
-
_path = "";
|
|
181
|
-
_add;
|
|
182
|
-
_remove;
|
|
183
|
-
_update;
|
|
184
216
|
/**
|
|
185
217
|
* Gets the path that this repository is watching.
|
|
186
218
|
*/ get path() {
|
|
@@ -267,7 +299,7 @@ const promises$1 = require('fs/promises');
|
|
|
267
299
|
// Kick off the initial seed operation with an even loop
|
|
268
300
|
// invocation.
|
|
269
301
|
await helpfulFn.sleep(100);
|
|
270
|
-
await this._watcher
|
|
302
|
+
await this._watcher?.start();
|
|
271
303
|
}
|
|
272
304
|
/**
|
|
273
305
|
* Resets the repository as if it was initially created.
|
|
@@ -300,6 +332,18 @@ const promises$1 = require('fs/promises');
|
|
|
300
332
|
const source = await this._nodes;
|
|
301
333
|
return source.retrieve(request);
|
|
302
334
|
}
|
|
335
|
+
constructor(){
|
|
336
|
+
_define_property$1(this, "_service", new ZFileSystemService());
|
|
337
|
+
_define_property$1(this, "_watcher", void 0);
|
|
338
|
+
_define_property$1(this, "_nodes", Promise.resolve(new helpfulQuery.ZDataSourceStatic([])));
|
|
339
|
+
_define_property$1(this, "_globs", [
|
|
340
|
+
"**"
|
|
341
|
+
]);
|
|
342
|
+
_define_property$1(this, "_path", "");
|
|
343
|
+
_define_property$1(this, "_add", void 0);
|
|
344
|
+
_define_property$1(this, "_remove", void 0);
|
|
345
|
+
_define_property$1(this, "_update", void 0);
|
|
346
|
+
}
|
|
303
347
|
}
|
|
304
348
|
|
|
305
349
|
function resolvePathLike(path) {
|
|
@@ -336,25 +380,26 @@ function resolvePathLike(path) {
|
|
|
336
380
|
* operation still succeeds
|
|
337
381
|
*/ class ZStreamFolder {
|
|
338
382
|
async write(path) {
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
});
|
|
343
|
-
} catch {
|
|
344
|
-
// The folder may exist, but if it is a file then
|
|
345
|
-
// we have a conflict and in that case, we will throw an
|
|
346
|
-
// error. We are going to let stat fail if it cannot
|
|
347
|
-
// access the path (permission error).
|
|
348
|
-
const stats = await promises$1.stat(path);
|
|
349
|
-
if (stats.isFile()) {
|
|
350
|
-
const msg = `Cannot create folder, ${path}, because a file with the same name exists at the target location`;
|
|
351
|
-
throw new Error(msg);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
383
|
+
await promises$1.mkdir(path, {
|
|
384
|
+
recursive: true
|
|
385
|
+
});
|
|
354
386
|
return 0;
|
|
355
387
|
}
|
|
356
388
|
}
|
|
357
389
|
|
|
390
|
+
function _define_property(obj, key, value) {
|
|
391
|
+
if (key in obj) {
|
|
392
|
+
Object.defineProperty(obj, key, {
|
|
393
|
+
value: value,
|
|
394
|
+
enumerable: true,
|
|
395
|
+
configurable: true,
|
|
396
|
+
writable: true
|
|
397
|
+
});
|
|
398
|
+
} else {
|
|
399
|
+
obj[key] = value;
|
|
400
|
+
}
|
|
401
|
+
return obj;
|
|
402
|
+
}
|
|
358
403
|
/**
|
|
359
404
|
* A stream that can read and write to files.
|
|
360
405
|
*
|
|
@@ -365,18 +410,6 @@ function resolvePathLike(path) {
|
|
|
365
410
|
* that's under a certain size threshold will store it in memory for
|
|
366
411
|
* later retrieval.
|
|
367
412
|
*/ class ZStreamFile {
|
|
368
|
-
options;
|
|
369
|
-
static FileSizeDefault = 102400;
|
|
370
|
-
static MaxFilesDefault = 1000;
|
|
371
|
-
_cache = new Map();
|
|
372
|
-
/**
|
|
373
|
-
* Initializes a new instance of this object.
|
|
374
|
-
*
|
|
375
|
-
* @param options -
|
|
376
|
-
* The options for file read and writes.
|
|
377
|
-
*/ constructor(options = {}){
|
|
378
|
-
this.options = options;
|
|
379
|
-
}
|
|
380
413
|
async read(path, options) {
|
|
381
414
|
const _path = resolvePathLike(path);
|
|
382
415
|
const stats = await promises.stat(_path);
|
|
@@ -425,7 +458,20 @@ function resolvePathLike(path) {
|
|
|
425
458
|
}
|
|
426
459
|
return item.buffer;
|
|
427
460
|
}
|
|
461
|
+
/**
|
|
462
|
+
* Initializes a new instance of this object.
|
|
463
|
+
*
|
|
464
|
+
* @param options -
|
|
465
|
+
* The options for file read and writes.
|
|
466
|
+
*/ constructor(options = {}){
|
|
467
|
+
_define_property(this, "options", void 0);
|
|
468
|
+
_define_property(this, "_cache", void 0);
|
|
469
|
+
this.options = options;
|
|
470
|
+
this._cache = new Map();
|
|
471
|
+
}
|
|
428
472
|
}
|
|
473
|
+
_define_property(ZStreamFile, "FileSizeDefault", 102400); // One Hundred KibiBytes
|
|
474
|
+
_define_property(ZStreamFile, "MaxFilesDefault", 1000);
|
|
429
475
|
|
|
430
476
|
exports.ZFileRepository = ZFileRepository;
|
|
431
477
|
exports.ZFileSystemNodeBuilder = ZFileSystemNodeBuilder;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/file-system/file-system-node.mts","../src/file-system/file-system-service.mts","../src/file-watch/file-watch.mts","../src/file-repository/file-repository.mts","../src/resolve-path-like/resolve-path-like.ts","../src/sleep-watch-delay/sleep-watch-delay.mts","../src/stream/stream-folder.mts","../src/stream/stream-file.mts"],"sourcesContent":["import { isUndefined, omitBy } from \"lodash-es\";\nimport type { Stats } from \"node:fs\";\n\n/**\n * Represents a type of a file system node.\n */\nexport enum ZFileSystemNodeType {\n File = \"file\",\n Folder = \"folder\",\n}\n\nexport interface IZFileSystemNode {\n /**\n * The absolute path of the node.\n */\n path: string;\n\n /**\n * The type of the node (file or folder).\n */\n type: ZFileSystemNodeType;\n\n /**\n * The creation date of the node.\n */\n created?: string;\n\n /**\n * The modification date of the node.\n */\n updated?: string;\n\n /**\n * The size of the node in bytes.\n */\n size?: bigint;\n}\n\n/**\n * Represents a builder for a file system node.\n */\nexport class ZFileSystemNodeBuilder {\n private _node: IZFileSystemNode;\n\n public constructor() {\n this._node = {\n path: \"/\",\n type: ZFileSystemNodeType.Folder,\n };\n }\n\n public created(at?: Date | string | undefined) {\n this._node.created = at instanceof Date ? at.toJSON() : at;\n return this;\n }\n\n public updated(at?: Date | string | undefined) {\n this._node.updated = at instanceof Date ? at.toJSON() : at;\n return this;\n }\n\n public size(bytes: bigint | number | undefined) {\n this._node.size = typeof bytes == \"number\" ? BigInt(bytes) : bytes;\n return this;\n }\n\n public path(path: string) {\n this._node.path = path;\n return this;\n }\n\n public type(type: ZFileSystemNodeType) {\n this._node.type = type;\n return this;\n }\n\n public file = this.type.bind(this, ZFileSystemNodeType.File);\n public folder = this.type.bind(this, ZFileSystemNodeType.Folder);\n\n public stats(s: Stats) {\n const builder = this.size(s.size).created(s.birthtime).updated(s.mtime);\n return s.isFile() ? builder.file() : builder.folder();\n }\n\n public build() {\n const clone = structuredClone(this._node);\n return omitBy(clone, isUndefined) as IZFileSystemNode;\n }\n}\n","import { glob } from \"glob\";\nimport { access } from \"node:fs/promises\";\nimport { dirname, isAbsolute, resolve } from \"node:path\";\nimport { cwd } from \"node:process\";\nimport type { IZFileSystemNode } from \"./file-system-node.mjs\";\nimport { ZFileSystemNodeBuilder } from \"./file-system-node.mjs\";\n\n/**\n * Represents options for searches.\n */\nexport interface IZFileSystemSearchOptions {\n /**\n * The directory to search in.\n *\n * If this is not set, then the cwd of the application is used.\n */\n cwd?: string;\n\n /**\n * A flag that determines whether or not to load the\n * file system information.\n *\n * This is true by default.\n */\n stat?: boolean;\n}\n\n/**\n * Represents options for directory walking.\n */\nexport interface IZFileSystemWalkOptions {\n /**\n * The starting directory.\n *\n * The default is the current working directory\n *\n * @see process.cwd for more information.\n */\n start?: string;\n\n /**\n * The directory to stop at.\n *\n * The default is the root of the file system.\n */\n stop?: string;\n\n /**\n * The type of mode that the path must support in order\n * to be approved.\n *\n * The default is undefined and left up to the node api.\n */\n mode?: number;\n}\n\n/**\n * Represents a service to enumerate the file system.\n */\nexport interface IZFileSystemService {\n /**\n * Gets information about a node.\n *\n * @param path -\n * The path to get information for.\n *\n * @returns\n * Information about the node.\n */\n info(path: string): Promise<IZFileSystemNode>;\n\n /**\n * Reads all nodes that match a pattern.\n *\n * @param pattern -\n * The pattern string to match against or a list\n * of patterns to match.\n * @param options -\n * The options for the search.\n *\n * @returns\n * A list of path strings that match the given patterns.\n */\n search(\n pattern: string | string[],\n options?: IZFileSystemSearchOptions,\n ): Promise<IZFileSystemNode[]>;\n\n /**\n * Walks up a directory tree to search for existence of a given path.\n *\n * @param search -\n * The path to search for. This is the candidate folder path that\n * may or may not exist somewhere from the start directory all the\n * way up the directory tree.\n * @param options -\n * The given options for the search.\n *\n * @returns\n * The fully qualified path to the first path that matches the search\n * starting at the options start or the current working directory if not\n * specified. Returns null if no such directory exists.\n *\n * @example\n *\n * ```ts\n * import { resolve } from 'path'\n *\n * // Find any folder named .vscode from the current working directory all the way\n * // up the directory tree. Returns null if no vscode directory can be found.\n * const service = new ZFileSystemService();\n * const vscode = service.walk('.vscode');\n *\n * // Walk the directory tree from the current script and find the .config folder.\n * const config = service.walk('.config', { start: __dirname });\n *\n * // Walk the directory tree from the current script and stop when we reach\n * // at most 2 directories up.\n * const start = __dirname;\n * const stop = resolve(__dirname, '../..');\n * const file = service.walk('path/to/file.json', { start, stop });\n * ```\n */\n walk(\n search: string,\n options?: IZFileSystemWalkOptions,\n ): Promise<string | null>;\n}\n\n/**\n * Represents a node implementation of a file system service.\n */\nexport class ZFileSystemService implements IZFileSystemService {\n public async info(path: string): Promise<IZFileSystemNode> {\n const [file] = await this.search(path);\n return file;\n }\n\n public async search(\n pattern: string | string[],\n options?: IZFileSystemSearchOptions,\n ): Promise<IZFileSystemNode[]> {\n const paths = await glob(pattern, {\n stat: true,\n ...options,\n withFileTypes: true,\n });\n\n return paths.map((path) => {\n let info = new ZFileSystemNodeBuilder()\n .path(path.fullpath())\n .created(path.birthtime)\n .updated(path.atime)\n .size(path.size);\n\n // Note that for folders, node will return the size of the underlying OS metadata,\n // hence, why we remove the size on the folder here.\n info = path.isFile() ? info.file() : info.folder().size(undefined);\n\n return info.build();\n });\n }\n\n public async walk(search: string, options?: IZFileSystemWalkOptions) {\n const start = options?.start || cwd();\n const stop = options?.stop || \"/\";\n const mode = options?.mode;\n\n const _test = async (path: string) => {\n try {\n await access(path, mode);\n return true;\n } catch {\n return false;\n }\n };\n\n if (isAbsolute(search)) {\n return (await _test(search)) ? search : null;\n }\n\n let dir = start;\n do {\n const path = resolve(dir, search);\n const exists = await _test(path);\n\n if (exists) {\n return path;\n }\n\n dir = dir === stop ? \"\" : dirname(dir);\n } while (dir.length);\n\n return null;\n }\n}\n","import type { FSWatcher } from \"chokidar\";\nimport { watch } from \"chokidar\";\nimport type { Stats } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { Observable } from \"rxjs\";\nimport { Subject } from \"rxjs\";\nimport {\n ZFileSystemNodeBuilder,\n type IZFileSystemNode,\n} from \"../file-system/file-system-node.mjs\";\n\n/**\n * Represents and object that can watch a folder or file on the file system.\n */\nexport interface IZFileWatch {\n /**\n * Starts the watch operation.\n */\n start(): Promise<void>;\n\n /**\n * Stops the watch operation.\n */\n stop(): Promise<void>;\n\n /**\n * The stream for files being added.\n *\n * This can only occur if the target being watched\n * is a folder.\n *\n * @returns\n * The observable that will publish files that\n * get added.\n */\n add(): Observable<IZFileSystemNode>;\n\n /**\n * The stream for files being updated.\n *\n * If this watcher points to a folder, then all files\n * recursively will send when they get updated. If this\n * watcher points to a file, then this will only invoke\n * when the file is updated.\n *\n * @returns\n * The observable that will publish files and folders\n * that are updated.\n */\n update(): Observable<IZFileSystemNode>;\n\n /**\n * The stream for files and folders being deleted.\n *\n * If this watcher points to a folder, then all files under the\n * folder will be sent through this observable, including the\n * folder being watched. If this points to a file, then\n * this will only receive when the file is unlinked.\n *\n * @returns\n * The observable that will publish file and folders\n * that are unlinked and removed respectively. Note\n * that files and folders streamed this way will not\n * have their stats set.\n */\n remove(): Observable<IZFileSystemNode>;\n}\n\n/**\n * An implementation of the IZFileWatch.\n */\nexport class ZFileWatch implements IZFileWatch {\n private _add: Subject<IZFileSystemNode> = new Subject<IZFileSystemNode>();\n private _update: Subject<IZFileSystemNode> = new Subject<IZFileSystemNode>();\n private _remove: Subject<IZFileSystemNode> = new Subject<IZFileSystemNode>();\n private _watcher: FSWatcher | undefined;\n\n /**\n * Initializes a new instance of this object.\n *\n * @param path -\n * The path to watch.\n */\n public constructor(public readonly path: string) {}\n\n public async start() {\n await this.stop();\n\n this._watcher = watch(this.path, {\n usePolling: true,\n alwaysStat: true,\n ignoreInitial: true,\n\n awaitWriteFinish: {\n stabilityThreshold: 500,\n pollInterval: 50,\n },\n });\n\n function next(\n observable: Subject<IZFileSystemNode>,\n file: string,\n stats: Stats | undefined,\n ) {\n const node = new ZFileSystemNodeBuilder().path(resolve(this.path, file));\n observable.next(stats ? node.stats(stats).build() : node.build());\n }\n\n this._watcher\n .on(\"add\", next.bind(this, this._add))\n .on(\"addDir\", next.bind(this, this._add))\n .on(\"change\", next.bind(this, this._update))\n .on(\"unlink\", next.bind(this, this._remove))\n .on(\"unlinkDir\", next.bind(this, this._remove));\n\n return new Promise<void>((resolve) =>\n this._watcher?.on(\"ready\", () => resolve()),\n );\n }\n\n public async stop() {\n await this._watcher?.close();\n delete this._watcher;\n return Promise.resolve();\n }\n\n public add() {\n return this._add.asObservable();\n }\n\n public update() {\n return this._update.asObservable();\n }\n\n public remove() {\n return this._remove.asObservable();\n }\n}\n","import { firstDefined, sleep } from \"@zthun/helpful-fn\";\nimport type { IZDataRequest, IZDataSource } from \"@zthun/helpful-query\";\nimport { ZDataSourceStatic } from \"@zthun/helpful-query\";\nimport { find, findIndex, flatten, trimEnd, uniqBy } from \"lodash-es\";\nimport { minimatch } from \"minimatch\";\nimport { resolve, sep } from \"node:path\";\nimport type { Subscription } from \"rxjs\";\nimport {\n ZFileSystemNodeType,\n type IZFileSystemNode,\n} from \"../file-system/file-system-node.mjs\";\nimport {\n ZFileSystemService,\n type IZFileSystemService,\n} from \"../file-system/file-system-service.mjs\";\nimport { ZFileWatch, type IZFileWatch } from \"../file-watch/file-watch.mjs\";\n\n/**\n * Represents a repository for the file system.\n */\nexport interface IZFileRepository extends IZDataSource<IZFileSystemNode> {\n /**\n * Retrieves a single file from the repository.\n *\n * @param path -\n * The fully qualified path to the file.\n *\n * @returns\n * The node that represents the file. Returns null if no\n * such file exists.\n */\n get(path: string): Promise<IZFileSystemNode | null>;\n}\n\n/**\n * Represents an implementation of a ZFileRepository that watches\n * a given path scope.\n *\n * This repository is only concerned about files. Folders\n * will not be retrieved from this repository.\n */\nexport class ZFileRepository implements IZFileRepository {\n private _service: IZFileSystemService = new ZFileSystemService();\n private _watcher: IZFileWatch | undefined;\n private _nodes: Promise<ZDataSourceStatic<IZFileSystemNode>> =\n Promise.resolve(new ZDataSourceStatic<IZFileSystemNode>([]));\n private _globs: string[] = [\"**\"];\n private _path: string = \"\";\n private _add: Subscription | undefined;\n private _remove: Subscription | undefined;\n private _update: Subscription | undefined;\n\n /**\n * Gets the path that this repository is watching.\n */\n public get path() {\n return this._path;\n }\n\n /**\n * Gets the globs matchers that this repository is matching against.\n */\n public get globs() {\n return this._globs.slice();\n }\n\n /**\n * Initializes the repository with the given root and glob filter.\n *\n * This will initially scan the file system and setup watches.\n * If you call this method again, then the repository will be\n * {@link reset} and a new set of files will be added to the\n * repository.\n *\n * @param path -\n * The root path of the repository.\n * @param globs -\n * The optional relative globs of the repository. If this is falsy,\n * then ** is used. You can achieve the same kind of operation\n * using filters, but filtering out unwanted files frees up the internal\n * memory being used.\n */\n public async initialize(path: string, globs: string[] = [\"**\"]) {\n await this.reset();\n\n this._path = path;\n this._globs = globs;\n\n // Note that this all happens in the background and should\n // only be awaited later. So the search should not be\n // required to finish when existing this method. The only\n // requirement is that the repository is reset and the path +\n // glob scope is updated. Everything beyond here should not\n // be awaited - it will be awaited later once the caller\n // tries to retrieve the files using retrieve, get, or\n // count.\n const matches = globs.map((g) =>\n this._service.search(g, {\n cwd: path,\n stat: true,\n }),\n );\n\n this._nodes = Promise.all(matches)\n .then((nodes) => {\n const flat = flatten(nodes);\n const uniq = uniqBy(flat, (n) => n.path);\n return uniq.filter((n) => n.type === ZFileSystemNodeType.File);\n })\n .then((files) => {\n return new ZDataSourceStatic(files);\n });\n\n this._watcher = new ZFileWatch(path);\n\n this._add = this._watcher\n .add()\n .subscribe(async (node: IZFileSystemNode) => {\n if (\n node.type === ZFileSystemNodeType.File &&\n this._globs.some((g) => minimatch(node.path, resolve(this._path, g)))\n ) {\n const nodes = await this._nodes;\n this._nodes = nodes.insert(node);\n }\n });\n\n this._remove = this._watcher\n .remove()\n .subscribe(async (node: IZFileSystemNode) => {\n let nodes = await this._nodes;\n const path = trimEnd(node.path, sep);\n\n // It's possible that the node given was a folder. If that happens,\n // we need to remove all files that start with the given path.\n // If the node does point to a file, then there is no possibility that\n // more than 1 item would be removed.\n\n const next = async () =>\n findIndex(await nodes.items(), (n) => {\n return (\n n.path === path ||\n (n.path.startsWith(path) &&\n n.path.substring(path.length).charAt(0) === sep)\n );\n });\n\n for (let index = await next(); index >= 0; index = await next()) {\n nodes = await nodes.removeAt(index);\n }\n\n this._nodes = Promise.resolve(nodes);\n });\n\n this._update = this._watcher\n .update()\n .subscribe(async (node: IZFileSystemNode) => {\n const nodes = await this._nodes;\n const index = findIndex(\n await nodes.items(),\n (n) => n.path === node.path,\n );\n\n // It's possible node was filtered out by the globs, or\n // it is a directory. If so, then we won't have it in our\n // list.\n if (index >= 0) {\n const next = await nodes.removeAt(index);\n this._nodes = next.insert(node, index);\n }\n });\n\n // Kick off the initial seed operation with an even loop\n // invocation.\n await sleep(100);\n\n await this._watcher.start();\n }\n\n /**\n * Resets the repository as if it was initially created.\n */\n public async reset(): Promise<void> {\n await this._watcher?.stop();\n\n this._add?.unsubscribe();\n this._remove?.unsubscribe();\n this._update?.unsubscribe();\n\n delete this._add;\n delete this._remove;\n delete this._update;\n delete this._watcher;\n\n this._path = \"\";\n this._globs = [\"**\"];\n this._nodes = Promise.resolve(new ZDataSourceStatic<IZFileSystemNode>([]));\n }\n\n public async get(path: string): Promise<IZFileSystemNode | null> {\n const nodes = await this._nodes;\n const items = await nodes.items();\n const node = find(items, (f) => f.path === path);\n\n return firstDefined(null, node);\n }\n\n public async count(request: IZDataRequest): Promise<number> {\n const source = await this._nodes;\n return source.count(request);\n }\n\n public async retrieve(request: IZDataRequest): Promise<IZFileSystemNode[]> {\n const source = await this._nodes;\n return source.retrieve(request);\n }\n}\n","import type { PathLike } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nexport function resolvePathLike(path: PathLike): string {\n if (typeof path === \"string\") {\n return resolve(path);\n }\n\n if (path instanceof URL) {\n return fileURLToPath(path);\n }\n\n return resolve(path.toString());\n}\n","import { sleep } from \"@zthun/helpful-fn\";\n\n/**\n * The actual delay time that you should wait for a watch\n * operation to pick up your file changes.\n */\nexport const ZWatchDelay = 1500;\n\n/**\n * Performs a sleep long enough to allow a watch operation\n * to pick up a change.\n *\n * You should never really need this. Where it is useful\n * is for unit testing with IO operations and you want to\n * wait for your write operations to get picked up by\n * a file watch operation.\n */\nexport function sleepWatchDelay() {\n return sleep(ZWatchDelay);\n}\n","import type { PathLike } from \"fs\";\nimport { mkdir, stat } from \"fs/promises\";\nimport type { IZStreamWrite } from \"./stream-write.mjs\";\n\n/**\n * A stream that writes folders.\n *\n * Writing folders is idempotent. If the folder you\n * are trying to write already exists, then the write\n * operation still succeeds\n */\nexport class ZStreamFolder implements IZStreamWrite {\n public async write(path: PathLike): Promise<number> {\n try {\n await mkdir(path, { recursive: true });\n } catch {\n // The folder may exist, but if it is a file then\n // we have a conflict and in that case, we will throw an\n // error. We are going to let stat fail if it cannot\n // access the path (permission error).\n const stats = await stat(path);\n\n if (stats.isFile()) {\n const msg = `Cannot create folder, ${path}, because a file with the same name exists at the target location`;\n throw new Error(msg);\n }\n }\n\n return 0;\n }\n}\n","import type { PathLike, Stats } from \"node:fs\";\nimport { readFile, stat, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"path\";\nimport { resolvePathLike } from \"../resolve-path-like/resolve-path-like.js\";\nimport { ZStreamFolder } from \"./stream-folder.mjs\";\nimport type { IZStreamRead, IZStreamReadOptions } from \"./stream-read.mjs\";\nimport type { IZStreamWrite, IZStreamWriteOptions } from \"./stream-write.mjs\";\n\n/**\n * Options for the stream file object.\n */\nexport interface IZStreamFileOptions {\n /**\n * Cache options.\n *\n * A warning that file content caching will take up significant memory\n * if the file size is too big or the max files is too big. Make sure\n * you know what you're doing when you change the default values of this.\n */\n cache?: {\n /**\n * Maximum number of bytes a file can be before it will not be cached.\n * The default is 100 Kib (102400 bytes)\n *\n * @default 102400\n */\n fileSize?: bigint;\n /**\n * The maximum number of files that are to be cached. The cache order\n * is first in, first out. Set this to 0 to not cache anything. The\n * default is 1000.\n *\n * @default 1000\n */\n maxFiles?: number;\n };\n}\n\n/**\n * A stream that can read and write to files.\n *\n * This is mostly a wrapper to readFile and writeFile from node, but\n * with some optimizations.\n *\n * First, this class supports file content caching so reading in a file\n * that's under a certain size threshold will store it in memory for\n * later retrieval.\n */\nexport class ZStreamFile implements IZStreamWrite, IZStreamRead {\n private static readonly FileSizeDefault = 102400; // One Hundred KibiBytes\n private static readonly MaxFilesDefault = 1000;\n\n private _cache = new Map<string, { stats: Stats; buffer: Promise<Buffer> }>();\n\n /**\n * Initializes a new instance of this object.\n *\n * @param options -\n * The options for file read and writes.\n */\n public constructor(public readonly options: IZStreamFileOptions = {}) {}\n\n public async read(\n path: PathLike,\n options?: IZStreamReadOptions,\n ): Promise<Buffer> {\n const _path = resolvePathLike(path);\n\n const stats = await stat(_path);\n const cached = this._cache.get(_path);\n\n const buffer =\n cached && cached.stats.mtimeMs >= stats.mtimeMs\n ? cached.buffer\n : readFile(_path, options);\n\n return this._addToCache(_path, { stats, buffer });\n }\n\n public async write(\n path: PathLike,\n { buffer = Buffer.from(\"\") }: IZStreamWriteOptions = {},\n ): Promise<number> {\n const _path = resolvePathLike(path);\n const directory = dirname(_path);\n\n await new ZStreamFolder().write(directory);\n await writeFile(_path, buffer, { flush: true });\n\n // If this file specifically was cached earlier,\n // we can just remove it now so we make room for\n // another file. Consumers can just read the\n // file again to recache it.\n this._cache.delete(_path);\n\n return buffer.length;\n }\n\n private _addToCache(\n path: string,\n item: { stats: Stats; buffer: Promise<Buffer> },\n ) {\n const { cache = {} } = this.options;\n const {\n fileSize = ZStreamFile.FileSizeDefault,\n maxFiles = ZStreamFile.MaxFilesDefault,\n } = cache;\n\n if (item.stats.size > fileSize) {\n // In this case, the file size is too big to cache in memory,\n // so we're bowing out here.\n return item.buffer;\n }\n\n // We will remove this path from the cache first since\n // we want it to be the most recent file (at the end)\n // of the key list. The removal does nothing if the\n // file was not cached.\n this._cache.delete(path);\n this._cache.set(path, item);\n\n if (this._cache.size > maxFiles) {\n // Retrieving the keys from a javascript map is order\n // by the time in which the keys are created. So\n // we are going to remove the first key which is the\n // oldest.\n const itr = this._cache.keys();\n this._cache.delete(itr.next().value);\n }\n\n return item.buffer;\n }\n}\n"],"names":["ZFileSystemNodeType","ZFileSystemNodeBuilder","_node","path","type","created","at","Date","toJSON","updated","size","bytes","BigInt","file","bind","folder","stats","s","builder","birthtime","mtime","isFile","build","clone","structuredClone","omitBy","isUndefined","ZFileSystemService","info","search","pattern","options","paths","glob","stat","withFileTypes","map","fullpath","atime","undefined","walk","start","cwd","stop","mode","_test","access","isAbsolute","dir","resolve","exists","dirname","length","ZFileWatch","_add","Subject","_update","_remove","_watcher","watch","usePolling","alwaysStat","ignoreInitial","awaitWriteFinish","stabilityThreshold","pollInterval","next","observable","node","on","Promise","close","add","asObservable","update","remove","ZFileRepository","_service","_nodes","ZDataSourceStatic","_globs","_path","globs","slice","initialize","reset","matches","g","all","then","nodes","flat","flatten","uniq","uniqBy","n","filter","File","files","subscribe","some","minimatch","insert","trimEnd","sep","findIndex","items","startsWith","substring","charAt","index","removeAt","sleep","unsubscribe","get","find","f","firstDefined","count","request","source","retrieve","resolvePathLike","URL","fileURLToPath","toString","ZWatchDelay","sleepWatchDelay","ZStreamFolder","write","mkdir","recursive","msg","Error","ZStreamFile","FileSizeDefault","MaxFilesDefault","_cache","Map","read","cached","buffer","mtimeMs","readFile","_addToCache","Buffer","from","directory","writeFile","flush","delete","item","cache","fileSize","maxFiles","set","itr","keys","value"],"mappings":";;;;;;;;;;;;;;;;;;AAGA;;IAGO,IAAKA,mBAAAA,iBAAAA,SAAAA,mBAAAA,EAAAA;;;AAAAA,IAAAA,OAAAA,mBAAAA;AAGX,CAAA,CAAA,EAAA;AA6BD;;AAEC,IACM,MAAMC,sBAAAA,CAAAA;IACHC,KAAAA;IAER,WAAA,EAAqB;QACnB,IAAI,CAACA,KAAK,GAAG;YACXC,IAAAA,EAAM,GAAA;YACNC,IAAI,EAAA;AACN,SAAA;AACF,IAAA;AAEOC,IAAAA,OAAAA,CAAQC,EAA8B,EAAE;QAC7C,IAAI,CAACJ,KAAK,CAACG,OAAO,GAAGC,EAAAA,YAAcC,IAAAA,GAAOD,EAAAA,CAAGE,MAAM,EAAA,GAAKF,EAAAA;AACxD,QAAA,OAAO,IAAI;AACb,IAAA;AAEOG,IAAAA,OAAAA,CAAQH,EAA8B,EAAE;QAC7C,IAAI,CAACJ,KAAK,CAACO,OAAO,GAAGH,EAAAA,YAAcC,IAAAA,GAAOD,EAAAA,CAAGE,MAAM,EAAA,GAAKF,EAAAA;AACxD,QAAA,OAAO,IAAI;AACb,IAAA;AAEOI,IAAAA,IAAAA,CAAKC,KAAkC,EAAE;QAC9C,IAAI,CAACT,KAAK,CAACQ,IAAI,GAAG,OAAOC,KAAAA,IAAS,QAAA,GAAWC,MAAAA,CAAOD,KAAAA,CAAAA,GAASA,KAAAA;AAC7D,QAAA,OAAO,IAAI;AACb,IAAA;AAEOR,IAAAA,IAAAA,CAAKA,IAAY,EAAE;AACxB,QAAA,IAAI,CAACD,KAAK,CAACC,IAAI,GAAGA,IAAAA;AAClB,QAAA,OAAO,IAAI;AACb,IAAA;AAEOC,IAAAA,IAAAA,CAAKA,IAAyB,EAAE;AACrC,QAAA,IAAI,CAACF,KAAK,CAACE,IAAI,GAAGA,IAAAA;AAClB,QAAA,OAAO,IAAI;AACb,IAAA;AAEOS,IAAAA,IAAAA,GAAO,IAAI,CAACT,IAAI,CAACU,IAAI,CAAC,IAAI,EAAA,MAAA,CAAA;AAC1BC,IAAAA,MAAAA,GAAS,IAAI,CAACX,IAAI,CAACU,IAAI,CAAC,IAAI,EAAA,QAAA,CAAA;AAE5BE,IAAAA,KAAAA,CAAMC,CAAQ,EAAE;AACrB,QAAA,MAAMC,UAAU,IAAI,CAACR,IAAI,CAACO,EAAEP,IAAI,CAAA,CAAEL,OAAO,CAACY,EAAEE,SAAS,CAAA,CAAEV,OAAO,CAACQ,EAAEG,KAAK,CAAA;AACtE,QAAA,OAAOH,EAAEI,MAAM,EAAA,GAAKH,QAAQL,IAAI,EAAA,GAAKK,QAAQH,MAAM,EAAA;AACrD,IAAA;IAEOO,KAAAA,GAAQ;AACb,QAAA,MAAMC,KAAAA,GAAQC,eAAAA,CAAgB,IAAI,CAACtB,KAAK,CAAA;AACxC,QAAA,OAAOuB,gBAAOF,KAAAA,EAAOG,oBAAAA,CAAAA;AACvB,IAAA;AACF;;ACyCA;;AAEC,IACM,MAAMC,kBAAAA,CAAAA;IACX,MAAaC,IAAAA,CAAKzB,IAAY,EAA6B;AACzD,QAAA,MAAM,CAACU,IAAAA,CAAK,GAAG,MAAM,IAAI,CAACgB,MAAM,CAAC1B,IAAAA,CAAAA;QACjC,OAAOU,IAAAA;AACT,IAAA;AAEA,IAAA,MAAagB,MAAAA,CACXC,OAA0B,EAC1BC,OAAmC,EACN;QAC7B,MAAMC,KAAAA,GAAQ,MAAMC,SAAAA,CAAKH,OAAAA,EAAS;YAChCI,IAAAA,EAAM,IAAA;AACN,YAAA,GAAGH,OAAO;YACVI,aAAAA,EAAe;AACjB,SAAA,CAAA;QAEA,OAAOH,KAAAA,CAAMI,GAAG,CAAC,CAACjC,IAAAA,GAAAA;YAChB,IAAIyB,IAAAA,GAAO,IAAI3B,sBAAAA,EAAAA,CACZE,IAAI,CAACA,IAAAA,CAAKkC,QAAQ,IAClBhC,OAAO,CAACF,KAAKgB,SAAS,CAAA,CACtBV,OAAO,CAACN,IAAAA,CAAKmC,KAAK,CAAA,CAClB5B,IAAI,CAACP,IAAAA,CAAKO,IAAI,CAAA;;;YAIjBkB,IAAAA,GAAOzB,IAAAA,CAAKkB,MAAM,EAAA,GAAKO,IAAAA,CAAKf,IAAI,KAAKe,IAAAA,CAAKb,MAAM,EAAA,CAAGL,IAAI,CAAC6B,SAAAA,CAAAA;AAExD,YAAA,OAAOX,KAAKN,KAAK,EAAA;AACnB,QAAA,CAAA,CAAA;AACF,IAAA;AAEA,IAAA,MAAakB,IAAAA,CAAKX,MAAc,EAAEE,OAAiC,EAAE;QACnE,MAAMU,KAAAA,GAAQV,SAASU,KAAAA,IAASC,gBAAAA,EAAAA;QAChC,MAAMC,IAAAA,GAAOZ,SAASY,IAAAA,IAAQ,GAAA;AAC9B,QAAA,MAAMC,OAAOb,OAAAA,EAASa,IAAAA;AAEtB,QAAA,MAAMC,QAAQ,OAAO1C,IAAAA,GAAAA;YACnB,IAAI;AACF,gBAAA,MAAM2C,gBAAO3C,IAAAA,EAAMyC,IAAAA,CAAAA;gBACnB,OAAO,IAAA;AACT,YAAA,CAAA,CAAE,OAAM;gBACN,OAAO,KAAA;AACT,YAAA;AACF,QAAA,CAAA;AAEA,QAAA,IAAIG,qBAAWlB,MAAAA,CAAAA,EAAS;AACtB,YAAA,OAAO,MAAOgB,KAAAA,CAAMhB,MAAAA,CAAAA,GAAWA,MAAAA,GAAS,IAAA;AAC1C,QAAA;AAEA,QAAA,IAAImB,GAAAA,GAAMP,KAAAA;QACV,GAAG;YACD,MAAMtC,IAAAA,GAAO8C,kBAAQD,GAAAA,EAAKnB,MAAAA,CAAAA;YAC1B,MAAMqB,MAAAA,GAAS,MAAML,KAAAA,CAAM1C,IAAAA,CAAAA;AAE3B,YAAA,IAAI+C,MAAAA,EAAQ;gBACV,OAAO/C,IAAAA;AACT,YAAA;YAEA6C,GAAAA,GAAMA,GAAAA,KAAQL,IAAAA,GAAO,EAAA,GAAKQ,iBAAAA,CAAQH,GAAAA,CAAAA;QACpC,CAAA,OAASA,GAAAA,CAAII,MAAM;QAEnB,OAAO,IAAA;AACT,IAAA;AACF;;AC/HA;;AAEC,IACM,MAAMC,UAAAA,CAAAA;;AACHC,IAAAA,IAAAA,GAAkC,IAAIC,YAAAA,EAAAA;AACtCC,IAAAA,OAAAA,GAAqC,IAAID,YAAAA,EAAAA;AACzCE,IAAAA,OAAAA,GAAqC,IAAIF,YAAAA,EAAAA;IACzCG,QAAAA;AAER;;;;;MAMA,WAAA,CAAmB,IAA4B,CAAE;aAAdvD,IAAAA,GAAAA,IAAAA;AAAe,IAAA;AAElD,IAAA,MAAasC,KAAAA,GAAQ;QACnB,MAAM,IAAI,CAACE,IAAI,EAAA;AAEf,QAAA,IAAI,CAACe,QAAQ,GAAGC,eAAM,IAAI,CAACxD,IAAI,EAAE;YAC/ByD,UAAAA,EAAY,IAAA;YACZC,UAAAA,EAAY,IAAA;YACZC,aAAAA,EAAe,IAAA;YAEfC,gBAAAA,EAAkB;gBAChBC,kBAAAA,EAAoB,GAAA;gBACpBC,YAAAA,EAAc;AAChB;AACF,SAAA,CAAA;AAEA,QAAA,SAASC,IAAAA,CACPC,UAAqC,EACrCtD,IAAY,EACZG,KAAwB,EAAA;YAExB,MAAMoD,IAAAA,GAAO,IAAInE,sBAAAA,EAAAA,CAAyBE,IAAI,CAAC8C,iBAAAA,CAAQ,IAAI,CAAC9C,IAAI,EAAEU,IAAAA,CAAAA,CAAAA;YAClEsD,UAAAA,CAAWD,IAAI,CAAClD,KAAAA,GAAQoD,IAAAA,CAAKpD,KAAK,CAACA,KAAAA,CAAAA,CAAOM,KAAK,EAAA,GAAK8C,IAAAA,CAAK9C,KAAK,EAAA,CAAA;AAChE,QAAA;AAEA,QAAA,IAAI,CAACoC,QAAQ,CACVW,EAAE,CAAC,KAAA,EAAOH,IAAAA,CAAKpD,IAAI,CAAC,IAAI,EAAE,IAAI,CAACwC,IAAI,CAAA,CAAA,CACnCe,EAAE,CAAC,QAAA,EAAUH,IAAAA,CAAKpD,IAAI,CAAC,IAAI,EAAE,IAAI,CAACwC,IAAI,CAAA,CAAA,CACtCe,EAAE,CAAC,QAAA,EAAUH,IAAAA,CAAKpD,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC0C,OAAO,CAAA,CAAA,CACzCa,EAAE,CAAC,QAAA,EAAUH,IAAAA,CAAKpD,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC2C,OAAO,CAAA,CAAA,CACzCY,EAAE,CAAC,WAAA,EAAaH,IAAAA,CAAKpD,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC2C,OAAO,CAAA,CAAA;QAE/C,OAAO,IAAIa,OAAAA,CAAc,CAACrB,OAAAA,GACxB,IAAI,CAACS,QAAQ,EAAEW,EAAAA,CAAG,OAAA,EAAS,IAAMpB,OAAAA,EAAAA,CAAAA,CAAAA;AAErC,IAAA;AAEA,IAAA,MAAaN,IAAAA,GAAO;QAClB,MAAM,IAAI,CAACe,QAAQ,EAAEa,KAAAA,EAAAA;QACrB,OAAO,IAAI,CAACb,QAAQ;AACpB,QAAA,OAAOY,QAAQrB,OAAO,EAAA;AACxB,IAAA;IAEOuB,GAAAA,GAAM;AACX,QAAA,OAAO,IAAI,CAAClB,IAAI,CAACmB,YAAY,EAAA;AAC/B,IAAA;IAEOC,MAAAA,GAAS;AACd,QAAA,OAAO,IAAI,CAAClB,OAAO,CAACiB,YAAY,EAAA;AAClC,IAAA;IAEOE,MAAAA,GAAS;AACd,QAAA,OAAO,IAAI,CAAClB,OAAO,CAACgB,YAAY,EAAA;AAClC,IAAA;AACF;;ACvGA;;;;;;AAMC,IACM,MAAMG,eAAAA,CAAAA;AACHC,IAAAA,QAAAA,GAAgC,IAAIlD,kBAAAA,EAAAA;IACpC+B,QAAAA;AACAoB,IAAAA,MAAAA,GACNR,QAAQrB,OAAO,CAAC,IAAI8B,8BAAAA,CAAoC,EAAE,CAAA,CAAA;IACpDC,MAAAA,GAAmB;AAAC,QAAA;KAAK;AACzBC,IAAAA,KAAAA,GAAgB,EAAA;IAChB3B,IAAAA;IACAG,OAAAA;IACAD,OAAAA;AAER;;AAEC,MACD,IAAWrD,IAAAA,GAAO;QAChB,OAAO,IAAI,CAAC8E,KAAK;AACnB,IAAA;AAEA;;AAEC,MACD,IAAWC,KAAAA,GAAQ;AACjB,QAAA,OAAO,IAAI,CAACF,MAAM,CAACG,KAAK,EAAA;AAC1B,IAAA;AAEA;;;;;;;;;;;;;;;AAeC,MACD,MAAaC,UAAAA,CAAWjF,IAAY,EAAE+E,KAAAA,GAAkB;AAAC,QAAA;KAAK,EAAE;QAC9D,MAAM,IAAI,CAACG,KAAK,EAAA;QAEhB,IAAI,CAACJ,KAAK,GAAG9E,IAAAA;QACb,IAAI,CAAC6E,MAAM,GAAGE,KAAAA;;;;;;;;;AAUd,QAAA,MAAMI,OAAAA,GAAUJ,KAAAA,CAAM9C,GAAG,CAAC,CAACmD,CAAAA,GACzB,IAAI,CAACV,QAAQ,CAAChD,MAAM,CAAC0D,CAAAA,EAAG;gBACtB7C,GAAAA,EAAKvC,IAAAA;gBACL+B,IAAAA,EAAM;AACR,aAAA,CAAA,CAAA;QAGF,IAAI,CAAC4C,MAAM,GAAGR,OAAAA,CAAQkB,GAAG,CAACF,OAAAA,CAAAA,CACvBG,IAAI,CAAC,CAACC,KAAAA,GAAAA;AACL,YAAA,MAAMC,OAAOC,gBAAAA,CAAQF,KAAAA,CAAAA;AACrB,YAAA,MAAMG,OAAOC,eAAAA,CAAOH,IAAAA,EAAM,CAACI,CAAAA,GAAMA,EAAE5F,IAAI,CAAA;YACvC,OAAO0F,IAAAA,CAAKG,MAAM,CAAC,CAACD,IAAMA,CAAAA,CAAE3F,IAAI,KAAKJ,mBAAAA,CAAoBiG,IAAI,CAAA;QAC/D,CAAA,CAAA,CACCR,IAAI,CAAC,CAACS,KAAAA,GAAAA;AACL,YAAA,OAAO,IAAInB,8BAAAA,CAAkBmB,KAAAA,CAAAA;AAC/B,QAAA,CAAA,CAAA;AAEF,QAAA,IAAI,CAACxC,QAAQ,GAAG,IAAIL,UAAAA,CAAWlD,IAAAA,CAAAA;QAE/B,IAAI,CAACmD,IAAI,GAAG,IAAI,CAACI,QAAQ,CACtBc,GAAG,EAAA,CACH2B,SAAS,CAAC,OAAO/B,IAAAA,GAAAA;YAChB,IACEA,IAAAA,CAAKhE,IAAI,KAAKJ,mBAAAA,CAAoBiG,IAAI,IACtC,IAAI,CAACjB,MAAM,CAACoB,IAAI,CAAC,CAACb,CAAAA,GAAMc,mBAAAA,CAAUjC,IAAAA,CAAKjE,IAAI,EAAE8C,kBAAQ,IAAI,CAACgC,KAAK,EAAEM,CAAAA,CAAAA,CAAAA,CAAAA,EACjE;AACA,gBAAA,MAAMG,KAAAA,GAAQ,MAAM,IAAI,CAACZ,MAAM;AAC/B,gBAAA,IAAI,CAACA,MAAM,GAAGY,KAAAA,CAAMY,MAAM,CAAClC,IAAAA,CAAAA;AAC7B,YAAA;AACF,QAAA,CAAA,CAAA;QAEF,IAAI,CAACX,OAAO,GAAG,IAAI,CAACC,QAAQ,CACzBiB,MAAM,EAAA,CACNwB,SAAS,CAAC,OAAO/B,IAAAA,GAAAA;AAChB,YAAA,IAAIsB,KAAAA,GAAQ,MAAM,IAAI,CAACZ,MAAM;AAC7B,YAAA,MAAM3E,IAAAA,GAAOoG,gBAAAA,CAAQnC,IAAAA,CAAKjE,IAAI,EAAEqG,aAAAA,CAAAA;;;;;AAOhC,YAAA,MAAMtC,OAAO,UACXuC,kBAAAA,CAAU,MAAMf,KAAAA,CAAMgB,KAAK,IAAI,CAACX,CAAAA,GAAAA;oBAC9B,OACEA,CAAAA,CAAE5F,IAAI,KAAKA,IAAAA,IACV4F,EAAE5F,IAAI,CAACwG,UAAU,CAACxG,IAAAA,CAAAA,IACjB4F,EAAE5F,IAAI,CAACyG,SAAS,CAACzG,IAAAA,CAAKiD,MAAM,CAAA,CAAEyD,MAAM,CAAC,CAAA,CAAA,KAAOL,aAAAA;AAElD,gBAAA,CAAA,CAAA;YAEF,IAAK,IAAIM,QAAQ,MAAM5C,IAAAA,EAAAA,EAAQ4C,SAAS,CAAA,EAAGA,KAAAA,GAAQ,MAAM5C,IAAAA,EAAAA,CAAQ;gBAC/DwB,KAAAA,GAAQ,MAAMA,KAAAA,CAAMqB,QAAQ,CAACD,KAAAA,CAAAA;AAC/B,YAAA;AAEA,YAAA,IAAI,CAAChC,MAAM,GAAGR,OAAAA,CAAQrB,OAAO,CAACyC,KAAAA,CAAAA;AAChC,QAAA,CAAA,CAAA;QAEF,IAAI,CAAClC,OAAO,GAAG,IAAI,CAACE,QAAQ,CACzBgB,MAAM,EAAA,CACNyB,SAAS,CAAC,OAAO/B,IAAAA,GAAAA;AAChB,YAAA,MAAMsB,KAAAA,GAAQ,MAAM,IAAI,CAACZ,MAAM;AAC/B,YAAA,MAAMgC,KAAAA,GAAQL,kBAAAA,CACZ,MAAMf,KAAAA,CAAMgB,KAAK,EAAA,EACjB,CAACX,CAAAA,GAAMA,CAAAA,CAAE5F,IAAI,KAAKiE,IAAAA,CAAKjE,IAAI,CAAA;;;;AAM7B,YAAA,IAAI2G,SAAS,CAAA,EAAG;AACd,gBAAA,MAAM5C,IAAAA,GAAO,MAAMwB,KAAAA,CAAMqB,QAAQ,CAACD,KAAAA,CAAAA;AAClC,gBAAA,IAAI,CAAChC,MAAM,GAAGZ,IAAAA,CAAKoC,MAAM,CAAClC,IAAAA,EAAM0C,KAAAA,CAAAA;AAClC,YAAA;AACF,QAAA,CAAA,CAAA;;;AAIF,QAAA,MAAME,eAAAA,CAAM,GAAA,CAAA;AAEZ,QAAA,MAAM,IAAI,CAACtD,QAAQ,CAACjB,KAAK,EAAA;AAC3B,IAAA;AAEA;;AAEC,MACD,MAAa4C,KAAAA,GAAuB;QAClC,MAAM,IAAI,CAAC3B,QAAQ,EAAEf,IAAAA,EAAAA;QAErB,IAAI,CAACW,IAAI,EAAE2D,WAAAA,EAAAA;QACX,IAAI,CAACxD,OAAO,EAAEwD,WAAAA,EAAAA;QACd,IAAI,CAACzD,OAAO,EAAEyD,WAAAA,EAAAA;QAEd,OAAO,IAAI,CAAC3D,IAAI;QAChB,OAAO,IAAI,CAACG,OAAO;QACnB,OAAO,IAAI,CAACD,OAAO;QACnB,OAAO,IAAI,CAACE,QAAQ;QAEpB,IAAI,CAACuB,KAAK,GAAG,EAAA;QACb,IAAI,CAACD,MAAM,GAAG;AAAC,YAAA;AAAK,SAAA;QACpB,IAAI,CAACF,MAAM,GAAGR,OAAAA,CAAQrB,OAAO,CAAC,IAAI8B,+BAAoC,EAAE,CAAA,CAAA;AAC1E,IAAA;IAEA,MAAamC,GAAAA,CAAI/G,IAAY,EAAoC;AAC/D,QAAA,MAAMuF,KAAAA,GAAQ,MAAM,IAAI,CAACZ,MAAM;QAC/B,MAAM4B,KAAAA,GAAQ,MAAMhB,KAAAA,CAAMgB,KAAK,EAAA;AAC/B,QAAA,MAAMtC,OAAO+C,aAAAA,CAAKT,KAAAA,EAAO,CAACU,CAAAA,GAAMA,CAAAA,CAAEjH,IAAI,KAAKA,IAAAA,CAAAA;AAE3C,QAAA,OAAOkH,uBAAa,IAAA,EAAMjD,IAAAA,CAAAA;AAC5B,IAAA;IAEA,MAAakD,KAAAA,CAAMC,OAAsB,EAAmB;AAC1D,QAAA,MAAMC,MAAAA,GAAS,MAAM,IAAI,CAAC1C,MAAM;QAChC,OAAO0C,MAAAA,CAAOF,KAAK,CAACC,OAAAA,CAAAA;AACtB,IAAA;IAEA,MAAaE,QAAAA,CAASF,OAAsB,EAA+B;AACzE,QAAA,MAAMC,MAAAA,GAAS,MAAM,IAAI,CAAC1C,MAAM;QAChC,OAAO0C,MAAAA,CAAOC,QAAQ,CAACF,OAAAA,CAAAA;AACzB,IAAA;AACF;;ACpNO,SAASG,gBAAgBvH,IAAc,EAAA;IAC5C,IAAI,OAAOA,SAAS,QAAA,EAAU;AAC5B,QAAA,OAAO8C,iBAAAA,CAAQ9C,IAAAA,CAAAA;AACjB,IAAA;AAEA,IAAA,IAAIA,gBAAgBwH,GAAAA,EAAK;AACvB,QAAA,OAAOC,sBAAAA,CAAczH,IAAAA,CAAAA;AACvB,IAAA;IAEA,OAAO8C,iBAAAA,CAAQ9C,KAAK0H,QAAQ,EAAA,CAAA;AAC9B;;ACZA;;;IAIO,MAAMC,WAAAA,GAAc;AAE3B;;;;;;;;AAQC,IACM,SAASC,eAAAA,GAAAA;AACd,IAAA,OAAOf,eAAAA,CAAMc,WAAAA,CAAAA;AACf;;ACfA;;;;;;AAMC,IACM,MAAME,aAAAA,CAAAA;IACX,MAAaC,KAAAA,CAAM9H,IAAc,EAAmB;QAClD,IAAI;AACF,YAAA,MAAM+H,iBAAM/H,IAAAA,EAAM;gBAAEgI,SAAAA,EAAW;AAAK,aAAA,CAAA;AACtC,QAAA,CAAA,CAAE,OAAM;;;;;YAKN,MAAMnH,KAAAA,GAAQ,MAAMkB,eAAAA,CAAK/B,IAAAA,CAAAA;YAEzB,IAAIa,KAAAA,CAAMK,MAAM,EAAA,EAAI;AAClB,gBAAA,MAAM+G,MAAM,CAAC,sBAAsB,EAAEjI,IAAAA,CAAK,iEAAiE,CAAC;AAC5G,gBAAA,MAAM,IAAIkI,KAAAA,CAAMD,GAAAA,CAAAA;AAClB,YAAA;AACF,QAAA;QAEA,OAAO,CAAA;AACT,IAAA;AACF;;ACQA;;;;;;;;;AASC,IACM,MAAME,WAAAA,CAAAA;;AACX,IAAA,OAAwBC,kBAAkB,MAAA;AAC1C,IAAA,OAAwBC,kBAAkB,IAAA;AAElCC,IAAAA,MAAAA,GAAS,IAAIC,GAAAA,EAAAA;AAErB;;;;;AAKC,MACD,WAAA,CAAmC3G,OAAAA,GAA+B,EAAE,CAAE;aAAnCA,OAAAA,GAAAA,OAAAA;AAAoC,IAAA;AAEvE,IAAA,MAAa4G,IAAAA,CACXxI,IAAc,EACd4B,OAA6B,EACZ;AACjB,QAAA,MAAMkD,QAAQyC,eAAAA,CAAgBvH,IAAAA,CAAAA;QAE9B,MAAMa,KAAAA,GAAQ,MAAMkB,aAAAA,CAAK+C,KAAAA,CAAAA;AACzB,QAAA,MAAM2D,SAAS,IAAI,CAACH,MAAM,CAACvB,GAAG,CAACjC,KAAAA,CAAAA;AAE/B,QAAA,MAAM4D,MAAAA,GACJD,MAAAA,IAAUA,MAAAA,CAAO5H,KAAK,CAAC8H,OAAO,IAAI9H,KAAAA,CAAM8H,OAAO,GAC3CF,MAAAA,CAAOC,MAAM,GACbE,kBAAS9D,KAAAA,EAAOlD,OAAAA,CAAAA;AAEtB,QAAA,OAAO,IAAI,CAACiH,WAAW,CAAC/D,KAAAA,EAAO;AAAEjE,YAAAA,KAAAA;AAAO6H,YAAAA;AAAO,SAAA,CAAA;AACjD,IAAA;AAEA,IAAA,MAAaZ,KAAAA,CACX9H,MAAc,EACd,EAAE0I,MAAAA,GAASI,MAAAA,CAAOC,IAAI,CAAC,EAAA,CAAG,EAAwB,GAAG,EAAE,EACtC;AACjB,QAAA,MAAMjE,QAAQyC,eAAAA,CAAgBvH,MAAAA,CAAAA;AAC9B,QAAA,MAAMgJ,YAAYhG,YAAAA,CAAQ8B,KAAAA,CAAAA;QAE1B,MAAM,IAAI+C,aAAAA,EAAAA,CAAgBC,KAAK,CAACkB,SAAAA,CAAAA;QAChC,MAAMC,kBAAAA,CAAUnE,OAAO4D,MAAAA,EAAQ;YAAEQ,KAAAA,EAAO;AAAK,SAAA,CAAA;;;;;AAM7C,QAAA,IAAI,CAACZ,MAAM,CAACa,MAAM,CAACrE,KAAAA,CAAAA;AAEnB,QAAA,OAAO4D,OAAOzF,MAAM;AACtB,IAAA;IAEQ4F,WAAAA,CACN7I,IAAY,EACZoJ,IAA+C,EAC/C;QACA,MAAM,EAAEC,QAAQ,EAAE,EAAE,GAAG,IAAI,CAACzH,OAAO;QACnC,MAAM,EACJ0H,WAAWnB,WAAAA,CAAYC,eAAe,EACtCmB,QAAAA,GAAWpB,WAAAA,CAAYE,eAAe,EACvC,GAAGgB,KAAAA;AAEJ,QAAA,IAAID,IAAAA,CAAKvI,KAAK,CAACN,IAAI,GAAG+I,QAAAA,EAAU;;;AAG9B,YAAA,OAAOF,KAAKV,MAAM;AACpB,QAAA;;;;;AAMA,QAAA,IAAI,CAACJ,MAAM,CAACa,MAAM,CAACnJ,IAAAA,CAAAA;AACnB,QAAA,IAAI,CAACsI,MAAM,CAACkB,GAAG,CAACxJ,IAAAA,EAAMoJ,IAAAA,CAAAA;AAEtB,QAAA,IAAI,IAAI,CAACd,MAAM,CAAC/H,IAAI,GAAGgJ,QAAAA,EAAU;;;;;AAK/B,YAAA,MAAME,GAAAA,GAAM,IAAI,CAACnB,MAAM,CAACoB,IAAI,EAAA;YAC5B,IAAI,CAACpB,MAAM,CAACa,MAAM,CAACM,GAAAA,CAAI1F,IAAI,GAAG4F,KAAK,CAAA;AACrC,QAAA;AAEA,QAAA,OAAOP,KAAKV,MAAM;AACpB,IAAA;AACF;;;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/file-system/file-system-node.mts","../src/file-system/file-system-service.mts","../src/file-watch/file-watch.mts","../src/file-repository/file-repository.mts","../src/resolve-path-like/resolve-path-like.ts","../src/sleep-watch-delay/sleep-watch-delay.mts","../src/stream/stream-folder.mts","../src/stream/stream-file.mts"],"sourcesContent":["import { isUndefined, omitBy } from \"lodash-es\";\nimport type { Stats } from \"node:fs\";\n\n/**\n * Represents a type of a file system node.\n */\nexport enum ZFileSystemNodeType {\n File = \"file\",\n Folder = \"folder\",\n}\n\nexport interface IZFileSystemNode {\n /**\n * The absolute path of the node.\n */\n path: string;\n\n /**\n * The type of the node (file or folder).\n */\n type: ZFileSystemNodeType;\n\n /**\n * The creation date of the node.\n */\n created?: string;\n\n /**\n * The modification date of the node.\n */\n updated?: string;\n\n /**\n * The size of the node in bytes.\n */\n size?: bigint;\n}\n\n/**\n * Represents a builder for a file system node.\n */\nexport class ZFileSystemNodeBuilder {\n private _node: IZFileSystemNode;\n\n public constructor() {\n this._node = {\n path: \"/\",\n type: ZFileSystemNodeType.Folder,\n };\n }\n\n public created(at?: Date | string | undefined) {\n this._node.created = at instanceof Date ? at.toJSON() : at;\n return this;\n }\n\n public updated(at?: Date | string | undefined) {\n this._node.updated = at instanceof Date ? at.toJSON() : at;\n return this;\n }\n\n public size(bytes: bigint | number | undefined) {\n this._node.size = typeof bytes == \"number\" ? BigInt(bytes) : bytes;\n return this;\n }\n\n public path(path: string) {\n this._node.path = path;\n return this;\n }\n\n public type(type: ZFileSystemNodeType) {\n this._node.type = type;\n return this;\n }\n\n public file = this.type.bind(this, ZFileSystemNodeType.File);\n public folder = this.type.bind(this, ZFileSystemNodeType.Folder);\n\n public stats(s: Stats) {\n const builder = this.size(s.size).created(s.birthtime).updated(s.mtime);\n return s.isFile() ? builder.file() : builder.folder();\n }\n\n public build() {\n const clone = structuredClone(this._node);\n return omitBy(clone, isUndefined) as IZFileSystemNode;\n }\n}\n","import { glob } from \"glob\";\nimport { access } from \"node:fs/promises\";\nimport { dirname, isAbsolute, resolve } from \"node:path\";\nimport { cwd } from \"node:process\";\nimport type { IZFileSystemNode } from \"./file-system-node.mjs\";\nimport { ZFileSystemNodeBuilder } from \"./file-system-node.mjs\";\n\n/**\n * Represents options for searches.\n */\nexport interface IZFileSystemSearchOptions {\n /**\n * The directory to search in.\n *\n * If this is not set, then the cwd of the application is used.\n */\n cwd?: string;\n\n /**\n * A flag that determines whether or not to load the\n * file system information.\n *\n * This is true by default.\n */\n stat?: boolean;\n}\n\n/**\n * Represents options for directory walking.\n */\nexport interface IZFileSystemWalkOptions {\n /**\n * The starting directory.\n *\n * The default is the current working directory\n *\n * @see process.cwd for more information.\n */\n start?: string;\n\n /**\n * The directory to stop at.\n *\n * The default is the root of the file system.\n */\n stop?: string;\n\n /**\n * The type of mode that the path must support in order\n * to be approved.\n *\n * The default is undefined and left up to the node api.\n */\n mode?: number;\n}\n\n/**\n * Represents a service to enumerate the file system.\n */\nexport interface IZFileSystemService {\n /**\n * Gets information about a node.\n *\n * @param path -\n * The path to get information for.\n *\n * @returns\n * Information about the node.\n */\n info(path: string): Promise<IZFileSystemNode>;\n\n /**\n * Reads all nodes that match a pattern.\n *\n * @param pattern -\n * The pattern string to match against or a list\n * of patterns to match.\n * @param options -\n * The options for the search.\n *\n * @returns\n * A list of path strings that match the given patterns.\n */\n search(\n pattern: string | string[],\n options?: IZFileSystemSearchOptions,\n ): Promise<IZFileSystemNode[]>;\n\n /**\n * Walks up a directory tree to search for existence of a given path.\n *\n * @param search -\n * The path to search for. This is the candidate folder path that\n * may or may not exist somewhere from the start directory all the\n * way up the directory tree.\n * @param options -\n * The given options for the search.\n *\n * @returns\n * The fully qualified path to the first path that matches the search\n * starting at the options start or the current working directory if not\n * specified. Returns null if no such directory exists.\n *\n * @example\n *\n * ```ts\n * import { resolve } from 'path'\n *\n * // Find any folder named .vscode from the current working directory all the way\n * // up the directory tree. Returns null if no vscode directory can be found.\n * const service = new ZFileSystemService();\n * const vscode = service.walk('.vscode');\n *\n * // Walk the directory tree from the current script and find the .config folder.\n * const config = service.walk('.config', { start: __dirname });\n *\n * // Walk the directory tree from the current script and stop when we reach\n * // at most 2 directories up.\n * const start = __dirname;\n * const stop = resolve(__dirname, '../..');\n * const file = service.walk('path/to/file.json', { start, stop });\n * ```\n */\n walk(\n search: string,\n options?: IZFileSystemWalkOptions,\n ): Promise<string | null>;\n}\n\n/**\n * Represents a node implementation of a file system service.\n */\nexport class ZFileSystemService implements IZFileSystemService {\n public async info(path: string): Promise<IZFileSystemNode> {\n const [file] = await this.search(path);\n return file;\n }\n\n public async search(\n pattern: string | string[],\n options?: IZFileSystemSearchOptions,\n ): Promise<IZFileSystemNode[]> {\n const paths = await glob(pattern, {\n stat: true,\n ...options,\n withFileTypes: true,\n });\n\n return paths.map((path) => {\n let info = new ZFileSystemNodeBuilder()\n .path(path.fullpath())\n .created(path.birthtime)\n .updated(path.atime)\n .size(path.size);\n\n // Note that for folders, node will return the size of the underlying OS metadata,\n // hence, why we remove the size on the folder here.\n info = path.isFile() ? info.file() : info.folder().size(undefined);\n\n return info.build();\n });\n }\n\n public async walk(search: string, options?: IZFileSystemWalkOptions) {\n const start = options?.start || cwd();\n const stop = options?.stop || \"/\";\n const mode = options?.mode;\n\n const _test = async (path: string) => {\n try {\n await access(path, mode);\n return true;\n } catch {\n return false;\n }\n };\n\n if (isAbsolute(search)) {\n return (await _test(search)) ? search : null;\n }\n\n let dir = start;\n do {\n const path = resolve(dir, search);\n const exists = await _test(path);\n\n if (exists) {\n return path;\n }\n\n dir = dir === stop ? \"\" : dirname(dir);\n } while (dir.length);\n\n return null;\n }\n}\n","import type { FSWatcher } from \"chokidar\";\nimport { watch } from \"chokidar\";\nimport type { Stats } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { Observable } from \"rxjs\";\nimport { Subject } from \"rxjs\";\nimport {\n ZFileSystemNodeBuilder,\n type IZFileSystemNode,\n} from \"../file-system/file-system-node.mjs\";\n\n/**\n * Represents and object that can watch a folder or file on the file system.\n */\nexport interface IZFileWatch {\n /**\n * Starts the watch operation.\n */\n start(): Promise<void>;\n\n /**\n * Stops the watch operation.\n */\n stop(): Promise<void>;\n\n /**\n * The stream for files being added.\n *\n * This can only occur if the target being watched\n * is a folder.\n *\n * @returns\n * The observable that will publish files that\n * get added.\n */\n add(): Observable<IZFileSystemNode>;\n\n /**\n * The stream for files being updated.\n *\n * If this watcher points to a folder, then all files\n * recursively will send when they get updated. If this\n * watcher points to a file, then this will only invoke\n * when the file is updated.\n *\n * @returns\n * The observable that will publish files and folders\n * that are updated.\n */\n update(): Observable<IZFileSystemNode>;\n\n /**\n * The stream for files and folders being deleted.\n *\n * If this watcher points to a folder, then all files under the\n * folder will be sent through this observable, including the\n * folder being watched. If this points to a file, then\n * this will only receive when the file is unlinked.\n *\n * @returns\n * The observable that will publish file and folders\n * that are unlinked and removed respectively. Note\n * that files and folders streamed this way will not\n * have their stats set.\n */\n remove(): Observable<IZFileSystemNode>;\n}\n\n/**\n * An implementation of the IZFileWatch.\n */\nexport class ZFileWatch implements IZFileWatch {\n private _add: Subject<IZFileSystemNode> = new Subject<IZFileSystemNode>();\n private _update: Subject<IZFileSystemNode> = new Subject<IZFileSystemNode>();\n private _remove: Subject<IZFileSystemNode> = new Subject<IZFileSystemNode>();\n private _watcher: FSWatcher | undefined;\n\n /**\n * Initializes a new instance of this object.\n *\n * @param path -\n * The path to watch.\n */\n public constructor(public readonly path: string) {}\n\n public async start() {\n await this.stop();\n\n this._watcher = watch(this.path, {\n usePolling: true,\n alwaysStat: true,\n ignoreInitial: true,\n\n awaitWriteFinish: {\n stabilityThreshold: 500,\n pollInterval: 50,\n },\n });\n\n function next(\n observable: Subject<IZFileSystemNode>,\n file: string,\n stats: Stats | undefined,\n ) {\n const node = new ZFileSystemNodeBuilder().path(resolve(this.path, file));\n observable.next(stats ? node.stats(stats).build() : node.build());\n }\n\n this._watcher\n .on(\"add\", next.bind(this, this._add))\n .on(\"addDir\", next.bind(this, this._add))\n .on(\"change\", next.bind(this, this._update))\n .on(\"unlink\", next.bind(this, this._remove))\n .on(\"unlinkDir\", next.bind(this, this._remove));\n\n return new Promise<void>((resolve) =>\n this._watcher?.on(\"ready\", () => resolve()),\n );\n }\n\n public async stop() {\n await this._watcher?.close();\n delete this._watcher;\n return Promise.resolve();\n }\n\n public add() {\n return this._add.asObservable();\n }\n\n public update() {\n return this._update.asObservable();\n }\n\n public remove() {\n return this._remove.asObservable();\n }\n}\n","import { firstDefined, sleep } from \"@zthun/helpful-fn\";\nimport type { IZDataRequest, IZDataSource } from \"@zthun/helpful-query\";\nimport { ZDataSourceStatic } from \"@zthun/helpful-query\";\nimport { find, findIndex, flatten, trimEnd, uniqBy } from \"lodash-es\";\nimport { minimatch } from \"minimatch\";\nimport { resolve, sep } from \"node:path\";\nimport type { Subscription } from \"rxjs\";\nimport {\n ZFileSystemNodeType,\n type IZFileSystemNode,\n} from \"../file-system/file-system-node.mjs\";\nimport {\n ZFileSystemService,\n type IZFileSystemService,\n} from \"../file-system/file-system-service.mjs\";\nimport { ZFileWatch, type IZFileWatch } from \"../file-watch/file-watch.mjs\";\n\n/**\n * Represents a repository for the file system.\n */\nexport interface IZFileRepository extends IZDataSource<IZFileSystemNode> {\n /**\n * Retrieves a single file from the repository.\n *\n * @param path -\n * The fully qualified path to the file.\n *\n * @returns\n * The node that represents the file. Returns null if no\n * such file exists.\n */\n get(path: string): Promise<IZFileSystemNode | null>;\n}\n\n/**\n * Represents an implementation of a ZFileRepository that watches\n * a given path scope.\n *\n * This repository is only concerned about files. Folders\n * will not be retrieved from this repository.\n */\nexport class ZFileRepository implements IZFileRepository {\n private _service: IZFileSystemService = new ZFileSystemService();\n private _watcher: IZFileWatch | undefined;\n private _nodes: Promise<ZDataSourceStatic<IZFileSystemNode>> =\n Promise.resolve(new ZDataSourceStatic<IZFileSystemNode>([]));\n private _globs: string[] = [\"**\"];\n private _path: string = \"\";\n private _add: Subscription | undefined;\n private _remove: Subscription | undefined;\n private _update: Subscription | undefined;\n\n /**\n * Gets the path that this repository is watching.\n */\n public get path() {\n return this._path;\n }\n\n /**\n * Gets the globs matchers that this repository is matching against.\n */\n public get globs() {\n return this._globs.slice();\n }\n\n /**\n * Initializes the repository with the given root and glob filter.\n *\n * This will initially scan the file system and setup watches.\n * If you call this method again, then the repository will be\n * {@link reset} and a new set of files will be added to the\n * repository.\n *\n * @param path -\n * The root path of the repository.\n * @param globs -\n * The optional relative globs of the repository. If this is falsy,\n * then ** is used. You can achieve the same kind of operation\n * using filters, but filtering out unwanted files frees up the internal\n * memory being used.\n */\n public async initialize(path: string, globs: string[] = [\"**\"]) {\n await this.reset();\n\n this._path = path;\n this._globs = globs;\n\n // Note that this all happens in the background and should\n // only be awaited later. So the search should not be\n // required to finish when existing this method. The only\n // requirement is that the repository is reset and the path +\n // glob scope is updated. Everything beyond here should not\n // be awaited - it will be awaited later once the caller\n // tries to retrieve the files using retrieve, get, or\n // count.\n const matches = globs.map((g) =>\n this._service.search(g, {\n cwd: path,\n stat: true,\n }),\n );\n\n this._nodes = Promise.all(matches)\n .then((nodes) => {\n const flat = flatten(nodes);\n const uniq = uniqBy(flat, (n) => n.path);\n return uniq.filter((n) => n.type === ZFileSystemNodeType.File);\n })\n .then((files) => {\n return new ZDataSourceStatic(files);\n });\n\n this._watcher = new ZFileWatch(path);\n\n this._add = this._watcher\n .add()\n .subscribe(async (node: IZFileSystemNode) => {\n if (\n node.type === ZFileSystemNodeType.File &&\n this._globs.some((g) => minimatch(node.path, resolve(this._path, g)))\n ) {\n const nodes = await this._nodes;\n this._nodes = nodes.insert(node);\n }\n });\n\n this._remove = this._watcher\n .remove()\n .subscribe(async (node: IZFileSystemNode) => {\n let nodes = await this._nodes;\n const path = trimEnd(node.path, sep);\n\n // It's possible that the node given was a folder. If that happens,\n // we need to remove all files that start with the given path.\n // If the node does point to a file, then there is no possibility that\n // more than 1 item would be removed.\n\n const next = async () =>\n findIndex(await nodes.items(), (n) => {\n return (\n n.path === path ||\n (n.path.startsWith(path) &&\n n.path.substring(path.length).charAt(0) === sep)\n );\n });\n\n for (let index = await next(); index >= 0; index = await next()) {\n nodes = await nodes.removeAt(index);\n }\n\n this._nodes = Promise.resolve(nodes);\n });\n\n this._update = this._watcher\n .update()\n .subscribe(async (node: IZFileSystemNode) => {\n const nodes = await this._nodes;\n const index = findIndex(\n await nodes.items(),\n (n) => n.path === node.path,\n );\n\n // It's possible node was filtered out by the globs, or\n // it is a directory. If so, then we won't have it in our\n // list.\n if (index >= 0) {\n const next = await nodes.removeAt(index);\n this._nodes = next.insert(node, index);\n }\n });\n\n // Kick off the initial seed operation with an even loop\n // invocation.\n await sleep(100);\n\n await this._watcher?.start();\n }\n\n /**\n * Resets the repository as if it was initially created.\n */\n public async reset(): Promise<void> {\n await this._watcher?.stop();\n\n this._add?.unsubscribe();\n this._remove?.unsubscribe();\n this._update?.unsubscribe();\n\n delete this._add;\n delete this._remove;\n delete this._update;\n delete this._watcher;\n\n this._path = \"\";\n this._globs = [\"**\"];\n this._nodes = Promise.resolve(new ZDataSourceStatic<IZFileSystemNode>([]));\n }\n\n public async get(path: string): Promise<IZFileSystemNode | null> {\n const nodes = await this._nodes;\n const items = await nodes.items();\n const node = find(items, (f) => f.path === path);\n\n return firstDefined(null, node);\n }\n\n public async count(request: IZDataRequest): Promise<number> {\n const source = await this._nodes;\n return source.count(request);\n }\n\n public async retrieve(request: IZDataRequest): Promise<IZFileSystemNode[]> {\n const source = await this._nodes;\n return source.retrieve(request);\n }\n}\n","import type { PathLike } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nexport function resolvePathLike(path: PathLike): string {\n if (typeof path === \"string\") {\n return resolve(path);\n }\n\n if (path instanceof URL) {\n return fileURLToPath(path);\n }\n\n return resolve(path.toString());\n}\n","import { sleep } from \"@zthun/helpful-fn\";\n\n/**\n * The actual delay time that you should wait for a watch\n * operation to pick up your file changes.\n */\nexport const ZWatchDelay = 1500;\n\n/**\n * Performs a sleep long enough to allow a watch operation\n * to pick up a change.\n *\n * You should never really need this. Where it is useful\n * is for unit testing with IO operations and you want to\n * wait for your write operations to get picked up by\n * a file watch operation.\n */\nexport function sleepWatchDelay() {\n return sleep(ZWatchDelay);\n}\n","import type { PathLike } from \"fs\";\nimport { mkdir } from \"fs/promises\";\nimport type { IZStreamWrite } from \"./stream-write.mjs\";\n\n/**\n * A stream that writes folders.\n *\n * Writing folders is idempotent. If the folder you\n * are trying to write already exists, then the write\n * operation still succeeds\n */\nexport class ZStreamFolder implements IZStreamWrite {\n public async write(path: PathLike): Promise<number> {\n await mkdir(path, { recursive: true });\n\n return 0;\n }\n}\n","import type { PathLike, Stats } from \"node:fs\";\nimport { readFile, stat, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"path\";\nimport { resolvePathLike } from \"../resolve-path-like/resolve-path-like.js\";\nimport { ZStreamFolder } from \"./stream-folder.mjs\";\nimport type { IZStreamRead, IZStreamReadOptions } from \"./stream-read.mjs\";\nimport type { IZStreamWrite, IZStreamWriteOptions } from \"./stream-write.mjs\";\n\n/**\n * Options for the stream file object.\n */\nexport interface IZStreamFileOptions {\n /**\n * Cache options.\n *\n * A warning that file content caching will take up significant memory\n * if the file size is too big or the max files is too big. Make sure\n * you know what you're doing when you change the default values of this.\n */\n cache?: {\n /**\n * Maximum number of bytes a file can be before it will not be cached.\n * The default is 100 Kib (102400 bytes)\n *\n * @default 102400\n */\n fileSize?: bigint;\n /**\n * The maximum number of files that are to be cached. The cache order\n * is first in, first out. Set this to 0 to not cache anything. The\n * default is 1000.\n *\n * @default 1000\n */\n maxFiles?: number;\n };\n}\n\n/**\n * A stream that can read and write to files.\n *\n * This is mostly a wrapper to readFile and writeFile from node, but\n * with some optimizations.\n *\n * First, this class supports file content caching so reading in a file\n * that's under a certain size threshold will store it in memory for\n * later retrieval.\n */\nexport class ZStreamFile implements IZStreamWrite, IZStreamRead {\n private static readonly FileSizeDefault = 102400; // One Hundred KibiBytes\n private static readonly MaxFilesDefault = 1000;\n\n private _cache = new Map<string, { stats: Stats; buffer: Promise<Buffer> }>();\n\n /**\n * Initializes a new instance of this object.\n *\n * @param options -\n * The options for file read and writes.\n */\n public constructor(public readonly options: IZStreamFileOptions = {}) {}\n\n public async read(\n path: PathLike,\n options?: IZStreamReadOptions,\n ): Promise<Buffer> {\n const _path = resolvePathLike(path);\n\n const stats = await stat(_path);\n const cached = this._cache.get(_path);\n\n const buffer =\n cached && cached.stats.mtimeMs >= stats.mtimeMs\n ? cached.buffer\n : readFile(_path, options);\n\n return this._addToCache(_path, { stats, buffer });\n }\n\n public async write(\n path: PathLike,\n { buffer = Buffer.from(\"\") }: IZStreamWriteOptions = {},\n ): Promise<number> {\n const _path = resolvePathLike(path);\n const directory = dirname(_path);\n\n await new ZStreamFolder().write(directory);\n await writeFile(_path, buffer, { flush: true });\n\n // If this file specifically was cached earlier,\n // we can just remove it now so we make room for\n // another file. Consumers can just read the\n // file again to recache it.\n this._cache.delete(_path);\n\n return buffer.length;\n }\n\n private _addToCache(\n path: string,\n item: { stats: Stats; buffer: Promise<Buffer> },\n ) {\n const { cache = {} } = this.options;\n const {\n fileSize = ZStreamFile.FileSizeDefault,\n maxFiles = ZStreamFile.MaxFilesDefault,\n } = cache;\n\n if (item.stats.size > fileSize) {\n // In this case, the file size is too big to cache in memory,\n // so we're bowing out here.\n return item.buffer;\n }\n\n // We will remove this path from the cache first since\n // we want it to be the most recent file (at the end)\n // of the key list. The removal does nothing if the\n // file was not cached.\n this._cache.delete(path);\n this._cache.set(path, item);\n\n if (this._cache.size > maxFiles) {\n // Retrieving the keys from a javascript map is order\n // by the time in which the keys are created. So\n // we are going to remove the first key which is the\n // oldest.\n const itr = this._cache.keys();\n this._cache.delete(itr.next().value);\n }\n\n return item.buffer;\n }\n}\n"],"names":["ZFileSystemNodeType","ZFileSystemNodeBuilder","created","at","_node","Date","toJSON","updated","size","bytes","BigInt","path","type","stats","s","builder","birthtime","mtime","isFile","file","folder","build","clone","structuredClone","omitBy","isUndefined","_define_property","bind","ZFileSystemService","info","search","pattern","options","paths","glob","stat","withFileTypes","map","fullpath","atime","undefined","walk","start","cwd","stop","mode","_test","access","isAbsolute","dir","resolve","exists","dirname","length","ZFileWatch","_watcher","watch","usePolling","alwaysStat","ignoreInitial","awaitWriteFinish","stabilityThreshold","pollInterval","next","observable","node","on","_add","_update","_remove","Promise","close","add","asObservable","update","remove","Subject","ZFileRepository","_path","globs","_globs","slice","initialize","reset","matches","g","_service","_nodes","all","then","nodes","flat","flatten","uniq","uniqBy","n","filter","File","files","ZDataSourceStatic","subscribe","some","minimatch","insert","trimEnd","sep","findIndex","items","startsWith","substring","charAt","index","removeAt","sleep","unsubscribe","get","find","f","firstDefined","count","request","source","retrieve","resolvePathLike","URL","fileURLToPath","toString","ZWatchDelay","sleepWatchDelay","ZStreamFolder","write","mkdir","recursive","ZStreamFile","read","cached","_cache","buffer","mtimeMs","readFile","_addToCache","Buffer","from","directory","writeFile","flush","delete","item","cache","fileSize","FileSizeDefault","maxFiles","MaxFilesDefault","set","itr","keys","value","Map"],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -6,4 +6,5 @@ export * from './resolve-path-like/resolve-path-like.js';
|
|
|
6
6
|
export * from './sleep-watch-delay/sleep-watch-delay.mjs';
|
|
7
7
|
export * from './stream/stream-file.mjs';
|
|
8
8
|
export * from './stream/stream-folder.mjs';
|
|
9
|
+
export * from './stream/stream-read.mjs';
|
|
9
10
|
export * from './stream/stream-write.mjs';
|
package/dist/index.js
CHANGED
|
@@ -4,14 +4,27 @@ import { omitBy, isUndefined, flatten, uniqBy, trimEnd, findIndex, find } from '
|
|
|
4
4
|
import { minimatch } from 'minimatch';
|
|
5
5
|
import { isAbsolute, resolve, dirname, sep } from 'node:path';
|
|
6
6
|
import { glob } from 'glob';
|
|
7
|
-
import { access, stat
|
|
7
|
+
import { access, stat, readFile, writeFile } from 'node:fs/promises';
|
|
8
8
|
import { cwd } from 'node:process';
|
|
9
9
|
import { watch } from 'chokidar';
|
|
10
10
|
import { Subject } from 'rxjs';
|
|
11
11
|
import { fileURLToPath } from 'node:url';
|
|
12
12
|
import { dirname as dirname$1 } from 'path';
|
|
13
|
-
import { mkdir
|
|
13
|
+
import { mkdir } from 'fs/promises';
|
|
14
14
|
|
|
15
|
+
function _define_property$3(obj, key, value) {
|
|
16
|
+
if (key in obj) {
|
|
17
|
+
Object.defineProperty(obj, key, {
|
|
18
|
+
value: value,
|
|
19
|
+
enumerable: true,
|
|
20
|
+
configurable: true,
|
|
21
|
+
writable: true
|
|
22
|
+
});
|
|
23
|
+
} else {
|
|
24
|
+
obj[key] = value;
|
|
25
|
+
}
|
|
26
|
+
return obj;
|
|
27
|
+
}
|
|
15
28
|
/**
|
|
16
29
|
* Represents a type of a file system node.
|
|
17
30
|
*/ var ZFileSystemNodeType = /*#__PURE__*/ function(ZFileSystemNodeType) {
|
|
@@ -22,13 +35,6 @@ import { mkdir, stat } from 'fs/promises';
|
|
|
22
35
|
/**
|
|
23
36
|
* Represents a builder for a file system node.
|
|
24
37
|
*/ class ZFileSystemNodeBuilder {
|
|
25
|
-
_node;
|
|
26
|
-
constructor(){
|
|
27
|
-
this._node = {
|
|
28
|
-
path: "/",
|
|
29
|
-
type: "folder"
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
38
|
created(at) {
|
|
33
39
|
this._node.created = at instanceof Date ? at.toJSON() : at;
|
|
34
40
|
return this;
|
|
@@ -49,8 +55,6 @@ import { mkdir, stat } from 'fs/promises';
|
|
|
49
55
|
this._node.type = type;
|
|
50
56
|
return this;
|
|
51
57
|
}
|
|
52
|
-
file = this.type.bind(this, "file");
|
|
53
|
-
folder = this.type.bind(this, "folder");
|
|
54
58
|
stats(s) {
|
|
55
59
|
const builder = this.size(s.size).created(s.birthtime).updated(s.mtime);
|
|
56
60
|
return s.isFile() ? builder.file() : builder.folder();
|
|
@@ -59,6 +63,15 @@ import { mkdir, stat } from 'fs/promises';
|
|
|
59
63
|
const clone = structuredClone(this._node);
|
|
60
64
|
return omitBy(clone, isUndefined);
|
|
61
65
|
}
|
|
66
|
+
constructor(){
|
|
67
|
+
_define_property$3(this, "_node", void 0);
|
|
68
|
+
_define_property$3(this, "file", this.type.bind(this, "file"));
|
|
69
|
+
_define_property$3(this, "folder", this.type.bind(this, "folder"));
|
|
70
|
+
this._node = {
|
|
71
|
+
path: "/",
|
|
72
|
+
type: "folder"
|
|
73
|
+
};
|
|
74
|
+
}
|
|
62
75
|
}
|
|
63
76
|
|
|
64
77
|
/**
|
|
@@ -110,22 +123,22 @@ import { mkdir, stat } from 'fs/promises';
|
|
|
110
123
|
}
|
|
111
124
|
}
|
|
112
125
|
|
|
126
|
+
function _define_property$2(obj, key, value) {
|
|
127
|
+
if (key in obj) {
|
|
128
|
+
Object.defineProperty(obj, key, {
|
|
129
|
+
value: value,
|
|
130
|
+
enumerable: true,
|
|
131
|
+
configurable: true,
|
|
132
|
+
writable: true
|
|
133
|
+
});
|
|
134
|
+
} else {
|
|
135
|
+
obj[key] = value;
|
|
136
|
+
}
|
|
137
|
+
return obj;
|
|
138
|
+
}
|
|
113
139
|
/**
|
|
114
140
|
* An implementation of the IZFileWatch.
|
|
115
141
|
*/ class ZFileWatch {
|
|
116
|
-
path;
|
|
117
|
-
_add = new Subject();
|
|
118
|
-
_update = new Subject();
|
|
119
|
-
_remove = new Subject();
|
|
120
|
-
_watcher;
|
|
121
|
-
/**
|
|
122
|
-
* Initializes a new instance of this object.
|
|
123
|
-
*
|
|
124
|
-
* @param path -
|
|
125
|
-
* The path to watch.
|
|
126
|
-
*/ constructor(path){
|
|
127
|
-
this.path = path;
|
|
128
|
-
}
|
|
129
142
|
async start() {
|
|
130
143
|
await this.stop();
|
|
131
144
|
this._watcher = watch(this.path, {
|
|
@@ -158,8 +171,37 @@ import { mkdir, stat } from 'fs/promises';
|
|
|
158
171
|
remove() {
|
|
159
172
|
return this._remove.asObservable();
|
|
160
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Initializes a new instance of this object.
|
|
176
|
+
*
|
|
177
|
+
* @param path -
|
|
178
|
+
* The path to watch.
|
|
179
|
+
*/ constructor(path){
|
|
180
|
+
_define_property$2(this, "path", void 0);
|
|
181
|
+
_define_property$2(this, "_add", void 0);
|
|
182
|
+
_define_property$2(this, "_update", void 0);
|
|
183
|
+
_define_property$2(this, "_remove", void 0);
|
|
184
|
+
_define_property$2(this, "_watcher", void 0);
|
|
185
|
+
this.path = path;
|
|
186
|
+
this._add = new Subject();
|
|
187
|
+
this._update = new Subject();
|
|
188
|
+
this._remove = new Subject();
|
|
189
|
+
}
|
|
161
190
|
}
|
|
162
191
|
|
|
192
|
+
function _define_property$1(obj, key, value) {
|
|
193
|
+
if (key in obj) {
|
|
194
|
+
Object.defineProperty(obj, key, {
|
|
195
|
+
value: value,
|
|
196
|
+
enumerable: true,
|
|
197
|
+
configurable: true,
|
|
198
|
+
writable: true
|
|
199
|
+
});
|
|
200
|
+
} else {
|
|
201
|
+
obj[key] = value;
|
|
202
|
+
}
|
|
203
|
+
return obj;
|
|
204
|
+
}
|
|
163
205
|
/**
|
|
164
206
|
* Represents an implementation of a ZFileRepository that watches
|
|
165
207
|
* a given path scope.
|
|
@@ -167,16 +209,6 @@ import { mkdir, stat } from 'fs/promises';
|
|
|
167
209
|
* This repository is only concerned about files. Folders
|
|
168
210
|
* will not be retrieved from this repository.
|
|
169
211
|
*/ class ZFileRepository {
|
|
170
|
-
_service = new ZFileSystemService();
|
|
171
|
-
_watcher;
|
|
172
|
-
_nodes = Promise.resolve(new ZDataSourceStatic([]));
|
|
173
|
-
_globs = [
|
|
174
|
-
"**"
|
|
175
|
-
];
|
|
176
|
-
_path = "";
|
|
177
|
-
_add;
|
|
178
|
-
_remove;
|
|
179
|
-
_update;
|
|
180
212
|
/**
|
|
181
213
|
* Gets the path that this repository is watching.
|
|
182
214
|
*/ get path() {
|
|
@@ -263,7 +295,7 @@ import { mkdir, stat } from 'fs/promises';
|
|
|
263
295
|
// Kick off the initial seed operation with an even loop
|
|
264
296
|
// invocation.
|
|
265
297
|
await sleep(100);
|
|
266
|
-
await this._watcher
|
|
298
|
+
await this._watcher?.start();
|
|
267
299
|
}
|
|
268
300
|
/**
|
|
269
301
|
* Resets the repository as if it was initially created.
|
|
@@ -296,6 +328,18 @@ import { mkdir, stat } from 'fs/promises';
|
|
|
296
328
|
const source = await this._nodes;
|
|
297
329
|
return source.retrieve(request);
|
|
298
330
|
}
|
|
331
|
+
constructor(){
|
|
332
|
+
_define_property$1(this, "_service", new ZFileSystemService());
|
|
333
|
+
_define_property$1(this, "_watcher", void 0);
|
|
334
|
+
_define_property$1(this, "_nodes", Promise.resolve(new ZDataSourceStatic([])));
|
|
335
|
+
_define_property$1(this, "_globs", [
|
|
336
|
+
"**"
|
|
337
|
+
]);
|
|
338
|
+
_define_property$1(this, "_path", "");
|
|
339
|
+
_define_property$1(this, "_add", void 0);
|
|
340
|
+
_define_property$1(this, "_remove", void 0);
|
|
341
|
+
_define_property$1(this, "_update", void 0);
|
|
342
|
+
}
|
|
299
343
|
}
|
|
300
344
|
|
|
301
345
|
function resolvePathLike(path) {
|
|
@@ -332,25 +376,26 @@ function resolvePathLike(path) {
|
|
|
332
376
|
* operation still succeeds
|
|
333
377
|
*/ class ZStreamFolder {
|
|
334
378
|
async write(path) {
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
});
|
|
339
|
-
} catch {
|
|
340
|
-
// The folder may exist, but if it is a file then
|
|
341
|
-
// we have a conflict and in that case, we will throw an
|
|
342
|
-
// error. We are going to let stat fail if it cannot
|
|
343
|
-
// access the path (permission error).
|
|
344
|
-
const stats = await stat(path);
|
|
345
|
-
if (stats.isFile()) {
|
|
346
|
-
const msg = `Cannot create folder, ${path}, because a file with the same name exists at the target location`;
|
|
347
|
-
throw new Error(msg);
|
|
348
|
-
}
|
|
349
|
-
}
|
|
379
|
+
await mkdir(path, {
|
|
380
|
+
recursive: true
|
|
381
|
+
});
|
|
350
382
|
return 0;
|
|
351
383
|
}
|
|
352
384
|
}
|
|
353
385
|
|
|
386
|
+
function _define_property(obj, key, value) {
|
|
387
|
+
if (key in obj) {
|
|
388
|
+
Object.defineProperty(obj, key, {
|
|
389
|
+
value: value,
|
|
390
|
+
enumerable: true,
|
|
391
|
+
configurable: true,
|
|
392
|
+
writable: true
|
|
393
|
+
});
|
|
394
|
+
} else {
|
|
395
|
+
obj[key] = value;
|
|
396
|
+
}
|
|
397
|
+
return obj;
|
|
398
|
+
}
|
|
354
399
|
/**
|
|
355
400
|
* A stream that can read and write to files.
|
|
356
401
|
*
|
|
@@ -361,21 +406,9 @@ function resolvePathLike(path) {
|
|
|
361
406
|
* that's under a certain size threshold will store it in memory for
|
|
362
407
|
* later retrieval.
|
|
363
408
|
*/ class ZStreamFile {
|
|
364
|
-
options;
|
|
365
|
-
static FileSizeDefault = 102400;
|
|
366
|
-
static MaxFilesDefault = 1000;
|
|
367
|
-
_cache = new Map();
|
|
368
|
-
/**
|
|
369
|
-
* Initializes a new instance of this object.
|
|
370
|
-
*
|
|
371
|
-
* @param options -
|
|
372
|
-
* The options for file read and writes.
|
|
373
|
-
*/ constructor(options = {}){
|
|
374
|
-
this.options = options;
|
|
375
|
-
}
|
|
376
409
|
async read(path, options) {
|
|
377
410
|
const _path = resolvePathLike(path);
|
|
378
|
-
const stats = await stat
|
|
411
|
+
const stats = await stat(_path);
|
|
379
412
|
const cached = this._cache.get(_path);
|
|
380
413
|
const buffer = cached && cached.stats.mtimeMs >= stats.mtimeMs ? cached.buffer : readFile(_path, options);
|
|
381
414
|
return this._addToCache(_path, {
|
|
@@ -421,7 +454,20 @@ function resolvePathLike(path) {
|
|
|
421
454
|
}
|
|
422
455
|
return item.buffer;
|
|
423
456
|
}
|
|
457
|
+
/**
|
|
458
|
+
* Initializes a new instance of this object.
|
|
459
|
+
*
|
|
460
|
+
* @param options -
|
|
461
|
+
* The options for file read and writes.
|
|
462
|
+
*/ constructor(options = {}){
|
|
463
|
+
_define_property(this, "options", void 0);
|
|
464
|
+
_define_property(this, "_cache", void 0);
|
|
465
|
+
this.options = options;
|
|
466
|
+
this._cache = new Map();
|
|
467
|
+
}
|
|
424
468
|
}
|
|
469
|
+
_define_property(ZStreamFile, "FileSizeDefault", 102400); // One Hundred KibiBytes
|
|
470
|
+
_define_property(ZStreamFile, "MaxFilesDefault", 1000);
|
|
425
471
|
|
|
426
472
|
export { ZFileRepository, ZFileSystemNodeBuilder, ZFileSystemNodeType, ZFileSystemService, ZFileWatch, ZStreamFile, ZStreamFolder, ZWatchDelay, resolvePathLike, sleepWatchDelay };
|
|
427
473
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/file-system/file-system-node.mts","../src/file-system/file-system-service.mts","../src/file-watch/file-watch.mts","../src/file-repository/file-repository.mts","../src/resolve-path-like/resolve-path-like.ts","../src/sleep-watch-delay/sleep-watch-delay.mts","../src/stream/stream-folder.mts","../src/stream/stream-file.mts"],"sourcesContent":["import { isUndefined, omitBy } from \"lodash-es\";\nimport type { Stats } from \"node:fs\";\n\n/**\n * Represents a type of a file system node.\n */\nexport enum ZFileSystemNodeType {\n File = \"file\",\n Folder = \"folder\",\n}\n\nexport interface IZFileSystemNode {\n /**\n * The absolute path of the node.\n */\n path: string;\n\n /**\n * The type of the node (file or folder).\n */\n type: ZFileSystemNodeType;\n\n /**\n * The creation date of the node.\n */\n created?: string;\n\n /**\n * The modification date of the node.\n */\n updated?: string;\n\n /**\n * The size of the node in bytes.\n */\n size?: bigint;\n}\n\n/**\n * Represents a builder for a file system node.\n */\nexport class ZFileSystemNodeBuilder {\n private _node: IZFileSystemNode;\n\n public constructor() {\n this._node = {\n path: \"/\",\n type: ZFileSystemNodeType.Folder,\n };\n }\n\n public created(at?: Date | string | undefined) {\n this._node.created = at instanceof Date ? at.toJSON() : at;\n return this;\n }\n\n public updated(at?: Date | string | undefined) {\n this._node.updated = at instanceof Date ? at.toJSON() : at;\n return this;\n }\n\n public size(bytes: bigint | number | undefined) {\n this._node.size = typeof bytes == \"number\" ? BigInt(bytes) : bytes;\n return this;\n }\n\n public path(path: string) {\n this._node.path = path;\n return this;\n }\n\n public type(type: ZFileSystemNodeType) {\n this._node.type = type;\n return this;\n }\n\n public file = this.type.bind(this, ZFileSystemNodeType.File);\n public folder = this.type.bind(this, ZFileSystemNodeType.Folder);\n\n public stats(s: Stats) {\n const builder = this.size(s.size).created(s.birthtime).updated(s.mtime);\n return s.isFile() ? builder.file() : builder.folder();\n }\n\n public build() {\n const clone = structuredClone(this._node);\n return omitBy(clone, isUndefined) as IZFileSystemNode;\n }\n}\n","import { glob } from \"glob\";\nimport { access } from \"node:fs/promises\";\nimport { dirname, isAbsolute, resolve } from \"node:path\";\nimport { cwd } from \"node:process\";\nimport type { IZFileSystemNode } from \"./file-system-node.mjs\";\nimport { ZFileSystemNodeBuilder } from \"./file-system-node.mjs\";\n\n/**\n * Represents options for searches.\n */\nexport interface IZFileSystemSearchOptions {\n /**\n * The directory to search in.\n *\n * If this is not set, then the cwd of the application is used.\n */\n cwd?: string;\n\n /**\n * A flag that determines whether or not to load the\n * file system information.\n *\n * This is true by default.\n */\n stat?: boolean;\n}\n\n/**\n * Represents options for directory walking.\n */\nexport interface IZFileSystemWalkOptions {\n /**\n * The starting directory.\n *\n * The default is the current working directory\n *\n * @see process.cwd for more information.\n */\n start?: string;\n\n /**\n * The directory to stop at.\n *\n * The default is the root of the file system.\n */\n stop?: string;\n\n /**\n * The type of mode that the path must support in order\n * to be approved.\n *\n * The default is undefined and left up to the node api.\n */\n mode?: number;\n}\n\n/**\n * Represents a service to enumerate the file system.\n */\nexport interface IZFileSystemService {\n /**\n * Gets information about a node.\n *\n * @param path -\n * The path to get information for.\n *\n * @returns\n * Information about the node.\n */\n info(path: string): Promise<IZFileSystemNode>;\n\n /**\n * Reads all nodes that match a pattern.\n *\n * @param pattern -\n * The pattern string to match against or a list\n * of patterns to match.\n * @param options -\n * The options for the search.\n *\n * @returns\n * A list of path strings that match the given patterns.\n */\n search(\n pattern: string | string[],\n options?: IZFileSystemSearchOptions,\n ): Promise<IZFileSystemNode[]>;\n\n /**\n * Walks up a directory tree to search for existence of a given path.\n *\n * @param search -\n * The path to search for. This is the candidate folder path that\n * may or may not exist somewhere from the start directory all the\n * way up the directory tree.\n * @param options -\n * The given options for the search.\n *\n * @returns\n * The fully qualified path to the first path that matches the search\n * starting at the options start or the current working directory if not\n * specified. Returns null if no such directory exists.\n *\n * @example\n *\n * ```ts\n * import { resolve } from 'path'\n *\n * // Find any folder named .vscode from the current working directory all the way\n * // up the directory tree. Returns null if no vscode directory can be found.\n * const service = new ZFileSystemService();\n * const vscode = service.walk('.vscode');\n *\n * // Walk the directory tree from the current script and find the .config folder.\n * const config = service.walk('.config', { start: __dirname });\n *\n * // Walk the directory tree from the current script and stop when we reach\n * // at most 2 directories up.\n * const start = __dirname;\n * const stop = resolve(__dirname, '../..');\n * const file = service.walk('path/to/file.json', { start, stop });\n * ```\n */\n walk(\n search: string,\n options?: IZFileSystemWalkOptions,\n ): Promise<string | null>;\n}\n\n/**\n * Represents a node implementation of a file system service.\n */\nexport class ZFileSystemService implements IZFileSystemService {\n public async info(path: string): Promise<IZFileSystemNode> {\n const [file] = await this.search(path);\n return file;\n }\n\n public async search(\n pattern: string | string[],\n options?: IZFileSystemSearchOptions,\n ): Promise<IZFileSystemNode[]> {\n const paths = await glob(pattern, {\n stat: true,\n ...options,\n withFileTypes: true,\n });\n\n return paths.map((path) => {\n let info = new ZFileSystemNodeBuilder()\n .path(path.fullpath())\n .created(path.birthtime)\n .updated(path.atime)\n .size(path.size);\n\n // Note that for folders, node will return the size of the underlying OS metadata,\n // hence, why we remove the size on the folder here.\n info = path.isFile() ? info.file() : info.folder().size(undefined);\n\n return info.build();\n });\n }\n\n public async walk(search: string, options?: IZFileSystemWalkOptions) {\n const start = options?.start || cwd();\n const stop = options?.stop || \"/\";\n const mode = options?.mode;\n\n const _test = async (path: string) => {\n try {\n await access(path, mode);\n return true;\n } catch {\n return false;\n }\n };\n\n if (isAbsolute(search)) {\n return (await _test(search)) ? search : null;\n }\n\n let dir = start;\n do {\n const path = resolve(dir, search);\n const exists = await _test(path);\n\n if (exists) {\n return path;\n }\n\n dir = dir === stop ? \"\" : dirname(dir);\n } while (dir.length);\n\n return null;\n }\n}\n","import type { FSWatcher } from \"chokidar\";\nimport { watch } from \"chokidar\";\nimport type { Stats } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { Observable } from \"rxjs\";\nimport { Subject } from \"rxjs\";\nimport {\n ZFileSystemNodeBuilder,\n type IZFileSystemNode,\n} from \"../file-system/file-system-node.mjs\";\n\n/**\n * Represents and object that can watch a folder or file on the file system.\n */\nexport interface IZFileWatch {\n /**\n * Starts the watch operation.\n */\n start(): Promise<void>;\n\n /**\n * Stops the watch operation.\n */\n stop(): Promise<void>;\n\n /**\n * The stream for files being added.\n *\n * This can only occur if the target being watched\n * is a folder.\n *\n * @returns\n * The observable that will publish files that\n * get added.\n */\n add(): Observable<IZFileSystemNode>;\n\n /**\n * The stream for files being updated.\n *\n * If this watcher points to a folder, then all files\n * recursively will send when they get updated. If this\n * watcher points to a file, then this will only invoke\n * when the file is updated.\n *\n * @returns\n * The observable that will publish files and folders\n * that are updated.\n */\n update(): Observable<IZFileSystemNode>;\n\n /**\n * The stream for files and folders being deleted.\n *\n * If this watcher points to a folder, then all files under the\n * folder will be sent through this observable, including the\n * folder being watched. If this points to a file, then\n * this will only receive when the file is unlinked.\n *\n * @returns\n * The observable that will publish file and folders\n * that are unlinked and removed respectively. Note\n * that files and folders streamed this way will not\n * have their stats set.\n */\n remove(): Observable<IZFileSystemNode>;\n}\n\n/**\n * An implementation of the IZFileWatch.\n */\nexport class ZFileWatch implements IZFileWatch {\n private _add: Subject<IZFileSystemNode> = new Subject<IZFileSystemNode>();\n private _update: Subject<IZFileSystemNode> = new Subject<IZFileSystemNode>();\n private _remove: Subject<IZFileSystemNode> = new Subject<IZFileSystemNode>();\n private _watcher: FSWatcher | undefined;\n\n /**\n * Initializes a new instance of this object.\n *\n * @param path -\n * The path to watch.\n */\n public constructor(public readonly path: string) {}\n\n public async start() {\n await this.stop();\n\n this._watcher = watch(this.path, {\n usePolling: true,\n alwaysStat: true,\n ignoreInitial: true,\n\n awaitWriteFinish: {\n stabilityThreshold: 500,\n pollInterval: 50,\n },\n });\n\n function next(\n observable: Subject<IZFileSystemNode>,\n file: string,\n stats: Stats | undefined,\n ) {\n const node = new ZFileSystemNodeBuilder().path(resolve(this.path, file));\n observable.next(stats ? node.stats(stats).build() : node.build());\n }\n\n this._watcher\n .on(\"add\", next.bind(this, this._add))\n .on(\"addDir\", next.bind(this, this._add))\n .on(\"change\", next.bind(this, this._update))\n .on(\"unlink\", next.bind(this, this._remove))\n .on(\"unlinkDir\", next.bind(this, this._remove));\n\n return new Promise<void>((resolve) =>\n this._watcher?.on(\"ready\", () => resolve()),\n );\n }\n\n public async stop() {\n await this._watcher?.close();\n delete this._watcher;\n return Promise.resolve();\n }\n\n public add() {\n return this._add.asObservable();\n }\n\n public update() {\n return this._update.asObservable();\n }\n\n public remove() {\n return this._remove.asObservable();\n }\n}\n","import { firstDefined, sleep } from \"@zthun/helpful-fn\";\nimport type { IZDataRequest, IZDataSource } from \"@zthun/helpful-query\";\nimport { ZDataSourceStatic } from \"@zthun/helpful-query\";\nimport { find, findIndex, flatten, trimEnd, uniqBy } from \"lodash-es\";\nimport { minimatch } from \"minimatch\";\nimport { resolve, sep } from \"node:path\";\nimport type { Subscription } from \"rxjs\";\nimport {\n ZFileSystemNodeType,\n type IZFileSystemNode,\n} from \"../file-system/file-system-node.mjs\";\nimport {\n ZFileSystemService,\n type IZFileSystemService,\n} from \"../file-system/file-system-service.mjs\";\nimport { ZFileWatch, type IZFileWatch } from \"../file-watch/file-watch.mjs\";\n\n/**\n * Represents a repository for the file system.\n */\nexport interface IZFileRepository extends IZDataSource<IZFileSystemNode> {\n /**\n * Retrieves a single file from the repository.\n *\n * @param path -\n * The fully qualified path to the file.\n *\n * @returns\n * The node that represents the file. Returns null if no\n * such file exists.\n */\n get(path: string): Promise<IZFileSystemNode | null>;\n}\n\n/**\n * Represents an implementation of a ZFileRepository that watches\n * a given path scope.\n *\n * This repository is only concerned about files. Folders\n * will not be retrieved from this repository.\n */\nexport class ZFileRepository implements IZFileRepository {\n private _service: IZFileSystemService = new ZFileSystemService();\n private _watcher: IZFileWatch | undefined;\n private _nodes: Promise<ZDataSourceStatic<IZFileSystemNode>> =\n Promise.resolve(new ZDataSourceStatic<IZFileSystemNode>([]));\n private _globs: string[] = [\"**\"];\n private _path: string = \"\";\n private _add: Subscription | undefined;\n private _remove: Subscription | undefined;\n private _update: Subscription | undefined;\n\n /**\n * Gets the path that this repository is watching.\n */\n public get path() {\n return this._path;\n }\n\n /**\n * Gets the globs matchers that this repository is matching against.\n */\n public get globs() {\n return this._globs.slice();\n }\n\n /**\n * Initializes the repository with the given root and glob filter.\n *\n * This will initially scan the file system and setup watches.\n * If you call this method again, then the repository will be\n * {@link reset} and a new set of files will be added to the\n * repository.\n *\n * @param path -\n * The root path of the repository.\n * @param globs -\n * The optional relative globs of the repository. If this is falsy,\n * then ** is used. You can achieve the same kind of operation\n * using filters, but filtering out unwanted files frees up the internal\n * memory being used.\n */\n public async initialize(path: string, globs: string[] = [\"**\"]) {\n await this.reset();\n\n this._path = path;\n this._globs = globs;\n\n // Note that this all happens in the background and should\n // only be awaited later. So the search should not be\n // required to finish when existing this method. The only\n // requirement is that the repository is reset and the path +\n // glob scope is updated. Everything beyond here should not\n // be awaited - it will be awaited later once the caller\n // tries to retrieve the files using retrieve, get, or\n // count.\n const matches = globs.map((g) =>\n this._service.search(g, {\n cwd: path,\n stat: true,\n }),\n );\n\n this._nodes = Promise.all(matches)\n .then((nodes) => {\n const flat = flatten(nodes);\n const uniq = uniqBy(flat, (n) => n.path);\n return uniq.filter((n) => n.type === ZFileSystemNodeType.File);\n })\n .then((files) => {\n return new ZDataSourceStatic(files);\n });\n\n this._watcher = new ZFileWatch(path);\n\n this._add = this._watcher\n .add()\n .subscribe(async (node: IZFileSystemNode) => {\n if (\n node.type === ZFileSystemNodeType.File &&\n this._globs.some((g) => minimatch(node.path, resolve(this._path, g)))\n ) {\n const nodes = await this._nodes;\n this._nodes = nodes.insert(node);\n }\n });\n\n this._remove = this._watcher\n .remove()\n .subscribe(async (node: IZFileSystemNode) => {\n let nodes = await this._nodes;\n const path = trimEnd(node.path, sep);\n\n // It's possible that the node given was a folder. If that happens,\n // we need to remove all files that start with the given path.\n // If the node does point to a file, then there is no possibility that\n // more than 1 item would be removed.\n\n const next = async () =>\n findIndex(await nodes.items(), (n) => {\n return (\n n.path === path ||\n (n.path.startsWith(path) &&\n n.path.substring(path.length).charAt(0) === sep)\n );\n });\n\n for (let index = await next(); index >= 0; index = await next()) {\n nodes = await nodes.removeAt(index);\n }\n\n this._nodes = Promise.resolve(nodes);\n });\n\n this._update = this._watcher\n .update()\n .subscribe(async (node: IZFileSystemNode) => {\n const nodes = await this._nodes;\n const index = findIndex(\n await nodes.items(),\n (n) => n.path === node.path,\n );\n\n // It's possible node was filtered out by the globs, or\n // it is a directory. If so, then we won't have it in our\n // list.\n if (index >= 0) {\n const next = await nodes.removeAt(index);\n this._nodes = next.insert(node, index);\n }\n });\n\n // Kick off the initial seed operation with an even loop\n // invocation.\n await sleep(100);\n\n await this._watcher.start();\n }\n\n /**\n * Resets the repository as if it was initially created.\n */\n public async reset(): Promise<void> {\n await this._watcher?.stop();\n\n this._add?.unsubscribe();\n this._remove?.unsubscribe();\n this._update?.unsubscribe();\n\n delete this._add;\n delete this._remove;\n delete this._update;\n delete this._watcher;\n\n this._path = \"\";\n this._globs = [\"**\"];\n this._nodes = Promise.resolve(new ZDataSourceStatic<IZFileSystemNode>([]));\n }\n\n public async get(path: string): Promise<IZFileSystemNode | null> {\n const nodes = await this._nodes;\n const items = await nodes.items();\n const node = find(items, (f) => f.path === path);\n\n return firstDefined(null, node);\n }\n\n public async count(request: IZDataRequest): Promise<number> {\n const source = await this._nodes;\n return source.count(request);\n }\n\n public async retrieve(request: IZDataRequest): Promise<IZFileSystemNode[]> {\n const source = await this._nodes;\n return source.retrieve(request);\n }\n}\n","import type { PathLike } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nexport function resolvePathLike(path: PathLike): string {\n if (typeof path === \"string\") {\n return resolve(path);\n }\n\n if (path instanceof URL) {\n return fileURLToPath(path);\n }\n\n return resolve(path.toString());\n}\n","import { sleep } from \"@zthun/helpful-fn\";\n\n/**\n * The actual delay time that you should wait for a watch\n * operation to pick up your file changes.\n */\nexport const ZWatchDelay = 1500;\n\n/**\n * Performs a sleep long enough to allow a watch operation\n * to pick up a change.\n *\n * You should never really need this. Where it is useful\n * is for unit testing with IO operations and you want to\n * wait for your write operations to get picked up by\n * a file watch operation.\n */\nexport function sleepWatchDelay() {\n return sleep(ZWatchDelay);\n}\n","import type { PathLike } from \"fs\";\nimport { mkdir, stat } from \"fs/promises\";\nimport type { IZStreamWrite } from \"./stream-write.mjs\";\n\n/**\n * A stream that writes folders.\n *\n * Writing folders is idempotent. If the folder you\n * are trying to write already exists, then the write\n * operation still succeeds\n */\nexport class ZStreamFolder implements IZStreamWrite {\n public async write(path: PathLike): Promise<number> {\n try {\n await mkdir(path, { recursive: true });\n } catch {\n // The folder may exist, but if it is a file then\n // we have a conflict and in that case, we will throw an\n // error. We are going to let stat fail if it cannot\n // access the path (permission error).\n const stats = await stat(path);\n\n if (stats.isFile()) {\n const msg = `Cannot create folder, ${path}, because a file with the same name exists at the target location`;\n throw new Error(msg);\n }\n }\n\n return 0;\n }\n}\n","import type { PathLike, Stats } from \"node:fs\";\nimport { readFile, stat, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"path\";\nimport { resolvePathLike } from \"../resolve-path-like/resolve-path-like.js\";\nimport { ZStreamFolder } from \"./stream-folder.mjs\";\nimport type { IZStreamRead, IZStreamReadOptions } from \"./stream-read.mjs\";\nimport type { IZStreamWrite, IZStreamWriteOptions } from \"./stream-write.mjs\";\n\n/**\n * Options for the stream file object.\n */\nexport interface IZStreamFileOptions {\n /**\n * Cache options.\n *\n * A warning that file content caching will take up significant memory\n * if the file size is too big or the max files is too big. Make sure\n * you know what you're doing when you change the default values of this.\n */\n cache?: {\n /**\n * Maximum number of bytes a file can be before it will not be cached.\n * The default is 100 Kib (102400 bytes)\n *\n * @default 102400\n */\n fileSize?: bigint;\n /**\n * The maximum number of files that are to be cached. The cache order\n * is first in, first out. Set this to 0 to not cache anything. The\n * default is 1000.\n *\n * @default 1000\n */\n maxFiles?: number;\n };\n}\n\n/**\n * A stream that can read and write to files.\n *\n * This is mostly a wrapper to readFile and writeFile from node, but\n * with some optimizations.\n *\n * First, this class supports file content caching so reading in a file\n * that's under a certain size threshold will store it in memory for\n * later retrieval.\n */\nexport class ZStreamFile implements IZStreamWrite, IZStreamRead {\n private static readonly FileSizeDefault = 102400; // One Hundred KibiBytes\n private static readonly MaxFilesDefault = 1000;\n\n private _cache = new Map<string, { stats: Stats; buffer: Promise<Buffer> }>();\n\n /**\n * Initializes a new instance of this object.\n *\n * @param options -\n * The options for file read and writes.\n */\n public constructor(public readonly options: IZStreamFileOptions = {}) {}\n\n public async read(\n path: PathLike,\n options?: IZStreamReadOptions,\n ): Promise<Buffer> {\n const _path = resolvePathLike(path);\n\n const stats = await stat(_path);\n const cached = this._cache.get(_path);\n\n const buffer =\n cached && cached.stats.mtimeMs >= stats.mtimeMs\n ? cached.buffer\n : readFile(_path, options);\n\n return this._addToCache(_path, { stats, buffer });\n }\n\n public async write(\n path: PathLike,\n { buffer = Buffer.from(\"\") }: IZStreamWriteOptions = {},\n ): Promise<number> {\n const _path = resolvePathLike(path);\n const directory = dirname(_path);\n\n await new ZStreamFolder().write(directory);\n await writeFile(_path, buffer, { flush: true });\n\n // If this file specifically was cached earlier,\n // we can just remove it now so we make room for\n // another file. Consumers can just read the\n // file again to recache it.\n this._cache.delete(_path);\n\n return buffer.length;\n }\n\n private _addToCache(\n path: string,\n item: { stats: Stats; buffer: Promise<Buffer> },\n ) {\n const { cache = {} } = this.options;\n const {\n fileSize = ZStreamFile.FileSizeDefault,\n maxFiles = ZStreamFile.MaxFilesDefault,\n } = cache;\n\n if (item.stats.size > fileSize) {\n // In this case, the file size is too big to cache in memory,\n // so we're bowing out here.\n return item.buffer;\n }\n\n // We will remove this path from the cache first since\n // we want it to be the most recent file (at the end)\n // of the key list. The removal does nothing if the\n // file was not cached.\n this._cache.delete(path);\n this._cache.set(path, item);\n\n if (this._cache.size > maxFiles) {\n // Retrieving the keys from a javascript map is order\n // by the time in which the keys are created. So\n // we are going to remove the first key which is the\n // oldest.\n const itr = this._cache.keys();\n this._cache.delete(itr.next().value);\n }\n\n return item.buffer;\n }\n}\n"],"names":["ZFileSystemNodeType","ZFileSystemNodeBuilder","_node","path","type","created","at","Date","toJSON","updated","size","bytes","BigInt","file","bind","folder","stats","s","builder","birthtime","mtime","isFile","build","clone","structuredClone","omitBy","isUndefined","ZFileSystemService","info","search","pattern","options","paths","glob","stat","withFileTypes","map","fullpath","atime","undefined","walk","start","cwd","stop","mode","_test","access","isAbsolute","dir","resolve","exists","dirname","length","ZFileWatch","_add","Subject","_update","_remove","_watcher","watch","usePolling","alwaysStat","ignoreInitial","awaitWriteFinish","stabilityThreshold","pollInterval","next","observable","node","on","Promise","close","add","asObservable","update","remove","ZFileRepository","_service","_nodes","ZDataSourceStatic","_globs","_path","globs","slice","initialize","reset","matches","g","all","then","nodes","flat","flatten","uniq","uniqBy","n","filter","File","files","subscribe","some","minimatch","insert","trimEnd","sep","findIndex","items","startsWith","substring","charAt","index","removeAt","sleep","unsubscribe","get","find","f","firstDefined","count","request","source","retrieve","resolvePathLike","URL","fileURLToPath","toString","ZWatchDelay","sleepWatchDelay","ZStreamFolder","write","mkdir","recursive","msg","Error","ZStreamFile","FileSizeDefault","MaxFilesDefault","_cache","Map","read","cached","buffer","mtimeMs","readFile","_addToCache","Buffer","from","directory","writeFile","flush","delete","item","cache","fileSize","maxFiles","set","itr","keys","value"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/file-system/file-system-node.mts","../src/file-system/file-system-service.mts","../src/file-watch/file-watch.mts","../src/file-repository/file-repository.mts","../src/resolve-path-like/resolve-path-like.ts","../src/sleep-watch-delay/sleep-watch-delay.mts","../src/stream/stream-folder.mts","../src/stream/stream-file.mts"],"sourcesContent":["import { isUndefined, omitBy } from \"lodash-es\";\nimport type { Stats } from \"node:fs\";\n\n/**\n * Represents a type of a file system node.\n */\nexport enum ZFileSystemNodeType {\n File = \"file\",\n Folder = \"folder\",\n}\n\nexport interface IZFileSystemNode {\n /**\n * The absolute path of the node.\n */\n path: string;\n\n /**\n * The type of the node (file or folder).\n */\n type: ZFileSystemNodeType;\n\n /**\n * The creation date of the node.\n */\n created?: string;\n\n /**\n * The modification date of the node.\n */\n updated?: string;\n\n /**\n * The size of the node in bytes.\n */\n size?: bigint;\n}\n\n/**\n * Represents a builder for a file system node.\n */\nexport class ZFileSystemNodeBuilder {\n private _node: IZFileSystemNode;\n\n public constructor() {\n this._node = {\n path: \"/\",\n type: ZFileSystemNodeType.Folder,\n };\n }\n\n public created(at?: Date | string | undefined) {\n this._node.created = at instanceof Date ? at.toJSON() : at;\n return this;\n }\n\n public updated(at?: Date | string | undefined) {\n this._node.updated = at instanceof Date ? at.toJSON() : at;\n return this;\n }\n\n public size(bytes: bigint | number | undefined) {\n this._node.size = typeof bytes == \"number\" ? BigInt(bytes) : bytes;\n return this;\n }\n\n public path(path: string) {\n this._node.path = path;\n return this;\n }\n\n public type(type: ZFileSystemNodeType) {\n this._node.type = type;\n return this;\n }\n\n public file = this.type.bind(this, ZFileSystemNodeType.File);\n public folder = this.type.bind(this, ZFileSystemNodeType.Folder);\n\n public stats(s: Stats) {\n const builder = this.size(s.size).created(s.birthtime).updated(s.mtime);\n return s.isFile() ? builder.file() : builder.folder();\n }\n\n public build() {\n const clone = structuredClone(this._node);\n return omitBy(clone, isUndefined) as IZFileSystemNode;\n }\n}\n","import { glob } from \"glob\";\nimport { access } from \"node:fs/promises\";\nimport { dirname, isAbsolute, resolve } from \"node:path\";\nimport { cwd } from \"node:process\";\nimport type { IZFileSystemNode } from \"./file-system-node.mjs\";\nimport { ZFileSystemNodeBuilder } from \"./file-system-node.mjs\";\n\n/**\n * Represents options for searches.\n */\nexport interface IZFileSystemSearchOptions {\n /**\n * The directory to search in.\n *\n * If this is not set, then the cwd of the application is used.\n */\n cwd?: string;\n\n /**\n * A flag that determines whether or not to load the\n * file system information.\n *\n * This is true by default.\n */\n stat?: boolean;\n}\n\n/**\n * Represents options for directory walking.\n */\nexport interface IZFileSystemWalkOptions {\n /**\n * The starting directory.\n *\n * The default is the current working directory\n *\n * @see process.cwd for more information.\n */\n start?: string;\n\n /**\n * The directory to stop at.\n *\n * The default is the root of the file system.\n */\n stop?: string;\n\n /**\n * The type of mode that the path must support in order\n * to be approved.\n *\n * The default is undefined and left up to the node api.\n */\n mode?: number;\n}\n\n/**\n * Represents a service to enumerate the file system.\n */\nexport interface IZFileSystemService {\n /**\n * Gets information about a node.\n *\n * @param path -\n * The path to get information for.\n *\n * @returns\n * Information about the node.\n */\n info(path: string): Promise<IZFileSystemNode>;\n\n /**\n * Reads all nodes that match a pattern.\n *\n * @param pattern -\n * The pattern string to match against or a list\n * of patterns to match.\n * @param options -\n * The options for the search.\n *\n * @returns\n * A list of path strings that match the given patterns.\n */\n search(\n pattern: string | string[],\n options?: IZFileSystemSearchOptions,\n ): Promise<IZFileSystemNode[]>;\n\n /**\n * Walks up a directory tree to search for existence of a given path.\n *\n * @param search -\n * The path to search for. This is the candidate folder path that\n * may or may not exist somewhere from the start directory all the\n * way up the directory tree.\n * @param options -\n * The given options for the search.\n *\n * @returns\n * The fully qualified path to the first path that matches the search\n * starting at the options start or the current working directory if not\n * specified. Returns null if no such directory exists.\n *\n * @example\n *\n * ```ts\n * import { resolve } from 'path'\n *\n * // Find any folder named .vscode from the current working directory all the way\n * // up the directory tree. Returns null if no vscode directory can be found.\n * const service = new ZFileSystemService();\n * const vscode = service.walk('.vscode');\n *\n * // Walk the directory tree from the current script and find the .config folder.\n * const config = service.walk('.config', { start: __dirname });\n *\n * // Walk the directory tree from the current script and stop when we reach\n * // at most 2 directories up.\n * const start = __dirname;\n * const stop = resolve(__dirname, '../..');\n * const file = service.walk('path/to/file.json', { start, stop });\n * ```\n */\n walk(\n search: string,\n options?: IZFileSystemWalkOptions,\n ): Promise<string | null>;\n}\n\n/**\n * Represents a node implementation of a file system service.\n */\nexport class ZFileSystemService implements IZFileSystemService {\n public async info(path: string): Promise<IZFileSystemNode> {\n const [file] = await this.search(path);\n return file;\n }\n\n public async search(\n pattern: string | string[],\n options?: IZFileSystemSearchOptions,\n ): Promise<IZFileSystemNode[]> {\n const paths = await glob(pattern, {\n stat: true,\n ...options,\n withFileTypes: true,\n });\n\n return paths.map((path) => {\n let info = new ZFileSystemNodeBuilder()\n .path(path.fullpath())\n .created(path.birthtime)\n .updated(path.atime)\n .size(path.size);\n\n // Note that for folders, node will return the size of the underlying OS metadata,\n // hence, why we remove the size on the folder here.\n info = path.isFile() ? info.file() : info.folder().size(undefined);\n\n return info.build();\n });\n }\n\n public async walk(search: string, options?: IZFileSystemWalkOptions) {\n const start = options?.start || cwd();\n const stop = options?.stop || \"/\";\n const mode = options?.mode;\n\n const _test = async (path: string) => {\n try {\n await access(path, mode);\n return true;\n } catch {\n return false;\n }\n };\n\n if (isAbsolute(search)) {\n return (await _test(search)) ? search : null;\n }\n\n let dir = start;\n do {\n const path = resolve(dir, search);\n const exists = await _test(path);\n\n if (exists) {\n return path;\n }\n\n dir = dir === stop ? \"\" : dirname(dir);\n } while (dir.length);\n\n return null;\n }\n}\n","import type { FSWatcher } from \"chokidar\";\nimport { watch } from \"chokidar\";\nimport type { Stats } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { Observable } from \"rxjs\";\nimport { Subject } from \"rxjs\";\nimport {\n ZFileSystemNodeBuilder,\n type IZFileSystemNode,\n} from \"../file-system/file-system-node.mjs\";\n\n/**\n * Represents and object that can watch a folder or file on the file system.\n */\nexport interface IZFileWatch {\n /**\n * Starts the watch operation.\n */\n start(): Promise<void>;\n\n /**\n * Stops the watch operation.\n */\n stop(): Promise<void>;\n\n /**\n * The stream for files being added.\n *\n * This can only occur if the target being watched\n * is a folder.\n *\n * @returns\n * The observable that will publish files that\n * get added.\n */\n add(): Observable<IZFileSystemNode>;\n\n /**\n * The stream for files being updated.\n *\n * If this watcher points to a folder, then all files\n * recursively will send when they get updated. If this\n * watcher points to a file, then this will only invoke\n * when the file is updated.\n *\n * @returns\n * The observable that will publish files and folders\n * that are updated.\n */\n update(): Observable<IZFileSystemNode>;\n\n /**\n * The stream for files and folders being deleted.\n *\n * If this watcher points to a folder, then all files under the\n * folder will be sent through this observable, including the\n * folder being watched. If this points to a file, then\n * this will only receive when the file is unlinked.\n *\n * @returns\n * The observable that will publish file and folders\n * that are unlinked and removed respectively. Note\n * that files and folders streamed this way will not\n * have their stats set.\n */\n remove(): Observable<IZFileSystemNode>;\n}\n\n/**\n * An implementation of the IZFileWatch.\n */\nexport class ZFileWatch implements IZFileWatch {\n private _add: Subject<IZFileSystemNode> = new Subject<IZFileSystemNode>();\n private _update: Subject<IZFileSystemNode> = new Subject<IZFileSystemNode>();\n private _remove: Subject<IZFileSystemNode> = new Subject<IZFileSystemNode>();\n private _watcher: FSWatcher | undefined;\n\n /**\n * Initializes a new instance of this object.\n *\n * @param path -\n * The path to watch.\n */\n public constructor(public readonly path: string) {}\n\n public async start() {\n await this.stop();\n\n this._watcher = watch(this.path, {\n usePolling: true,\n alwaysStat: true,\n ignoreInitial: true,\n\n awaitWriteFinish: {\n stabilityThreshold: 500,\n pollInterval: 50,\n },\n });\n\n function next(\n observable: Subject<IZFileSystemNode>,\n file: string,\n stats: Stats | undefined,\n ) {\n const node = new ZFileSystemNodeBuilder().path(resolve(this.path, file));\n observable.next(stats ? node.stats(stats).build() : node.build());\n }\n\n this._watcher\n .on(\"add\", next.bind(this, this._add))\n .on(\"addDir\", next.bind(this, this._add))\n .on(\"change\", next.bind(this, this._update))\n .on(\"unlink\", next.bind(this, this._remove))\n .on(\"unlinkDir\", next.bind(this, this._remove));\n\n return new Promise<void>((resolve) =>\n this._watcher?.on(\"ready\", () => resolve()),\n );\n }\n\n public async stop() {\n await this._watcher?.close();\n delete this._watcher;\n return Promise.resolve();\n }\n\n public add() {\n return this._add.asObservable();\n }\n\n public update() {\n return this._update.asObservable();\n }\n\n public remove() {\n return this._remove.asObservable();\n }\n}\n","import { firstDefined, sleep } from \"@zthun/helpful-fn\";\nimport type { IZDataRequest, IZDataSource } from \"@zthun/helpful-query\";\nimport { ZDataSourceStatic } from \"@zthun/helpful-query\";\nimport { find, findIndex, flatten, trimEnd, uniqBy } from \"lodash-es\";\nimport { minimatch } from \"minimatch\";\nimport { resolve, sep } from \"node:path\";\nimport type { Subscription } from \"rxjs\";\nimport {\n ZFileSystemNodeType,\n type IZFileSystemNode,\n} from \"../file-system/file-system-node.mjs\";\nimport {\n ZFileSystemService,\n type IZFileSystemService,\n} from \"../file-system/file-system-service.mjs\";\nimport { ZFileWatch, type IZFileWatch } from \"../file-watch/file-watch.mjs\";\n\n/**\n * Represents a repository for the file system.\n */\nexport interface IZFileRepository extends IZDataSource<IZFileSystemNode> {\n /**\n * Retrieves a single file from the repository.\n *\n * @param path -\n * The fully qualified path to the file.\n *\n * @returns\n * The node that represents the file. Returns null if no\n * such file exists.\n */\n get(path: string): Promise<IZFileSystemNode | null>;\n}\n\n/**\n * Represents an implementation of a ZFileRepository that watches\n * a given path scope.\n *\n * This repository is only concerned about files. Folders\n * will not be retrieved from this repository.\n */\nexport class ZFileRepository implements IZFileRepository {\n private _service: IZFileSystemService = new ZFileSystemService();\n private _watcher: IZFileWatch | undefined;\n private _nodes: Promise<ZDataSourceStatic<IZFileSystemNode>> =\n Promise.resolve(new ZDataSourceStatic<IZFileSystemNode>([]));\n private _globs: string[] = [\"**\"];\n private _path: string = \"\";\n private _add: Subscription | undefined;\n private _remove: Subscription | undefined;\n private _update: Subscription | undefined;\n\n /**\n * Gets the path that this repository is watching.\n */\n public get path() {\n return this._path;\n }\n\n /**\n * Gets the globs matchers that this repository is matching against.\n */\n public get globs() {\n return this._globs.slice();\n }\n\n /**\n * Initializes the repository with the given root and glob filter.\n *\n * This will initially scan the file system and setup watches.\n * If you call this method again, then the repository will be\n * {@link reset} and a new set of files will be added to the\n * repository.\n *\n * @param path -\n * The root path of the repository.\n * @param globs -\n * The optional relative globs of the repository. If this is falsy,\n * then ** is used. You can achieve the same kind of operation\n * using filters, but filtering out unwanted files frees up the internal\n * memory being used.\n */\n public async initialize(path: string, globs: string[] = [\"**\"]) {\n await this.reset();\n\n this._path = path;\n this._globs = globs;\n\n // Note that this all happens in the background and should\n // only be awaited later. So the search should not be\n // required to finish when existing this method. The only\n // requirement is that the repository is reset and the path +\n // glob scope is updated. Everything beyond here should not\n // be awaited - it will be awaited later once the caller\n // tries to retrieve the files using retrieve, get, or\n // count.\n const matches = globs.map((g) =>\n this._service.search(g, {\n cwd: path,\n stat: true,\n }),\n );\n\n this._nodes = Promise.all(matches)\n .then((nodes) => {\n const flat = flatten(nodes);\n const uniq = uniqBy(flat, (n) => n.path);\n return uniq.filter((n) => n.type === ZFileSystemNodeType.File);\n })\n .then((files) => {\n return new ZDataSourceStatic(files);\n });\n\n this._watcher = new ZFileWatch(path);\n\n this._add = this._watcher\n .add()\n .subscribe(async (node: IZFileSystemNode) => {\n if (\n node.type === ZFileSystemNodeType.File &&\n this._globs.some((g) => minimatch(node.path, resolve(this._path, g)))\n ) {\n const nodes = await this._nodes;\n this._nodes = nodes.insert(node);\n }\n });\n\n this._remove = this._watcher\n .remove()\n .subscribe(async (node: IZFileSystemNode) => {\n let nodes = await this._nodes;\n const path = trimEnd(node.path, sep);\n\n // It's possible that the node given was a folder. If that happens,\n // we need to remove all files that start with the given path.\n // If the node does point to a file, then there is no possibility that\n // more than 1 item would be removed.\n\n const next = async () =>\n findIndex(await nodes.items(), (n) => {\n return (\n n.path === path ||\n (n.path.startsWith(path) &&\n n.path.substring(path.length).charAt(0) === sep)\n );\n });\n\n for (let index = await next(); index >= 0; index = await next()) {\n nodes = await nodes.removeAt(index);\n }\n\n this._nodes = Promise.resolve(nodes);\n });\n\n this._update = this._watcher\n .update()\n .subscribe(async (node: IZFileSystemNode) => {\n const nodes = await this._nodes;\n const index = findIndex(\n await nodes.items(),\n (n) => n.path === node.path,\n );\n\n // It's possible node was filtered out by the globs, or\n // it is a directory. If so, then we won't have it in our\n // list.\n if (index >= 0) {\n const next = await nodes.removeAt(index);\n this._nodes = next.insert(node, index);\n }\n });\n\n // Kick off the initial seed operation with an even loop\n // invocation.\n await sleep(100);\n\n await this._watcher?.start();\n }\n\n /**\n * Resets the repository as if it was initially created.\n */\n public async reset(): Promise<void> {\n await this._watcher?.stop();\n\n this._add?.unsubscribe();\n this._remove?.unsubscribe();\n this._update?.unsubscribe();\n\n delete this._add;\n delete this._remove;\n delete this._update;\n delete this._watcher;\n\n this._path = \"\";\n this._globs = [\"**\"];\n this._nodes = Promise.resolve(new ZDataSourceStatic<IZFileSystemNode>([]));\n }\n\n public async get(path: string): Promise<IZFileSystemNode | null> {\n const nodes = await this._nodes;\n const items = await nodes.items();\n const node = find(items, (f) => f.path === path);\n\n return firstDefined(null, node);\n }\n\n public async count(request: IZDataRequest): Promise<number> {\n const source = await this._nodes;\n return source.count(request);\n }\n\n public async retrieve(request: IZDataRequest): Promise<IZFileSystemNode[]> {\n const source = await this._nodes;\n return source.retrieve(request);\n }\n}\n","import type { PathLike } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nexport function resolvePathLike(path: PathLike): string {\n if (typeof path === \"string\") {\n return resolve(path);\n }\n\n if (path instanceof URL) {\n return fileURLToPath(path);\n }\n\n return resolve(path.toString());\n}\n","import { sleep } from \"@zthun/helpful-fn\";\n\n/**\n * The actual delay time that you should wait for a watch\n * operation to pick up your file changes.\n */\nexport const ZWatchDelay = 1500;\n\n/**\n * Performs a sleep long enough to allow a watch operation\n * to pick up a change.\n *\n * You should never really need this. Where it is useful\n * is for unit testing with IO operations and you want to\n * wait for your write operations to get picked up by\n * a file watch operation.\n */\nexport function sleepWatchDelay() {\n return sleep(ZWatchDelay);\n}\n","import type { PathLike } from \"fs\";\nimport { mkdir } from \"fs/promises\";\nimport type { IZStreamWrite } from \"./stream-write.mjs\";\n\n/**\n * A stream that writes folders.\n *\n * Writing folders is idempotent. If the folder you\n * are trying to write already exists, then the write\n * operation still succeeds\n */\nexport class ZStreamFolder implements IZStreamWrite {\n public async write(path: PathLike): Promise<number> {\n await mkdir(path, { recursive: true });\n\n return 0;\n }\n}\n","import type { PathLike, Stats } from \"node:fs\";\nimport { readFile, stat, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"path\";\nimport { resolvePathLike } from \"../resolve-path-like/resolve-path-like.js\";\nimport { ZStreamFolder } from \"./stream-folder.mjs\";\nimport type { IZStreamRead, IZStreamReadOptions } from \"./stream-read.mjs\";\nimport type { IZStreamWrite, IZStreamWriteOptions } from \"./stream-write.mjs\";\n\n/**\n * Options for the stream file object.\n */\nexport interface IZStreamFileOptions {\n /**\n * Cache options.\n *\n * A warning that file content caching will take up significant memory\n * if the file size is too big or the max files is too big. Make sure\n * you know what you're doing when you change the default values of this.\n */\n cache?: {\n /**\n * Maximum number of bytes a file can be before it will not be cached.\n * The default is 100 Kib (102400 bytes)\n *\n * @default 102400\n */\n fileSize?: bigint;\n /**\n * The maximum number of files that are to be cached. The cache order\n * is first in, first out. Set this to 0 to not cache anything. The\n * default is 1000.\n *\n * @default 1000\n */\n maxFiles?: number;\n };\n}\n\n/**\n * A stream that can read and write to files.\n *\n * This is mostly a wrapper to readFile and writeFile from node, but\n * with some optimizations.\n *\n * First, this class supports file content caching so reading in a file\n * that's under a certain size threshold will store it in memory for\n * later retrieval.\n */\nexport class ZStreamFile implements IZStreamWrite, IZStreamRead {\n private static readonly FileSizeDefault = 102400; // One Hundred KibiBytes\n private static readonly MaxFilesDefault = 1000;\n\n private _cache = new Map<string, { stats: Stats; buffer: Promise<Buffer> }>();\n\n /**\n * Initializes a new instance of this object.\n *\n * @param options -\n * The options for file read and writes.\n */\n public constructor(public readonly options: IZStreamFileOptions = {}) {}\n\n public async read(\n path: PathLike,\n options?: IZStreamReadOptions,\n ): Promise<Buffer> {\n const _path = resolvePathLike(path);\n\n const stats = await stat(_path);\n const cached = this._cache.get(_path);\n\n const buffer =\n cached && cached.stats.mtimeMs >= stats.mtimeMs\n ? cached.buffer\n : readFile(_path, options);\n\n return this._addToCache(_path, { stats, buffer });\n }\n\n public async write(\n path: PathLike,\n { buffer = Buffer.from(\"\") }: IZStreamWriteOptions = {},\n ): Promise<number> {\n const _path = resolvePathLike(path);\n const directory = dirname(_path);\n\n await new ZStreamFolder().write(directory);\n await writeFile(_path, buffer, { flush: true });\n\n // If this file specifically was cached earlier,\n // we can just remove it now so we make room for\n // another file. Consumers can just read the\n // file again to recache it.\n this._cache.delete(_path);\n\n return buffer.length;\n }\n\n private _addToCache(\n path: string,\n item: { stats: Stats; buffer: Promise<Buffer> },\n ) {\n const { cache = {} } = this.options;\n const {\n fileSize = ZStreamFile.FileSizeDefault,\n maxFiles = ZStreamFile.MaxFilesDefault,\n } = cache;\n\n if (item.stats.size > fileSize) {\n // In this case, the file size is too big to cache in memory,\n // so we're bowing out here.\n return item.buffer;\n }\n\n // We will remove this path from the cache first since\n // we want it to be the most recent file (at the end)\n // of the key list. The removal does nothing if the\n // file was not cached.\n this._cache.delete(path);\n this._cache.set(path, item);\n\n if (this._cache.size > maxFiles) {\n // Retrieving the keys from a javascript map is order\n // by the time in which the keys are created. So\n // we are going to remove the first key which is the\n // oldest.\n const itr = this._cache.keys();\n this._cache.delete(itr.next().value);\n }\n\n return item.buffer;\n }\n}\n"],"names":["ZFileSystemNodeType","ZFileSystemNodeBuilder","created","at","_node","Date","toJSON","updated","size","bytes","BigInt","path","type","stats","s","builder","birthtime","mtime","isFile","file","folder","build","clone","structuredClone","omitBy","isUndefined","_define_property","bind","ZFileSystemService","info","search","pattern","options","paths","glob","stat","withFileTypes","map","fullpath","atime","undefined","walk","start","cwd","stop","mode","_test","access","isAbsolute","dir","resolve","exists","dirname","length","ZFileWatch","_watcher","watch","usePolling","alwaysStat","ignoreInitial","awaitWriteFinish","stabilityThreshold","pollInterval","next","observable","node","on","_add","_update","_remove","Promise","close","add","asObservable","update","remove","Subject","ZFileRepository","_path","globs","_globs","slice","initialize","reset","matches","g","_service","_nodes","all","then","nodes","flat","flatten","uniq","uniqBy","n","filter","File","files","ZDataSourceStatic","subscribe","some","minimatch","insert","trimEnd","sep","findIndex","items","startsWith","substring","charAt","index","removeAt","sleep","unsubscribe","get","find","f","firstDefined","count","request","source","retrieve","resolvePathLike","URL","fileURLToPath","toString","ZWatchDelay","sleepWatchDelay","ZStreamFolder","write","mkdir","recursive","ZStreamFile","read","cached","_cache","buffer","mtimeMs","readFile","_addToCache","Buffer","from","directory","writeFile","flush","delete","item","cache","fileSize","FileSizeDefault","maxFiles","MaxFilesDefault","set","itr","keys","value","Map"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zthun/crumbtrail-fs",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.4",
|
|
4
4
|
"description": "A better file system module for node",
|
|
5
5
|
"author": "Anthony Bonta",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"access": "public"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@zthun/helpful-fn": "^9.
|
|
32
|
-
"@zthun/helpful-query": "^9.
|
|
31
|
+
"@zthun/helpful-fn": "^9.8.0",
|
|
32
|
+
"@zthun/helpful-query": "^9.8.0",
|
|
33
33
|
"chokidar": "^4.0.3",
|
|
34
34
|
"glob": "^11.0.3",
|
|
35
35
|
"lodash-es": "^4.17.21",
|
|
@@ -37,15 +37,15 @@
|
|
|
37
37
|
"rxjs": "^7.8.2"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@zthun/janitor-build-config": "^19.
|
|
40
|
+
"@zthun/janitor-build-config": "^19.4.1",
|
|
41
41
|
"typescript": "^5.9.3",
|
|
42
|
-
"vite": "^7.1.
|
|
43
|
-
"vitest": "^
|
|
42
|
+
"vite": "^7.1.11",
|
|
43
|
+
"vitest": "^4.0.1",
|
|
44
44
|
"vitest-mock-extended": "^3.1.0"
|
|
45
45
|
},
|
|
46
46
|
"files": [
|
|
47
47
|
"dist"
|
|
48
48
|
],
|
|
49
49
|
"sideEffects": false,
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "f2016ca545ae3f157021af14bc508a6e274fed34"
|
|
51
51
|
}
|