memfs 3.4.13 → 3.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/node.d.ts CHANGED
@@ -9,17 +9,31 @@ export declare const SEP = "/";
9
9
  */
10
10
  export declare class Node extends EventEmitter {
11
11
  ino: number;
12
- uid: number;
13
- gid: number;
14
- atime: Date;
15
- mtime: Date;
16
- ctime: Date;
12
+ private _uid;
13
+ private _gid;
14
+ private _atime;
15
+ private _mtime;
16
+ private _ctime;
17
17
  buf: Buffer;
18
- perm: number;
18
+ private _perm;
19
19
  mode: number;
20
- nlink: number;
20
+ private _nlink;
21
21
  symlink: string[];
22
22
  constructor(ino: number, perm?: number);
23
+ set ctime(ctime: Date);
24
+ get ctime(): Date;
25
+ set uid(uid: number);
26
+ get uid(): number;
27
+ set gid(gid: number);
28
+ get gid(): number;
29
+ set atime(atime: Date);
30
+ get atime(): Date;
31
+ set mtime(mtime: Date);
32
+ get mtime(): Date;
33
+ set perm(perm: number);
34
+ get perm(): number;
35
+ set nlink(nlink: number);
36
+ get nlink(): number;
23
37
  getString(encoding?: string): string;
24
38
  setString(str: string): void;
25
39
  getBuffer(): Buffer;
package/lib/node.js CHANGED
@@ -34,22 +34,99 @@ var Node = /** @class */ (function (_super) {
34
34
  if (perm === void 0) { perm = 438; }
35
35
  var _this = _super.call(this) || this;
36
36
  // User ID and group ID.
37
- _this.uid = getuid();
38
- _this.gid = getgid();
39
- _this.atime = new Date();
40
- _this.mtime = new Date();
41
- _this.ctime = new Date();
42
- _this.perm = 438; // Permissions `chmod`, `fchmod`
37
+ _this._uid = getuid();
38
+ _this._gid = getgid();
39
+ _this._atime = new Date();
40
+ _this._mtime = new Date();
41
+ _this._ctime = new Date();
42
+ _this._perm = 438; // Permissions `chmod`, `fchmod`
43
43
  _this.mode = S_IFREG; // S_IFDIR, S_IFREG, etc.. (file by default?)
44
44
  // Number of hard links pointing at this Node.
45
- _this.nlink = 1;
46
- _this.perm = perm;
45
+ _this._nlink = 1;
46
+ _this._perm = perm;
47
47
  _this.mode |= perm;
48
48
  _this.ino = ino;
49
49
  return _this;
50
50
  }
51
+ Object.defineProperty(Node.prototype, "ctime", {
52
+ get: function () {
53
+ return this._ctime;
54
+ },
55
+ set: function (ctime) {
56
+ this._ctime = ctime;
57
+ },
58
+ enumerable: false,
59
+ configurable: true
60
+ });
61
+ Object.defineProperty(Node.prototype, "uid", {
62
+ get: function () {
63
+ return this._uid;
64
+ },
65
+ set: function (uid) {
66
+ this._uid = uid;
67
+ this.ctime = new Date();
68
+ },
69
+ enumerable: false,
70
+ configurable: true
71
+ });
72
+ Object.defineProperty(Node.prototype, "gid", {
73
+ get: function () {
74
+ return this._gid;
75
+ },
76
+ set: function (gid) {
77
+ this._gid = gid;
78
+ this.ctime = new Date();
79
+ },
80
+ enumerable: false,
81
+ configurable: true
82
+ });
83
+ Object.defineProperty(Node.prototype, "atime", {
84
+ get: function () {
85
+ return this._atime;
86
+ },
87
+ set: function (atime) {
88
+ this._atime = atime;
89
+ this.ctime = new Date();
90
+ },
91
+ enumerable: false,
92
+ configurable: true
93
+ });
94
+ Object.defineProperty(Node.prototype, "mtime", {
95
+ get: function () {
96
+ return this._mtime;
97
+ },
98
+ set: function (mtime) {
99
+ this._mtime = mtime;
100
+ this.ctime = new Date();
101
+ },
102
+ enumerable: false,
103
+ configurable: true
104
+ });
105
+ Object.defineProperty(Node.prototype, "perm", {
106
+ get: function () {
107
+ return this._perm;
108
+ },
109
+ set: function (perm) {
110
+ this._perm = perm;
111
+ this.ctime = new Date();
112
+ },
113
+ enumerable: false,
114
+ configurable: true
115
+ });
116
+ Object.defineProperty(Node.prototype, "nlink", {
117
+ get: function () {
118
+ return this._nlink;
119
+ },
120
+ set: function (nlink) {
121
+ this._nlink = nlink;
122
+ this.ctime = new Date();
123
+ },
124
+ enumerable: false,
125
+ configurable: true
126
+ });
51
127
  Node.prototype.getString = function (encoding) {
52
128
  if (encoding === void 0) { encoding = 'utf8'; }
129
+ this.atime = new Date();
53
130
  return this.getBuffer().toString(encoding);
54
131
  };
55
132
  Node.prototype.setString = function (str) {
@@ -58,6 +135,7 @@ var Node = /** @class */ (function (_super) {
58
135
  this.touch();
59
136
  };
60
137
  Node.prototype.getBuffer = function () {
138
+ this.atime = new Date();
61
139
  if (!this.buf)
62
140
  this.setBuffer((0, buffer_1.bufferAllocUnsafe)(0));
63
141
  return (0, buffer_1.bufferFrom)(this.buf); // Return a copy.
@@ -115,6 +193,7 @@ var Node = /** @class */ (function (_super) {
115
193
  if (off === void 0) { off = 0; }
116
194
  if (len === void 0) { len = buf.byteLength; }
117
195
  if (pos === void 0) { pos = 0; }
196
+ this.atime = new Date();
118
197
  if (!this.buf)
119
198
  this.buf = (0, buffer_1.bufferAllocUnsafe)(0);
120
199
  var actualLen = len;
@@ -244,9 +323,12 @@ var Link = /** @class */ (function (_super) {
244
323
  // Recursively sync children steps, e.g. in case of dir rename
245
324
  set: function (val) {
246
325
  this._steps = val;
247
- for (var _i = 0, _a = Object.values(this.children); _i < _a.length; _i++) {
248
- var child = _a[_i];
249
- child === null || child === void 0 ? void 0 : child.syncSteps();
326
+ for (var _i = 0, _a = Object.entries(this.children); _i < _a.length; _i++) {
327
+ var _b = _a[_i], child = _b[0], link = _b[1];
328
+ if (child === '.' || child === '..') {
329
+ continue;
330
+ }
331
+ link === null || link === void 0 ? void 0 : link.syncSteps();
250
332
  }
251
333
  },
252
334
  enumerable: false,
@@ -264,10 +346,8 @@ var Link = /** @class */ (function (_super) {
264
346
  var link = new Link(this.vol, this, name);
265
347
  link.setNode(node);
266
348
  if (node.isDirectory()) {
267
- // link.setChild('.', link);
268
- // link.getNode().nlink++;
269
- // link.setChild('..', this);
270
- // this.getNode().nlink++;
349
+ link.children['.'] = link;
350
+ link.getNode().nlink++;
271
351
  }
272
352
  this.setChild(name, link);
273
353
  return link;
@@ -277,15 +357,28 @@ var Link = /** @class */ (function (_super) {
277
357
  this.children[name] = link;
278
358
  link.parent = this;
279
359
  this.length++;
360
+ var node = link.getNode();
361
+ if (node.isDirectory()) {
362
+ link.children['..'] = this;
363
+ this.getNode().nlink++;
364
+ }
365
+ this.getNode().mtime = new Date();
280
366
  this.emit('child:add', link, this);
281
367
  return link;
282
368
  };
283
369
  Link.prototype.deleteChild = function (link) {
370
+ var node = link.getNode();
371
+ if (node.isDirectory()) {
372
+ delete link.children['..'];
373
+ this.getNode().nlink--;
374
+ }
284
375
  delete this.children[link.getName()];
285
376
  this.length--;
377
+ this.getNode().mtime = new Date();
286
378
  this.emit('child:delete', link, this);
287
379
  };
288
380
  Link.prototype.getChild = function (name) {
381
+ this.getNode().mtime = new Date();
289
382
  if (Object.hasOwnProperty.call(this.children, name)) {
290
383
  return this.children[name];
291
384
  }
package/lib/volume.d.ts CHANGED
@@ -440,9 +440,9 @@ export declare class FSWatcher extends EventEmitter {
440
440
  _encoding: BufferEncoding;
441
441
  _link: Link;
442
442
  _timer: any;
443
+ private _listenerRemovers;
443
444
  constructor(vol: Volume);
444
445
  private _getName;
445
- private _onNodeChange;
446
446
  private _onParentChild;
447
447
  private _emit;
448
448
  private _persist;
package/lib/volume.js CHANGED
@@ -500,10 +500,10 @@ var Volume = /** @class */ (function () {
500
500
  }
501
501
  return FSWatcher;
502
502
  }(FSWatcher));
503
- // root.setChild('.', root);
504
- // root.getNode().nlink++;
505
- // root.setChild('..', root);
506
- // root.getNode().nlink++;
503
+ root.setChild('.', root);
504
+ root.getNode().nlink++;
505
+ root.setChild('..', root);
506
+ root.getNode().nlink++;
507
507
  this.root = root;
508
508
  }
509
509
  Volume.fromJSON = function (json, cwd) {
@@ -715,6 +715,9 @@ var Volume = /** @class */ (function () {
715
715
  link = link.parent;
716
716
  }
717
717
  for (var name_1 in children) {
718
+ if (name_1 === '.' || name_1 === '..') {
719
+ continue;
720
+ }
718
721
  isEmpty = false;
719
722
  var child = link.getChild(name_1);
720
723
  if (!child) {
@@ -1423,7 +1426,7 @@ var Volume = /** @class */ (function () {
1423
1426
  var list_1 = [];
1424
1427
  for (var name_2 in link.children) {
1425
1428
  var child = link.getChild(name_2);
1426
- if (!child) {
1429
+ if (!child || name_2 === '.' || name_2 === '..') {
1427
1430
  continue;
1428
1431
  }
1429
1432
  list_1.push(Dirent_1.default.build(child, options.encoding));
@@ -1440,6 +1443,9 @@ var Volume = /** @class */ (function () {
1440
1443
  }
1441
1444
  var list = [];
1442
1445
  for (var name_3 in link.children) {
1446
+ if (name_3 === '.' || name_3 === '..') {
1447
+ continue;
1448
+ }
1443
1449
  list.push((0, encoding_1.strToEncoding)(name_3, options.encoding));
1444
1450
  }
1445
1451
  if (!isWin && options.encoding !== 'buffer')
@@ -2217,9 +2223,8 @@ var FSWatcher = /** @class */ (function (_super) {
2217
2223
  // _persistent: boolean = true;
2218
2224
  _this._recursive = false;
2219
2225
  _this._encoding = encoding_1.ENCODING_UTF8;
2220
- _this._onNodeChange = function () {
2221
- _this._emit('change');
2222
- };
2226
+ // inode -> removers
2227
+ _this._listenerRemovers = new Map();
2223
2228
  _this._onParentChild = function (link) {
2224
2229
  if (link.getName() === _this._getName()) {
2225
2230
  _this._emit('rename');
@@ -2251,6 +2256,7 @@ var FSWatcher = /** @class */ (function (_super) {
2251
2256
  return this._steps[this._steps.length - 1];
2252
2257
  };
2253
2258
  FSWatcher.prototype.start = function (path, persistent, recursive, encoding) {
2259
+ var _this = this;
2254
2260
  if (persistent === void 0) { persistent = true; }
2255
2261
  if (recursive === void 0) { recursive = false; }
2256
2262
  if (encoding === void 0) { encoding = encoding_1.ENCODING_UTF8; }
@@ -2269,9 +2275,74 @@ var FSWatcher = /** @class */ (function (_super) {
2269
2275
  error.errno = err.code;
2270
2276
  throw error;
2271
2277
  }
2272
- this._link.getNode().on('change', this._onNodeChange);
2273
- this._link.on('child:add', this._onNodeChange);
2274
- this._link.on('child:delete', this._onNodeChange);
2278
+ var watchLinkNodeChanged = function (link) {
2279
+ var _a;
2280
+ var filepath = link.getPath();
2281
+ var node = link.getNode();
2282
+ var onNodeChange = function () { return _this.emit('change', 'change', relative(_this._filename, filepath)); };
2283
+ node.on('change', onNodeChange);
2284
+ var removers = (_a = _this._listenerRemovers.get(node.ino)) !== null && _a !== void 0 ? _a : [];
2285
+ removers.push(function () { return node.removeListener('change', onNodeChange); });
2286
+ _this._listenerRemovers.set(node.ino, removers);
2287
+ };
2288
+ var watchLinkChildrenChanged = function (link) {
2289
+ var _a;
2290
+ var node = link.getNode();
2291
+ // when a new link added
2292
+ var onLinkChildAdd = function (l) {
2293
+ _this.emit('change', 'rename', relative(_this._filename, l.getPath()));
2294
+ setTimeout(function () {
2295
+ // 1. watch changes of the new link-node
2296
+ watchLinkNodeChanged(l);
2297
+ // 2. watch changes of the new link-node's children
2298
+ watchLinkChildrenChanged(l);
2299
+ });
2300
+ };
2301
+ // when a new link deleted
2302
+ var onLinkChildDelete = function (l) {
2303
+ // remove the listeners of the children nodes
2304
+ var removeLinkNodeListeners = function (curLink) {
2305
+ var ino = curLink.getNode().ino;
2306
+ var removers = _this._listenerRemovers.get(ino);
2307
+ if (removers) {
2308
+ removers.forEach(function (r) { return r(); });
2309
+ _this._listenerRemovers.delete(ino);
2310
+ }
2311
+ Object.values(curLink.children).forEach(function (childLink) {
2312
+ if (childLink) {
2313
+ removeLinkNodeListeners(childLink);
2314
+ }
2315
+ });
2316
+ };
2317
+ removeLinkNodeListeners(l);
2318
+ _this.emit('change', 'rename', relative(_this._filename, l.getPath()));
2319
+ };
2320
+ // children nodes changed
2321
+ Object.entries(link.children).forEach(function (_a) {
2322
+ var name = _a[0], childLink = _a[1];
2323
+ if (childLink && name !== '.' && name !== '..') {
2324
+ watchLinkNodeChanged(childLink);
2325
+ }
2326
+ });
2327
+ // link children add/remove
2328
+ link.on('child:add', onLinkChildAdd);
2329
+ link.on('child:delete', onLinkChildDelete);
2330
+ var removers = (_a = _this._listenerRemovers.get(node.ino)) !== null && _a !== void 0 ? _a : [];
2331
+ removers.push(function () {
2332
+ link.removeListener('child:add', onLinkChildAdd);
2333
+ link.removeListener('child:delete', onLinkChildDelete);
2334
+ });
2335
+ if (recursive) {
2336
+ Object.entries(link.children).forEach(function (_a) {
2337
+ var name = _a[0], childLink = _a[1];
2338
+ if (childLink && name !== '.' && name !== '..') {
2339
+ watchLinkChildrenChanged(childLink);
2340
+ }
2341
+ });
2342
+ }
2343
+ };
2344
+ watchLinkNodeChanged(this._link);
2345
+ watchLinkChildrenChanged(this._link);
2275
2346
  var parent = this._link.parent;
2276
2347
  if (parent) {
2277
2348
  // parent.on('child:add', this._onParentChild);
@@ -2283,7 +2354,10 @@ var FSWatcher = /** @class */ (function (_super) {
2283
2354
  };
2284
2355
  FSWatcher.prototype.close = function () {
2285
2356
  clearTimeout(this._timer);
2286
- this._link.getNode().removeListener('change', this._onNodeChange);
2357
+ this._listenerRemovers.forEach(function (removers) {
2358
+ removers.forEach(function (r) { return r(); });
2359
+ });
2360
+ this._listenerRemovers.clear();
2287
2361
  var parent = this._link.parent;
2288
2362
  if (parent) {
2289
2363
  // parent.removeListener('child:add', this._onParentChild);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memfs",
3
- "version": "3.4.13",
3
+ "version": "3.5.1",
4
4
  "description": "In-memory file-system with Node's fs API.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",