@niceties/draftlog-appender 1.2.8 → 1.3.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.
- package/dist/core.cjs +178 -98
- package/dist/core.d.ts +1 -1
- package/dist/core.mjs +178 -98
- package/dist/details/canvas.d.ts +2 -2
- package/dist/details/model.d.ts +14 -14
- package/dist/details/split-by-lines.d.ts +1 -0
- package/dist/details/terminal.d.ts +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/dist/core.cjs
CHANGED
|
@@ -3,78 +3,181 @@
|
|
|
3
3
|
var draftlog = require('draftlog');
|
|
4
4
|
var list = require('@slimlib/list');
|
|
5
5
|
|
|
6
|
-
const
|
|
6
|
+
const allColumnsListeners = new Set();
|
|
7
|
+
function subscribeToTerminalResize(listener) {
|
|
8
|
+
allColumnsListeners.add(new WeakRef(listener));
|
|
9
|
+
}
|
|
10
|
+
process.stdout.on('resize', () => {
|
|
11
|
+
for (const listener of allColumnsListeners) {
|
|
12
|
+
const realListener = listener.deref();
|
|
13
|
+
if (realListener) {
|
|
14
|
+
realListener();
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
allColumnsListeners.delete(listener);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
function splitByLines(message) {
|
|
23
|
+
var _a;
|
|
24
|
+
return (_a = message
|
|
25
|
+
.match(getSubstringsRegex())) !== null && _a !== void 0 ? _a : [];
|
|
26
|
+
}
|
|
27
|
+
let substringsRegex, substringsColumns;
|
|
28
|
+
function getSubstringsRegex() {
|
|
29
|
+
const newColumns = process.stdout.columns || 80;
|
|
30
|
+
if (substringsColumns !== newColumns) {
|
|
31
|
+
substringsRegex = new RegExp(`.{1,${newColumns}}`, 'g');
|
|
32
|
+
substringsColumns = newColumns;
|
|
33
|
+
}
|
|
34
|
+
return substringsRegex;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function createCanvas(spinner, formatter, ident) {
|
|
7
38
|
draftlog(console);
|
|
8
39
|
draftlog.defaults.canReWrite = false;
|
|
9
40
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
10
41
|
const updaters = [];
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
};
|
|
17
|
-
return
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
42
|
+
let lastModel;
|
|
43
|
+
subscribeToTerminalResize(() => {
|
|
44
|
+
if (lastModel) {
|
|
45
|
+
modelFn(lastModel, true);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
return modelFn;
|
|
49
|
+
function modelFn(model, dirty = false) {
|
|
50
|
+
lastModel = model;
|
|
51
|
+
if (model.skipLines) {
|
|
52
|
+
updaters.splice(0, model.skipLines);
|
|
53
|
+
model.skipLines = 0;
|
|
21
54
|
}
|
|
22
|
-
let key = 0
|
|
55
|
+
let key = 0;
|
|
23
56
|
const stack = [];
|
|
24
57
|
for (const item of model) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
58
|
+
if (dirty || item.dirty || item.status) {
|
|
59
|
+
let prefix = getPrefix(item.status, model.tick), prefixUpdated = false;
|
|
60
|
+
const subitems = splitByLines(item.message);
|
|
61
|
+
for (const message of subitems) {
|
|
62
|
+
let updater = updaters[key++];
|
|
63
|
+
if (!updater) {
|
|
64
|
+
updater = console.draft(' ');
|
|
65
|
+
updaters.push(updater);
|
|
66
|
+
}
|
|
67
|
+
updater(formatter({
|
|
68
|
+
loglevel: item.loglevel,
|
|
69
|
+
message,
|
|
70
|
+
context: item.context,
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
72
|
+
action: (item.status === undefined ? 3 /* log */ : undefined),
|
|
73
|
+
tag: item.tag
|
|
74
|
+
}, prefix, ident * stack.length));
|
|
75
|
+
if (subitems.length > 1 && typeof prefix === 'string' && !prefixUpdated) {
|
|
76
|
+
prefix = prefix.replaceAll(/./g, ' ');
|
|
77
|
+
prefixUpdated = true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (item.dirty) {
|
|
81
|
+
item.dirty = false;
|
|
42
82
|
dirty = true;
|
|
43
83
|
}
|
|
44
84
|
}
|
|
45
|
-
|
|
46
|
-
|
|
85
|
+
else {
|
|
86
|
+
// iterate
|
|
87
|
+
key += splitByLines(item.message).length;
|
|
88
|
+
}
|
|
47
89
|
if (stack[stack.length - 1] === item) {
|
|
48
90
|
stack[stack.length - 1] = null;
|
|
49
91
|
}
|
|
50
|
-
if (item.
|
|
51
|
-
stack.push(item.
|
|
92
|
+
if (item.lastLeaf) {
|
|
93
|
+
stack.push(item.lastLeaf);
|
|
52
94
|
}
|
|
53
95
|
while (stack.length && stack[stack.length - 1] == null) {
|
|
54
96
|
stack.pop();
|
|
55
97
|
}
|
|
56
98
|
}
|
|
57
|
-
|
|
58
|
-
|
|
99
|
+
while (key < updaters.length) {
|
|
100
|
+
updaters[key++]('');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function getPrefix(status, tick) {
|
|
104
|
+
// status is truthy when it is inprogress
|
|
105
|
+
return status ? spinner.frames[tick] :
|
|
106
|
+
// status not null when it is finished
|
|
107
|
+
status != null;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
59
110
|
|
|
60
|
-
|
|
111
|
+
/******************************************************************************
|
|
112
|
+
Copyright (c) Microsoft Corporation.
|
|
113
|
+
|
|
114
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
115
|
+
purpose with or without fee is hereby granted.
|
|
116
|
+
|
|
117
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
118
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
119
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
120
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
121
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
122
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
123
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
124
|
+
***************************************************************************** */
|
|
125
|
+
|
|
126
|
+
function __rest(s, e) {
|
|
127
|
+
var t = {};
|
|
128
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
129
|
+
t[p] = s[p];
|
|
130
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
131
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
132
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
133
|
+
t[p[i]] = s[p[i]];
|
|
134
|
+
}
|
|
135
|
+
return t;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function createModel(logAboveSpinners) {
|
|
61
139
|
const model = new list.List();
|
|
62
140
|
const itemById = Object.create(null);
|
|
63
|
-
|
|
141
|
+
model.tick = model.skipLines = model.spinning = 0;
|
|
142
|
+
return [(_a) => {
|
|
143
|
+
var { action } = _a, item = __rest(_a, ["action"]);
|
|
144
|
+
// item has status undefined, so it is static by default
|
|
145
|
+
item.dirty = true;
|
|
146
|
+
const { inputId } = item;
|
|
147
|
+
if (action === 0 /* start */) {
|
|
148
|
+
item.status = 1 /* inprogress */;
|
|
149
|
+
}
|
|
150
|
+
if (action === 2 /* finish */) {
|
|
151
|
+
item.status = 0 /* finished */;
|
|
152
|
+
}
|
|
153
|
+
if (action !== 3 /* log */) {
|
|
154
|
+
// if status still empty in the original item or item does not exists it will remain empty and static
|
|
155
|
+
updateModel(inputId, item);
|
|
156
|
+
}
|
|
157
|
+
cleanupModel();
|
|
158
|
+
if (action === 3 /* log */) {
|
|
159
|
+
appendToModel(item, logAboveSpinners);
|
|
160
|
+
}
|
|
161
|
+
return model;
|
|
162
|
+
}, () => {
|
|
163
|
+
cleanupModel();
|
|
164
|
+
return model;
|
|
165
|
+
}];
|
|
166
|
+
function appendToModel(item, head) {
|
|
64
167
|
if (head) {
|
|
65
168
|
list.prepend(model, item);
|
|
66
169
|
}
|
|
67
170
|
else {
|
|
68
171
|
list.append(model, item);
|
|
69
172
|
}
|
|
70
|
-
model.
|
|
71
|
-
}
|
|
72
|
-
|
|
173
|
+
model.spinning += (item.status || 0);
|
|
174
|
+
}
|
|
175
|
+
function updateModel(inputId, options) {
|
|
73
176
|
const modelItem = itemById[inputId];
|
|
74
177
|
if (!modelItem) {
|
|
75
|
-
const item = Object.assign({
|
|
178
|
+
const item = Object.assign({ inputId: inputId }, options);
|
|
76
179
|
itemById[inputId] = item;
|
|
77
|
-
const itemParentId = item.
|
|
180
|
+
const itemParentId = item.parentId;
|
|
78
181
|
if (itemParentId != null) {
|
|
79
182
|
putIntoChildren(itemParentId, item, item);
|
|
80
183
|
}
|
|
@@ -83,81 +186,62 @@ const createModel = (logAboveSpinners) => {
|
|
|
83
186
|
}
|
|
84
187
|
}
|
|
85
188
|
else {
|
|
86
|
-
const statusDiff = (options.
|
|
87
|
-
const moveIntoParent = options.
|
|
189
|
+
const statusDiff = (options.status || 0) - (modelItem.status || 0);
|
|
190
|
+
const moveIntoParent = options.parentId != null && modelItem.parentId == null;
|
|
88
191
|
Object.assign(modelItem, options);
|
|
89
|
-
model.
|
|
192
|
+
model.spinning += statusDiff;
|
|
90
193
|
if (moveIntoParent) {
|
|
91
194
|
const lastLeaf = getLastLeaf(modelItem);
|
|
92
|
-
model.
|
|
93
|
-
modelItem.
|
|
195
|
+
model.spinning -= (modelItem.status || 0);
|
|
196
|
+
modelItem.dirty = true;
|
|
94
197
|
list.removeRange(modelItem, lastLeaf);
|
|
95
|
-
putIntoChildren(modelItem.
|
|
198
|
+
putIntoChildren(modelItem.parentId, modelItem, lastLeaf);
|
|
96
199
|
}
|
|
97
200
|
}
|
|
98
|
-
}
|
|
99
|
-
|
|
201
|
+
}
|
|
202
|
+
function putIntoChildren(itemParentId, begin, end) {
|
|
100
203
|
let parent = itemById[itemParentId];
|
|
101
204
|
if (!parent) {
|
|
102
|
-
parent = {
|
|
205
|
+
parent = { inputId: itemParentId, message: '', loglevel: 0, ref: new WeakRef(model) };
|
|
103
206
|
appendToModel(parent, false);
|
|
104
207
|
itemById[itemParentId] = parent;
|
|
105
208
|
}
|
|
106
209
|
list.appendRange((getLastLeaf(parent)), begin, end);
|
|
107
|
-
parent.
|
|
108
|
-
model.
|
|
109
|
-
}
|
|
110
|
-
|
|
210
|
+
parent.lastLeaf = begin;
|
|
211
|
+
model.spinning += (begin.status || 0);
|
|
212
|
+
}
|
|
213
|
+
function cleanupModel() {
|
|
111
214
|
var _a;
|
|
112
215
|
for (const item of model) {
|
|
113
|
-
if (!((_a = item.
|
|
114
|
-
model.
|
|
115
|
-
item.
|
|
216
|
+
if (!((_a = item.ref) === null || _a === void 0 ? void 0 : _a.deref())) {
|
|
217
|
+
model.skipLines += 1;
|
|
218
|
+
item.inputId != null && delete itemById[item.inputId];
|
|
116
219
|
list.remove(item);
|
|
117
220
|
}
|
|
118
221
|
else {
|
|
119
222
|
break;
|
|
120
223
|
}
|
|
121
224
|
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
return [({ message: text, inputId, action, loglevel, ref, parentId, context, tag }) => {
|
|
125
|
-
// item has status undefined, so it is static by default
|
|
126
|
-
const item = { text_: text, loglevel_: loglevel, ref_: ref, parentId_: parentId, dirty_: true, context_: context, tag_: tag };
|
|
127
|
-
if (action === 0 /* start */) {
|
|
128
|
-
item.status_ = 1 /* inprogress */;
|
|
129
|
-
}
|
|
130
|
-
if (action === 2 /* finish */) {
|
|
131
|
-
item.status_ = 0 /* finished */;
|
|
132
|
-
}
|
|
133
|
-
if (action !== 3 /* log */) {
|
|
134
|
-
// if status still empty in the original item or item does not exists it will remain empty and static
|
|
135
|
-
updateModel(inputId, item);
|
|
136
|
-
}
|
|
137
|
-
cleanupModel();
|
|
138
|
-
if (action === 3 /* log */) {
|
|
139
|
-
appendToModel(item, logAboveSpinners);
|
|
140
|
-
}
|
|
141
|
-
return model;
|
|
142
|
-
}, () => {
|
|
143
|
-
cleanupModel();
|
|
144
|
-
return model;
|
|
145
|
-
}];
|
|
146
|
-
};
|
|
225
|
+
}
|
|
226
|
+
}
|
|
147
227
|
function getLastLeaf(modelItem) {
|
|
148
228
|
let lastLeaf = modelItem;
|
|
149
|
-
while (lastLeaf.
|
|
150
|
-
lastLeaf = lastLeaf.
|
|
229
|
+
while (lastLeaf.lastLeaf) {
|
|
230
|
+
lastLeaf = lastLeaf.lastLeaf;
|
|
151
231
|
}
|
|
152
232
|
return lastLeaf;
|
|
153
233
|
}
|
|
154
234
|
|
|
155
|
-
|
|
235
|
+
function createDraftlogAppender(spinner, formatter, logAboveSpinners, ident) {
|
|
156
236
|
let interval;
|
|
157
237
|
const [updateModel, getModel] = createModel(logAboveSpinners);
|
|
158
238
|
const renderModel = createCanvas(spinner, formatter, ident);
|
|
159
|
-
|
|
160
|
-
|
|
239
|
+
return (message) => {
|
|
240
|
+
renderModel(updateModel(message));
|
|
241
|
+
checkTimeout();
|
|
242
|
+
};
|
|
243
|
+
function checkTimeout() {
|
|
244
|
+
const spinning = getModel().spinning;
|
|
161
245
|
if (spinning && !interval) {
|
|
162
246
|
interval = setInterval(updateSpinners, spinner.interval);
|
|
163
247
|
interval.unref(); // unref immidiately just in case
|
|
@@ -166,17 +250,13 @@ const createDraftlogAppender = (spinner, formatter, logAboveSpinners, ident) =>
|
|
|
166
250
|
clearInterval(interval);
|
|
167
251
|
interval = undefined;
|
|
168
252
|
}
|
|
169
|
-
}
|
|
170
|
-
|
|
253
|
+
}
|
|
254
|
+
function updateSpinners() {
|
|
171
255
|
const model = getModel();
|
|
172
|
-
model.
|
|
173
|
-
model.
|
|
256
|
+
model.tick++;
|
|
257
|
+
model.tick %= spinner.frames.length;
|
|
174
258
|
renderModel(model);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
renderModel(updateModel(message));
|
|
178
|
-
checkTimeout();
|
|
179
|
-
};
|
|
180
|
-
};
|
|
259
|
+
}
|
|
260
|
+
}
|
|
181
261
|
|
|
182
262
|
exports.createDraftlogAppender = createDraftlogAppender;
|
package/dist/core.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { Formatter, LogMessage } from '@niceties/logger/types';
|
|
2
2
|
import { Spinner } from './spinners';
|
|
3
|
-
export declare
|
|
3
|
+
export declare function createDraftlogAppender(spinner: Spinner, formatter: Formatter, logAboveSpinners: boolean, ident: number): (message: LogMessage) => void;
|
package/dist/core.mjs
CHANGED
|
@@ -1,78 +1,181 @@
|
|
|
1
1
|
import draftlog from 'draftlog';
|
|
2
2
|
import { List, prepend, append, removeRange, appendRange, remove } from '@slimlib/list';
|
|
3
3
|
|
|
4
|
-
const
|
|
4
|
+
const allColumnsListeners = new Set();
|
|
5
|
+
function subscribeToTerminalResize(listener) {
|
|
6
|
+
allColumnsListeners.add(new WeakRef(listener));
|
|
7
|
+
}
|
|
8
|
+
process.stdout.on('resize', () => {
|
|
9
|
+
for (const listener of allColumnsListeners) {
|
|
10
|
+
const realListener = listener.deref();
|
|
11
|
+
if (realListener) {
|
|
12
|
+
realListener();
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
allColumnsListeners.delete(listener);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
function splitByLines(message) {
|
|
21
|
+
var _a;
|
|
22
|
+
return (_a = message
|
|
23
|
+
.match(getSubstringsRegex())) !== null && _a !== void 0 ? _a : [];
|
|
24
|
+
}
|
|
25
|
+
let substringsRegex, substringsColumns;
|
|
26
|
+
function getSubstringsRegex() {
|
|
27
|
+
const newColumns = process.stdout.columns || 80;
|
|
28
|
+
if (substringsColumns !== newColumns) {
|
|
29
|
+
substringsRegex = new RegExp(`.{1,${newColumns}}`, 'g');
|
|
30
|
+
substringsColumns = newColumns;
|
|
31
|
+
}
|
|
32
|
+
return substringsRegex;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function createCanvas(spinner, formatter, ident) {
|
|
5
36
|
draftlog(console);
|
|
6
37
|
draftlog.defaults.canReWrite = false;
|
|
7
38
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8
39
|
const updaters = [];
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
};
|
|
15
|
-
return
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
40
|
+
let lastModel;
|
|
41
|
+
subscribeToTerminalResize(() => {
|
|
42
|
+
if (lastModel) {
|
|
43
|
+
modelFn(lastModel, true);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
return modelFn;
|
|
47
|
+
function modelFn(model, dirty = false) {
|
|
48
|
+
lastModel = model;
|
|
49
|
+
if (model.skipLines) {
|
|
50
|
+
updaters.splice(0, model.skipLines);
|
|
51
|
+
model.skipLines = 0;
|
|
19
52
|
}
|
|
20
|
-
let key = 0
|
|
53
|
+
let key = 0;
|
|
21
54
|
const stack = [];
|
|
22
55
|
for (const item of model) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
56
|
+
if (dirty || item.dirty || item.status) {
|
|
57
|
+
let prefix = getPrefix(item.status, model.tick), prefixUpdated = false;
|
|
58
|
+
const subitems = splitByLines(item.message);
|
|
59
|
+
for (const message of subitems) {
|
|
60
|
+
let updater = updaters[key++];
|
|
61
|
+
if (!updater) {
|
|
62
|
+
updater = console.draft(' ');
|
|
63
|
+
updaters.push(updater);
|
|
64
|
+
}
|
|
65
|
+
updater(formatter({
|
|
66
|
+
loglevel: item.loglevel,
|
|
67
|
+
message,
|
|
68
|
+
context: item.context,
|
|
69
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
70
|
+
action: (item.status === undefined ? 3 /* log */ : undefined),
|
|
71
|
+
tag: item.tag
|
|
72
|
+
}, prefix, ident * stack.length));
|
|
73
|
+
if (subitems.length > 1 && typeof prefix === 'string' && !prefixUpdated) {
|
|
74
|
+
prefix = prefix.replaceAll(/./g, ' ');
|
|
75
|
+
prefixUpdated = true;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (item.dirty) {
|
|
79
|
+
item.dirty = false;
|
|
40
80
|
dirty = true;
|
|
41
81
|
}
|
|
42
82
|
}
|
|
43
|
-
|
|
44
|
-
|
|
83
|
+
else {
|
|
84
|
+
// iterate
|
|
85
|
+
key += splitByLines(item.message).length;
|
|
86
|
+
}
|
|
45
87
|
if (stack[stack.length - 1] === item) {
|
|
46
88
|
stack[stack.length - 1] = null;
|
|
47
89
|
}
|
|
48
|
-
if (item.
|
|
49
|
-
stack.push(item.
|
|
90
|
+
if (item.lastLeaf) {
|
|
91
|
+
stack.push(item.lastLeaf);
|
|
50
92
|
}
|
|
51
93
|
while (stack.length && stack[stack.length - 1] == null) {
|
|
52
94
|
stack.pop();
|
|
53
95
|
}
|
|
54
96
|
}
|
|
55
|
-
|
|
56
|
-
|
|
97
|
+
while (key < updaters.length) {
|
|
98
|
+
updaters[key++]('');
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function getPrefix(status, tick) {
|
|
102
|
+
// status is truthy when it is inprogress
|
|
103
|
+
return status ? spinner.frames[tick] :
|
|
104
|
+
// status not null when it is finished
|
|
105
|
+
status != null;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
57
108
|
|
|
58
|
-
|
|
109
|
+
/******************************************************************************
|
|
110
|
+
Copyright (c) Microsoft Corporation.
|
|
111
|
+
|
|
112
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
113
|
+
purpose with or without fee is hereby granted.
|
|
114
|
+
|
|
115
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
116
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
117
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
118
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
119
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
120
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
121
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
122
|
+
***************************************************************************** */
|
|
123
|
+
|
|
124
|
+
function __rest(s, e) {
|
|
125
|
+
var t = {};
|
|
126
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
127
|
+
t[p] = s[p];
|
|
128
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
129
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
130
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
131
|
+
t[p[i]] = s[p[i]];
|
|
132
|
+
}
|
|
133
|
+
return t;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function createModel(logAboveSpinners) {
|
|
59
137
|
const model = new List();
|
|
60
138
|
const itemById = Object.create(null);
|
|
61
|
-
|
|
139
|
+
model.tick = model.skipLines = model.spinning = 0;
|
|
140
|
+
return [(_a) => {
|
|
141
|
+
var { action } = _a, item = __rest(_a, ["action"]);
|
|
142
|
+
// item has status undefined, so it is static by default
|
|
143
|
+
item.dirty = true;
|
|
144
|
+
const { inputId } = item;
|
|
145
|
+
if (action === 0 /* start */) {
|
|
146
|
+
item.status = 1 /* inprogress */;
|
|
147
|
+
}
|
|
148
|
+
if (action === 2 /* finish */) {
|
|
149
|
+
item.status = 0 /* finished */;
|
|
150
|
+
}
|
|
151
|
+
if (action !== 3 /* log */) {
|
|
152
|
+
// if status still empty in the original item or item does not exists it will remain empty and static
|
|
153
|
+
updateModel(inputId, item);
|
|
154
|
+
}
|
|
155
|
+
cleanupModel();
|
|
156
|
+
if (action === 3 /* log */) {
|
|
157
|
+
appendToModel(item, logAboveSpinners);
|
|
158
|
+
}
|
|
159
|
+
return model;
|
|
160
|
+
}, () => {
|
|
161
|
+
cleanupModel();
|
|
162
|
+
return model;
|
|
163
|
+
}];
|
|
164
|
+
function appendToModel(item, head) {
|
|
62
165
|
if (head) {
|
|
63
166
|
prepend(model, item);
|
|
64
167
|
}
|
|
65
168
|
else {
|
|
66
169
|
append(model, item);
|
|
67
170
|
}
|
|
68
|
-
model.
|
|
69
|
-
}
|
|
70
|
-
|
|
171
|
+
model.spinning += (item.status || 0);
|
|
172
|
+
}
|
|
173
|
+
function updateModel(inputId, options) {
|
|
71
174
|
const modelItem = itemById[inputId];
|
|
72
175
|
if (!modelItem) {
|
|
73
|
-
const item = Object.assign({
|
|
176
|
+
const item = Object.assign({ inputId: inputId }, options);
|
|
74
177
|
itemById[inputId] = item;
|
|
75
|
-
const itemParentId = item.
|
|
178
|
+
const itemParentId = item.parentId;
|
|
76
179
|
if (itemParentId != null) {
|
|
77
180
|
putIntoChildren(itemParentId, item, item);
|
|
78
181
|
}
|
|
@@ -81,81 +184,62 @@ const createModel = (logAboveSpinners) => {
|
|
|
81
184
|
}
|
|
82
185
|
}
|
|
83
186
|
else {
|
|
84
|
-
const statusDiff = (options.
|
|
85
|
-
const moveIntoParent = options.
|
|
187
|
+
const statusDiff = (options.status || 0) - (modelItem.status || 0);
|
|
188
|
+
const moveIntoParent = options.parentId != null && modelItem.parentId == null;
|
|
86
189
|
Object.assign(modelItem, options);
|
|
87
|
-
model.
|
|
190
|
+
model.spinning += statusDiff;
|
|
88
191
|
if (moveIntoParent) {
|
|
89
192
|
const lastLeaf = getLastLeaf(modelItem);
|
|
90
|
-
model.
|
|
91
|
-
modelItem.
|
|
193
|
+
model.spinning -= (modelItem.status || 0);
|
|
194
|
+
modelItem.dirty = true;
|
|
92
195
|
removeRange(modelItem, lastLeaf);
|
|
93
|
-
putIntoChildren(modelItem.
|
|
196
|
+
putIntoChildren(modelItem.parentId, modelItem, lastLeaf);
|
|
94
197
|
}
|
|
95
198
|
}
|
|
96
|
-
}
|
|
97
|
-
|
|
199
|
+
}
|
|
200
|
+
function putIntoChildren(itemParentId, begin, end) {
|
|
98
201
|
let parent = itemById[itemParentId];
|
|
99
202
|
if (!parent) {
|
|
100
|
-
parent = {
|
|
203
|
+
parent = { inputId: itemParentId, message: '', loglevel: 0, ref: new WeakRef(model) };
|
|
101
204
|
appendToModel(parent, false);
|
|
102
205
|
itemById[itemParentId] = parent;
|
|
103
206
|
}
|
|
104
207
|
appendRange((getLastLeaf(parent)), begin, end);
|
|
105
|
-
parent.
|
|
106
|
-
model.
|
|
107
|
-
}
|
|
108
|
-
|
|
208
|
+
parent.lastLeaf = begin;
|
|
209
|
+
model.spinning += (begin.status || 0);
|
|
210
|
+
}
|
|
211
|
+
function cleanupModel() {
|
|
109
212
|
var _a;
|
|
110
213
|
for (const item of model) {
|
|
111
|
-
if (!((_a = item.
|
|
112
|
-
model.
|
|
113
|
-
item.
|
|
214
|
+
if (!((_a = item.ref) === null || _a === void 0 ? void 0 : _a.deref())) {
|
|
215
|
+
model.skipLines += 1;
|
|
216
|
+
item.inputId != null && delete itemById[item.inputId];
|
|
114
217
|
remove(item);
|
|
115
218
|
}
|
|
116
219
|
else {
|
|
117
220
|
break;
|
|
118
221
|
}
|
|
119
222
|
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return [({ message: text, inputId, action, loglevel, ref, parentId, context, tag }) => {
|
|
123
|
-
// item has status undefined, so it is static by default
|
|
124
|
-
const item = { text_: text, loglevel_: loglevel, ref_: ref, parentId_: parentId, dirty_: true, context_: context, tag_: tag };
|
|
125
|
-
if (action === 0 /* start */) {
|
|
126
|
-
item.status_ = 1 /* inprogress */;
|
|
127
|
-
}
|
|
128
|
-
if (action === 2 /* finish */) {
|
|
129
|
-
item.status_ = 0 /* finished */;
|
|
130
|
-
}
|
|
131
|
-
if (action !== 3 /* log */) {
|
|
132
|
-
// if status still empty in the original item or item does not exists it will remain empty and static
|
|
133
|
-
updateModel(inputId, item);
|
|
134
|
-
}
|
|
135
|
-
cleanupModel();
|
|
136
|
-
if (action === 3 /* log */) {
|
|
137
|
-
appendToModel(item, logAboveSpinners);
|
|
138
|
-
}
|
|
139
|
-
return model;
|
|
140
|
-
}, () => {
|
|
141
|
-
cleanupModel();
|
|
142
|
-
return model;
|
|
143
|
-
}];
|
|
144
|
-
};
|
|
223
|
+
}
|
|
224
|
+
}
|
|
145
225
|
function getLastLeaf(modelItem) {
|
|
146
226
|
let lastLeaf = modelItem;
|
|
147
|
-
while (lastLeaf.
|
|
148
|
-
lastLeaf = lastLeaf.
|
|
227
|
+
while (lastLeaf.lastLeaf) {
|
|
228
|
+
lastLeaf = lastLeaf.lastLeaf;
|
|
149
229
|
}
|
|
150
230
|
return lastLeaf;
|
|
151
231
|
}
|
|
152
232
|
|
|
153
|
-
|
|
233
|
+
function createDraftlogAppender(spinner, formatter, logAboveSpinners, ident) {
|
|
154
234
|
let interval;
|
|
155
235
|
const [updateModel, getModel] = createModel(logAboveSpinners);
|
|
156
236
|
const renderModel = createCanvas(spinner, formatter, ident);
|
|
157
|
-
|
|
158
|
-
|
|
237
|
+
return (message) => {
|
|
238
|
+
renderModel(updateModel(message));
|
|
239
|
+
checkTimeout();
|
|
240
|
+
};
|
|
241
|
+
function checkTimeout() {
|
|
242
|
+
const spinning = getModel().spinning;
|
|
159
243
|
if (spinning && !interval) {
|
|
160
244
|
interval = setInterval(updateSpinners, spinner.interval);
|
|
161
245
|
interval.unref(); // unref immidiately just in case
|
|
@@ -164,17 +248,13 @@ const createDraftlogAppender = (spinner, formatter, logAboveSpinners, ident) =>
|
|
|
164
248
|
clearInterval(interval);
|
|
165
249
|
interval = undefined;
|
|
166
250
|
}
|
|
167
|
-
}
|
|
168
|
-
|
|
251
|
+
}
|
|
252
|
+
function updateSpinners() {
|
|
169
253
|
const model = getModel();
|
|
170
|
-
model.
|
|
171
|
-
model.
|
|
254
|
+
model.tick++;
|
|
255
|
+
model.tick %= spinner.frames.length;
|
|
172
256
|
renderModel(model);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
renderModel(updateModel(message));
|
|
176
|
-
checkTimeout();
|
|
177
|
-
};
|
|
178
|
-
};
|
|
257
|
+
}
|
|
258
|
+
}
|
|
179
259
|
|
|
180
260
|
export { createDraftlogAppender };
|
package/dist/details/canvas.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Formatter } from '@niceties/logger/types';
|
|
2
|
-
import { Model } from './model';
|
|
3
2
|
import { Spinner } from '../spinners';
|
|
4
|
-
|
|
3
|
+
import { Model } from './model';
|
|
4
|
+
export declare function createCanvas(spinner: Spinner, formatter: Formatter, ident: number): (model: Model, dirty?: boolean) => void;
|
package/dist/details/model.d.ts
CHANGED
|
@@ -5,20 +5,20 @@ export declare const enum ItemStatus {
|
|
|
5
5
|
inprogress = 1
|
|
6
6
|
}
|
|
7
7
|
export interface ModelItem extends Partial<ListNode> {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
8
|
+
inputId?: number;
|
|
9
|
+
message: string;
|
|
10
|
+
status?: ItemStatus;
|
|
11
|
+
loglevel: LogLevel;
|
|
12
|
+
ref?: WeakRef<never>;
|
|
13
|
+
parentId?: number;
|
|
14
|
+
dirty?: boolean;
|
|
15
|
+
lastLeaf?: ModelItem;
|
|
16
|
+
tag?: string;
|
|
17
|
+
context?: any;
|
|
18
18
|
}
|
|
19
19
|
export declare type Model = List<ModelItem> & {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
skipLines: number;
|
|
21
|
+
tick: number;
|
|
22
|
+
spinning: number;
|
|
23
23
|
};
|
|
24
|
-
export declare
|
|
24
|
+
export declare function createModel(logAboveSpinners: boolean): [(logMessage: LogMessage) => Model, () => Model];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function splitByLines(message: string): string[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function subscribeToTerminalResize(listener: () => void): void;
|
package/dist/index.cjs
CHANGED
|
@@ -14,7 +14,7 @@ if (!process.env.CI) {
|
|
|
14
14
|
const spinner = supportsUnicode ? spinners.dots : spinners.line;
|
|
15
15
|
const formatter = formatUtils.createFormatter(defaultFormatting.colors, supportsUnicode ? defaultFormatting.unicodePrefixes : defaultFormatting.asciiPrefixes, defaultFormatting.tagFactory);
|
|
16
16
|
let minLogLevel = 1 /* info */;
|
|
17
|
-
globalAppender.appender(appenderUtils.filterMessages((message) => message.loglevel >= minLogLevel
|
|
17
|
+
globalAppender.appender(appenderUtils.filterMessages((message) => message.loglevel >= minLogLevel, core.createDraftlogAppender(spinner, formatter, true, 2), // eslint-disable-line indent
|
|
18
18
|
{ setMinLevel(logLevel) { minLogLevel = logLevel; } } // eslint-disable-line indent
|
|
19
19
|
));
|
|
20
20
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -12,7 +12,7 @@ if (!process.env.CI) {
|
|
|
12
12
|
const spinner = supportsUnicode ? dots : line;
|
|
13
13
|
const formatter = createFormatter(colors, supportsUnicode ? unicodePrefixes : asciiPrefixes, tagFactory);
|
|
14
14
|
let minLogLevel = 1 /* info */;
|
|
15
|
-
appender(filterMessages((message) => message.loglevel >= minLogLevel
|
|
15
|
+
appender(filterMessages((message) => message.loglevel >= minLogLevel, createDraftlogAppender(spinner, formatter, true, 2), // eslint-disable-line indent
|
|
16
16
|
{ setMinLevel(logLevel) { minLogLevel = logLevel; } } // eslint-disable-line indent
|
|
17
17
|
));
|
|
18
18
|
}
|
package/package.json
CHANGED