webpack-dev-service 0.10.0 → 0.10.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.
Files changed (57) hide show
  1. package/cjs/client/client.cjs +128 -0
  2. package/cjs/client/events.cjs +64 -0
  3. package/cjs/client/hot.cjs +111 -0
  4. package/cjs/client/index.cjs +15 -0
  5. package/cjs/client/main.cjs +59 -0
  6. package/cjs/client/ui/overlay.cjs +233 -0
  7. package/cjs/client/ui/progress.cjs +92 -0
  8. package/cjs/client/ui/utils.cjs +136 -0
  9. package/cjs/server/compose.cjs +56 -0
  10. package/cjs/server/dev/Service.cjs +269 -0
  11. package/cjs/server/dev/index.cjs +60 -0
  12. package/cjs/server/dev/middleware.cjs +96 -0
  13. package/cjs/server/dev/utils/fs.cjs +29 -0
  14. package/cjs/server/dev/utils/hash.cjs +46 -0
  15. package/cjs/server/dev/utils/http.cjs +227 -0
  16. package/cjs/server/dev/utils/path.cjs +46 -0
  17. package/cjs/server/dev/utils/paths.cjs +59 -0
  18. package/cjs/server/dev/utils/ready.cjs +23 -0
  19. package/cjs/server/dev/utils/setupHooks.cjs +106 -0
  20. package/cjs/server/dev/utils/setupOutputFileSystem.cjs +31 -0
  21. package/cjs/server/dev/utils/setupWatching.cjs +43 -0
  22. package/cjs/server/dev/utils/setupWriteToDisk.cjs +54 -0
  23. package/cjs/server/hot/Socket.cjs +185 -0
  24. package/cjs/server/hot/index.cjs +34 -0
  25. package/cjs/server/hot/utils.cjs +100 -0
  26. package/cjs/server/index.cjs +1 -1
  27. package/cjs/server/schema.cjs +127 -0
  28. package/cjs/server/utils.cjs +45 -0
  29. package/esm/client/client.js +126 -0
  30. package/esm/client/events.js +60 -0
  31. package/esm/client/hot.js +106 -0
  32. package/esm/client/index.js +10 -0
  33. package/esm/client/main.js +57 -0
  34. package/esm/client/ui/overlay.js +231 -0
  35. package/esm/client/ui/progress.js +90 -0
  36. package/esm/client/ui/utils.js +123 -0
  37. package/esm/server/compose.js +54 -0
  38. package/esm/server/dev/Service.js +260 -0
  39. package/esm/server/dev/index.js +58 -0
  40. package/esm/server/dev/middleware.js +94 -0
  41. package/esm/server/dev/utils/fs.js +27 -0
  42. package/esm/server/dev/utils/hash.js +44 -0
  43. package/esm/server/dev/utils/http.js +216 -0
  44. package/esm/server/dev/utils/path.js +42 -0
  45. package/esm/server/dev/utils/paths.js +57 -0
  46. package/esm/server/dev/utils/ready.js +21 -0
  47. package/esm/server/dev/utils/setupHooks.js +98 -0
  48. package/esm/server/dev/utils/setupOutputFileSystem.js +29 -0
  49. package/esm/server/dev/utils/setupWatching.js +41 -0
  50. package/esm/server/dev/utils/setupWriteToDisk.js +52 -0
  51. package/esm/server/hot/Socket.js +176 -0
  52. package/esm/server/hot/index.js +32 -0
  53. package/esm/server/hot/utils.js +93 -0
  54. package/esm/server/index.js +37 -0
  55. package/esm/server/schema.js +125 -0
  56. package/esm/server/utils.js +37 -0
  57. package/package.json +4 -4
