Link.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.Link = void 0;
  4. const fs_node_utils_1 = require("@jsonjoy.com/fs-node-utils");
  5. const fanout_1 = require("thingies/lib/fanout");
  6. const { S_IFREG } = fs_node_utils_1.constants;
  7. /**
  8. * Represents a hard link that points to an i-node `node`.
  9. */
  10. class Link {
  11. get steps() {
  12. return this._steps;
  13. }
  14. // Recursively sync children steps, e.g. in case of dir rename
  15. set steps(val) {
  16. this._steps = val;
  17. for (const [child, link] of this.children.entries()) {
  18. if (child === '.' || child === '..') {
  19. continue;
  20. }
  21. link?.syncSteps();
  22. }
  23. }
  24. constructor(vol, parent, name) {
  25. this.changes = new fanout_1.FanOut();
  26. this.children = new Map();
  27. // Path to this node as Array: ['usr', 'bin', 'node'].
  28. this._steps = [];
  29. // "i-node" number of the node.
  30. this.ino = 0;
  31. // Number of children.
  32. this.length = 0;
  33. this.vol = vol;
  34. this.parent = parent;
  35. this.name = name;
  36. this.syncSteps();
  37. }
  38. setNode(node) {
  39. this.node = node;
  40. this.ino = node.ino;
  41. }
  42. getNode() {
  43. return this.node;
  44. }
  45. createChild(name, node = this.vol.createNode(S_IFREG | 0o666)) {
  46. const link = new Link(this.vol, this, name);
  47. link.setNode(node);
  48. if (node.isDirectory()) {
  49. link.children.set('.', link);
  50. link.getNode().nlink++;
  51. }
  52. this.setChild(name, link);
  53. return link;
  54. }
  55. setChild(name, link = new Link(this.vol, this, name)) {
  56. this.children.set(name, link);
  57. link.parent = this;
  58. this.length++;
  59. const node = link.getNode();
  60. if (node.isDirectory()) {
  61. link.children.set('..', this);
  62. this.getNode().nlink++;
  63. }
  64. this.getNode().mtime = new Date();
  65. this.changes.emit(['child:add', link, this]);
  66. return link;
  67. }
  68. deleteChild(link) {
  69. const node = link.getNode();
  70. if (node.isDirectory()) {
  71. link.children.delete('..');
  72. this.getNode().nlink--;
  73. }
  74. this.children.delete(link.getName());
  75. this.length--;
  76. this.getNode().mtime = new Date();
  77. this.changes.emit(['child:del', link, this]);
  78. }
  79. getChild(name) {
  80. this.getNode().atime = new Date();
  81. return this.children.get(name);
  82. }
  83. getPath() {
  84. return this.steps.join("/" /* PATH.SEP */);
  85. }
  86. getParentPath() {
  87. const parent = this.steps.slice(0, -1).join("/" /* PATH.SEP */);
  88. return parent ? parent : "/" /* PATH.SEP */;
  89. }
  90. getName() {
  91. return this.steps[this.steps.length - 1];
  92. }
  93. toJSON() {
  94. return {
  95. steps: this.steps,
  96. ino: this.ino,
  97. children: Array.from(this.children.keys()),
  98. };
  99. }
  100. syncSteps() {
  101. this.steps = this.parent ? this.parent.steps.concat([this.name]) : [this.name];
  102. }
  103. }
  104. exports.Link = Link;
  105. //# sourceMappingURL=Link.js.map