@zthun/crumbtrail-fs 2.4.5 → 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,497 +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
- return Promise.resolve();
187
- }
188
- add() {
189
- return this._add.asObservable();
190
- }
191
- update() {
192
- return this._update.asObservable();
193
- }
194
- remove() {
195
- return this._remove.asObservable();
196
- }
197
- /**
198
- * Initializes a new instance of this object.
199
- *
200
- * @param path -
201
- * The path to watch.
202
- */ constructor(path){
203
- _define_property$2(this, "path", void 0);
204
- _define_property$2(this, "_add", void 0);
205
- _define_property$2(this, "_update", void 0);
206
- _define_property$2(this, "_remove", void 0);
207
- _define_property$2(this, "_watcher", void 0);
208
- this.path = path;
209
- this._add = new rxjs.Subject();
210
- this._update = new rxjs.Subject();
211
- this._remove = new rxjs.Subject();
212
- }
213
- }
214
-
215
- function _define_property$1(obj, key, value) {
216
- if (key in obj) {
217
- Object.defineProperty(obj, key, {
218
- value: value,
219
- enumerable: true,
220
- configurable: true,
221
- writable: true
222
- });
223
- } else {
224
- obj[key] = value;
225
- }
226
- return obj;
227
- }
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
228
172
  /**
229
- * Represents an implementation of a ZFileRepository that watches
230
- * a given path scope.
231
- *
232
- * This repository is only concerned about files. Folders
233
- * will not be retrieved from this repository.
234
- */ class ZFileRepository {
235
- /**
236
- * Gets the path that this repository is watching.
237
- */ get path() {
238
- return this._path;
239
- }
240
- /**
241
- * Gets the globs matchers that this repository is matching against.
242
- */ get globs() {
243
- return this._globs.slice();
244
- }
245
- /**
246
- * Initializes the repository with the given root and glob filter.
247
- *
248
- * This will initially scan the file system and setup watches.
249
- * If you call this method again, then the repository will be
250
- * {@link reset} and a new set of files will be added to the
251
- * repository.
252
- *
253
- * @param path -
254
- * The root path of the repository.
255
- * @param globs -
256
- * The optional relative globs of the repository. If this is falsy,
257
- * then ** is used. You can achieve the same kind of operation
258
- * using filters, but filtering out unwanted files frees up the internal
259
- * memory being used.
260
- */ async initialize(path, globs = [
261
- "**"
262
- ]) {
263
- await this.reset();
264
- this._path = path;
265
- this._globs = globs;
266
- // Note that this all happens in the background and should
267
- // only be awaited later. So the search should not be
268
- // required to finish when existing this method. The only
269
- // requirement is that the repository is reset and the path +
270
- // glob scope is updated. Everything beyond here should not
271
- // be awaited - it will be awaited later once the caller
272
- // tries to retrieve the files using retrieve, get, or
273
- // count.
274
- const matches = globs.map((g)=>this._service.search(g, {
275
- cwd: path,
276
- stat: true
277
- }));
278
- this._nodes = Promise.all(matches).then((nodes)=>{
279
- const flat = lodashEs.flatten(nodes);
280
- const uniq = lodashEs.uniqBy(flat, (n)=>n.path);
281
- return uniq.filter((n)=>n.type === ZFileSystemNodeType.File);
282
- }).then((files)=>{
283
- return new helpfulQuery.ZDataSourceStatic(files);
284
- });
285
- this._watcher = new ZFileWatch(path);
286
- this._add = this._watcher.add().subscribe(async (node)=>{
287
- if (node.type === ZFileSystemNodeType.File && this._globs.some((g)=>minimatch.minimatch(node.path, node_path.resolve(this._path, g)))) {
288
- const nodes = await this._nodes;
289
- this._nodes = nodes.insert(node);
290
- }
291
- });
292
- this._remove = this._watcher.remove().subscribe(async (node)=>{
293
- let nodes = await this._nodes;
294
- const path = lodashEs.trimEnd(node.path, node_path.sep);
295
- // It's possible that the node given was a folder. If that happens,
296
- // we need to remove all files that start with the given path.
297
- // If the node does point to a file, then there is no possibility that
298
- // more than 1 item would be removed.
299
- const next = async ()=>lodashEs.findIndex(await nodes.items(), (n)=>{
300
- return n.path === path || n.path.startsWith(path) && n.path.substring(path.length).charAt(0) === node_path.sep;
301
- });
302
- for(let index = await next(); index >= 0; index = await next()){
303
- nodes = await nodes.removeAt(index);
304
- }
305
- this._nodes = Promise.resolve(nodes);
306
- });
307
- this._update = this._watcher.update().subscribe(async (node)=>{
308
- const nodes = await this._nodes;
309
- const index = lodashEs.findIndex(await nodes.items(), (n)=>n.path === node.path);
310
- // It's possible node was filtered out by the globs, or
311
- // it is a directory. If so, then we won't have it in our
312
- // list.
313
- if (index >= 0) {
314
- const next = await nodes.removeAt(index);
315
- this._nodes = next.insert(node, index);
316
- }
317
- });
318
- // Kick off the initial seed operation with an even loop
319
- // invocation.
320
- await helpfulFn.sleep(100);
321
- await this._watcher?.start();
322
- }
323
- /**
324
- * Resets the repository as if it was initially created.
325
- */ async reset() {
326
- await this._watcher?.stop();
327
- this._add?.unsubscribe();
328
- this._remove?.unsubscribe();
329
- this._update?.unsubscribe();
330
- delete this._add;
331
- delete this._remove;
332
- delete this._update;
333
- delete this._watcher;
334
- this._path = "";
335
- this._globs = [
336
- "**"
337
- ];
338
- this._nodes = Promise.resolve(new helpfulQuery.ZDataSourceStatic([]));
339
- }
340
- async get(path) {
341
- const nodes = await this._nodes;
342
- const items = await nodes.items();
343
- const node = lodashEs.find(items, (f)=>f.path === path);
344
- return helpfulFn.firstDefined(null, node);
345
- }
346
- async count(request) {
347
- const source = await this._nodes;
348
- return source.count(request);
349
- }
350
- async retrieve(request) {
351
- const source = await this._nodes;
352
- return source.retrieve(request);
353
- }
354
- constructor(){
355
- _define_property$1(this, "_service", new ZFileSystemService());
356
- _define_property$1(this, "_watcher", void 0);
357
- _define_property$1(this, "_nodes", Promise.resolve(new helpfulQuery.ZDataSourceStatic([])));
358
- _define_property$1(this, "_globs", [
359
- "**"
360
- ]);
361
- _define_property$1(this, "_path", "");
362
- _define_property$1(this, "_add", void 0);
363
- _define_property$1(this, "_remove", void 0);
364
- _define_property$1(this, "_update", void 0);
365
- }
366
- }
367
-
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
368
279
  function resolvePathLike(path) {
369
- if (typeof path === "string") {
370
- return node_path.resolve(path);
371
- }
372
- if (path instanceof URL) {
373
- return node_url.fileURLToPath(path);
374
- }
375
- 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());
376
283
  }
