@niceties/draftlog-appender 1.0.0-alpha.2

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Konstantin Shutkin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # Draftlog Appender
2
+
3
+ Appender for [`'@niceites/logger'`](../logger/README.md) implemented using draftlog package.
4
+
5
+ - Uses animation in the console to display log messages
6
+
7
+ - Small size
8
+
9
+ - Doesn't hold your event loop on exit
10
+
11
+ - Creates maximum one active interval (timer) at a time
12
+
13
+ - Supports multilevel spinners
14
+
15
+ ![Example](./example.gif "In terminal")
16
+ ![Example](./cmdexe.gif "In windows terminal")
17
+
18
+ # Installation
19
+
20
+ ```
21
+ yarn add @niceties/draftlog-appender
22
+ ```
23
+
24
+ or
25
+
26
+ ```
27
+ npm install --save @niceties/draftlog-appender
28
+ ```
29
+
30
+ # Example
31
+
32
+ To install appender use next import:
33
+
34
+ ```javascript
35
+ import "@niceties/draftlog-appender";
36
+ ```
37
+
38
+ It is better to do it before other imports so default appender in `'@niceites/logger'` not installed.
39
+
40
+ ## Subpackages
41
+
42
+ Default subpackage `'@niceties/draftlog-appender'` exports nothing.
43
+
44
+ Subpackage `'@niceties/draftlog-appender/core'` exports `createDraftlogAppender()` factory.
45
+
46
+ Subpackage `'@niceties/draftlog-appender/spinners'` exports spinners definitions used in default config.
47
+
48
+ ## Prior art
49
+
50
+ - [draftlog](https://github.com/ivanseidel/node-draftlog)
51
+ - [dreidels](https://github.com/SweetMNM/dreidels)
52
+ - [ora](https://github.com/sindresorhus/ora)
53
+ - [Spinnies](https://github.com/jcarpanelli/spinnies)
54
+
55
+ # License
56
+
57
+ [MIT](./LICENSE)
@@ -0,0 +1,3 @@
1
+ {
2
+ "types": "../dist/core.d.ts"
3
+ }
package/dist/core.d.ts ADDED
@@ -0,0 +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;
package/dist/core.js ADDED
@@ -0,0 +1,167 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var draftlog = require('draftlog');
6
+
7
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
+
9
+ var draftlog__default = /*#__PURE__*/_interopDefaultLegacy(draftlog);
10
+
11
+ function createCanvas(spinner, formatter, ident) {
12
+ draftlog__default["default"](console);
13
+ draftlog__default["default"].defaults.canReWrite = false;
14
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
+ const updaters = [];
16
+ return (model) => {
17
+ if (model.skipLines_) {
18
+ updaters.splice(0, model.skipLines_);
19
+ model.skipLines_ = 0;
20
+ }
21
+ let key = 0;
22
+ const stack = [[...model.items_]];
23
+ while (stack.length) {
24
+ const item = stack[stack.length - 1].shift();
25
+ let updater = updaters[Number(key)];
26
+ if (!updater) {
27
+ updater = console.draft(' ');
28
+ updaters.push(updater);
29
+ }
30
+ const prefix = getMessageFormat(item.status_, model.tick_);
31
+ updater(formatter(item.text_, item.loglevel_, prefix, ident * (stack.length - 1)));
32
+ // iterate
33
+ ++key;
34
+ if (item.children_.length) {
35
+ stack.push([...item.children_]);
36
+ }
37
+ while (stack.length && stack[stack.length - 1].length === 0) {
38
+ stack.pop();
39
+ }
40
+ }
41
+ };
42
+ function getMessageFormat(status, tick) {
43
+ // status is truthy when it is inprogress
44
+ const prefix = status ? (spinner.frames[tick]) :
45
+ // status not null when it is finished
46
+ status != null;
47
+ return prefix;
48
+ }
49
+ }
50
+
51
+ function createModel(logAboveSpinners) {
52
+ const model = {
53
+ skipLines_: 0,
54
+ tick_: 0,
55
+ spinning_: 0,
56
+ items_: []
57
+ };
58
+ const itemById = Object.create(null);
59
+ return [({ message: text, inputId, action, loglevel, ref, parentId }) => {
60
+ // item has status undefined, so it is static by default
61
+ const item = { text_: text, loglevel_: loglevel, ref_: ref, parentId_: parentId, children_: [] };
62
+ if (action === 0 /* start */) {
63
+ item.status_ = 1 /* inprogress */;
64
+ }
65
+ if (action === 2 /* finish */) {
66
+ item.status_ = 0 /* finished */;
67
+ }
68
+ if (action !== 3 /* log */) {
69
+ // if status still empty in the original item, or item does not exists it will remain empty and static
70
+ updateModel(inputId, item);
71
+ }
72
+ cleanupModel();
73
+ if (action === 3 /* log */) {
74
+ append(item, logAboveSpinners);
75
+ }
76
+ return model;
77
+ }, () => {
78
+ cleanupModel();
79
+ return model;
80
+ }];
81
+ function append(item, head) {
82
+ model.items_[head ? 'unshift' : 'push'](item);
83
+ model.spinning_ += (item.status_ || 0);
84
+ }
85
+ function updateModel(inputId, options) {
86
+ const modelItem = itemById[inputId];
87
+ if (!modelItem) {
88
+ const item = Object.assign({ inputId_: inputId }, options);
89
+ itemById[inputId] = item;
90
+ const itemParentId = item.parentId_;
91
+ if (itemParentId != null) {
92
+ putIntoChildren(itemParentId, item);
93
+ }
94
+ else {
95
+ append(item, false);
96
+ }
97
+ }
98
+ else {
99
+ const statusDiff = (options.status_ || 0) - (modelItem.status_ || 0);
100
+ delete options.children_;
101
+ const moveIntoParent = options.parentId_ != null && modelItem.parentId_ == null;
102
+ Object.assign(modelItem, options);
103
+ model.spinning_ += statusDiff;
104
+ if (moveIntoParent) {
105
+ model.items_ = model.items_.filter(item => item !== modelItem);
106
+ model.spinning_ -= (modelItem.status_ || 0);
107
+ putIntoChildren(modelItem.parentId_, modelItem);
108
+ }
109
+ }
110
+ }
111
+ function putIntoChildren(itemParentId, item) {
112
+ let parent = itemById[itemParentId];
113
+ if (!parent) {
114
+ parent = { inputId_: itemParentId, text_: '', children_: [], loglevel_: 0, ref_: new WeakRef(model) };
115
+ append(parent, false);
116
+ itemById[itemParentId] = parent;
117
+ }
118
+ parent.children_.push(item);
119
+ model.spinning_ += (item.status_ || 0);
120
+ }
121
+ function cleanupModel() {
122
+ var _a;
123
+ for (const item of model.items_) {
124
+ if (!((_a = item.ref_) === null || _a === void 0 ? void 0 : _a.deref()) && !item.children_.some(item => { var _a; return (_a = item.ref_) === null || _a === void 0 ? void 0 : _a.deref(); })) {
125
+ model.skipLines_ += 1 + item.children_.length;
126
+ model.items_.shift();
127
+ let currentItem = item;
128
+ do {
129
+ currentItem.inputId_ != null && delete itemById[currentItem.inputId_];
130
+ model.spinning_ -= (currentItem.status_ || 0);
131
+ } while ((currentItem = item.children_.pop()));
132
+ }
133
+ else {
134
+ break;
135
+ }
136
+ }
137
+ }
138
+ }
139
+
140
+ function createDraftlogAppender(spinner, formatter, logAboveSpinners, ident) {
141
+ let interval;
142
+ const [updateModel, getModel] = createModel(logAboveSpinners);
143
+ const renderModel = createCanvas(spinner, formatter, ident);
144
+ return function draftlogAppender(message) {
145
+ renderModel(updateModel(message));
146
+ checkTimeout();
147
+ };
148
+ function checkTimeout() {
149
+ const spinning = getModel().spinning_;
150
+ if (spinning && !interval) {
151
+ interval = setInterval(updateSpinners, spinner.interval);
152
+ interval.unref(); // unref immidiately just in case
153
+ }
154
+ else if (!spinning && interval) {
155
+ clearInterval(interval);
156
+ interval = undefined;
157
+ }
158
+ }
159
+ function updateSpinners() {
160
+ const model = getModel();
161
+ model.tick_++;
162
+ model.tick_ %= spinner.frames.length;
163
+ renderModel(model);
164
+ }
165
+ }
166
+
167
+ exports.createDraftlogAppender = createDraftlogAppender;
package/dist/core.mjs ADDED
@@ -0,0 +1,159 @@
1
+ import draftlog from 'draftlog';
2
+
3
+ function createCanvas(spinner, formatter, ident) {
4
+ draftlog(console);
5
+ draftlog.defaults.canReWrite = false;
6
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
+ const updaters = [];
8
+ return (model) => {
9
+ if (model.skipLines_) {
10
+ updaters.splice(0, model.skipLines_);
11
+ model.skipLines_ = 0;
12
+ }
13
+ let key = 0;
14
+ const stack = [[...model.items_]];
15
+ while (stack.length) {
16
+ const item = stack[stack.length - 1].shift();
17
+ let updater = updaters[Number(key)];
18
+ if (!updater) {
19
+ updater = console.draft(' ');
20
+ updaters.push(updater);
21
+ }
22
+ const prefix = getMessageFormat(item.status_, model.tick_);
23
+ updater(formatter(item.text_, item.loglevel_, prefix, ident * (stack.length - 1)));
24
+ // iterate
25
+ ++key;
26
+ if (item.children_.length) {
27
+ stack.push([...item.children_]);
28
+ }
29
+ while (stack.length && stack[stack.length - 1].length === 0) {
30
+ stack.pop();
31
+ }
32
+ }
33
+ };
34
+ function getMessageFormat(status, tick) {
35
+ // status is truthy when it is inprogress
36
+ const prefix = status ? (spinner.frames[tick]) :
37
+ // status not null when it is finished
38
+ status != null;
39
+ return prefix;
40
+ }
41
+ }
42
+
43
+ function createModel(logAboveSpinners) {
44
+ const model = {
45
+ skipLines_: 0,
46
+ tick_: 0,
47
+ spinning_: 0,
48
+ items_: []
49
+ };
50
+ const itemById = Object.create(null);
51
+ return [({ message: text, inputId, action, loglevel, ref, parentId }) => {
52
+ // item has status undefined, so it is static by default
53
+ const item = { text_: text, loglevel_: loglevel, ref_: ref, parentId_: parentId, children_: [] };
54
+ if (action === 0 /* start */) {
55
+ item.status_ = 1 /* inprogress */;
56
+ }
57
+ if (action === 2 /* finish */) {
58
+ item.status_ = 0 /* finished */;
59
+ }
60
+ if (action !== 3 /* log */) {
61
+ // if status still empty in the original item, or item does not exists it will remain empty and static
62
+ updateModel(inputId, item);
63
+ }
64
+ cleanupModel();
65
+ if (action === 3 /* log */) {
66
+ append(item, logAboveSpinners);
67
+ }
68
+ return model;
69
+ }, () => {
70
+ cleanupModel();
71
+ return model;
72
+ }];
73
+ function append(item, head) {
74
+ model.items_[head ? 'unshift' : 'push'](item);
75
+ model.spinning_ += (item.status_ || 0);
76
+ }
77
+ function updateModel(inputId, options) {
78
+ const modelItem = itemById[inputId];
79
+ if (!modelItem) {
80
+ const item = Object.assign({ inputId_: inputId }, options);
81
+ itemById[inputId] = item;
82
+ const itemParentId = item.parentId_;
83
+ if (itemParentId != null) {
84
+ putIntoChildren(itemParentId, item);
85
+ }
86
+ else {
87
+ append(item, false);
88
+ }
89
+ }
90
+ else {
91
+ const statusDiff = (options.status_ || 0) - (modelItem.status_ || 0);
92
+ delete options.children_;
93
+ const moveIntoParent = options.parentId_ != null && modelItem.parentId_ == null;
94
+ Object.assign(modelItem, options);
95
+ model.spinning_ += statusDiff;
96
+ if (moveIntoParent) {
97
+ model.items_ = model.items_.filter(item => item !== modelItem);
98
+ model.spinning_ -= (modelItem.status_ || 0);
99
+ putIntoChildren(modelItem.parentId_, modelItem);
100
+ }
101
+ }
102
+ }
103
+ function putIntoChildren(itemParentId, item) {
104
+ let parent = itemById[itemParentId];
105
+ if (!parent) {
106
+ parent = { inputId_: itemParentId, text_: '', children_: [], loglevel_: 0, ref_: new WeakRef(model) };
107
+ append(parent, false);
108
+ itemById[itemParentId] = parent;
109
+ }
110
+ parent.children_.push(item);
111
+ model.spinning_ += (item.status_ || 0);
112
+ }
113
+ function cleanupModel() {
114
+ var _a;
115
+ for (const item of model.items_) {
116
+ if (!((_a = item.ref_) === null || _a === void 0 ? void 0 : _a.deref()) && !item.children_.some(item => { var _a; return (_a = item.ref_) === null || _a === void 0 ? void 0 : _a.deref(); })) {
117
+ model.skipLines_ += 1 + item.children_.length;
118
+ model.items_.shift();
119
+ let currentItem = item;
120
+ do {
121
+ currentItem.inputId_ != null && delete itemById[currentItem.inputId_];
122
+ model.spinning_ -= (currentItem.status_ || 0);
123
+ } while ((currentItem = item.children_.pop()));
124
+ }
125
+ else {
126
+ break;
127
+ }
128
+ }
129
+ }
130
+ }
131
+
132
+ function createDraftlogAppender(spinner, formatter, logAboveSpinners, ident) {
133
+ let interval;
134
+ const [updateModel, getModel] = createModel(logAboveSpinners);
135
+ const renderModel = createCanvas(spinner, formatter, ident);
136
+ return function draftlogAppender(message) {
137
+ renderModel(updateModel(message));
138
+ checkTimeout();
139
+ };
140
+ function checkTimeout() {
141
+ const spinning = getModel().spinning_;
142
+ if (spinning && !interval) {
143
+ interval = setInterval(updateSpinners, spinner.interval);
144
+ interval.unref(); // unref immidiately just in case
145
+ }
146
+ else if (!spinning && interval) {
147
+ clearInterval(interval);
148
+ interval = undefined;
149
+ }
150
+ }
151
+ function updateSpinners() {
152
+ const model = getModel();
153
+ model.tick_++;
154
+ model.tick_ %= spinner.frames.length;
155
+ renderModel(model);
156
+ }
157
+ }
158
+
159
+ export { createDraftlogAppender };
@@ -0,0 +1,2 @@
1
+ !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("draftlog")):"function"==typeof define&&define.amd?define(["exports","draftlog"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).nicetiesDraftlogAppenderCore={},e.draftlog)}(this,(function(e,n){"use strict";function t(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var o=t(n);function l(e){const n={t:0,o:0,l:0,i:[]},t=Object.create(null);return[({message:c,inputId:u,action:f,loglevel:r,ref:s,parentId:d})=>{const a={u:c,_:r,p:s,v:d,g:[]};return 0===f&&(a.I=1),2===f&&(a.I=0),3!==f&&function(e,i){const c=t[e];if(c){const e=(i.I||0)-(c.I||0);delete i.g;const t=null!=i.v&&null==c.v;Object.assign(c,i),n.l+=e,t&&(n.i=n.i.filter((e=>e!==c)),n.l-=c.I||0,l(c.v,c))}else{const n=Object.assign({h:e},i);t[e]=n;const c=n.v;null!=c?l(c,n):o(n,!1)}}(u,a),i(),3===f&&o(a,e),n},()=>(i(),n)];function o(e,t){n.i[t?"unshift":"push"](e),n.l+=e.I||0}function l(e,l){let i=t[e];i||(i={h:e,u:"",g:[],_:0,p:new WeakRef(n)},o(i,!1),t[e]=i),i.g.push(l),n.l+=l.I||0}function i(){var e;for(const o of n.i){if((null===(e=o.p)||void 0===e?void 0:e.deref())||o.g.some((e=>{var n;return null===(n=e.p)||void 0===n?void 0:n.deref()})))break;{n.t+=1+o.g.length,n.i.shift();let e=o;do{null!=e.h&&delete t[e.h],n.l-=e.I||0}while(e=o.g.pop())}}}}e.createDraftlogAppender=function(e,n,t,i){let c;const[u,f]=l(t),r=function(e,n,t){o.default(console),o.default.defaults.canReWrite=!1;const l=[];return e=>{e.t&&(l.splice(0,e.t),e.t=0);let o=0;const c=[[...e.i]];for(;c.length;){const u=c[c.length-1].shift();let f=l[Number(o)];f||(f=console.draft(" "),l.push(f));const r=i(u.I,e.o);for(f(n(u.u,u._,r,t*(c.length-1))),++o,u.g.length&&c.push([...u.g]);c.length&&0===c[c.length-1].length;)c.pop()}};function i(n,t){return n?e.frames[t]:null!=n}}(e,n,i);return function(n){r(u(n)),function(){const n=f().l;n&&!c?(c=setInterval(s,e.interval),c.unref()):!n&&c&&(clearInterval(c),c=void 0)}()};function s(){const n=f();n.o++,n.o%=e.frames.length,r(n)}},Object.defineProperty(e,"__esModule",{value:!0})}));
2
+ //# sourceMappingURL=core.umd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.umd.js","sources":["../src/details/model.ts","../src/core.ts","../src/details/canvas.ts"],"sourcesContent":["import { Action, LogLevel, LogMessage } from '@niceties/logger/types';\n\nexport const enum ItemStatus {\n finished,\n inprogress\n}\nexport interface ModelItem {\n inputId_?: number;\n text_: string;\n status_?: ItemStatus; // undefined means static\n loglevel_: LogLevel;\n ref_?: WeakRef<never>;\n parentId_?: number;\n next_?: ModelItem;\n children_: ModelItem[];\n}\n\nexport type Model = {\n items_: ModelItem[];\n skipLines_: number;\n tick_: number;\n spinning_: number;\n}\n\nexport function createModel(logAboveSpinners: boolean): [(logMessage: LogMessage) => Model, () => Model] {\n const model: Model = {\n skipLines_: 0,\n tick_: 0,\n spinning_: 0,\n items_: []\n };\n const itemById: {[key: number]: ModelItem} = Object.create(null);\n return [({ message: text, inputId, action, loglevel, ref, parentId }: LogMessage): Model => {\n // item has status undefined, so it is static by default\n const item: ModelItem = { text_: text, loglevel_: loglevel, ref_: ref, parentId_: parentId, children_: [] };\n if (action === Action.start) {\n item.status_ = ItemStatus.inprogress;\n }\n if (action === Action.finish) {\n item.status_ = ItemStatus.finished;\n }\n if (action !== Action.log) {\n // if status still empty in the original item, or item does not exists it will remain empty and static\n updateModel(inputId as number, item);\n }\n cleanupModel();\n if (action === Action.log) {\n append(item, logAboveSpinners);\n }\n return model;\n }, () => {\n cleanupModel();\n return model;\n }];\n\n function append(item: ModelItem, head: boolean) {\n model.items_[head ? 'unshift' : 'push'](item);\n model.spinning_ += (item.status_ || 0);\n }\n\n function updateModel(inputId: number, options: ModelItem): void {\n const modelItem = itemById[inputId];\n if (!modelItem) {\n const item: ModelItem = {inputId_: inputId, ...options};\n itemById[inputId] = item;\n const itemParentId = item.parentId_;\n if (itemParentId != null) {\n putIntoChildren(itemParentId, item);\n } else {\n append(item, false);\n }\n } else {\n const statusDiff = (options.status_ || 0) - (modelItem.status_ || 0);\n delete (options as Partial<ModelItem>).children_;\n const moveIntoParent = options.parentId_ != null && modelItem.parentId_ == null;\n Object.assign(modelItem, options);\n model.spinning_ += statusDiff;\n if (moveIntoParent) {\n model.items_ = model.items_.filter(item => item !== modelItem);\n model.spinning_ -= (modelItem.status_ || 0);\n putIntoChildren(modelItem.parentId_ as number, modelItem);\n }\n }\n }\n\n function putIntoChildren(itemParentId: number, item: ModelItem) {\n let parent = itemById[itemParentId];\n if (!parent) {\n parent = { inputId_: itemParentId, text_: '', children_: [], loglevel_: 0, ref_: new WeakRef(model) as WeakRef<never> };\n append(parent, false);\n itemById[itemParentId] = parent;\n }\n parent.children_.push(item);\n model.spinning_ += (item.status_ || 0);\n }\n\n function cleanupModel() {\n for (const item of model.items_) {\n if (!item.ref_?.deref() && !item.children_.some(item => item.ref_?.deref())) {\n model.skipLines_ += 1 + item.children_.length;\n model.items_.shift();\n let currentItem: ModelItem | undefined = item;\n do {\n currentItem.inputId_ != null && delete itemById[currentItem.inputId_];\n model.spinning_ -= (currentItem.status_ || 0);\n } while ((currentItem = item.children_.pop()));\n } else {\n break;\n }\n }\n }\n}","import { Formatter, LogMessage } from '@niceties/logger/types';\nimport { createCanvas } from './details/canvas';\nimport { createModel } from './details/model';\nimport { Spinner } from './spinners';\n\nexport function createDraftlogAppender(spinner: Spinner, formatter: Formatter, logAboveSpinners: boolean, ident: number) {\n let interval: NodeJS.Timer | undefined;\n\n const [updateModel, getModel] = createModel(logAboveSpinners);\n const renderModel = createCanvas(spinner, formatter, ident);\n\n return function draftlogAppender(message: LogMessage) {\n renderModel(updateModel(message));\n checkTimeout();\n };\n\n function checkTimeout() {\n const spinning = getModel().spinning_;\n if (spinning && !interval) {\n interval = setInterval(updateSpinners, spinner.interval);\n interval.unref(); // unref immidiately just in case\n } else if (!spinning && interval) {\n clearInterval(interval);\n interval = undefined;\n }\n }\n\n function updateSpinners() {\n const model = getModel();\n model.tick_++;\n model.tick_ %= spinner.frames.length;\n renderModel(model);\n }\n}\n\n\n","import draftlog from 'draftlog';\n\nimport { Formatter } from '@niceties/logger/types';\n\nimport { ItemStatus, Model, ModelItem } from './model';\nimport { Spinner } from '../spinners';\n\ninterface DraftlogConfig {\n defaults: {\n canReWrite: boolean,\n maximumLinesUp: number\n }\n}\n\nexport function createCanvas(spinner: Spinner, formatter: Formatter, ident: number) {\n draftlog(console);\n (draftlog as never as DraftlogConfig).defaults.canReWrite = false;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const updaters: Array<(message?: any, ...optionalParams: any[]) => void> = [];\n\n return (model: Model) => {\n if (model.skipLines_) {\n updaters.splice(0, model.skipLines_);\n model.skipLines_ = 0;\n }\n let key = 0;\n const stack = [[...model.items_]];\n while (stack.length) {\n const item = stack[stack.length - 1].shift() as ModelItem;\n let updater = updaters[Number(key)];\n if (!updater) {\n updater = console.draft(' ');\n updaters.push(updater);\n }\n const prefix = getMessageFormat(item.status_ as ItemStatus, model.tick_);\n updater(formatter(item.text_, item.loglevel_, prefix, ident * (stack.length - 1)));\n // iterate\n ++key;\n if (item.children_.length) {\n stack.push([...item.children_]);\n }\n while (stack.length && stack[stack.length - 1].length === 0) {\n stack.pop();\n }\n }\n };\n\n function getMessageFormat(status: ItemStatus, tick: number): string | boolean {\n // status is truthy when it is inprogress\n const prefix = status ? (spinner.frames[tick]) :\n // status not null when it is finished\n status != null;\n return prefix;\n }\n}\n"],"names":["createModel","logAboveSpinners","model","skipLines_","tick_","spinning_","items_","itemById","Object","create","message","text","inputId","action","loglevel","ref","parentId","item","text_","loglevel_","ref_","parentId_","children_","status_","options","modelItem","statusDiff","moveIntoParent","assign","filter","putIntoChildren","inputId_","itemParentId","append","updateModel","cleanupModel","head","parent","WeakRef","push","deref","some","length","shift","currentItem","pop","spinner","formatter","ident","interval","getModel","renderModel","draftlog","console","defaults","canReWrite","updaters","splice","key","stack","updater","Number","draft","prefix","getMessageFormat","status","tick","frames","createCanvas","spinning","setInterval","updateSpinners","unref","clearInterval","undefined","checkTimeout"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { Formatter } from '@niceties/logger/types';
2
+ import { Model } from './model';
3
+ import { Spinner } from '../spinners';
4
+ export declare function createCanvas(spinner: Spinner, formatter: Formatter, ident: number): (model: Model) => void;
@@ -0,0 +1,22 @@
1
+ import { LogLevel, LogMessage } from '@niceties/logger/types';
2
+ export declare const enum ItemStatus {
3
+ finished = 0,
4
+ inprogress = 1
5
+ }
6
+ export interface ModelItem {
7
+ inputId_?: number;
8
+ text_: string;
9
+ status_?: ItemStatus;
10
+ loglevel_: LogLevel;
11
+ ref_?: WeakRef<never>;
12
+ parentId_?: number;
13
+ next_?: ModelItem;
14
+ children_: ModelItem[];
15
+ }
16
+ export declare type Model = {
17
+ items_: ModelItem[];
18
+ skipLines_: number;
19
+ tick_: number;
20
+ spinning_: number;
21
+ };
22
+ export declare function createModel(logAboveSpinners: boolean): [(logMessage: LogMessage) => Model, () => Model];
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ var core = require('@niceties/logger/core');
4
+ var formatUtils = require('@niceties/logger/format-utils');
5
+ var defaultFormatting = require('@niceties/logger/default-formatting');
6
+ var core$1 = require('./core.js');
7
+ var spinners = require('./spinners.js');
8
+ require('draftlog');
9
+
10
+ const supportsUnicode = formatUtils.terminalSupportsUnicode();
11
+ const spinner = supportsUnicode ? spinners.dots : spinners.line;
12
+ const formatter = formatUtils.createFormatter(defaultFormatting.colors, supportsUnicode ? defaultFormatting.unicodePrefixes : defaultFormatting.asciiPrefixes);
13
+ core.appender(core$1.createDraftlogAppender(spinner, formatter, false, 2));
package/dist/index.mjs ADDED
@@ -0,0 +1,11 @@
1
+ import { appender } from '@niceties/logger/core';
2
+ import { terminalSupportsUnicode, createFormatter } from '@niceties/logger/format-utils';
3
+ import { colors, unicodePrefixes, asciiPrefixes } from '@niceties/logger/default-formatting';
4
+ import { createDraftlogAppender } from './core.mjs';
5
+ import { dots, line } from './spinners.mjs';
6
+ import 'draftlog';
7
+
8
+ const supportsUnicode = terminalSupportsUnicode();
9
+ const spinner = supportsUnicode ? dots : line;
10
+ const formatter = createFormatter(colors, supportsUnicode ? unicodePrefixes : asciiPrefixes);
11
+ appender(createDraftlogAppender(spinner, formatter, false, 2));
@@ -0,0 +1,2 @@
1
+ !function(e,i){"object"==typeof exports&&"undefined"!=typeof module?i(require("@niceties/logger/core"),require("@niceties/logger/format-utils"),require("@niceties/logger/default-formatting"),require("./core"),require("./spinners")):"function"==typeof define&&define.amd?define(["@niceties/logger/core","@niceties/logger/format-utils","@niceties/logger/default-formatting","./core","./spinners"],i):i((e="undefined"!=typeof globalThis?globalThis:e||self).nicetiesLoggerCore,e.nicetiesLoggerFormatUtils,e.nicetiesLoggerDefaultFormatting,e.nicetiesDraftlogAppenderCore,e.nicetiesDraftlogAppenderSpinners)}(this,(function(e,i,t,r,o){"use strict";const n=i.terminalSupportsUnicode(),s=n?o.dots:o.line,f=i.createFormatter(t.colors,n?t.unicodePrefixes:t.asciiPrefixes);e.appender(r.createDraftlogAppender(s,f,!1,2))}));
2
+ //# sourceMappingURL=index.umd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.umd.js","sources":["../src/index.ts"],"sourcesContent":["import { appender } from '@niceties/logger/core';\nimport { terminalSupportsUnicode, createFormatter } from '@niceties/logger/format-utils';\nimport { colors, unicodePrefixes, asciiPrefixes } from '@niceties/logger/default-formatting';\nimport { createDraftlogAppender } from './core';\nimport { dots, line } from './spinners';\n\nconst supportsUnicode = terminalSupportsUnicode();\nconst spinner = supportsUnicode ? dots : line;\nconst formatter = createFormatter(colors, supportsUnicode ? unicodePrefixes : asciiPrefixes);\n\nappender(createDraftlogAppender(spinner, formatter, false, 2));\n\n"],"names":["supportsUnicode","terminalSupportsUnicode","spinner","dots","line","formatter","createFormatter","colors","unicodePrefixes","asciiPrefixes","createDraftlogAppender"],"mappings":"koBAMA,MAAMA,EAAkBC,4BAClBC,EAAUF,EAAkBG,OAAOC,OACnCC,EAAYC,kBAAgBC,SAAQP,EAAkBQ,kBAAkBC,4BAErEC,yBAAuBR,EAASG,GAAW,EAAO"}
@@ -0,0 +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
+ };
@@ -0,0 +1,15 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const dots = {
6
+ interval: 50,
7
+ frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
8
+ };
9
+ const line = {
10
+ interval: 130,
11
+ frames: ['-', '\\', '|', '/']
12
+ };
13
+
14
+ exports.dots = dots;
15
+ exports.line = line;
@@ -0,0 +1,10 @@
1
+ const dots = {
2
+ interval: 50,
3
+ frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
4
+ };
5
+ const line = {
6
+ interval: 130,
7
+ frames: ['-', '\\', '|', '/']
8
+ };
9
+
10
+ export { dots, line };
@@ -0,0 +1,2 @@
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).nicetiesDraftlogAppenderSpinners={})}(this,(function(e){"use strict";e.dots={interval:50,frames:["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"]},e.line={interval:130,frames:["-","\\","|","/"]},Object.defineProperty(e,"__esModule",{value:!0})}));
2
+ //# sourceMappingURL=spinners.umd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinners.umd.js","sources":["../src/spinners.ts"],"sourcesContent":["export interface Spinner {\n\tinterval: number;\n\tframes: string[];\n}\n\nexport const dots = {\n interval: 50,\n frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']\n};\n\nexport const line = {\n interval: 130,\n frames: ['-', '\\\\', '|', '/']\n};\n"],"names":["interval","frames"],"mappings":"+QAKoB,CAChBA,SAAU,GACVC,OAAQ,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,aAGtC,CAChBD,SAAU,IACVC,OAAQ,CAAC,IAAK,KAAM,IAAK"}
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "version": "1.0.0-alpha.2",
3
+ "license": "MIT",
4
+ "name": "@niceties/draftlog-appender",
5
+ "author": "Konstantin Shutkin",
6
+ "funding": "https://www.donationalerts.com/r/excitingcode",
7
+ "type": "module",
8
+ "exports": {
9
+ ".": {
10
+ "require": "./dist/index.cjs",
11
+ "default": "./dist/index.mjs"
12
+ },
13
+ "./core": {
14
+ "require": "./dist/core.cjs",
15
+ "default": "./dist/core.mjs"
16
+ },
17
+ "./spinners": {
18
+ "require": "./spinners/dist/spinners.cjs",
19
+ "default": "./spinners/dist/spinners.mjs"
20
+ }
21
+ },
22
+ "main": "./dist/index.cjs",
23
+ "module": "./dist/index.mjs",
24
+ "typings": "./dist/index.d.ts",
25
+ "unpkg": "./dist/index.umd.js",
26
+ "files": [
27
+ "dist",
28
+ "core",
29
+ "spinners"
30
+ ],
31
+ "engines": {
32
+ "node": ">=14.8"
33
+ },
34
+ "scripts": {
35
+ "build": "rimraf ./dist && rollup -c",
36
+ "dev": "rimraf ./dist && rollup -c -w",
37
+ "test": "node --expose-gc ../node_modules/jest-cli/bin/jest.js --collectCoverage",
38
+ "lint": "eslint ./src",
39
+ "semantic-release": "npx semantic-release"
40
+ },
41
+ "devDependencies": {
42
+ "@rollup/plugin-commonjs": "21.0.1",
43
+ "@rollup/plugin-node-resolve": "13.0.6",
44
+ "@semantic-release/changelog": "6.0.1",
45
+ "@semantic-release/commit-analyzer": "9.0.1",
46
+ "@semantic-release/git": "10.0.1",
47
+ "@semantic-release/npm": "8.0.2",
48
+ "@semantic-release/release-notes-generator": "10.0.2",
49
+ "@types/jest": "27.0.2",
50
+ "@typescript-eslint/eslint-plugin": "5.3.0",
51
+ "@typescript-eslint/parser": "5.3.0",
52
+ "conventional-changelog-angular": "5.0.13",
53
+ "eslint": "8.1.0",
54
+ "jest": "27.3.1",
55
+ "lodash": "4.17.21",
56
+ "niceties": "1.1.0",
57
+ "rimraf": "3.0.2",
58
+ "rollup": "2.60.1",
59
+ "rollup-plugin-terser": "7.0.2",
60
+ "rollup-plugin-typescript2": "0.31.1",
61
+ "semantic-release": "18.0.0",
62
+ "semantic-release-monorepo": "7.0.5",
63
+ "ts-jest": "27.0.7",
64
+ "typescript": "4.4.x"
65
+ },
66
+ "dependencies": {
67
+ "@niceties/logger": "^1.0.0-alpha.2",
68
+ "draftlog": "^1.0.13"
69
+ }
70
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "types": "../dist/spinners.d.ts"
3
+ }