@niceties/draftlog-appender 1.3.0 → 1.3.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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2021 Konstantin Shutkin
3
+ Copyright (c) 2023 Konstantin Shutkin
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
21
+ SOFTWARE.
package/README.md CHANGED
@@ -15,7 +15,7 @@ Appender for [`'@niceites/logger'`](../logger/README.md) implemented using draft
15
15
  ![Example](./example.gif "In terminal")
16
16
  ![Example](./cmdexe.gif "In windows terminal")
17
17
 
18
- ### [Changlelog](./CHANGELOG.md)
18
+ ### [Changelog](./CHANGELOG.md)
19
19
 
20
20
  # Installation
21
21
 
@@ -39,7 +39,7 @@ To install appender use next import:
39
39
  import "@niceties/draftlog-appender";
40
40
  ```
41
41
 
42
- It is better to do it before other imports so default appender in `'@niceites/logger'` not installed.
42
+ It is better to do it before other imports so the default appender in `'@niceites/logger'` is not installed.
43
43
 
44
44
  ## Subpackages
45
45
 
@@ -58,4 +58,4 @@ Subpackage `'@niceties/draftlog-appender/spinners'` exports spinners definitions
58
58
 
59
59
  # License
60
60
 
61
- [MIT](./LICENSE)
61
+ [MIT](https://github.com/kshutkin/niceties/blob/main/LICENSE)
package/dist/core.cjs CHANGED
@@ -3,260 +3,231 @@
3
3
  var draftlog = require('draftlog');
4
4
  var list = require('@slimlib/list');
5
5
 
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
- }
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
20
  });
21
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;
22
+ function splitByLines(message) {
23
+ return message
24
+ .match(getSubstringsRegex()) ?? [];
35
25
  }
36
-
37
- function createCanvas(spinner, formatter, ident) {
38
- draftlog(console);
39
- draftlog.defaults.canReWrite = false;
40
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
41
- const updaters = [];
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;
54
- }
55
- let key = 0;
56
- const stack = [];
57
- for (const item of model) {
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;
82
- dirty = true;
83
- }
84
- }
85
- else {
86
- // iterate
87
- key += splitByLines(item.message).length;
88
- }
89
- if (stack[stack.length - 1] === item) {
90
- stack[stack.length - 1] = null;
91
- }
92
- if (item.lastLeaf) {
93
- stack.push(item.lastLeaf);
94
- }
95
- while (stack.length && stack[stack.length - 1] == null) {
96
- stack.pop();
97
- }
98
- }
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
- }
26
+ let substringsRegex, substringsColumns;
27
+ function getSubstringsRegex() {
28
+ const newColumns = process.stdout.columns || 80;
29
+ if (substringsColumns !== newColumns) {
30
+ substringsRegex = new RegExp(`.{1,${newColumns}}`, 'g');
31
+ substringsColumns = newColumns;
32
+ }
33
+ return substringsRegex;
109
34
  }
110
35
 
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;
36
+ function createCanvas(spinner, formatter, ident) {
37
+ draftlog(console);
38
+ draftlog.defaults.canReWrite = false;
39
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
40
+ const updaters = [];
41
+ let lastModel;
42
+ subscribeToTerminalResize(() => {
43
+ if (lastModel) {
44
+ modelFn(lastModel, true);
45
+ }
46
+ });
47
+ return modelFn;
48
+ function modelFn(model, dirty = false) {
49
+ lastModel = model;
50
+ if (model.skipLines) {
51
+ updaters.splice(0, model.skipLines);
52
+ model.skipLines = 0;
53
+ }
54
+ let key = 0;
55
+ const stack = [];
56
+ for (const item of model) {
57
+ if (dirty || item.dirty || item.status) {
58
+ let prefix = getPrefix(item.status, model.tick), prefixUpdated = false;
59
+ const subitems = splitByLines(item.message);
60
+ for (const message of subitems) {
61
+ let updater = updaters[key++];
62
+ if (!updater) {
63
+ updater = console.draft(' ');
64
+ updaters.push(updater);
65
+ }
66
+ updater(formatter({
67
+ loglevel: item.loglevel,
68
+ message,
69
+ context: item.context,
70
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
71
+ action: (item.status === undefined ? 3 /* Action.log */ : undefined),
72
+ tag: item.tag
73
+ }, prefix, ident * stack.length));
74
+ if (subitems.length > 1 && typeof prefix === 'string' && !prefixUpdated) {
75
+ prefix = prefix.replaceAll(/./g, ' ');
76
+ prefixUpdated = true;
77
+ }
78
+ }
79
+ if (item.dirty) {
80
+ item.dirty = false;
81
+ dirty = true;
82
+ }
83
+ }
84
+ else {
85
+ // iterate
86
+ key += splitByLines(item.message).length;
87
+ }
88
+ if (stack[stack.length - 1] === item) {
89
+ stack[stack.length - 1] = null;
90
+ }
91
+ if (item.lastLeaf) {
92
+ stack.push(item.lastLeaf);
93
+ }
94
+ while (stack.length && stack[stack.length - 1] == null) {
95
+ stack.pop();
96
+ }
97
+ }
98
+ while (key < updaters.length) {
99
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
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
+ }
136
109
  }
137
110
 
138
- function createModel(logAboveSpinners) {
139
- const model = new list.List();
140
- const itemById = Object.create(null);
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) {
167
- if (head) {
168
- list.prepend(model, item);
169
- }
170
- else {
171
- list.append(model, item);
172
- }
173
- model.spinning += (item.status || 0);
174
- }
175
- function updateModel(inputId, options) {
176
- const modelItem = itemById[inputId];
177
- if (!modelItem) {
178
- const item = Object.assign({ inputId: inputId }, options);
179
- itemById[inputId] = item;
180
- const itemParentId = item.parentId;
181
- if (itemParentId != null) {
182
- putIntoChildren(itemParentId, item, item);
183
- }
184
- else {
185
- appendToModel(item, false);
186
- }
187
- }
188
- else {
189
- const statusDiff = (options.status || 0) - (modelItem.status || 0);
190
- const moveIntoParent = options.parentId != null && modelItem.parentId == null;
191
- Object.assign(modelItem, options);
192
- model.spinning += statusDiff;
193
- if (moveIntoParent) {
194
- const lastLeaf = getLastLeaf(modelItem);
195
- model.spinning -= (modelItem.status || 0);
196
- modelItem.dirty = true;
197
- list.removeRange(modelItem, lastLeaf);
198
- putIntoChildren(modelItem.parentId, modelItem, lastLeaf);
199
- }
200
- }
201
- }
202
- function putIntoChildren(itemParentId, begin, end) {
203
- let parent = itemById[itemParentId];
204
- if (!parent) {
205
- parent = { inputId: itemParentId, message: '', loglevel: 0, ref: new WeakRef(model) };
206
- appendToModel(parent, false);
207
- itemById[itemParentId] = parent;
208
- }
209
- list.appendRange((getLastLeaf(parent)), begin, end);
210
- parent.lastLeaf = begin;
211
- model.spinning += (begin.status || 0);
212
- }
213
- function cleanupModel() {
214
- var _a;
215
- for (const item of model) {
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];
219
- list.remove(item);
220
- }
221
- else {
222
- break;
223
- }
224
- }
225
- }
226
- }
227
- function getLastLeaf(modelItem) {
228
- let lastLeaf = modelItem;
229
- while (lastLeaf.lastLeaf) {
230
- lastLeaf = lastLeaf.lastLeaf;
231
- }
232
- return lastLeaf;
111
+ function createModel(logAboveSpinners) {
112
+ const model = new list.List();
113
+ const itemById = Object.create(null);
114
+ model.tick = model.skipLines = model.spinning = 0;
115
+ return [({ action, ...item }) => {
116
+ // item has status undefined, so it is static by default
117
+ item.dirty = true;
118
+ const { inputId } = item;
119
+ if (action === 0 /* Action.start */) {
120
+ item.status = 1 /* ItemStatus.inprogress */;
121
+ }
122
+ if (action === 2 /* Action.finish */) {
123
+ item.status = 0 /* ItemStatus.finished */;
124
+ }
125
+ if (action !== 3 /* Action.log */) {
126
+ // if status still empty in the original item or item does not exists it will remain empty and static
127
+ updateModel(inputId, item);
128
+ }
129
+ cleanupModel();
130
+ if (action === 3 /* Action.log */) {
131
+ appendToModel(item, logAboveSpinners);
132
+ }
133
+ return model;
134
+ }, () => {
135
+ cleanupModel();
136
+ return model;
137
+ }];
138
+ function appendToModel(item, head) {
139
+ if (head) {
140
+ list.prepend(model, item);
141
+ }
142
+ else {
143
+ list.append(model, item);
144
+ }
145
+ model.spinning += (item.status || 0);
146
+ }
147
+ function updateModel(inputId, options) {
148
+ const modelItem = itemById[inputId];
149
+ if (!modelItem) {
150
+ const item = { inputId: inputId, ...options };
151
+ itemById[inputId] = item;
152
+ const itemParentId = item.parentId;
153
+ if (itemParentId != null) {
154
+ putIntoChildren(itemParentId, item, item);
155
+ }
156
+ else {
157
+ appendToModel(item, false);
158
+ }
159
+ }
160
+ else {
161
+ const statusDiff = (options.status || 0) - (modelItem.status || 0);
162
+ const moveIntoParent = options.parentId != null && modelItem.parentId == null;
163
+ Object.assign(modelItem, options);
164
+ model.spinning += statusDiff;
165
+ if (moveIntoParent) {
166
+ const lastLeaf = getLastLeaf(modelItem);
167
+ model.spinning -= (modelItem.status || 0);
168
+ modelItem.dirty = true;
169
+ list.removeRange(modelItem, lastLeaf);
170
+ putIntoChildren(modelItem.parentId, modelItem, lastLeaf);
171
+ }
172
+ }
173
+ }
174
+ function putIntoChildren(itemParentId, begin, end) {
175
+ let parent = itemById[itemParentId];
176
+ if (!parent) {
177
+ parent = { inputId: itemParentId, message: '', loglevel: 0, ref: new WeakRef(model) };
178
+ appendToModel(parent, false);
179
+ itemById[itemParentId] = parent;
180
+ }
181
+ list.appendRange((getLastLeaf(parent)), begin, end);
182
+ parent.lastLeaf = begin;
183
+ model.spinning += (begin.status || 0);
184
+ }
185
+ function cleanupModel() {
186
+ for (const item of model) {
187
+ if (!item.ref?.deref()) {
188
+ model.skipLines += 1;
189
+ item.inputId != null && delete itemById[item.inputId];
190
+ list.remove(item);
191
+ }
192
+ else {
193
+ break;
194
+ }
195
+ }
196
+ }
197
+ }
198
+ function getLastLeaf(modelItem) {
199
+ let lastLeaf = modelItem;
200
+ while (lastLeaf.lastLeaf) {
201
+ lastLeaf = lastLeaf.lastLeaf;
202
+ }
203
+ return lastLeaf;
233
204
  }
234
205
 
235
- function createDraftlogAppender(spinner, formatter, logAboveSpinners, ident) {
236
- let interval;
237
- const [updateModel, getModel] = createModel(logAboveSpinners);
238
- const renderModel = createCanvas(spinner, formatter, ident);
239
- return (message) => {
240
- renderModel(updateModel(message));
241
- checkTimeout();
242
- };
243
- function checkTimeout() {
244
- const spinning = getModel().spinning;
245
- if (spinning && !interval) {
246
- interval = setInterval(updateSpinners, spinner.interval);
247
- interval.unref(); // unref immidiately just in case
248
- }
249
- else if (!spinning && interval) {
250
- clearInterval(interval);
251
- interval = undefined;
252
- }
253
- }
254
- function updateSpinners() {
255
- const model = getModel();
256
- model.tick++;
257
- model.tick %= spinner.frames.length;
258
- renderModel(model);
259
- }
206
+ function createDraftlogAppender(spinner, formatter, logAboveSpinners, ident) {
207
+ let interval;
208
+ const [updateModel, getModel] = createModel(logAboveSpinners);
209
+ const renderModel = createCanvas(spinner, formatter, ident);
210
+ return (message) => {
211
+ renderModel(updateModel(message));
212
+ checkTimeout();
213
+ };
214
+ function checkTimeout() {
215
+ const spinning = getModel().spinning;
216
+ if (spinning && !interval) {
217
+ interval = setInterval(updateSpinners, spinner.interval);
218
+ interval.unref(); // unref immidiately just in case
219
+ }
220
+ else if (!spinning && interval) {
221
+ clearInterval(interval);
222
+ interval = undefined;
223
+ }
224
+ }
225
+ function updateSpinners() {
226
+ const model = getModel();
227
+ model.tick++;
228
+ model.tick %= spinner.frames.length;
229
+ renderModel(model);
230
+ }
260
231
  }
261
232
 
262
233
  exports.createDraftlogAppender = createDraftlogAppender;
package/dist/core.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { Formatter, LogMessage } from '@niceties/logger/types';
2
- import { Spinner } from './spinners';
3
- export declare function createDraftlogAppender(spinner: Spinner, formatter: Formatter, logAboveSpinners: boolean, ident: number): (message: LogMessage) => void;
1
+ import { Formatter, LogMessage } from '@niceties/logger/types';
2
+ import { Spinner } from './spinners';
3
+ export declare function createDraftlogAppender(spinner: Spinner, formatter: Formatter, logAboveSpinners: boolean, ident: number): (message: LogMessage) => void;
package/dist/core.mjs CHANGED
@@ -1,260 +1,231 @@
1
1
  import draftlog from 'draftlog';
2
2
  import { List, prepend, append, removeRange, appendRange, remove } from '@slimlib/list';
3
3
 
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
- }
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
18
  });
19
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;
20
+ function splitByLines(message) {
21
+ return message
22
+ .match(getSubstringsRegex()) ?? [];
33
23
  }
34
-
35
- function createCanvas(spinner, formatter, ident) {
36
- draftlog(console);
37
- draftlog.defaults.canReWrite = false;
38
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
39
- const updaters = [];
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;
52
- }
53
- let key = 0;
54
- const stack = [];
55
- for (const item of model) {
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;
80
- dirty = true;
81
- }
82
- }
83
- else {
84
- // iterate
85
- key += splitByLines(item.message).length;
86
- }
87
- if (stack[stack.length - 1] === item) {
88
- stack[stack.length - 1] = null;
89
- }
90
- if (item.lastLeaf) {
91
- stack.push(item.lastLeaf);
92
- }
93
- while (stack.length && stack[stack.length - 1] == null) {
94
- stack.pop();
95
- }
96
- }
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
- }
24
+ let substringsRegex, substringsColumns;
25
+ function getSubstringsRegex() {
26
+ const newColumns = process.stdout.columns || 80;
27
+ if (substringsColumns !== newColumns) {
28
+ substringsRegex = new RegExp(`.{1,${newColumns}}`, 'g');
29
+ substringsColumns = newColumns;
30
+ }
31
+ return substringsRegex;
107
32
  }
108
33
 
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;
34
+ function createCanvas(spinner, formatter, ident) {
35
+ draftlog(console);
36
+ draftlog.defaults.canReWrite = false;
37
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
+ const updaters = [];
39
+ let lastModel;
40
+ subscribeToTerminalResize(() => {
41
+ if (lastModel) {
42
+ modelFn(lastModel, true);
43
+ }
44
+ });
45
+ return modelFn;
46
+ function modelFn(model, dirty = false) {
47
+ lastModel = model;
48
+ if (model.skipLines) {
49
+ updaters.splice(0, model.skipLines);
50
+ model.skipLines = 0;
51
+ }
52
+ let key = 0;
53
+ const stack = [];
54
+ for (const item of model) {
55
+ if (dirty || item.dirty || item.status) {
56
+ let prefix = getPrefix(item.status, model.tick), prefixUpdated = false;
57
+ const subitems = splitByLines(item.message);
58
+ for (const message of subitems) {
59
+ let updater = updaters[key++];
60
+ if (!updater) {
61
+ updater = console.draft(' ');
62
+ updaters.push(updater);
63
+ }
64
+ updater(formatter({
65
+ loglevel: item.loglevel,
66
+ message,
67
+ context: item.context,
68
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
69
+ action: (item.status === undefined ? 3 /* Action.log */ : undefined),
70
+ tag: item.tag
71
+ }, prefix, ident * stack.length));
72
+ if (subitems.length > 1 && typeof prefix === 'string' && !prefixUpdated) {
73
+ prefix = prefix.replaceAll(/./g, ' ');
74
+ prefixUpdated = true;
75
+ }
76
+ }
77
+ if (item.dirty) {
78
+ item.dirty = false;
79
+ dirty = true;
80
+ }
81
+ }
82
+ else {
83
+ // iterate
84
+ key += splitByLines(item.message).length;
85
+ }
86
+ if (stack[stack.length - 1] === item) {
87
+ stack[stack.length - 1] = null;
88
+ }
89
+ if (item.lastLeaf) {
90
+ stack.push(item.lastLeaf);
91
+ }
92
+ while (stack.length && stack[stack.length - 1] == null) {
93
+ stack.pop();
94
+ }
95
+ }
96
+ while (key < updaters.length) {
97
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
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
+ }
134
107
  }
135
108
 
136
- function createModel(logAboveSpinners) {
137
- const model = new List();
138
- const itemById = Object.create(null);
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) {
165
- if (head) {
166
- prepend(model, item);
167
- }
168
- else {
169
- append(model, item);
170
- }
171
- model.spinning += (item.status || 0);
172
- }
173
- function updateModel(inputId, options) {
174
- const modelItem = itemById[inputId];
175
- if (!modelItem) {
176
- const item = Object.assign({ inputId: inputId }, options);
177
- itemById[inputId] = item;
178
- const itemParentId = item.parentId;
179
- if (itemParentId != null) {
180
- putIntoChildren(itemParentId, item, item);
181
- }
182
- else {
183
- appendToModel(item, false);
184
- }
185
- }
186
- else {
187
- const statusDiff = (options.status || 0) - (modelItem.status || 0);
188
- const moveIntoParent = options.parentId != null && modelItem.parentId == null;
189
- Object.assign(modelItem, options);
190
- model.spinning += statusDiff;
191
- if (moveIntoParent) {
192
- const lastLeaf = getLastLeaf(modelItem);
193
- model.spinning -= (modelItem.status || 0);
194
- modelItem.dirty = true;
195
- removeRange(modelItem, lastLeaf);
196
- putIntoChildren(modelItem.parentId, modelItem, lastLeaf);
197
- }
198
- }
199
- }
200
- function putIntoChildren(itemParentId, begin, end) {
201
- let parent = itemById[itemParentId];
202
- if (!parent) {
203
- parent = { inputId: itemParentId, message: '', loglevel: 0, ref: new WeakRef(model) };
204
- appendToModel(parent, false);
205
- itemById[itemParentId] = parent;
206
- }
207
- appendRange((getLastLeaf(parent)), begin, end);
208
- parent.lastLeaf = begin;
209
- model.spinning += (begin.status || 0);
210
- }
211
- function cleanupModel() {
212
- var _a;
213
- for (const item of model) {
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];
217
- remove(item);
218
- }
219
- else {
220
- break;
221
- }
222
- }
223
- }
224
- }
225
- function getLastLeaf(modelItem) {
226
- let lastLeaf = modelItem;
227
- while (lastLeaf.lastLeaf) {
228
- lastLeaf = lastLeaf.lastLeaf;
229
- }
230
- return lastLeaf;
109
+ function createModel(logAboveSpinners) {
110
+ const model = new List();
111
+ const itemById = Object.create(null);
112
+ model.tick = model.skipLines = model.spinning = 0;
113
+ return [({ action, ...item }) => {
114
+ // item has status undefined, so it is static by default
115
+ item.dirty = true;
116
+ const { inputId } = item;
117
+ if (action === 0 /* Action.start */) {
118
+ item.status = 1 /* ItemStatus.inprogress */;
119
+ }
120
+ if (action === 2 /* Action.finish */) {
121
+ item.status = 0 /* ItemStatus.finished */;
122
+ }
123
+ if (action !== 3 /* Action.log */) {
124
+ // if status still empty in the original item or item does not exists it will remain empty and static
125
+ updateModel(inputId, item);
126
+ }
127
+ cleanupModel();
128
+ if (action === 3 /* Action.log */) {
129
+ appendToModel(item, logAboveSpinners);
130
+ }
131
+ return model;
132
+ }, () => {
133
+ cleanupModel();
134
+ return model;
135
+ }];
136
+ function appendToModel(item, head) {
137
+ if (head) {
138
+ prepend(model, item);
139
+ }
140
+ else {
141
+ append(model, item);
142
+ }
143
+ model.spinning += (item.status || 0);
144
+ }
145
+ function updateModel(inputId, options) {
146
+ const modelItem = itemById[inputId];
147
+ if (!modelItem) {
148
+ const item = { inputId: inputId, ...options };
149
+ itemById[inputId] = item;
150
+ const itemParentId = item.parentId;
151
+ if (itemParentId != null) {
152
+ putIntoChildren(itemParentId, item, item);
153
+ }
154
+ else {
155
+ appendToModel(item, false);
156
+ }
157
+ }
158
+ else {
159
+ const statusDiff = (options.status || 0) - (modelItem.status || 0);
160
+ const moveIntoParent = options.parentId != null && modelItem.parentId == null;
161
+ Object.assign(modelItem, options);
162
+ model.spinning += statusDiff;
163
+ if (moveIntoParent) {
164
+ const lastLeaf = getLastLeaf(modelItem);
165
+ model.spinning -= (modelItem.status || 0);
166
+ modelItem.dirty = true;
167
+ removeRange(modelItem, lastLeaf);
168
+ putIntoChildren(modelItem.parentId, modelItem, lastLeaf);
169
+ }
170
+ }
171
+ }
172
+ function putIntoChildren(itemParentId, begin, end) {
173
+ let parent = itemById[itemParentId];
174
+ if (!parent) {
175
+ parent = { inputId: itemParentId, message: '', loglevel: 0, ref: new WeakRef(model) };
176
+ appendToModel(parent, false);
177
+ itemById[itemParentId] = parent;
178
+ }
179
+ appendRange((getLastLeaf(parent)), begin, end);
180
+ parent.lastLeaf = begin;
181
+ model.spinning += (begin.status || 0);
182
+ }
183
+ function cleanupModel() {
184
+ for (const item of model) {
185
+ if (!item.ref?.deref()) {
186
+ model.skipLines += 1;
187
+ item.inputId != null && delete itemById[item.inputId];
188
+ remove(item);
189
+ }
190
+ else {
191
+ break;
192
+ }
193
+ }
194
+ }
195
+ }
196
+ function getLastLeaf(modelItem) {
197
+ let lastLeaf = modelItem;
198
+ while (lastLeaf.lastLeaf) {
199
+ lastLeaf = lastLeaf.lastLeaf;
200
+ }
201
+ return lastLeaf;
231
202
  }
232
203
 
233
- function createDraftlogAppender(spinner, formatter, logAboveSpinners, ident) {
234
- let interval;
235
- const [updateModel, getModel] = createModel(logAboveSpinners);
236
- const renderModel = createCanvas(spinner, formatter, ident);
237
- return (message) => {
238
- renderModel(updateModel(message));
239
- checkTimeout();
240
- };
241
- function checkTimeout() {
242
- const spinning = getModel().spinning;
243
- if (spinning && !interval) {
244
- interval = setInterval(updateSpinners, spinner.interval);
245
- interval.unref(); // unref immidiately just in case
246
- }
247
- else if (!spinning && interval) {
248
- clearInterval(interval);
249
- interval = undefined;
250
- }
251
- }
252
- function updateSpinners() {
253
- const model = getModel();
254
- model.tick++;
255
- model.tick %= spinner.frames.length;
256
- renderModel(model);
257
- }
204
+ function createDraftlogAppender(spinner, formatter, logAboveSpinners, ident) {
205
+ let interval;
206
+ const [updateModel, getModel] = createModel(logAboveSpinners);
207
+ const renderModel = createCanvas(spinner, formatter, ident);
208
+ return (message) => {
209
+ renderModel(updateModel(message));
210
+ checkTimeout();
211
+ };
212
+ function checkTimeout() {
213
+ const spinning = getModel().spinning;
214
+ if (spinning && !interval) {
215
+ interval = setInterval(updateSpinners, spinner.interval);
216
+ interval.unref(); // unref immidiately just in case
217
+ }
218
+ else if (!spinning && interval) {
219
+ clearInterval(interval);
220
+ interval = undefined;
221
+ }
222
+ }
223
+ function updateSpinners() {
224
+ const model = getModel();
225
+ model.tick++;
226
+ model.tick %= spinner.frames.length;
227
+ renderModel(model);
228
+ }
258
229
  }
259
230
 
260
231
  export { createDraftlogAppender };
@@ -1,4 +1,4 @@
1
- import { Formatter } from '@niceties/logger/types';
2
- import { Spinner } from '../spinners';
3
- import { Model } from './model';
4
- export declare function createCanvas(spinner: Spinner, formatter: Formatter, ident: number): (model: Model, dirty?: boolean) => void;
1
+ import { Formatter } from '@niceties/logger/types';
2
+ import { Spinner } from '../spinners';
3
+ import { Model } from './model';
4
+ export declare function createCanvas(spinner: Spinner, formatter: Formatter, ident: number): (model: Model, dirty?: boolean) => void;
@@ -1,24 +1,24 @@
1
- import { LogLevel, LogMessage } from '@niceties/logger/types';
2
- import { List, ListNode } from '@slimlib/list';
3
- export declare const enum ItemStatus {
4
- finished = 0,
5
- inprogress = 1
6
- }
7
- export interface ModelItem extends Partial<ListNode> {
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
- }
19
- export declare type Model = List<ModelItem> & {
20
- skipLines: number;
21
- tick: number;
22
- spinning: number;
23
- };
24
- export declare function createModel(logAboveSpinners: boolean): [(logMessage: LogMessage) => Model, () => Model];
1
+ import { LogLevel, LogMessage } from '@niceties/logger/types';
2
+ import { List, ListNode } from '@slimlib/list';
3
+ export declare const enum ItemStatus {
4
+ finished = 0,
5
+ inprogress = 1
6
+ }
7
+ export interface ModelItem extends Partial<ListNode> {
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
+ }
19
+ export type Model = List<ModelItem> & {
20
+ skipLines: number;
21
+ tick: number;
22
+ spinning: number;
23
+ };
24
+ export declare function createModel(logAboveSpinners: boolean): [(logMessage: LogMessage) => Model, () => Model];
@@ -1 +1 @@
1
- export default function splitByLines(message: string): string[];
1
+ export default function splitByLines(message: string): string[];
@@ -1 +1 @@
1
- export declare function subscribeToTerminalResize(listener: () => void): void;
1
+ export declare function subscribeToTerminalResize(listener: () => void): void;
package/dist/index.cjs CHANGED
@@ -9,12 +9,12 @@ var spinners = require('./spinners.cjs');
9
9
  require('draftlog');
10
10
  require('@slimlib/list');
11
11
 
12
- if (!process.env.CI) {
13
- const supportsUnicode = formatUtils.terminalSupportsUnicode();
14
- const spinner = supportsUnicode ? spinners.dots : spinners.line;
15
- const formatter = formatUtils.createFormatter(defaultFormatting.colors, supportsUnicode ? defaultFormatting.unicodePrefixes : defaultFormatting.asciiPrefixes, defaultFormatting.tagFactory);
16
- let minLogLevel = 1 /* info */;
17
- globalAppender.appender(appenderUtils.filterMessages((message) => message.loglevel >= minLogLevel, core.createDraftlogAppender(spinner, formatter, true, 2), // eslint-disable-line indent
18
- { setMinLevel(logLevel) { minLogLevel = logLevel; } } // eslint-disable-line indent
19
- ));
12
+ if (!process.env.CI) {
13
+ const supportsUnicode = formatUtils.terminalSupportsUnicode();
14
+ const spinner = supportsUnicode ? spinners.dots : spinners.line;
15
+ const formatter = formatUtils.createFormatter(defaultFormatting.colors, supportsUnicode ? defaultFormatting.unicodePrefixes : defaultFormatting.asciiPrefixes, defaultFormatting.tagFactory);
16
+ let minLogLevel = 1 /* LogLevel.info */;
17
+ globalAppender.appender(appenderUtils.filterMessages((message) => message.loglevel >= minLogLevel, core.createDraftlogAppender(spinner, formatter, true, 2), // eslint-disable-line indent
18
+ { setMinLevel(logLevel) { minLogLevel = logLevel; } } // eslint-disable-line indent
19
+ ));
20
20
  }
package/dist/index.d.ts CHANGED
@@ -1 +1 @@
1
- export {};
1
+ export {};
package/dist/index.mjs CHANGED
@@ -7,12 +7,12 @@ import { dots, line } from './spinners.mjs';
7
7
  import 'draftlog';
8
8
  import '@slimlib/list';
9
9
 
10
- if (!process.env.CI) {
11
- const supportsUnicode = terminalSupportsUnicode();
12
- const spinner = supportsUnicode ? dots : line;
13
- const formatter = createFormatter(colors, supportsUnicode ? unicodePrefixes : asciiPrefixes, tagFactory);
14
- let minLogLevel = 1 /* info */;
15
- appender(filterMessages((message) => message.loglevel >= minLogLevel, createDraftlogAppender(spinner, formatter, true, 2), // eslint-disable-line indent
16
- { setMinLevel(logLevel) { minLogLevel = logLevel; } } // eslint-disable-line indent
17
- ));
10
+ if (!process.env.CI) {
11
+ const supportsUnicode = terminalSupportsUnicode();
12
+ const spinner = supportsUnicode ? dots : line;
13
+ const formatter = createFormatter(colors, supportsUnicode ? unicodePrefixes : asciiPrefixes, tagFactory);
14
+ let minLogLevel = 1 /* LogLevel.info */;
15
+ appender(filterMessages((message) => message.loglevel >= minLogLevel, createDraftlogAppender(spinner, formatter, true, 2), // eslint-disable-line indent
16
+ { setMinLevel(logLevel) { minLogLevel = logLevel; } } // eslint-disable-line indent
17
+ ));
18
18
  }
package/dist/spinners.cjs CHANGED
@@ -1,12 +1,12 @@
1
1
  'use strict';
2
2
 
3
- const dots = {
4
- interval: 50,
5
- frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
6
- };
7
- const line = {
8
- interval: 130,
9
- frames: ['-', '\\', '|', '/']
3
+ const dots = {
4
+ interval: 50,
5
+ frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
6
+ };
7
+ const line = {
8
+ interval: 130,
9
+ frames: ['-', '\\', '|', '/']
10
10
  };
11
11
 
12
12
  exports.dots = dots;
@@ -1,12 +1,12 @@
1
- export interface Spinner {
2
- interval: number;
3
- frames: string[];
4
- }
5
- export declare const dots: {
6
- interval: number;
7
- frames: string[];
8
- };
9
- export declare const line: {
10
- interval: number;
11
- frames: string[];
12
- };
1
+ export interface Spinner {
2
+ interval: number;
3
+ frames: string[];
4
+ }
5
+ export declare const dots: {
6
+ interval: number;
7
+ frames: string[];
8
+ };
9
+ export declare const line: {
10
+ interval: number;
11
+ frames: string[];
12
+ };
package/dist/spinners.mjs CHANGED
@@ -1,10 +1,10 @@
1
- const dots = {
2
- interval: 50,
3
- frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
4
- };
5
- const line = {
6
- interval: 130,
7
- frames: ['-', '\\', '|', '/']
1
+ const dots = {
2
+ interval: 50,
3
+ frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
4
+ };
5
+ const line = {
6
+ interval: 130,
7
+ frames: ['-', '\\', '|', '/']
8
8
  };
9
9
 
10
10
  export { dots, line };
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.3.0",
2
+ "version": "1.3.1",
3
3
  "license": "MIT",
4
4
  "name": "@niceties/draftlog-appender",
5
5
  "author": {
@@ -48,36 +48,20 @@
48
48
  "draftlog",
49
49
  "appender"
50
50
  ],
51
- "scripts": {
52
- "build": "pkgbld-internal",
53
- "test": "node --expose-gc ../node_modules/jest-cli/bin/jest.js --collectCoverage",
54
- "lint": "eslint ./src",
55
- "semantic-release": "npx semantic-release"
56
- },
57
51
  "devDependencies": {
58
- "@semantic-release/changelog": "6.0.1",
59
- "@semantic-release/commit-analyzer": "9.0.1",
60
- "@semantic-release/git": "10.0.1",
61
- "@semantic-release/npm": "8.0.2",
62
- "@semantic-release/release-notes-generator": "10.0.2",
63
- "@types/jest": "27.4.0",
64
- "@typescript-eslint/eslint-plugin": "5.11.0",
65
- "@typescript-eslint/parser": "5.11.0",
66
- "conventional-changelog-angular": "5.0.13",
67
- "eslint": "8.8.0",
68
- "jest": "27.5.1",
69
- "semantic-release": "18.0.0",
70
- "semantic-release-monorepo": "7.0.5",
71
- "ts-jest": "27.1.3",
72
- "typescript": "4.6.x",
73
- "update-monorepo-package-json": "0.2.0",
74
- "pkgbld-internal": "1.0.4"
52
+ "tslib": "2.5.0",
53
+ "@niceties/logger": "1.1.11"
75
54
  },
76
55
  "peerDependencies": {
77
- "@niceties/logger": "^1.1.10"
56
+ "@niceties/logger": "^1.1.11"
78
57
  },
79
58
  "dependencies": {
80
59
  "draftlog": "^1.0.13",
81
60
  "@slimlib/list": "^1.0.3"
61
+ },
62
+ "scripts": {
63
+ "build": "pkgbld-internal",
64
+ "test": "node --expose-gc ../node_modules/jest/bin/jest.js --collectCoverage",
65
+ "lint": "eslint ./src"
82
66
  }
83
- }
67
+ }