@@ -0,0 +1,128 @@
1
+ /**
2
+ * @package webpack-dev-service
3
+ * @license MIT
4
+ * @version 0.10.2
5
+ * @author nuintun <nuintun@qq.com>
6
+ * @description A koa 2 middleware for webpack development and hot reloading.
7
+ * @see https://github.com/nuintun/webpack-dev-service#readme
8
+ */
9
+
10
+ 'use strict';
11
+
12
+ const events = require('./events.cjs');
13
+ const overlay = require('./ui/overlay.cjs');
14
+ const progress = require('./ui/progress.cjs');
15
+ const hot = require('./hot.cjs');
16
+
17
+ /**
18
+ * @module client
19
+ */
20
+ function createClient(options) {
21
+ let updateTimer;
22
+ const UPDATE_DELAY = 128;
23
+ const RETRY_INTERVAL = 3000;
24
+ const progress$1 = new progress();
25
+ const overlay$1 = new overlay(options.name);
26
+ const fallback = () => {
27
+ if (options.reload) {
28
+ self.location.reload();
29
+ } else {
30
+ console.warn('Use fallback update but you turn off live reload, please reload by yourself.');
31
+ }
32
+ };
33
+ const applyUpdateAsync = () => {
34
+ updateTimer = self.setTimeout(() => {
35
+ hot.applyUpdate(options.hmr, fallback);
36
+ }, UPDATE_DELAY);
37
+ };
38
+ const onInvalid = () => {
39
+ clearTimeout(updateTimer);
40
+ if (options.progress) {
41
+ progress$1.update(0);
42
+ progress$1.show();
43
+ }
44
+ };
45
+ const onProgress = ({ value }) => {
46
+ if (options.progress) {
47
+ progress$1.update(value);
48
+ }
49
+ };
50
+ const onHash = ({ hash }) => {
51
+ hot.setHash(hash);
52
+ };
53
+ const setIssues = (type, issues) => {
54
+ if (options.overlay) {
55
+ overlay$1.setIssues(type, issues);
56
+ }
57
+ const maps = {
58
+ errors: ['\x1b[38;2;100;30;22m\x1b[48;2;255;95;88m ERROR \x1b[0m', 'error'],
59
+ warnings: ['\x1b[38;2;32;39;35m\x1b[48;2;255;189;46m WARNING \x1b[0m', 'warn']
60
+ };
61
+ const [name, method] = maps[type];
62
+ const debug = console[method];
63
+ for (const { moduleName, chunkName, message } of issues) {
64
+ const filename = moduleName || chunkName || 'unknown';
65
+ debug(`${name} in ${filename}\n${message}`);
66
+ }
67
+ };
68
+ const onIssues = ({ errors, warnings }) => {
69
+ progress$1.hide();
70
+ setIssues('errors', errors);
71
+ setIssues('warnings', warnings);
72
+ if (options.overlay) {
73
+ overlay$1.show();
74
+ }
75
+ if (errors.length <= 0) {
76
+ applyUpdateAsync();
77
+ }
78
+ };
79
+ const onOk = () => {
80
+ overlay$1.hide();
81
+ progress$1.hide();
82
+ applyUpdateAsync();
83
+ };
84
+ const parseMessage = message => {
85
+ try {
86
+ return JSON.parse(message.data);
87
+ } catch (_a) {
88
+ return null;
89
+ }
90
+ };
91
+ const createWebSocket = url => {
92
+ const ws = new WebSocket(url);
93
+ ws.onmessage = message => {
94
+ const parsed = parseMessage(message);
95
+ if (parsed) {
96
+ const { action, payload } = parsed;
97
+ switch (action) {
98
+ case 'invalid':
99
+ onInvalid();
100
+ break;
101
+ case 'progress':
102
+ onProgress(payload);
103
+ break;
104
+ case 'hash':
105
+ onHash(payload);
106
+ break;
107
+ case 'issues':
108
+ onIssues(payload);
109
+ break;
110
+ case 'ok':
111
+ onOk();
112
+ break;
113
+ }
114
+ events.emit(action, payload, options);
115
+ }
116
+ };
117
+ ws.onclose = () => {
118
+ overlay$1.hide();
119
+ progress$1.hide();
120
+ setTimeout(() => {
121
+ createWebSocket(url);
122
+ }, RETRY_INTERVAL);
123
+ };
124
+ };
125
+ createWebSocket(`${options.origin}${options.path}`);
126
+ }
127
+
128
+ module.exports = createClient;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * @package webpack-dev-service
3
+ * @license MIT
4
+ * @version 0.10.2
5
+ * @author nuintun <nuintun@qq.com>
6
+ * @description A koa 2 middleware for webpack development and hot reloading.
7
+ * @see https://github.com/nuintun/webpack-dev-service#readme
8
+ */
9
+
10
+ 'use strict';
11
+
12
+ /**
13
+ * @module events
14
+ */
15
+ const events = {
16
+ ok: [],
17
+ hash: [],
18
+ issues: [],
19
+ invalid: [],
20
+ progress: []
21
+ };
22
+ /**
23
+ * @function on
24
+ * @description Add an event listener callback.
25
+ * @param event Event name.
26
+ * @param callback Event listener callback.
27
+ */
28
+ function on(event, callback) {
29
+ const callbacks = events[event];
30
+ if (callbacks) {
31
+ callbacks.push(callback);
32
+ }
33
+ }
34
+ /**
35
+ * @function off
36
+ * @description Remove an event listener callback.
37
+ * @param event Event name.
38
+ * @param callback Event listener callback.
39
+ */
40
+ function off(event, callback) {
41
+ const callbacks = events[event];
42
+ if (callbacks) {
43
+ if (callback) {
44
+ const index = callbacks.indexOf(callback);
45
+ if (index >= 0) {
46
+ callbacks.splice(index, 1);
47
+ }
48
+ } else {
49
+ events[event] = [];
50
+ }
51
+ }
52
+ }
53
+ function emit(event, message, options) {
54
+ const callbacks = events[event];
55
+ if (callbacks && callbacks.length > 0) {
56
+ for (const callback of callbacks) {
57
+ callback(message, options);
58
+ }
59
+ }
60
+ }
61
+
62
+ exports.emit = emit;
63
+ exports.off = off;
64
+ exports.on = on;
@@ -0,0 +1,111 @@
1
+ /**
2
+ * @package webpack-dev-service
3
+ * @license MIT
4
+ * @version 0.10.2
5
+ * @author nuintun <nuintun@qq.com>
6
+ * @description A koa 2 middleware for webpack development and hot reloading.
7
+ * @see https://github.com/nuintun/webpack-dev-service#readme
8
+ */
9
+
10
+ 'use strict';
11
+
12
+ /**
13
+ * @module hot
14
+ */
15
+ // Last error.
16
+ let error;
17
+ // Last update hash.
18
+ let hash = __webpack_hash__;
19
+ // HMR status.
20
+ let status = 'idle';
21
+ /**
22
+ * @function isUpdateAvailable
23
+ * @description Is there a newer version of this code available.
24
+ */
25
+ function isUpdateAvailable() {
26
+ // __webpack_hash__ is the hash of the current compilation.
27
+ // It's a global variable injected by webpack.
28
+ return hash !== __webpack_hash__;
29
+ }
30
+ /**
31
+ * @function setHash
32
+ * @description Set webpack hash.
33
+ * @param value - The new hash value.
34
+ */
35
+ function setHash(value) {
36
+ hash = value;
37
+ }
38
+ /**
39
+ * @function setStatus
40
+ * @description Set hot status.
41
+ * @param value The new status of the hot update.
42
+ */
43
+ function setStatus(value) {
44
+ status = value;
45
+ }
46
+ // Initialize status.
47
+ if (module.hot) {
48
+ setStatus(module.hot.status());
49
+ }
50
+ /**
51
+ * @function applyUpdate
52
+ * @description Apply update.
53
+ * @param hmr Whether to enable HMR.
54
+ * @param fallback Fallback function when HMR fail.
55
+ */
56
+ function applyUpdate(hmr, fallback) {
57
+ // Update available.
58
+ if (isUpdateAvailable()) {
59
+ // HMR enabled.
60
+ if (hmr && module.hot) {
61
+ switch (status) {
62
+ case 'idle':
63
+ // Set status.
64
+ setStatus('check');
65
+ // Auto check and apply updates.
66
+ module.hot
67
+ .check(true)
68
+ .then(updated => {
69
+ // Update status.
70
+ setStatus(module.hot.status());
71
+ // When updated modules is available,
72
+ // it indicates server is ready to serve new bundle.
73
+ if (updated) {
74
+ // While update completed, do it again until no update available.
75
+ applyUpdate(hmr, fallback);
76
+ }
77
+ })
78
+ .catch(exception => {
79
+ // Get status.
80
+ const status = module.hot.status();
81
+ // Update status.
82
+ switch (status) {
83
+ case 'fail':
84
+ case 'abort':
85
+ setStatus(status);
86
+ default:
87
+ setStatus('fail');
88
+ }
89
+ // Cache error.
90
+ error = exception;
91
+ // Call fallback.
92
+ fallback(error);
93
+ });
94
+ break;
95
+ case 'fail':
96
+ case 'abort':
97
+ // Call fallback.
98
+ fallback(error);
99
+ break;
100
+ }
101
+ } else {
102
+ // HMR disabled.
103
+ fallback();
104
+ }
105
+ }
106
+ }
107
+
108
+ exports.applyUpdate = applyUpdate;
109
+ exports.isUpdateAvailable = isUpdateAvailable;
110
+ exports.setHash = setHash;
111
+ exports.setStatus = setStatus;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @package webpack-dev-service
3
+ * @license MIT
4
+ * @version 0.10.2
5
+ * @author nuintun <nuintun@qq.com>
6
+ * @description A koa 2 middleware for webpack development and hot reloading.
7
+ * @see https://github.com/nuintun/webpack-dev-service#readme
8
+ */
9
+
10
+ 'use strict';
11
+
12
+ const events = require('./events.cjs');
13
+
14
+ exports.off = events.off;
15
+ exports.on = events.on;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @package webpack-dev-service
3
+ * @license MIT
4
+ * @version 0.10.2
5
+ * @author nuintun <nuintun@qq.com>
6
+ * @description A koa 2 middleware for webpack development and hot reloading.
7
+ * @see https://github.com/nuintun/webpack-dev-service#readme
8
+ */
9
+
10
+ 'use strict';
11
+
12
+ const client = require('./client.cjs');
13
+
14
+ /**
15
+ * @module main
16
+ */
17
+ const isTLS = protocol => {
18
+ return protocol === 'https:';
19
+ };
20
+ const getCurrentScript = () => {
21
+ const { currentScript } = document;
22
+ if (currentScript) {
23
+ return currentScript;
24
+ }
25
+ };
26
+ const getProtocol = (params, protocol) => {
27
+ switch (params.get('wss')) {
28
+ case 'true':
29
+ return 'wss:';
30
+ case 'false':
31
+ return 'ws:';
32
+ default:
33
+ return isTLS(protocol) ? 'wss:' : 'ws:';
34
+ }
35
+ };
36
+ const getOrigin = params => {
37
+ const { location } = self;
38
+ const script = getCurrentScript();
39
+ if (script) {
40
+ const url = new URL(script.src, location.href);
41
+ const protocol = getProtocol(params, url.protocol);
42
+ return `${protocol}//${url.host}`;
43
+ }
44
+ const protocol = getProtocol(params, location.protocol);
45
+ return `${protocol}//${location.host}`;
46
+ };
47
+ const getOptions = () => {
48
+ const params = new URLSearchParams(__resourceQuery);
49
+ return {
50
+ origin: getOrigin(params),
51
+ hmr: params.get('hmr') !== 'false',
52
+ path: params.get('path') || '/hot',
53
+ name: params.get('name') || 'webpack',
54
+ reload: params.get('reload') !== 'false',
55
+ overlay: params.get('overlay') !== 'false',
56
+ progress: params.get('progress') !== 'false'
57
+ };
58
+ };
59
+ client(getOptions());
@@ -0,0 +1,233 @@
1
+ /**
2
+ * @package webpack-dev-service
3
+ * @license MIT
4
+ * @version 0.10.2
5
+ * @author nuintun <nuintun@qq.com>
6
+ * @description A koa 2 middleware for webpack development and hot reloading.
7
+ * @see https://github.com/nuintun/webpack-dev-service#readme
8
+ */
9
+
10
+ 'use strict';
11
+
12
+ const utils = require('./utils.cjs');
13
+
14
+ /**
15
+ * @module overlay
16
+ * @see https://github.com/shellscape/webpack-plugin-serve
17
+ */
18
+ const OVERLAY = 'wds-overlay';
19
+ const CSS = `
20
+ .${OVERLAY} {
21
+ top:0;
22
+ left: 0;
23
+ right: 0;
24
+ bottom: 0;
25
+ display: flex;
26
+ position: fixed;
27
+ font-size: 16px;
28
+ overflow: hidden;
29
+ font-style: normal;
30
+ font-weight: normal;
31
+ z-index: 2147483646;
32
+ flex-direction: column;
33
+ box-sizing: border-box;
34
+ transform-origin: center;
35
+ background: rgba(0, 0, 0, .85);
36
+ transform: scale(0) translateZ(0);
37
+ transition: transform .25s ease-out;
38
+ font-family: Consolas, "Lucida Console", monospace;
39
+ }
40
+ .${OVERLAY}-show {
41
+ transform: scale(1) translateZ(0);
42
+ }
43
+ .${OVERLAY}-close {
44
+ top: 16px;
45
+ right: 16px;
46
+ width: 16px;
47
+ height: 16px;
48
+ cursor: pointer;
49
+ position: absolute;
50
+ border-radius: 16px;
51
+ background: #ff5f58;
52
+ display: inline-block;
53
+ transform-origin: center;
54
+ box-shadow: #ff5f58 0 0 6px;
55
+ transform: rotate(0) translateZ(0);
56
+ transition: transform .25s ease-in-out;
57
+ }
58
+ .${OVERLAY}-close:before,
59
+ .${OVERLAY}-close:after {
60
+ top: 7px;
61
+ left: 3px;
62
+ content: "";
63
+ width: 10px;
64
+ height: 2px;
65
+ position: absolute;
66
+ background-color: white;
67
+ transform-origin: center;
68
+ }
69
+ .${OVERLAY}-close:before {
70
+ transform: rotate(45deg);
71
+ }
72
+ .${OVERLAY}-close:after {
73
+ transform: rotate(-45deg);
74
+ }
75
+ .${OVERLAY}-close:hover {
76
+ transform: rotate(180deg) translateZ(0);
77
+ }
78
+ .${OVERLAY}-title {
79
+ margin: 0;
80
+ color: #fff;
81
+ line-height: 16px;
82
+ text-align: center;
83
+ background: #282d35;
84
+ border-radius: 0 0 4px 4px;
85
+ padding: 16px 48px 16px 16px;
86
+ }
87
+ .${OVERLAY}-name {
88
+ font-weight: bold;
89
+ font-style: normal;
90
+ text-transform: uppercase;
91
+ }
92
+ .${OVERLAY}-errors-title,
93
+ .${OVERLAY}-warnings-title {
94
+ color: #ff5f58;
95
+ padding-left: 8px;
96
+ font-style: normal;
97
+ }
98
+ .${OVERLAY}-warnings-title {
99
+ color: #ffbd2e;
100
+ }
101
+ .${OVERLAY}-issues {
102
+ padding: 0 16px;
103
+ overflow-y: auto;
104
+ scrollbar-width: none;
105
+ -ms-overflow-style: none;
106
+ -ms-scroll-chaining: none;
107
+ overscroll-behavior: contain;
108
+ -webkit-overflow-scrolling: touch;
109
+ }
110
+ .${OVERLAY}-issues::-webkit-scrollbar {
111
+ display: none;
112
+ }
113
+ .${OVERLAY}-errors,
114
+ .${OVERLAY}-warnings {
115
+ color: #ddd;
116
+ padding: 16px;
117
+ margin: 16px 0;
118
+ display: block;
119
+ line-height: 1.2;
120
+ border-radius: 4px;
121
+ background: #282d35;
122
+ }
123
+ .${OVERLAY}-errors > section + section,
124
+ .${OVERLAY}-warnings > section + section {
125
+ margin: 16px 0 0;
126
+ }
127
+ .${OVERLAY}-errors > section > em,
128
+ .${OVERLAY}-warnings > section > em {
129
+ line-height: 1;
130
+ color: #641e16;
131
+ padding: 4px 8px;
132
+ font-style: normal;
133
+ border-radius: 4px;
134
+ font-weight: normal;
135
+ background: #ff5f58;
136
+ display: inline-block;
137
+ text-transform: uppercase;
138
+ }
139
+ .${OVERLAY}-warnings > section > em {
140
+ color: #3e2723;
141
+ background: #ffbd2e;
142
+ }
143
+ .${OVERLAY}-errors > section > pre,
144
+ .${OVERLAY}-warnings > section > pre {
145
+ margin: 0;
146
+ font-size: 14px;
147
+ font-family: inherit;
148
+ padding: 8px 0 0 16px;
149
+ white-space: pre-wrap;
150
+ overflow-wrap: anywhere;
151
+ }
152
+ .${OVERLAY}-errors > section > pre a,
153
+ .${OVERLAY}-warnings > section > pre a,
154
+ .${OVERLAY}-errors > section > pre span,
155
+ .${OVERLAY}-warnings > section > pre span {
156
+ display: inline-flex;
157
+ }
158
+ .${OVERLAY}-hidden {
159
+ display: none;
160
+ }
161
+ `;
162
+ const DEFAULT_NAME = 'webpack';
163
+ const HTML = `
164
+ <div class="${OVERLAY}">
165
+ <i class="${OVERLAY}-close"></i>
166
+ <div class="${OVERLAY}-title">
167
+ <em class="${OVERLAY}-name"></em>
168
+ <em class="${OVERLAY}-errors-title"></em>
169
+ <em class="${OVERLAY}-warnings-title"></em>
170
+ </div>
171
+ <aside class="${OVERLAY}-issues">
172
+ <article class="${OVERLAY}-errors ${OVERLAY}-hidden"></article>
173
+ <article class="${OVERLAY}-warnings ${OVERLAY}-hidden"></article>
174
+ </aside>
175
+ </div>
176
+ `;
177
+ class Overlay {
178
+ constructor(name) {
179
+ this.hidden = true;
180
+ const root = utils.getRootElement(OVERLAY);
181
+ utils.injectCSS(CSS, root);
182
+ const [dialog] = utils.appendHTML(HTML, root);
183
+ this.dialog = dialog;
184
+ this.name = dialog.querySelector(`.${OVERLAY}-name`);
185
+ this.close = dialog.querySelector(`.${OVERLAY}-close`);
186
+ this.errorsList = dialog.querySelector(`.${OVERLAY}-errors`);
187
+ this.warningsList = dialog.querySelector(`.${OVERLAY}-warnings`);
188
+ this.errorsTitle = dialog.querySelector(`.${OVERLAY}-errors-title`);
189
+ this.warningsTitle = dialog.querySelector(`.${OVERLAY}-warnings-title`);
190
+ this.name.innerHTML = `⭕ ${name || DEFAULT_NAME}`;
191
+ this.close.addEventListener('click', () => {
192
+ this.hide();
193
+ });
194
+ }
195
+ setIssues(type, issues) {
196
+ const count = issues.length;
197
+ const hidden = `${OVERLAY}-hidden`;
198
+ const problemMaps = {
199
+ errors: ['Error', this.errorsTitle, this.errorsList],
200
+ warnings: ['Warning', this.warningsTitle, this.warningsList]
201
+ };
202
+ const [name, problemTitle, problemList] = problemMaps[type];
203
+ if (count > 0) {
204
+ let html = '';
205
+ problemTitle.innerText = `${count} ${name}(s)`;
206
+ for (const { moduleName, chunkName, message } of issues) {
207
+ const details = utils.ansiToHTML(message);
208
+ const filename = moduleName || chunkName || 'unknown';
209
+ html += `<section><em>${name}</em> in ${filename}<pre>${details}</pre></section>`;
210
+ }
211
+ problemList.innerHTML = html;
212
+ problemList.classList.remove(hidden);
213
+ problemTitle.classList.remove(hidden);
214
+ } else {
215
+ problemList.classList.add(hidden);
216
+ problemTitle.classList.add(hidden);
217
+ }
218
+ }
219
+ show() {
220
+ if (this.hidden) {
221
+ this.hidden = false;
222
+ this.dialog.classList.add(`${OVERLAY}-show`);
223
+ }
224
+ }
225
+ hide() {
226
+ if (!this.hidden) {
227
+ this.hidden = true;
228
+ this.dialog.classList.remove(`${OVERLAY}-show`);
229
+ }
230
+ }
231
+ }
232
+
233
+ module.exports = Overlay;
@@ -0,0 +1,92 @@
1
+ /**
2
+ * @package webpack-dev-service
3
+ * @license MIT
4
+ * @version 0.10.2
5
+ * @author nuintun <nuintun@qq.com>
6
+ * @description A koa 2 middleware for webpack development and hot reloading.
7
+ * @see https://github.com/nuintun/webpack-dev-service#readme
8
+ */
9
+
10
+ 'use strict';
11
+
12
+ const utils = require('./utils.cjs');
13
+
14
+ /**
15
+ * @module progress
16
+ * @see https://github.com/shellscape/webpack-plugin-serve
17
+ * @see https://www.zhangxinxu.com/wordpress/2015/07/svg-circle-loading
18
+ */
19
+ const PROGRESS = 'wds-progress';
20
+ const PERIMETER = 2 * Math.PI * 44;
21
+ const CSS = `
22
+ .${PROGRESS} {
23
+ width: 48px;
24
+ right: 16px;
25
+ height: 48px;
26
+ bottom: 16px;
27
+ display: block;
28
+ font-size: 16px;
29
+ position: fixed;
30
+ cursor: default;
31
+ user-select: none;
32
+ font-style: normal;
33
+ font-weight: normal;
34
+ z-index: 2147483647;
35
+ transform-origin: center;
36
+ transform: scale(0) translateZ(0);
37
+ transition: transform .25s ease-out;
38
+ }
39
+ .${PROGRESS}-show {
40
+ transform: scale(1) translateZ(0);
41
+ }
42
+ .${PROGRESS}-track {
43
+ stroke: #badfac;
44
+ stroke-width: 8;
45
+ stroke-linecap: round;
46
+ fill: rgba(0, 0, 0, 0);
47
+ stroke-dasharray: ${PERIMETER};
48
+ stroke-dashoffset: ${PERIMETER};
49
+ transition: stroke-dashoffset .25s linear;
50
+ transform: matrix(0, -1, 1, 0, 0, 96) translateZ(0);
51
+ }
52
+ `;
53
+ const HTML = `
54
+ <svg class="${PROGRESS}" x="0" y="0" viewBox="0 0 96 96">
55
+ <circle fill="#282d35" cx="50%" cy="50%" r="44" />
56
+ <circle class="${PROGRESS}-track" cx="50%" cy="50%" r="44" />
57
+ <path fill="#fff" d="m48,83.213561l-31.122918,-17.60678l0,-35.21356l31.122918,-17.60678l31.122918,17.60678l0,35.21356l-31.122918,17.60678z" />
58
+ <path fill="#8ed6fb" d="m22.434956,31.608089l24.537982,-13.880011l0,10.810563l-15.288554,8.410172l-9.249428,-5.340723zm-1.678513,1.520052l0,29.027711l8.979458,-5.182262l0,-18.657318l-8.979458,-5.188131zm52.908373,-1.520052l-24.537982,-13.880011l0,10.810563l15.288554,8.410172l9.249428,-5.340723zm1.678513,1.520052l0,29.027711l-8.979458,-5.182262l0,-18.657318l8.979458,-5.188131zm-1.050538,30.905767l-25.165957,14.238016l0,-10.452558l16.121941,-8.867948l0.123247,-0.070427l8.920768,5.152918zm-52.485811,0l25.165957,14.238016l0,-10.452558l-16.121941,-8.867948l-0.123247,-0.070427l-8.920768,5.152918z" />
59
+ <path fill="#1c78c0" d="m49.126834,30.997721l15.083141,8.292793l0,16.432994l-15.083141,-8.709487l0,-16.016301zm-2.153896,0l-15.083141,8.292793l0,16.432994l15.083141,-8.709487l0,-16.016301zm16.215844,26.62732l-15.141831,8.328007l-15.141831,-8.328007l15.141831,-8.744701l15.141831,8.744701z" />
60
+ </svg>
61
+ `;
62
+ class Progress {
63
+ constructor() {
64
+ this.hidden = true;
65
+ const root = utils.getRootElement(PROGRESS);
66
+ utils.injectCSS(CSS, root);
67
+ [this.svg] = utils.appendHTML(HTML, root);
68
+ this.track = this.svg.querySelector(`.${PROGRESS}-track`);
69
+ }
70
+ update(value) {
71
+ value = Math.max(0, Math.min(100, value));
72
+ this.track.style.strokeDashoffset = (((100 - value) / 100) * PERIMETER).toString();
73
+ }
74
+ show() {
75
+ if (this.hidden) {
76
+ this.hidden = false;
77
+ clearTimeout(this.timer);
78
+ this.svg.classList.add(`${PROGRESS}-show`);
79
+ }
80
+ }
81
+ hide() {
82
+ if (!this.hidden) {
83
+ this.hidden = true;
84
+ this.timer = self.setTimeout(() => {
85
+ this.update(0);
86
+ this.svg.classList.remove(`${PROGRESS}-show`);
87
+ }, 300);
88
+ }
89
+ }
90
+ }
91
+
92
+ module.exports = Progress;