@datatruck/cli 0.34.4 → 0.35.0

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.
@@ -13,6 +13,7 @@ class ProgressManager {
13
13
  interval = (0, date_1.createTimer)();
14
14
  intervalMs;
15
15
  keydownListener;
16
+ pendingProgress;
16
17
  tty;
17
18
  mode;
18
19
  constructor(options) {
@@ -66,19 +67,51 @@ class ProgressManager {
66
67
  this.keydownListener = undefined;
67
68
  }
68
69
  }
69
- update(progress, cb) {
70
- if (!this.mode)
70
+ create(input, delay = 1000) {
71
+ const update = (progress, force) => {
72
+ const text = this.renderProgress(progress, force);
73
+ if (typeof text === "string") {
74
+ if (typeof input === "function") {
75
+ input(text);
76
+ }
77
+ else {
78
+ input.output = text;
79
+ }
80
+ }
81
+ };
82
+ const updatePending = () => {
83
+ const pendingProgress = this.pendingProgress;
84
+ if (pendingProgress) {
85
+ this.pendingProgress = undefined;
86
+ update(pendingProgress, true);
87
+ }
88
+ };
89
+ const interval = setInterval(updatePending, delay);
90
+ return {
91
+ update,
92
+ [Symbol.dispose]: () => {
93
+ clearInterval(interval);
94
+ updatePending();
95
+ },
96
+ };
97
+ }
98
+ renderProgress(progress, force = false) {
99
+ if (!this.mode) {
71
100
  return;
72
- if (this.mode === "interval") {
101
+ }
102
+ else if (this.mode === "interval") {
73
103
  if (this.interval) {
74
- if (!this.interval.reset(this.intervalMs))
104
+ if (!this.interval.reset(this.intervalMs) && !force) {
105
+ this.pendingProgress = progress;
75
106
  return;
107
+ }
76
108
  }
77
109
  else {
78
110
  this.interval = (0, date_1.createTimer)();
79
111
  }
80
112
  }
81
- cb(renderProgress(progress, this.tty).join("\n"));
113
+ this.pendingProgress = undefined;
114
+ return renderProgress(progress, this.tty).join("\n");
82
115
  }
83
116
  }
84
117
  exports.ProgressManager = ProgressManager;
@@ -5,6 +5,7 @@ export declare function ensureFreeDiskTempSpace(size: number | string): Promise<
5
5
  export declare function isTmpDir(path: string): boolean;
6
6
  export declare function rmTmpDir(input: string | string[]): Promise<void>;
7
7
  export declare function tmpDir(...keys: [string, ...string[]]): string;
8
+ export declare const collectors: Set<GargabeCollector>;
8
9
  export declare function mkTmpDir(...keys: [string, ...string[]]): Promise<string>;
9
10
  export declare function useTempDir(...keys: [string, ...string[]]): Promise<AsyncDisposable & {
10
11
  path: string;
@@ -12,15 +13,17 @@ export declare function useTempDir(...keys: [string, ...string[]]): Promise<Asyn
12
13
  export declare function useTempFile(path: string): AsyncDisposable & {
13
14
  path: string;
14
15
  };
15
- export declare class CleanupListener {
16
- readonly paths: string[];
17
- stop(): void;
18
- dispose(): Promise<void>;
19
- }
20
16
  export declare class GargabeCollector {
21
- protected listeners: Set<CleanupListener>;
22
- get pending(): boolean;
23
- cleanup(cb?: () => any): Promise<void>;
24
- cleanupOnFinish(cb: () => any): Promise<void>;
25
- cleanupIfFail(cb: () => any): Promise<CleanupListener>;
17
+ protected parent?: GargabeCollector | undefined;
18
+ readonly paths: Set<string>;
19
+ readonly children: Set<GargabeCollector>;
20
+ constructor(parent?: GargabeCollector | undefined);
21
+ pending(): boolean;
22
+ cleanup(): Promise<void>;
23
+ dispose(): Promise<void>;
24
+ disposeIfFail<T>(cb: () => Promise<T>): Promise<T>;
25
+ disposeOnFinish(): {
26
+ [Symbol.asyncDispose]: () => Promise<void>;
27
+ };
28
+ create(): GargabeCollector;
26
29
  }
package/lib/utils/temp.js CHANGED
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.GargabeCollector = exports.CleanupListener = exports.useTempFile = exports.useTempDir = exports.mkTmpDir = exports.tmpDir = exports.rmTmpDir = exports.isTmpDir = exports.ensureFreeDiskTempSpace = exports.sessionTmpDir = exports.parentTmpDir = void 0;
6
+ exports.GargabeCollector = exports.useTempFile = exports.useTempDir = exports.mkTmpDir = exports.collectors = exports.tmpDir = exports.rmTmpDir = exports.isTmpDir = exports.ensureFreeDiskTempSpace = exports.sessionTmpDir = exports.parentTmpDir = void 0;
7
7
  const globalData_1 = __importDefault(require("../globalData"));
8
8
  const fs_1 = require("./fs");
9
9
  const crypto_1 = require("crypto");
@@ -44,12 +44,15 @@ exports.rmTmpDir = rmTmpDir;
44
44
  function tmpDir(...keys) {
45
45
  const id = (0, crypto_1.randomUUID)().slice(0, 8);
46
46
  const path = (0, path_1.join)(sessionTmpDir(), [...keys, id].map(encodeURIComponent).join("-"));
47
- for (const listener of listeners)
48
- listener.paths.push(path);
47
+ if (exports.collectors.size) {
48
+ const lastListener = [...exports.collectors.values()].at(exports.collectors.size - 1);
49
+ if (lastListener)
50
+ lastListener.paths.add(path);
51
+ }
49
52
  return path;
50
53
  }
51
54
  exports.tmpDir = tmpDir;
52
- const listeners = new Set();
55
+ exports.collectors = new Set();
53
56
  async function mkTmpDir(...keys) {
54
57
  const path = tmpDir(...keys);
55
58
  await (0, promises_1.mkdir)(path, { recursive: true });
@@ -81,53 +84,57 @@ function useTempFile(path) {
81
84
  };
82
85
  }
83
86
  exports.useTempFile = useTempFile;
84
- class CleanupListener {
85
- paths = [];
86
- stop() {
87
- listeners.delete(this);
88
- }
89
- async dispose() {
90
- this.stop();
91
- await rmTmpDir(this.paths);
92
- }
93
- }
94
- exports.CleanupListener = CleanupListener;
95
87
  class GargabeCollector {
96
- listeners = new Set();
97
- get pending() {
98
- return this.listeners.size > 0;
88
+ parent;
89
+ paths = new Set();
90
+ children = new Set();
91
+ constructor(parent) {
92
+ this.parent = parent;
93
+ exports.collectors.add(this);
99
94
  }
100
- async cleanup(cb) {
101
- try {
102
- await cb?.();
103
- }
104
- finally {
105
- for (const listener of this.listeners) {
106
- this.listeners.delete(listener);
107
- await listener.dispose();
95
+ pending() {
96
+ if (this.paths.size)
97
+ return true;
98
+ for (const child of this.children)
99
+ if (child.pending())
100
+ return true;
101
+ return false;
102
+ }
103
+ async cleanup() {
104
+ for (const path of this.paths) {
105
+ try {
106
+ await rmTmpDir(path);
107
+ this.paths.delete(path);
108
108
  }
109
+ catch (_) { }
109
110
  }
111
+ for (const child of this.children)
112
+ await child.cleanup();
110
113
  }
111
- async cleanupOnFinish(cb) {
112
- const cleanup = new CleanupListener();
113
- try {
114
- await cb();
115
- }
116
- finally {
117
- cleanup.dispose();
118
- }
114
+ async dispose() {
115
+ await this.cleanup();
116
+ exports.collectors.delete(this);
119
117
  }
120
- async cleanupIfFail(cb) {
121
- const cleanup = new CleanupListener();
118
+ async disposeIfFail(cb) {
122
119
  try {
123
- await cb();
120
+ return await cb();
124
121
  }
125
122
  catch (error) {
126
- await cleanup.dispose();
123
+ await this.dispose();
127
124
  throw error;
128
125
  }
129
- this.listeners.add(cleanup);
130
- return cleanup;
126
+ }
127
+ disposeOnFinish() {
128
+ return {
129
+ [Symbol.asyncDispose]: async () => {
130
+ return this.dispose();
131
+ },
132
+ };
133
+ }
134
+ create() {
135
+ const gc = new GargabeCollector();
136
+ this.children.add(gc);
137
+ return gc;
131
138
  }
132
139
  }
133
140
  exports.GargabeCollector = GargabeCollector;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datatruck/cli",
3
- "version": "0.34.4",
3
+ "version": "0.35.0",
4
4
  "description": "Tool for creating and managing backups",
5
5
  "homepage": "https://github.com/swordev/datatruck#readme",
6
6
  "bugs": {