@zthun/crumbtrail-fs 2.4.6 → 2.4.9

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 CHANGED
@@ -1,496 +1,373 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
-
5
- const helpfulFn = require('@zthun/helpful-fn');
6
- const helpfulQuery = require('@zthun/helpful-query');
7
- const lodashEs = require('lodash-es');
8
- const minimatch = require('minimatch');
9
- const node_path = require('node:path');
10
- const glob = require('glob');
11
- const promises = require('node:fs/promises');
12
- const node_process = require('node:process');
13
- const chokidar = require('chokidar');
14
- const rxjs = require('rxjs');
15
- const node_url = require('node:url');
16
- const path = require('path');
17
- const promises$1 = require('fs/promises');
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
- }
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let node_path = require("node:path");
3
+ let _zthun_helpful_fn = require("@zthun/helpful-fn");
4
+ let _zthun_helpful_query = require("@zthun/helpful-query");
5
+ let lodash_es = require("lodash-es");
6
+ let minimatch = require("minimatch");
7
+ let node_fs_promises = require("node:fs/promises");
8
+ let node_process = require("node:process");
9
+ let glob = require("glob");
10
+ let chokidar = require("chokidar");
11
+ let rxjs = require("rxjs");
12
+ let node_url = require("node:url");
13
+ let path = require("path");
14
+ let fs_promises = require("fs/promises");
15
+ //#region src/file-system/file-system-node.mts
32
16
  /**
33
- * Represents a type of a file system node.
34
- */ var ZFileSystemNodeType = /*#__PURE__*/ function(ZFileSystemNodeType) {
35
- ZFileSystemNodeType["File"] = "file";
36
- ZFileSystemNodeType["Folder"] = "folder";
37
- return ZFileSystemNodeType;
17
+ * Represents a type of a file system node.
18
+ */ var ZFileSystemNodeType = /* @__PURE__ */ function(ZFileSystemNodeType) {
19
+ ZFileSystemNodeType["File"] = "file";
20
+ ZFileSystemNodeType["Folder"] = "folder";
21
+ return ZFileSystemNodeType;
38
22
  }({});
39
23
  /**
40
- * Represents a builder for a file system node.
41
- */ class ZFileSystemNodeBuilder {
42
- created(at) {
43
- this._node.created = at instanceof Date ? at.toJSON() : at;
44
- return this;
45
- }
46
- updated(at) {
47
- this._node.updated = at instanceof Date ? at.toJSON() : at;
48
- return this;
49
- }
50
- size(bytes) {
51
- this._node.size = typeof bytes == "number" ? BigInt(bytes) : bytes;
52
- return this;
53
- }
54
- path(path) {
55
- this._node.path = path;
56
- return this.decorate();
57
- }
58
- type(type) {
59
- this._node.type = type;
60
- return this.decorate();
61
- }
62
- stats(s) {
63
- const builder = this.size(s.size).created(s.birthtime).updated(s.mtime);
64
- return s.isFile() ? builder.file() : builder.folder();
65
- }
66
- build() {
67
- const clone = structuredClone(this._node);
68
- return lodashEs.omitBy(clone, lodashEs.isUndefined);
69
- }
70
- decorate() {
71
- const { path, type } = this._node;
72
- this._node.name = node_path.basename(path);
73
- this._node.extension = "";
74
- this._node.title = this._node.name;
75
- this._node.parent = node_path.dirname(path);
76
- if (type === "file") {
77
- const extension = node_path.extname(path);
78
- this._node.extension = extension;
79
- this._node.title = node_path.basename(path, extension);
80
- }
81
- if (!path || path === "/" || this._node.parent === ".") {
82
- this._node.parent = "";
83
- }
84
- return this;
85
- }
86
- constructor(){
87
- _define_property$3(this, "_node", {
88
- path: "/",
89
- type: "folder",
90
- extension: "",
91
- name: "",
92
- parent: "",
93
- title: ""
94
- });
95
- _define_property$3(this, "file", this.type.bind(this, "file"));
96
- _define_property$3(this, "folder", this.type.bind(this, "folder"));
97
- }
98
- }
99
-
24
+ * Represents a builder for a file system node.
25
+ */ var ZFileSystemNodeBuilder = class {
26
+ _node = {
27
+ path: "/",
28
+ type: "folder",
29
+ extension: "",
30
+ name: "",
31
+ parent: "",
32
+ title: ""
33
+ };
34
+ created(at) {
35
+ this._node.created = at instanceof Date ? at.toJSON() : at;
36
+ return this;
37
+ }
38
+ updated(at) {
39
+ this._node.updated = at instanceof Date ? at.toJSON() : at;
40
+ return this;
41
+ }
42
+ size(bytes) {
43
+ this._node.size = typeof bytes == "number" ? BigInt(bytes) : bytes;
44
+ return this;
45
+ }
46
+ path(path) {
47
+ this._node.path = path;
48
+ return this.decorate();
49
+ }
50
+ type(type) {
51
+ this._node.type = type;
52
+ return this.decorate();
53
+ }
54
+ file = this.type.bind(this, "file");
55
+ folder = this.type.bind(this, "folder");
56
+ stats(s) {
57
+ const builder = this.size(s.size).created(s.birthtime).updated(s.mtime);
58
+ return s.isFile() ? builder.file() : builder.folder();
59
+ }
60
+ build() {
61
+ return (0, lodash_es.omitBy)(structuredClone(this._node), lodash_es.isUndefined);
62
+ }
63
+ decorate() {
64
+ const { path, type } = this._node;
65
+ this._node.name = (0, node_path.basename)(path);
66
+ this._node.extension = "";
67
+ this._node.title = this._node.name;
68
+ this._node.parent = (0, node_path.dirname)(path);
69
+ if (type === "file") {
70
+ const extension = (0, node_path.extname)(path);
71
+ this._node.extension = extension;
72
+ this._node.title = (0, node_path.basename)(path, extension);
73
+ }
74
+ if (!path || path === "/" || this._node.parent === ".") this._node.parent = "";
75
+ return this;
76
+ }
77
+ };
78
+ //#endregion
79
+ //#region src/file-system/file-system-service.mts
100
80
  /**
101
- * Represents a node implementation of a file system service.
102
- */ class ZFileSystemService {
103
- async info(path) {
104
- const [file] = await this.search(path);
105
- return file;
106
- }
107
- async search(pattern, options) {
108
- const paths = await glob.glob(pattern, {
109
- stat: true,
110
- ...options,
111
- withFileTypes: true
112
- });
113
- return paths.map((path)=>{
114
- let info = new ZFileSystemNodeBuilder().path(path.fullpath()).created(path.birthtime).updated(path.atime).size(path.size);
115
- // Note that for folders, node will return the size of the underlying OS metadata,
116
- // hence, why we remove the size on the folder here.
117
- info = path.isFile() ? info.file() : info.folder().size(undefined);
118
- return info.build();
119
- });
120
- }
121
- async walk(search, options) {
122
- const start = options?.start || node_process.cwd();
123
- const stop = options?.stop || "/";
124
- const mode = options?.mode;
125
- const _test = async (path)=>{
126
- try {
127
- await promises.access(path, mode);
128
- return true;
129
- } catch {
130
- return false;
131
- }
132
- };
133
- if (node_path.isAbsolute(search)) {
134
- return await _test(search) ? search : null;
135
- }
136
- let dir = start;
137
- do {
138
- const path = node_path.resolve(dir, search);
139
- const exists = await _test(path);
140
- if (exists) {
141
- return path;
142
- }
143
- dir = dir === stop ? "" : node_path.dirname(dir);
144
- }while (dir.length)
145
- return null;
146
- }
147
- }
148
-
149
- function _define_property$2(obj, key, value) {
150
- if (key in obj) {
151
- Object.defineProperty(obj, key, {
152
- value: value,
153
- enumerable: true,
154
- configurable: true,
155
- writable: true
156
- });
157
- } else {
158
- obj[key] = value;
159
- }
160
- return obj;
161
- }
81
+ * Represents a node implementation of a file system service.
82
+ */ var ZFileSystemService = class {
83
+ async info(path) {
84
+ const [file] = await this.search(path);
85
+ return file;
86
+ }
87
+ async search(pattern, options) {
88
+ return (await (0, glob.glob)(pattern, {
89
+ stat: true,
90
+ ...options,
91
+ withFileTypes: true
92
+ })).map((path) => {
93
+ let info = new ZFileSystemNodeBuilder().path(path.fullpath()).created(path.birthtime).updated(path.atime).size(path.size);
94
+ info = path.isFile() ? info.file() : info.folder().size(void 0);
95
+ return info.build();
96
+ });
97
+ }
98
+ async walk(search, options) {
99
+ const start = options?.start || (0, node_process.cwd)();
100
+ const stop = options?.stop || "/";
101
+ const mode = options?.mode;
102
+ const _test = async (path) => {
103
+ try {
104
+ await (0, node_fs_promises.access)(path, mode);
105
+ return true;
106
+ } catch {
107
+ return false;
108
+ }
109
+ };
110
+ if ((0, node_path.isAbsolute)(search)) return await _test(search) ? search : null;
111
+ let dir = start;
112
+ do {
113
+ const path = (0, node_path.resolve)(dir, search);
114
+ if (await _test(path)) return path;
115
+ dir = dir === stop ? "" : (0, node_path.dirname)(dir);
116
+ } while (dir.length);
117
+ return null;
118
+ }
119
+ };
120
+ //#endregion
121
+ //#region src/file-watch/file-watch.mts
162
122
  /**
163
- * An implementation of the IZFileWatch.
164
- */ class ZFileWatch {
165
- async start() {
166
- await this.stop();
167
- this._watcher = chokidar.watch(this.path, {
168
- usePolling: true,
169
- alwaysStat: true,
170
- ignoreInitial: true,
171
- awaitWriteFinish: {
172
- stabilityThreshold: 500,
173
- pollInterval: 50
174
- }
175
- });
176
- function next(observable, file, stats) {
177
- const node = new ZFileSystemNodeBuilder().path(node_path.resolve(this.path, file));
178
- observable.next(stats ? node.stats(stats).build() : node.build());
179
- }
180
- this._watcher.on("add", next.bind(this, this._add)).on("addDir", next.bind(this, this._add)).on("change", next.bind(this, this._update)).on("unlink", next.bind(this, this._remove)).on("unlinkDir", next.bind(this, this._remove));
181
- return new Promise((resolve)=>this._watcher?.on("ready", ()=>resolve()));
182
- }
183
- async stop() {
184
- await this._watcher?.close();
185
- delete this._watcher;
186
- }
187
- add() {
188
- return this._add.asObservable();
189
- }
190
- update() {
191
- return this._update.asObservable();
192
- }
193
- remove() {
194
- return this._remove.asObservable();
195
- }
196
- /**
197
- * Initializes a new instance of this object.
198
- *
199
- * @param path -
200
- * The path to watch.
201
- */ constructor(path){
202
- _define_property$2(this, "path", void 0);
203
- _define_property$2(this, "_add", void 0);
204
- _define_property$2(this, "_update", void 0);
205
- _define_property$2(this, "_remove", void 0);
206
- _define_property$2(this, "_watcher", void 0);
207
- this.path = path;
208
- this._add = new rxjs.Subject();
209
- this._update = new rxjs.Subject();
210
- this._remove = new rxjs.Subject();
211
- }
212
- }
213
-
214
- function _define_property$1(obj, key, value) {
215
- if (key in obj) {
216
- Object.defineProperty(obj, key, {
217
- value: value,
218
- enumerable: true,
219
- configurable: true,
220
- writable: true
221
- });
222
- } else {
223
- obj[key] = value;
224
- }
225
- return obj;
226
- }
123
+ * An implementation of the IZFileWatch.
124
+ */ var ZFileWatch = class {
125
+ path;
126
+ _add = new rxjs.Subject();
127
+ _update = new rxjs.Subject();
128
+ _remove = new rxjs.Subject();
129
+ _watcher;
130
+ /**
131
+ * Initializes a new instance of this object.
132
+ *
133
+ * @param path -
134
+ * The path to watch.
135
+ */ constructor(path) {
136
+ this.path = path;
137
+ }
138
+ async start() {
139
+ await this.stop();
140
+ this._watcher = (0, chokidar.watch)(this.path, {
141
+ usePolling: true,
142
+ alwaysStat: true,
143
+ ignoreInitial: true,
144
+ awaitWriteFinish: {
145
+ stabilityThreshold: 500,
146
+ pollInterval: 50
147
+ }
148
+ });
149
+ function next(observable, file, stats) {
150
+ const node = new ZFileSystemNodeBuilder().path((0, node_path.resolve)(this.path, file));
151
+ observable.next(stats ? node.stats(stats).build() : node.build());
152
+ }
153
+ this._watcher.on("add", next.bind(this, this._add)).on("addDir", next.bind(this, this._add)).on("change", next.bind(this, this._update)).on("unlink", next.bind(this, this._remove)).on("unlinkDir", next.bind(this, this._remove));
154
+ return new Promise((resolve) => this._watcher?.on("ready", () => resolve()));
155
+ }
156
+ async stop() {
157
+ await this._watcher?.close();
158
+ delete this._watcher;
159
+ }
160
+ add() {
161
+ return this._add.asObservable();
162
+ }
163
+ update() {
164
+ return this._update.asObservable();
165
+ }
166
+ remove() {
167
+ return this._remove.asObservable();
168
+ }
169
+ };
170
+ //#endregion
171
+ //#region src/file-repository/file-repository.mts
227
172
  /**
228
- * Represents an implementation of a ZFileRepository that watches
229
- * a given path scope.
230
- *
231
- * This repository is only concerned about files. Folders
232
- * will not be retrieved from this repository.
233
- */ class ZFileRepository {
234
- /**
235
- * Gets the path that this repository is watching.
236
- */ get path() {
237
- return this._path;
238
- }
239
- /**
240
- * Gets the globs matchers that this repository is matching against.
241
- */ get globs() {
242
- return this._globs.slice();
243
- }
244
- /**
245
- * Initializes the repository with the given root and glob filter.
246
- *
247
- * This will initially scan the file system and setup watches.
248
- * If you call this method again, then the repository will be
249
- * {@link reset} and a new set of files will be added to the
250
- * repository.
251
- *
252
- * @param path -
253
- * The root path of the repository.
254
- * @param globs -
255
- * The optional relative globs of the repository. If this is falsy,
256
- * then ** is used. You can achieve the same kind of operation
257
- * using filters, but filtering out unwanted files frees up the internal
258
- * memory being used.
259
- */ async initialize(path, globs = [
260
- "**"
261
- ]) {
262
- await this.reset();
263
- this._path = path;
264
- this._globs = globs;
265
- // Note that this all happens in the background and should
266
- // only be awaited later. So the search should not be
267
- // required to finish when existing this method. The only
268
- // requirement is that the repository is reset and the path +
269
- // glob scope is updated. Everything beyond here should not
270
- // be awaited - it will be awaited later once the caller
271
- // tries to retrieve the files using retrieve, get, or
272
- // count.
273
- const matches = globs.map((g)=>this._service.search(g, {
274
- cwd: path,
275
- stat: true
276
- }));
277
- this._nodes = Promise.all(matches).then((nodes)=>{
278
- const flat = lodashEs.flatten(nodes);
279
- const uniq = lodashEs.uniqBy(flat, (n)=>n.path);
280
- return uniq.filter((n)=>n.type === ZFileSystemNodeType.File);
281
- }).then((files)=>{
282
- return new helpfulQuery.ZDataSourceStatic(files);
283
- });
284
- this._watcher = new ZFileWatch(path);
285
- this._add = this._watcher.add().subscribe(async (node)=>{
286
- if (node.type === ZFileSystemNodeType.File && this._globs.some((g)=>minimatch.minimatch(node.path, node_path.resolve(this._path, g)))) {
287
- const nodes = await this._nodes;
288
- this._nodes = nodes.insert(node);
289
- }
290
- });
291
- this._remove = this._watcher.remove().subscribe(async (node)=>{
292
- let nodes = await this._nodes;
293
- const path = lodashEs.trimEnd(node.path, node_path.sep);
294
- // It's possible that the node given was a folder. If that happens,
295
- // we need to remove all files that start with the given path.
296
- // If the node does point to a file, then there is no possibility that
297
- // more than 1 item would be removed.
298
- const next = async ()=>lodashEs.findIndex(await nodes.items(), (n)=>{
299
- return n.path === path || n.path.startsWith(path) && n.path.substring(path.length).charAt(0) === node_path.sep;
300
- });
301
- for(let index = await next(); index >= 0; index = await next()){
302
- nodes = await nodes.removeAt(index);
303
- }
304
- this._nodes = Promise.resolve(nodes);
305
- });
306
- this._update = this._watcher.update().subscribe(async (node)=>{
307
- const nodes = await this._nodes;
308
- const index = lodashEs.findIndex(await nodes.items(), (n)=>n.path === node.path);
309
- // It's possible node was filtered out by the globs, or
310
- // it is a directory. If so, then we won't have it in our
311
- // list.
312
- if (index >= 0) {
313
- const next = await nodes.removeAt(index);
314
- this._nodes = next.insert(node, index);
315
- }
316
- });
317
- // Kick off the initial seed operation with an even loop
318
- // invocation.
319
- await helpfulFn.sleep(100);
320
- await this._watcher?.start();
321
- }
322
- /**
323
- * Resets the repository as if it was initially created.
324
- */ async reset() {
325
- await this._watcher?.stop();
326
- this._add?.unsubscribe();
327
- this._remove?.unsubscribe();
328
- this._update?.unsubscribe();
329
- delete this._add;
330
- delete this._remove;
331
- delete this._update;
332
- delete this._watcher;
333
- this._path = "";
334
- this._globs = [
335
- "**"
336
- ];
337
- this._nodes = Promise.resolve(new helpfulQuery.ZDataSourceStatic([]));
338
- }
339
- async get(path) {
340
- const nodes = await this._nodes;
341
- const items = await nodes.items();
342
- const node = lodashEs.find(items, (f)=>f.path === path);
343
- return helpfulFn.firstDefined(null, node);
344
- }
345
- async count(request) {
346
- const source = await this._nodes;
347
- return source.count(request);
348
- }
349
- async retrieve(request) {
350
- const source = await this._nodes;
351
- return source.retrieve(request);
352
- }
353
- constructor(){
354
- _define_property$1(this, "_service", new ZFileSystemService());
355
- _define_property$1(this, "_watcher", void 0);
356
- _define_property$1(this, "_nodes", Promise.resolve(new helpfulQuery.ZDataSourceStatic([])));
357
- _define_property$1(this, "_globs", [
358
- "**"
359
- ]);
360
- _define_property$1(this, "_path", "");
361
- _define_property$1(this, "_add", void 0);
362
- _define_property$1(this, "_remove", void 0);
363
- _define_property$1(this, "_update", void 0);
364
- }
365
- }
366
-
173
+ * Represents an implementation of a ZFileRepository that watches
174
+ * a given path scope.
175
+ *
176
+ * This repository is only concerned about files. Folders
177
+ * will not be retrieved from this repository.
178
+ */ var ZFileRepository = class {
179
+ _service = new ZFileSystemService();
180
+ _watcher;
181
+ _nodes = Promise.resolve(new _zthun_helpful_query.ZDataSourceStatic([]));
182
+ _globs = ["**"];
183
+ _path = "";
184
+ _add;
185
+ _remove;
186
+ _update;
187
+ /**
188
+ * Gets the path that this repository is watching.
189
+ */ get path() {
190
+ return this._path;
191
+ }
192
+ /**
193
+ * Gets the globs matchers that this repository is matching against.
194
+ */ get globs() {
195
+ return this._globs.slice();
196
+ }
197
+ /**
198
+ * Initializes the repository with the given root and glob filter.
199
+ *
200
+ * This will initially scan the file system and setup watches.
201
+ * If you call this method again, then the repository will be
202
+ * {@link reset} and a new set of files will be added to the
203
+ * repository.
204
+ *
205
+ * @param path -
206
+ * The root path of the repository.
207
+ * @param globs -
208
+ * The optional relative globs of the repository. If this is falsy,
209
+ * then ** is used. You can achieve the same kind of operation
210
+ * using filters, but filtering out unwanted files frees up the internal
211
+ * memory being used.
212
+ */ async initialize(path, globs = ["**"]) {
213
+ await this.reset();
214
+ this._path = path;
215
+ this._globs = globs;
216
+ const matches = globs.map((g) => this._service.search(g, {
217
+ cwd: path,
218
+ stat: true
219
+ }));
220
+ this._nodes = Promise.all(matches).then((nodes) => {
221
+ return (0, lodash_es.uniqBy)((0, lodash_es.flatten)(nodes), (n) => n.path).filter((n) => n.type === ZFileSystemNodeType.File);
222
+ }).then((files) => {
223
+ return new _zthun_helpful_query.ZDataSourceStatic(files);
224
+ });
225
+ this._watcher = new ZFileWatch(path);
226
+ this._add = this._watcher.add().subscribe((node) => {
227
+ (async () => {
228
+ if (node.type === ZFileSystemNodeType.File && this._globs.some((g) => (0, minimatch.minimatch)(node.path, (0, node_path.resolve)(this._path, g)))) this._nodes = (await this._nodes).insert(node);
229
+ })();
230
+ });
231
+ this._remove = this._watcher.remove().subscribe((node) => {
232
+ (async () => {
233
+ let nodes = await this._nodes;
234
+ const path = (0, lodash_es.trimEnd)(node.path, node_path.sep);
235
+ const next = async () => (0, lodash_es.findIndex)(await nodes.items(), (n) => {
236
+ return n.path === path || n.path.startsWith(path) && n.path.substring(path.length).charAt(0) === node_path.sep;
237
+ });
238
+ for (let index = await next(); index >= 0; index = await next()) nodes = await nodes.removeAt(index);
239
+ this._nodes = Promise.resolve(nodes);
240
+ })();
241
+ });
242
+ this._update = this._watcher.update().subscribe((node) => {
243
+ (async () => {
244
+ const nodes = await this._nodes;
245
+ const index = (0, lodash_es.findIndex)(await nodes.items(), (n) => n.path === node.path);
246
+ if (index >= 0) this._nodes = (await nodes.removeAt(index)).insert(node, index);
247
+ })();
248
+ });
249
+ await (0, _zthun_helpful_fn.sleep)(100);
250
+ await this._watcher?.start();
251
+ }
252
+ /**
253
+ * Resets the repository as if it was initially created.
254
+ */ async reset() {
255
+ await this._watcher?.stop();
256
+ this._add?.unsubscribe();
257
+ this._remove?.unsubscribe();
258
+ this._update?.unsubscribe();
259
+ delete this._add;
260
+ delete this._remove;
261
+ delete this._update;
262
+ delete this._watcher;
263
+ this._path = "";
264
+ this._globs = ["**"];
265
+ this._nodes = Promise.resolve(new _zthun_helpful_query.ZDataSourceStatic([]));
266
+ }
267
+ async get(path) {
268
+ return (0, _zthun_helpful_fn.firstDefined)(null, (0, lodash_es.find)(await (await this._nodes).items(), (f) => f.path === path));
269
+ }
270
+ async count(request) {
271
+ return (await this._nodes).count(request);
272
+ }
273
+ async retrieve(request) {
274
+ return (await this._nodes).retrieve(request);
275
+ }
276
+ };
277
+ //#endregion
278
+ //#region src/resolve-path-like/resolve-path-like.ts
367
279
  function resolvePathLike(path) {
368
- if (typeof path === "string") {
369
- return node_path.resolve(path);
370
- }
371
- if (path instanceof URL) {
372
- return node_url.fileURLToPath(path);
373
- }
374
- return node_path.resolve(path.toString());
280
+ if (typeof path === "string") return (0, node_path.resolve)(path);
281
+ if (path instanceof URL) return (0, node_url.fileURLToPath)(path);
282
+ return (0, node_path.resolve)(path.toString());
375
283
  }
376
-
284
+ //#endregion
285
+ //#region src/sleep-watch-delay/sleep-watch-delay.mts
377
286
  /**
378
- * The actual delay time that you should wait for a watch
379
- * operation to pick up your file changes.
380
- */ const ZWatchDelay = 1500;
287
+ * The actual delay time that you should wait for a watch
288
+ * operation to pick up your file changes.
289
+ */ var ZWatchDelay = 1500;
381
290
  /**
382
- * Performs a sleep long enough to allow a watch operation
383
- * to pick up a change.
384
- *
385
- * You should never really need this. Where it is useful
386
- * is for unit testing with IO operations and you want to
387
- * wait for your write operations to get picked up by
388
- * a file watch operation.
389
- */ function sleepWatchDelay() {
390
- return helpfulFn.sleep(ZWatchDelay);
291
+ * Performs a sleep long enough to allow a watch operation
292
+ * to pick up a change.
293
+ *
294
+ * You should never really need this. Where it is useful
295
+ * is for unit testing with IO operations and you want to
296
+ * wait for your write operations to get picked up by
297
+ * a file watch operation.
298
+ */ function sleepWatchDelay() {
299
+ return (0, _zthun_helpful_fn.sleep)(ZWatchDelay);
391
300
  }
392
-
301
+ //#endregion
302
+ //#region src/stream/stream-folder.mts
393
303
  /**
394
- * A stream that writes folders.
395
- *
396
- * Writing folders is idempotent. If the folder you
397
- * are trying to write already exists, then the write
398
- * operation still succeeds
399
- */ class ZStreamFolder {
400
- async write(path) {
401
- await promises$1.mkdir(path, {
402
- recursive: true
403
- });
404
- return 0;
405
- }
406
- }
407
-
408
- function _define_property(obj, key, value) {
409
- if (key in obj) {
410
- Object.defineProperty(obj, key, {
411
- value: value,
412
- enumerable: true,
413
- configurable: true,
414
- writable: true
415
- });
416
- } else {
417
- obj[key] = value;
418
- }
419
- return obj;
420
- }
304
+ * A stream that writes folders.
305
+ *
306
+ * Writing folders is idempotent. If the folder you
307
+ * are trying to write already exists, then the write
308
+ * operation still succeeds
309
+ */ var ZStreamFolder = class {
310
+ async write(path) {
311
+ await (0, fs_promises.mkdir)(path, { recursive: true });
312
+ return 0;
313
+ }
314
+ };
315
+ //#endregion
316
+ //#region src/stream/stream-file.mts
421
317
  /**
422
- * A stream that can read and write to files.
423
- *
424
- * This is mostly a wrapper to readFile and writeFile from node, but
425
- * with some optimizations.
426
- *
427
- * First, this class supports file content caching so reading in a file
428
- * that's under a certain size threshold will store it in memory for
429
- * later retrieval.
430
- */ class ZStreamFile {
431
- async read(path, options) {
432
- const _path = resolvePathLike(path);
433
- const stats = await promises.stat(_path);
434
- const cached = this._cache.get(_path);
435
- const buffer = cached && cached.stats.mtimeMs >= stats.mtimeMs ? cached.buffer : promises.readFile(_path, options);
436
- return this._addToCache(_path, {
437
- stats,
438
- buffer
439
- });
440
- }
441
- async write(path$1, { buffer = Buffer.from("") } = {}) {
442
- const _path = resolvePathLike(path$1);
443
- const directory = path.dirname(_path);
444
- await new ZStreamFolder().write(directory);
445
- await promises.writeFile(_path, buffer, {
446
- flush: true
447
- });
448
- // If this file specifically was cached earlier,
449
- // we can just remove it now so we make room for
450
- // another file. Consumers can just read the
451
- // file again to recache it.
452
- this._cache.delete(_path);
453
- return buffer.length;
454
- }
455
- _addToCache(path, item) {
456
- const { cache = {} } = this.options;
457
- const { fileSize = ZStreamFile.FileSizeDefault, maxFiles = ZStreamFile.MaxFilesDefault } = cache;
458
- if (item.stats.size > fileSize) {
459
- // In this case, the file size is too big to cache in memory,
460
- // so we're bowing out here.
461
- return item.buffer;
462
- }
463
- // We will remove this path from the cache first since
464
- // we want it to be the most recent file (at the end)
465
- // of the key list. The removal does nothing if the
466
- // file was not cached.
467
- this._cache.delete(path);
468
- this._cache.set(path, item);
469
- if (this._cache.size > maxFiles) {
470
- // Retrieving the keys from a javascript map is order
471
- // by the time in which the keys are created. So
472
- // we are going to remove the first key which is the
473
- // oldest.
474
- const itr = this._cache.keys();
475
- this._cache.delete(itr.next().value);
476
- }
477
- return item.buffer;
478
- }
479
- /**
480
- * Initializes a new instance of this object.
481
- *
482
- * @param options -
483
- * The options for file read and writes.
484
- */ constructor(options = {}){
485
- _define_property(this, "options", void 0);
486
- _define_property(this, "_cache", void 0);
487
- this.options = options;
488
- this._cache = new Map();
489
- }
490
- }
491
- _define_property(ZStreamFile, "FileSizeDefault", 102400); // One Hundred KibiBytes
492
- _define_property(ZStreamFile, "MaxFilesDefault", 1000);
493
-
318
+ * A stream that can read and write to files.
319
+ *
320
+ * This is mostly a wrapper to readFile and writeFile from node, but
321
+ * with some optimizations.
322
+ *
323
+ * First, this class supports file content caching so reading in a file
324
+ * that's under a certain size threshold will store it in memory for
325
+ * later retrieval.
326
+ */ var ZStreamFile = class ZStreamFile {
327
+ options;
328
+ static FileSizeDefault = 102400;
329
+ static MaxFilesDefault = 1e3;
330
+ _cache = /* @__PURE__ */ new Map();
331
+ /**
332
+ * Initializes a new instance of this object.
333
+ *
334
+ * @param options -
335
+ * The options for file read and writes.
336
+ */ constructor(options = {}) {
337
+ this.options = options;
338
+ }
339
+ async read(path$1, options) {
340
+ const _path = resolvePathLike(path$1);
341
+ const stats = await (0, node_fs_promises.stat)(_path);
342
+ const cached = this._cache.get(_path);
343
+ const buffer = cached && cached.stats.mtimeMs >= stats.mtimeMs ? cached.buffer : (0, node_fs_promises.readFile)(_path, options);
344
+ return this._addToCache(_path, {
345
+ stats,
346
+ buffer
347
+ });
348
+ }
349
+ async write(path$2, { buffer = Buffer.from("") } = {}) {
350
+ const _path = resolvePathLike(path$2);
351
+ const directory = (0, path.dirname)(_path);
352
+ await new ZStreamFolder().write(directory);
353
+ await (0, node_fs_promises.writeFile)(_path, buffer, { flush: true });
354
+ this._cache.delete(_path);
355
+ return buffer.length;
356
+ }
357
+ _addToCache(path$3, item) {
358
+ const { cache = {} } = this.options;
359
+ const { fileSize = ZStreamFile.FileSizeDefault, maxFiles = ZStreamFile.MaxFilesDefault } = cache;
360
+ if (item.stats.size > fileSize) return item.buffer;
361
+ this._cache.delete(path$3);
362
+ this._cache.set(path$3, item);
363
+ if (this._cache.size > maxFiles) {
364
+ const itr = this._cache.keys();
365
+ this._cache.delete(itr.next().value);
366
+ }
367
+ return item.buffer;
368
+ }
369
+ };
370
+ //#endregion
494
371
  exports.ZFileRepository = ZFileRepository;
495
372
  exports.ZFileSystemNodeBuilder = ZFileSystemNodeBuilder;
496
373
  exports.ZFileSystemNodeType = ZFileSystemNodeType;
@@ -501,4 +378,5 @@ exports.ZStreamFolder = ZStreamFolder;
501
378
  exports.ZWatchDelay = ZWatchDelay;
502
379
  exports.resolvePathLike = resolvePathLike;
503
380
  exports.sleepWatchDelay = sleepWatchDelay;
504
- //# sourceMappingURL=index.cjs.map
381
+
382
+ //# sourceMappingURL=index.cjs.map