377
-
284
+ //#endregion
285
+ //#region src/sleep-watch-delay/sleep-watch-delay.mts
378
286
  /**
379
- * The actual delay time that you should wait for a watch
380
- * operation to pick up your file changes.
381
- */ 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;
382
290
  /**
383
- * Performs a sleep long enough to allow a watch operation
384
- * to pick up a change.
385
- *
386
- * You should never really need this. Where it is useful
387
- * is for unit testing with IO operations and you want to
388
- * wait for your write operations to get picked up by
389
- * a file watch operation.
390
- */ function sleepWatchDelay() {
391
- 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);
392
300
  }
393
-
301
+ //#endregion
302
+ //#region src/stream/stream-folder.mts
394
303
  /**
395
- * A stream that writes folders.
396
- *
397
- * Writing folders is idempotent. If the folder you
398
- * are trying to write already exists, then the write
399
- * operation still succeeds
400
- */ class ZStreamFolder {
401
- async write(path) {
402
- await promises$1.mkdir(path, {
403
- recursive: true
404
- });
405
- return 0;
406
- }
407
- }
408
-
409
- function _define_property(obj, key, value) {
410
- if (key in obj) {
411
- Object.defineProperty(obj, key, {
412
- value: value,
413
- enumerable: true,
414
- configurable: true,
415
- writable: true
416
- });
417
- } else {
418
- obj[key] = value;
419
- }
420
- return obj;
421
- }
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
422
317
  /**
423
- * A stream that can read and write to files.
424
- *
425
- * This is mostly a wrapper to readFile and writeFile from node, but
426
- * with some optimizations.
427
- *
428
- * First, this class supports file content caching so reading in a file
429
- * that's under a certain size threshold will store it in memory for
430
- * later retrieval.
431
- */ class ZStreamFile {
432
- async read(path, options) {
433
- const _path = resolvePathLike(path);
434
- const stats = await promises.stat(_path);
435
- const cached = this._cache.get(_path);
436
- const buffer = cached && cached.stats.mtimeMs >= stats.mtimeMs ? cached.buffer : promises.readFile(_path, options);
437
- return this._addToCache(_path, {
438
- stats,
439
- buffer
440
- });
441
- }
442
- async write(path$1, { buffer = Buffer.from("") } = {}) {
443
- const _path = resolvePathLike(path$1);
444
- const directory = path.dirname(_path);
445
- await new ZStreamFolder().write(directory);
446
- await promises.writeFile(_path, buffer, {
447
- flush: true
448
- });
449
- // If this file specifically was cached earlier,
450
- // we can just remove it now so we make room for
451
- // another file. Consumers can just read the
452
- // file again to recache it.
453
- this._cache.delete(_path);
454
- return buffer.length;
455
- }
456
- _addToCache(path, item) {
457
- const { cache = {} } = this.options;
458
- const { fileSize = ZStreamFile.FileSizeDefault, maxFiles = ZStreamFile.MaxFilesDefault } = cache;
459
- if (item.stats.size > fileSize) {
460
- // In this case, the file size is too big to cache in memory,
461
- // so we're bowing out here.
462
- return item.buffer;
463
- }
464
- // We will remove this path from the cache first since
465
- // we want it to be the most recent file (at the end)
466
- // of the key list. The removal does nothing if the
467
- // file was not cached.
468
- this._cache.delete(path);
469
- this._cache.set(path, item);
470
- if (this._cache.size > maxFiles) {
471
- // Retrieving the keys from a javascript map is order
472
- // by the time in which the keys are created. So
473
- // we are going to remove the first key which is the
474
- // oldest.
475
- const itr = this._cache.keys();
476
- this._cache.delete(itr.next().value);
477
- }
478
- return item.buffer;
479
- }
480
- /**
481
- * Initializes a new instance of this object.
482
- *
483
- * @param options -
484
- * The options for file read and writes.
485
- */ constructor(options = {}){
486
- _define_property(this, "options", void 0);
487
- _define_property(this, "_cache", void 0);
488
- this.options = options;
489
- this._cache = new Map();
490
- }
491
- }
492
- _define_property(ZStreamFile, "FileSizeDefault", 102400); // One Hundred KibiBytes
493
- _define_property(ZStreamFile, "MaxFilesDefault", 1000);
494
-
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
495
371
  exports.ZFileRepository = ZFileRepository;
496
372
  exports.ZFileSystemNodeBuilder = ZFileSystemNodeBuilder;
497
373
  exports.ZFileSystemNodeType = ZFileSystemNodeType;
@@ -502,4 +378,5 @@ exports.ZStreamFolder = ZStreamFolder;
502
378
  exports.ZWatchDelay = ZWatchDelay;
503
379
  exports.resolvePathLike = resolvePathLike;
504
380
  exports.sleepWatchDelay = sleepWatchDelay;
505
- //# sourceMappingURL=index.cjs.map
381
+
382
+ //# sourceMappingURL=index.cjs.map