anypack-plugin-serve 0.1.0-beta.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +320 -0
- package/client.js +20 -6
- package/lib/client/ClientSocket.js +19 -5
- package/lib/client/Compiler.js +145 -0
- package/lib/client/hmr.js +2 -2
- package/lib/client/log.js +8 -2
- package/lib/index.js +19 -14
- package/lib/middleware.js +3 -3
- package/lib/plugins/hmr.js +3 -3
- package/lib/plugins/ramdisk.js +2 -1
- package/lib/plugins/ramdisk_lib.js +4 -5
- package/lib/routes.js +52 -57
- package/package.json +7 -5
- package/lib/client/client.js +0 -114
- package/lib/client/overlays/progress-minimal.js +0 -118
- package/lib/client/overlays/progress.js +0 -170
- package/lib/client/overlays/status.js +0 -408
- package/lib/client/overlays/util.js +0 -46
package/lib/index.js
CHANGED
|
@@ -25,6 +25,9 @@ const { validate } = require('./validate');
|
|
|
25
25
|
const defaults = {
|
|
26
26
|
// leave `client` undefined
|
|
27
27
|
// client: null,
|
|
28
|
+
client: {
|
|
29
|
+
retry: true,
|
|
30
|
+
},
|
|
28
31
|
compress: null,
|
|
29
32
|
headers: null,
|
|
30
33
|
historyFallback: false,
|
|
@@ -46,7 +49,8 @@ const defaults = {
|
|
|
46
49
|
const key = 'anypack-plugin-serve';
|
|
47
50
|
const nanoid = customAlphabet('1234567890abcdef', 7);
|
|
48
51
|
|
|
49
|
-
let
|
|
52
|
+
let activeInstanceId = null;
|
|
53
|
+
let activeLog = null;
|
|
50
54
|
|
|
51
55
|
class AnypackPluginServe extends EventEmitter {
|
|
52
56
|
constructor(opts = {}) {
|
|
@@ -65,16 +69,18 @@ class AnypackPluginServe extends EventEmitter {
|
|
|
65
69
|
// of the plugin to be tested within the same context. If you find this, use this at your own
|
|
66
70
|
// peril.
|
|
67
71
|
/* istanbul ignore if */
|
|
68
|
-
if (!opts.allowMany &&
|
|
69
|
-
|
|
72
|
+
if (!opts.allowMany && activeInstanceId !== null) {
|
|
73
|
+
activeLog.error(
|
|
70
74
|
'Duplicate instances created. Only the first instance of this plugin will be active.',
|
|
71
75
|
);
|
|
72
76
|
return;
|
|
73
77
|
}
|
|
74
78
|
|
|
75
|
-
|
|
79
|
+
const instanceId = Symbol();
|
|
80
|
+
this._instanceId = instanceId;
|
|
81
|
+
activeInstanceId = instanceId;
|
|
76
82
|
|
|
77
|
-
const options =
|
|
83
|
+
const options = { ...defaults, ...opts };
|
|
78
84
|
|
|
79
85
|
if (options.compress === true) {
|
|
80
86
|
options.compress = {};
|
|
@@ -107,6 +113,7 @@ class AnypackPluginServe extends EventEmitter {
|
|
|
107
113
|
}
|
|
108
114
|
|
|
109
115
|
this.log = getLogger(options.log || {});
|
|
116
|
+
activeLog = this.log;
|
|
110
117
|
this.options = options;
|
|
111
118
|
this.compilers = [];
|
|
112
119
|
this.state = {};
|
|
@@ -117,7 +124,7 @@ class AnypackPluginServe extends EventEmitter {
|
|
|
117
124
|
|
|
118
125
|
// only allow once instance of the plugin to run for a build
|
|
119
126
|
/* istanbul ignore if */
|
|
120
|
-
if (
|
|
127
|
+
if (activeInstanceId !== this._instanceId) {
|
|
121
128
|
return;
|
|
122
129
|
}
|
|
123
130
|
|
|
@@ -125,13 +132,9 @@ class AnypackPluginServe extends EventEmitter {
|
|
|
125
132
|
}
|
|
126
133
|
|
|
127
134
|
attach() {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
apply(compiler) {
|
|
131
|
-
return self.hook(compiler);
|
|
132
|
-
},
|
|
135
|
+
return {
|
|
136
|
+
apply: (compiler) => this.hook(compiler),
|
|
133
137
|
};
|
|
134
|
-
return result;
|
|
135
138
|
}
|
|
136
139
|
|
|
137
140
|
// #138. handle emitted events that don't have a listener registered so they can be sent via WebSocket
|
|
@@ -151,7 +154,8 @@ class AnypackPluginServe extends EventEmitter {
|
|
|
151
154
|
}
|
|
152
155
|
|
|
153
156
|
hook(compiler) {
|
|
154
|
-
const { done, invalid, watchClose, watchRun } =
|
|
157
|
+
const { done, invalid, watchClose, watchRun, beforeCompile } =
|
|
158
|
+
compiler.hooks;
|
|
155
159
|
|
|
156
160
|
if (!compiler.wpsId) {
|
|
157
161
|
compiler.wpsId = nanoid();
|
|
@@ -199,6 +203,7 @@ class AnypackPluginServe extends EventEmitter {
|
|
|
199
203
|
|
|
200
204
|
// we do this emit because webpack caches and optimizes the hooks, so there's no way to detach
|
|
201
205
|
// a listener/hook.
|
|
206
|
+
beforeCompile.tap(key, () => this.emit('build', compiler.name, compiler));
|
|
202
207
|
done.tap(key, (stats) => this.emit('done', stats, compiler));
|
|
203
208
|
invalid.tap(key, (filePath) => this.emit('invalid', filePath, compiler));
|
|
204
209
|
watchClose.tap(key, () => this.emit('close', compiler));
|
|
@@ -234,7 +239,7 @@ class AnypackPluginServe extends EventEmitter {
|
|
|
234
239
|
wpsId: compiler.wpsId,
|
|
235
240
|
};
|
|
236
241
|
|
|
237
|
-
const defineObject =
|
|
242
|
+
const defineObject = { ...this.options, ...compilerData };
|
|
238
243
|
const defineData = { ʎɐɹɔosǝʌɹǝs: JSON.stringify(defineObject) };
|
|
239
244
|
const definePlugin = new compiler.webpack.DefinePlugin(defineData);
|
|
240
245
|
|
package/lib/middleware.js
CHANGED
|
@@ -126,11 +126,11 @@ const getBuiltins = (app, options) => {
|
|
|
126
126
|
}
|
|
127
127
|
};
|
|
128
128
|
|
|
129
|
-
const statik = (root, opts
|
|
130
|
-
const paths = [
|
|
129
|
+
const statik = (root, opts) => {
|
|
130
|
+
const paths = [root || options.static].flat();
|
|
131
131
|
staticPaths = paths;
|
|
132
132
|
for (const path of paths) {
|
|
133
|
-
app.use(sirv(path, opts));
|
|
133
|
+
app.use(sirv(path, opts ?? { dev: true }));
|
|
134
134
|
}
|
|
135
135
|
};
|
|
136
136
|
|
package/lib/plugins/hmr.js
CHANGED
|
@@ -27,15 +27,15 @@ const init = function init(compiler, log) {
|
|
|
27
27
|
);
|
|
28
28
|
|
|
29
29
|
/* istanbul ignore else */
|
|
30
|
-
if (
|
|
31
|
-
addPlugin(compiler);
|
|
32
|
-
} else {
|
|
30
|
+
if (hasHMRPlugin) {
|
|
33
31
|
log.error(
|
|
34
32
|
'anypack-plugin-serve adds HotModuleReplacementPlugin automatically. Please remove it from your config.',
|
|
35
33
|
);
|
|
36
34
|
throw new PluginExistsError(
|
|
37
35
|
'HotModuleReplacementPlugin exists in the specified configuration.',
|
|
38
36
|
);
|
|
37
|
+
} else {
|
|
38
|
+
addPlugin(compiler);
|
|
39
39
|
}
|
|
40
40
|
};
|
|
41
41
|
|
package/lib/plugins/ramdisk.js
CHANGED
|
@@ -29,8 +29,9 @@ const readPkgName = () => {
|
|
|
29
29
|
try {
|
|
30
30
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
31
31
|
return pkg.name;
|
|
32
|
-
} catch (
|
|
32
|
+
} catch (error) {
|
|
33
33
|
// istanbul ignore next
|
|
34
|
+
console.warn(`Could not read package name: ${error.message}`);
|
|
34
35
|
return null;
|
|
35
36
|
}
|
|
36
37
|
};
|
|
@@ -102,18 +102,17 @@ function run(command, ...args) {
|
|
|
102
102
|
|
|
103
103
|
class Ramdisk {
|
|
104
104
|
constructor(opts = {}) {
|
|
105
|
-
const partialOpts =
|
|
106
|
-
const options =
|
|
105
|
+
const partialOpts = { ...defaults, ...opts };
|
|
106
|
+
const options = {
|
|
107
|
+
...partialOpts,
|
|
107
108
|
blocks: partialOpts.bytes / partialOpts.blockSize,
|
|
108
|
-
}
|
|
109
|
+
};
|
|
109
110
|
|
|
110
111
|
this.options = options;
|
|
111
112
|
|
|
112
113
|
this.commands = getCommands();
|
|
113
114
|
this.options.diskPath = this.commands?.root(this.options);
|
|
114
115
|
|
|
115
|
-
// const options = Object.assign({}, opts, { root: commands.root });
|
|
116
|
-
|
|
117
116
|
this.init();
|
|
118
117
|
}
|
|
119
118
|
|
package/lib/routes.js
CHANGED
|
@@ -11,60 +11,65 @@
|
|
|
11
11
|
const { unstyle } = require('ansi-colors');
|
|
12
12
|
const stringify = require('json-stringify-safe');
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
modules: true,
|
|
22
|
-
timings: true,
|
|
23
|
-
exclude: ['node_modules', 'bower_components', 'components'],
|
|
24
|
-
};
|
|
14
|
+
function registerEvent(ee, socket, event, handler) {
|
|
15
|
+
ee.on(event, handler);
|
|
16
|
+
|
|
17
|
+
socket.on('close', () => {
|
|
18
|
+
ee.removeListener(event, handler);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
25
21
|
|
|
26
22
|
const setupRoutes = function setupRoutes() {
|
|
27
23
|
const { app, options } = this;
|
|
28
|
-
|
|
24
|
+
|
|
25
|
+
let buildDone = false;
|
|
26
|
+
this.on('build', () => {
|
|
27
|
+
buildDone = false;
|
|
28
|
+
});
|
|
29
|
+
this.on('done', () => {
|
|
30
|
+
buildDone = true;
|
|
31
|
+
});
|
|
32
|
+
|
|
29
33
|
const connect = async (req, _res) => {
|
|
30
34
|
if (req.ws) {
|
|
31
35
|
const socket = await req.ws();
|
|
32
|
-
|
|
36
|
+
let lastHash = null;
|
|
37
|
+
const send = (action, data) => {
|
|
33
38
|
if (socket.readyState !== 1) {
|
|
34
39
|
return;
|
|
35
40
|
}
|
|
36
|
-
socket.send(data);
|
|
41
|
+
socket.send(stringify({ action, data }));
|
|
37
42
|
};
|
|
38
43
|
|
|
39
|
-
|
|
40
|
-
send(
|
|
41
|
-
};
|
|
44
|
+
registerEvent(this, socket, 'build', (compilerName, { wpsId }) => {
|
|
45
|
+
send('build', { compilerName: compilerName ?? '<unknown>', wpsId });
|
|
46
|
+
});
|
|
42
47
|
|
|
43
|
-
socket
|
|
48
|
+
registerEvent(this, socket, 'done', (stats, { wpsId }) => {
|
|
44
49
|
const { hash } = stats;
|
|
45
50
|
|
|
46
|
-
if (
|
|
51
|
+
if (lastHash === hash) {
|
|
47
52
|
return;
|
|
48
53
|
}
|
|
49
54
|
|
|
50
|
-
send(
|
|
55
|
+
send('done', { hash, wpsId });
|
|
51
56
|
|
|
52
|
-
|
|
57
|
+
lastHash = hash;
|
|
53
58
|
|
|
54
|
-
|
|
59
|
+
if (stats.hasErrors() || stats.hasWarnings()) {
|
|
60
|
+
const renderedStats = stats.toJson('errors-warnings');
|
|
61
|
+
const { errors = [], warnings = [] } = renderedStats;
|
|
55
62
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}),
|
|
67
|
-
);
|
|
63
|
+
send('problems', {
|
|
64
|
+
hash,
|
|
65
|
+
wpsId,
|
|
66
|
+
errors: errors
|
|
67
|
+
.slice(0)
|
|
68
|
+
.map((e) => ({ ...e, message: unstyle(e.message) })),
|
|
69
|
+
warnings: warnings
|
|
70
|
+
.slice(0)
|
|
71
|
+
.map((e) => ({ ...e, message: unstyle(e.message) })),
|
|
72
|
+
});
|
|
68
73
|
|
|
69
74
|
if (errors.length) {
|
|
70
75
|
return;
|
|
@@ -73,41 +78,31 @@ const setupRoutes = function setupRoutes() {
|
|
|
73
78
|
|
|
74
79
|
if (options.hmr || options.liveReload) {
|
|
75
80
|
const action = options.liveReload ? 'reload' : 'replace';
|
|
76
|
-
send(
|
|
81
|
+
send(action, { hash, wpsId });
|
|
77
82
|
}
|
|
78
|
-
};
|
|
83
|
+
});
|
|
79
84
|
|
|
80
|
-
|
|
85
|
+
registerEvent(this, socket, 'invalid', (filePath, compiler) => {
|
|
86
|
+
const path = filePath ?? '<unknown>';
|
|
81
87
|
const context =
|
|
82
88
|
compiler.context || compiler.options.context || process.cwd();
|
|
83
|
-
const fileName =
|
|
89
|
+
const fileName = path?.replace?.(context, '') || path;
|
|
84
90
|
const { wpsId } = compiler;
|
|
85
91
|
|
|
86
|
-
send(
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
socket.progress = (data) => {
|
|
90
|
-
send(prep({ action: 'progress', data }));
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
for (const event of events) {
|
|
94
|
-
this.on(event, socket[event]);
|
|
92
|
+
send('invalid', { fileName, wpsId });
|
|
93
|
+
});
|
|
95
94
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
95
|
+
registerEvent(this, socket, 'progress', (data) => {
|
|
96
|
+
send('progress', data);
|
|
97
|
+
});
|
|
100
98
|
|
|
101
99
|
// #138. handle emitted events that don't have a listener registered, and forward the message
|
|
102
100
|
// onto the client via the socket
|
|
103
|
-
|
|
104
|
-
send(
|
|
105
|
-
this.on('unhandled', unhandled);
|
|
106
|
-
socket.on('close', () => {
|
|
107
|
-
this.off('unhandled', unhandled);
|
|
101
|
+
registerEvent(this, socket, 'unhandled', ({ eventName, data }) => {
|
|
102
|
+
send(eventName, data);
|
|
108
103
|
});
|
|
109
104
|
|
|
110
|
-
send(
|
|
105
|
+
send('connected', { buildDone });
|
|
111
106
|
}
|
|
112
107
|
};
|
|
113
108
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "anypack-plugin-serve",
|
|
3
|
-
"version": "0.1.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "A Development Server in a Webpack Plugin",
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
6
|
"repository": "onigoetz/anypack-plugin-serve",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@polka/compression": "^1.0.0-next.25",
|
|
35
35
|
"ansi-colors": "^4.1.3",
|
|
36
|
+
"anypack-overlay": "0.1.0",
|
|
36
37
|
"connect-history-api-fallback": "^2.0.0",
|
|
37
38
|
"empathic": "^2.0.0",
|
|
38
39
|
"http-proxy-middleware": "^3.0.5",
|
|
@@ -47,14 +48,15 @@
|
|
|
47
48
|
"ws": "^8.18.3"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
50
|
-
"@biomejs/biome": "2.
|
|
51
|
-
"@rstest/core": "^0.
|
|
52
|
-
"@rstest/coverage-istanbul": "^0.
|
|
51
|
+
"@biomejs/biome": "2.4.10",
|
|
52
|
+
"@rstest/core": "^0.9.0",
|
|
53
|
+
"@rstest/coverage-istanbul": "^0.3.0",
|
|
53
54
|
"del-cli": "7.0.0",
|
|
54
55
|
"get-port": "^7.1.0",
|
|
55
56
|
"node-fetch": "^3.3.2",
|
|
56
57
|
"puppeteer": "^24.34.0",
|
|
57
58
|
"random-js": "^2.1.0",
|
|
59
|
+
"rstest-sonar-reporter": "1.0.0",
|
|
58
60
|
"webpack": "^5.0.0",
|
|
59
61
|
"webpack-nano": "^1.0.0"
|
|
60
62
|
},
|
|
@@ -66,4 +68,4 @@
|
|
|
66
68
|
"server",
|
|
67
69
|
"webpack"
|
|
68
70
|
]
|
|
69
|
-
}
|
|
71
|
+
}
|
package/lib/client/client.js
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Copyright © 2018 Andrew Powell
|
|
3
|
-
|
|
4
|
-
This Source Code Form is subject to the terms of the Mozilla Public
|
|
5
|
-
License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
6
|
-
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
7
|
-
|
|
8
|
-
The above copyright notice and this permission notice shall be
|
|
9
|
-
included in all copies or substantial portions of this Source Code Form.
|
|
10
|
-
*/
|
|
11
|
-
const run = (buildHash, options) => {
|
|
12
|
-
const { address, client = {}, hmr, progress, secure, status } = options;
|
|
13
|
-
|
|
14
|
-
options.firstInstance = !window.anypackPluginServe;
|
|
15
|
-
|
|
16
|
-
window.anypackPluginServe = window.anypackPluginServe || {
|
|
17
|
-
compilers: {},
|
|
18
|
-
};
|
|
19
|
-
window.anypackPluginServe.silent = !!client.silent;
|
|
20
|
-
|
|
21
|
-
const { ClientSocket } = require('./ClientSocket.js');
|
|
22
|
-
const { replace } = require('./hmr.js');
|
|
23
|
-
const { error, info, warn } = require('./log.js')();
|
|
24
|
-
|
|
25
|
-
const protocol = secure ? 'wss' : 'ws';
|
|
26
|
-
const socket = new ClientSocket(
|
|
27
|
-
client,
|
|
28
|
-
`${client.protocol || protocol}://${client.address || address}/wps`,
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
const { compilerName } = options;
|
|
32
|
-
|
|
33
|
-
window.anypackPluginServe.compilers[compilerName] = {};
|
|
34
|
-
|
|
35
|
-
// prevents ECONNRESET errors on the server
|
|
36
|
-
window.addEventListener('beforeunload', () => socket.close());
|
|
37
|
-
|
|
38
|
-
socket.addEventListener('message', (message) => {
|
|
39
|
-
const { action, data = {} } = JSON.parse(message.data);
|
|
40
|
-
const { errors, hash = '<?>', warnings } = data || {};
|
|
41
|
-
const shortHash = hash.slice(0, 7);
|
|
42
|
-
const identifier = options.compilerName
|
|
43
|
-
? `(Compiler: ${options.compilerName}) `
|
|
44
|
-
: '';
|
|
45
|
-
const compiler = window.anypackPluginServe.compilers[compilerName];
|
|
46
|
-
const { wpsId } = data;
|
|
47
|
-
|
|
48
|
-
switch (action) {
|
|
49
|
-
case 'build':
|
|
50
|
-
compiler.done = false;
|
|
51
|
-
break;
|
|
52
|
-
case 'connected':
|
|
53
|
-
info(`WebSocket connected ${identifier}`);
|
|
54
|
-
break;
|
|
55
|
-
case 'done':
|
|
56
|
-
compiler.done = true;
|
|
57
|
-
break;
|
|
58
|
-
case 'problems':
|
|
59
|
-
if (data.errors.length) {
|
|
60
|
-
error(`${identifier}Build ${shortHash} produced errors:\n`, errors);
|
|
61
|
-
}
|
|
62
|
-
if (data.warnings.length) {
|
|
63
|
-
warn(
|
|
64
|
-
`${identifier}Build ${shortHash} produced warnings:\n`,
|
|
65
|
-
warnings,
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
break;
|
|
69
|
-
case 'reload':
|
|
70
|
-
window.location.reload();
|
|
71
|
-
break;
|
|
72
|
-
case 'replace':
|
|
73
|
-
// actions with a wpsId in tow indicate actions that should only be executed when the wpsId sent
|
|
74
|
-
// matches the wpsId set in options. this is how we can identify multiple compilers in the
|
|
75
|
-
// client.
|
|
76
|
-
if (wpsId && wpsId === options.wpsId) {
|
|
77
|
-
replace(buildHash, hash, hmr === 'refresh-on-failure');
|
|
78
|
-
}
|
|
79
|
-
break;
|
|
80
|
-
default:
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
if (options.firstInstance) {
|
|
85
|
-
if (progress === 'minimal') {
|
|
86
|
-
const { init } = require('./overlays/progress-minimal.js');
|
|
87
|
-
init(options, socket);
|
|
88
|
-
} else if (progress) {
|
|
89
|
-
const { init } = require('./overlays/progress.js');
|
|
90
|
-
init(options, socket);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (status) {
|
|
94
|
-
const { init } = require('./overlays/status.js');
|
|
95
|
-
init(options, socket);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (module.hot) {
|
|
99
|
-
info('Hot Module Replacement is active');
|
|
100
|
-
|
|
101
|
-
if (options.liveReload) {
|
|
102
|
-
info('Live Reload taking precedence over Hot Module Replacement');
|
|
103
|
-
}
|
|
104
|
-
} else {
|
|
105
|
-
warn('Hot Module Replacement is inactive');
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (!module.hot && options.liveReload) {
|
|
109
|
-
info('Live Reload is active');
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
module.exports = { run };
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Copyright © 2018 Andrew Powell, Matheus Gonçalves da Silva
|
|
3
|
-
|
|
4
|
-
This Source Code Form is subject to the terms of the Mozilla Public
|
|
5
|
-
License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
6
|
-
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
7
|
-
|
|
8
|
-
The above copyright notice and this permission notice shall be
|
|
9
|
-
included in all copies or substantial portions of this Source Code Form.
|
|
10
|
-
*/
|
|
11
|
-
const { addCss, addHtml } = require('./util.js');
|
|
12
|
-
|
|
13
|
-
const ns = 'wps-progress-minimal';
|
|
14
|
-
const html = `
|
|
15
|
-
<div id="${ns}" class="${ns}-hidden">
|
|
16
|
-
<div id="${ns}-bar"></div>
|
|
17
|
-
</div>
|
|
18
|
-
`;
|
|
19
|
-
const css = `
|
|
20
|
-
#${ns} {
|
|
21
|
-
position: fixed;
|
|
22
|
-
top: 0;
|
|
23
|
-
left: 0;
|
|
24
|
-
height: 4px;
|
|
25
|
-
width: 100vw;
|
|
26
|
-
z-index: 2147483645;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
#${ns}-bar {
|
|
30
|
-
width: 0%;
|
|
31
|
-
height: 4px;
|
|
32
|
-
background-color: rgb(186, 223, 172);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
@keyframes ${ns}-fade {
|
|
36
|
-
0% {
|
|
37
|
-
opacity: 1;
|
|
38
|
-
}
|
|
39
|
-
100% {
|
|
40
|
-
opacity: 0;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.${ns}-disappear {
|
|
45
|
-
animation: ${ns}-fade .3s;
|
|
46
|
-
animation-fill-mode: forwards;
|
|
47
|
-
animation-delay: .5s;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
.${ns}-hidden {
|
|
51
|
-
display: none;
|
|
52
|
-
}
|
|
53
|
-
`;
|
|
54
|
-
|
|
55
|
-
let hideOnPageVisible = false;
|
|
56
|
-
|
|
57
|
-
const update = (percent) => {
|
|
58
|
-
const bar = document.querySelector(`#${ns}-bar`);
|
|
59
|
-
bar.style.width = `${percent}%`;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
const reset = (wrapper) => {
|
|
63
|
-
wrapper.classList.add(`${ns}-disappear`);
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
const init = (options, socket) => {
|
|
67
|
-
if (options.firstInstance) {
|
|
68
|
-
document.addEventListener('DOMContentLoaded', () => {
|
|
69
|
-
addCss(css);
|
|
70
|
-
addHtml(html);
|
|
71
|
-
|
|
72
|
-
const wrapper = document.querySelector(`#${ns}`);
|
|
73
|
-
wrapper.addEventListener('animationend', () => {
|
|
74
|
-
update(0);
|
|
75
|
-
wrapper.classList.add(`${ns}-hidden`);
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
document.addEventListener('visibilitychange', () => {
|
|
80
|
-
if (!document.hidden && hideOnPageVisible) {
|
|
81
|
-
const wrapper = document.querySelector(`#${ns}`);
|
|
82
|
-
reset(wrapper);
|
|
83
|
-
hideOnPageVisible = false;
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
socket.addEventListener('message', (message) => {
|
|
89
|
-
const { action, data } = JSON.parse(message.data);
|
|
90
|
-
|
|
91
|
-
if (action !== 'progress') {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const percent = Math.floor(data.percent * 100);
|
|
96
|
-
const wrapper = document.querySelector(`#${ns}`);
|
|
97
|
-
|
|
98
|
-
if (wrapper) {
|
|
99
|
-
wrapper.classList.remove(`${ns}-hidden`, `${ns}-disappear`);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (data.percent === 1) {
|
|
103
|
-
if (document.hidden) {
|
|
104
|
-
hideOnPageVisible = true;
|
|
105
|
-
} else {
|
|
106
|
-
reset(wrapper);
|
|
107
|
-
}
|
|
108
|
-
} else {
|
|
109
|
-
hideOnPageVisible = false;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
update(percent);
|
|
113
|
-
});
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
module.exports = {
|
|
117
|
-
init,
|
|
118
|
-
};
|