mazey 1.4.37 → 2.0.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 CHANGED
@@ -1,317 +1,477 @@
1
- # Mazey
2
-
3
- [![NPM version][npm-image]][npm-url]
4
- [![l][l-image]][l-url]
5
-
6
- [npm-image]: https://img.shields.io/npm/v/mazey
7
- [npm-url]: https://npmjs.org/package/mazey
8
- [l-image]: https://img.shields.io/npm/l/mazey
9
- [l-url]: https://github.com/mazeyqian/mazey
10
-
11
- Mazey's library for front end.
12
-
13
- ## Install
14
-
15
- You can get Mazey via [npm](https://www.npmjs.com/package/mazey).
16
-
17
- ```
18
- npm install mazey --save
19
- ```
20
-
21
- ## Usage
22
-
23
- ### 加载资源
24
-
25
- 加载 JavaScript
26
-
27
- ```
28
- import { loadScript } from 'mazey';
29
-
30
- loadScript({
31
- url: 'http://www.mazey.net/js/plugin/jquery/jquery-2.1.1.min.js'
32
- })
33
- .then(
34
- res => {
35
- console.log(`加载 JavaScript: ${res}`);
36
- }
37
- )
38
- .catch(
39
- err => {
40
- console.error(`加载 JavaScript Error: ${err}`)
41
- }
42
- );
43
- ```
44
-
45
- 加载 CSS
46
-
47
- ```
48
- import { loadCSS } from 'mazey';
49
-
50
- loadCSS({
51
- url: 'http://www.mazey.net/css/mazey-base.css'
52
- })
53
- .then(
54
- res => {
55
- console.log(`加载 CSS: ${res}`);
56
- }
57
- )
58
- .catch(
59
- err => {
60
- console.error(`加载 CSS Error: ${err}`)
61
- }
62
- );
63
- ```
64
-
65
- 判断页面是否加载完成(兼容浏览器 `load` 事件已经触发过的情况)
66
-
67
- ```
68
- import { loadCSS } from 'mazey';
69
-
70
- windowLoaded({ timeout: 30 })
71
- .then(res => {
72
- console.log(`加载完成:${res}`); // 加载完成:load
73
- })
74
- .catch(err => {
75
- console.log(`加载超时或失败:${err}`);
76
- });
77
- ```
78
-
79
- ### 存储数据
80
-
81
- Storage
82
-
83
- ```
84
- import { setSessionStorage, getSessionStorage, setLocalStorage, getLocalStorage } from 'mazey';
85
-
86
- setSessionStorage('test', '123');
87
- getSessionStorage('test'); // 123
88
- setLocalStorage('test', '123');
89
- getLocalStorage('test'); // 123
90
- ```
91
-
92
- Cookie
93
-
94
- ```
95
- import { setCookie, getCookie } from 'mazey';
96
-
97
- setCookie('test', '123', 30, 'mazey.net'); // key value day domain
98
- getCookie('test'); // 123
99
- ```
100
-
101
- ### 操作 DOM
102
-
103
- 修改 `class`
104
-
105
- ```
106
- import { hasClass, addClass, removeClass } from 'mazey';
107
-
108
- const dom = document.querySelector('#box');
109
-
110
- // 判断 class
111
- hasClass(dom, 'test');
112
- // 增加 class
113
- addClass(dom, 'test');
114
- // 删除 class
115
- removeClass(dom, 'test');
116
- ```
117
-
118
- 添加内联样式
119
-
120
- ```
121
- import { addInlineStyle } from 'mazey';
122
-
123
- // 添加有 id 的内联样式,重复添加会更新内联样式而不是新增
124
- addInlineStyle({
125
- inlineStyle: `
126
- body {
127
- background-color: #333;
128
- }
129
- `,
130
- id: 'test',
131
- });
132
- // <style id="test">
133
- // body {
134
- // background-color: #333;
135
- // }
136
- // </style>
137
-
138
- // 添加无 id 的内联样式,重复添加会新增内联样式
139
- addInlineStyle({
140
- inlineStyle: `
141
- body {
142
- background-color: #444;
143
- }
144
- `,
145
- });
146
- // <style>
147
- // body {
148
- // background-color: #444;
149
- // }
150
- // </style>
151
- ```
152
-
153
- 添加自定义滚动条(适用于用 `transform` 移动的元素)
154
-
155
- ```
156
- import { customScrollBarForTransformEle } from 'mazey';
157
-
158
- // 使用类名
159
- customScrollBarForTransformEle({
160
- containerClassName: 'i-am-container',
161
- imgBoxClassName: 'i-am-img-father-i-can-transform',
162
- imgClassName: 'i-am-img',
163
- });
164
-
165
- // 使用 Dom 对象
166
- customScrollBarForTransformEle({
167
- containerClassName: 'i-am-container',
168
- imgBoxDom: document.querySelector('.i-am-img-father-i-can-transform'),
169
- imgDom: document.querySelector('.i-am-img-father-i-can-transform'),
170
- });
171
-
172
- // 按需直接隐藏滚动条
173
- customScrollBarForTransformEle({
174
- containerClassName: 'i-am-container',
175
- action: 'hide',
176
- });
177
- ```
178
-
179
- 计算适配容器宽度的图片的尺寸、距离顶部的距离
180
-
181
- ```
182
- import { calcContainImageSizeAndPosition } from 'mazey';
183
-
184
- // 如果高度不足以占满容器,使其垂直居中;如果高度比容器长,由上向下铺开
185
- calcContainImageSizeAndPosition({ oriImageWidth: 300, oriImageHeight: 300, viewportWidth: 375, viewportHeight: 812 });
186
- // {"targetImageWidth":375,"targetImageHeight":375,"top":218.5,"wPer":1.25}
187
- ```
188
-
189
- ### 网站性能
190
-
191
- 获取加载时间
192
-
193
- ```
194
- import { getPerformance } from 'mazey';
195
-
196
- // camelCase:true(默认) 以驼峰形式返回数据 / false 以下划线形式返回数据
197
- getPerformance({ camelCase: true })
198
- .then(res => {
199
- console.log(JSON.stringify(res));
200
- // {"deviceType":"pc","network":"3g","unloadTime":0,"redirectTime":0,"dnsTime":0,"tcpTime":0,"responseTime":65,"downloadTime":1,"domreadyTime":369,"onloadTime":441,"whiteTime":94,"renderTime":441,"decodedBodySize":210,"encodedBodySize":210}
201
- })
202
- .catch(console.error);
203
- ```
204
-
205
- | 指标 | 字段 | 计算⽅法 |
206
- | --- | --- | --- |
207
- | * DNS 查询时间 | dns_time | domainLookupEnd - domainLookupStart |
208
- | * 服务器连接时间 | tcp_time | connectEnd - connectStart |
209
- | * 服务器响应时间 | response_time | responseStart - requestStart |
210
- | * ⽩屏时间 | white_time | responseStart - navigationStart |
211
- | * DomReady 总时间 | domready_time | domContentLoadedEventStart - navigationStart |
212
- | * 页面加载时间 | onload_time | loadEventStart - navigationStart |
213
- | * EventEnd 总时间 | render_time | loadEventEnd -navigationStart |
214
- | 上个⽂档卸载时间 | unload_time | unloadEventEnd - unloadEventStart |
215
- | 重定向时间 | redirect_time | redirectEnd - redirectStart |
216
- | 客户端⽩屏时间 | custom_white_time | renderTiming - navigationStart |
217
- | SSL连接时间 | ssl_time | connectEnd - secureConnectionStart |
218
- | ⽹⻚下载时间 | download_time | responseEnd - responseStart |
219
- | FCP | first_contentful_paint_time | firstPaintTime |
220
-
221
- ### 公式计算
222
-
223
- 计算两个字符串的最长公共子串
224
-
225
- ```
226
- import { calLongestCommonSubstring } from 'mazey';
227
-
228
- calLongestCommonSubstring('fish', 'finish'); // 3
229
- ```
230
-
231
- 计算两个字符串的最长公共子序列
232
-
233
- ```
234
- import { calLongestCommonSubsequence } from 'mazey';
235
-
236
- calLongestCommonSubsequence('fish', 'finish'); // 4
237
- ```
238
-
239
- 命中概率(1% ~ 100%)
240
-
241
- ```
242
- import { inRate } from 'mazey';
243
-
244
- inRate(0.5); // 0.01 ~ 1 true / false
245
-
246
- // 测试准确性
247
- let trueCount = 0;
248
- let falseCount = 0;
249
- new Array(1000000).fill(0).forEach(() => {
250
- if (inRate(0.5)) {
251
- trueCount++;
252
- } else {
253
- falseCount++;
254
- }
255
- });
256
- console.log(trueCount, falseCount); // 499994 500006
257
- ```
258
-
259
- ### 浏览器信息
260
-
261
- ```
262
- import { getBrowserType } from 'mazey';
263
-
264
- getBrowserType(); // {"engine":"webkit","engineVs":"537.36","platform":"desktop","supporter":"chrome","supporterVs":"85.0.4183.121","system":"windows","systemVs":"10"}
265
- // 外壳和外壳版本 { shell: 'wechat', shellVs: '20' } shell: wechat qq uc 360 2345 sougou liebao maxthon
266
- ```
267
-
268
- ### 安全边际
269
-
270
- 判断是否是安全的 PWA 运行环境
271
-
272
- ```
273
- import { isSafePWAEnv } from 'mazey';
274
-
275
- isSafePWAEnv(); // true
276
- ```
277
-
278
- ### 函数
279
-
280
- 防抖
281
-
282
- ```
283
- import { debounce } from 'mazey';
284
-
285
- const foo = debounce(() => {
286
- console.log('执行 1 秒内再次执行无反应');
287
- }, 1000, { leading: true })
288
- ```
289
-
290
- 判断是否是有效数字
291
-
292
- ```
293
- import { isNumber } from 'mazey';
294
-
295
- isNumber(123); // true
296
- isNumber('123'); // false
297
- // 默认情况下 NaN、Infinity 不算有效数字
298
- isNumber(Infinity); // false
299
- isNumber(Infinity, { isUnFiniteAsNumber: true }); true
300
- isNumber(NaN); // false
301
- isNumber(NaN, { isNaNAsNumber: true, isUnFiniteAsNumber: true }); // true
302
- ```
303
-
304
- [更多接口>>](https://mazey.cn/docs/mazey/modules/_index_.html)
305
-
306
- ## Develop
307
-
308
- ```
309
- # dev
310
- npm run dev
311
-
312
- # build
313
- npm run build
314
-
315
- # documentation
316
- npm run docs
317
- ```
1
+ English | [简体中文](./README_CN.md)
2
+
3
+ # Mazey
4
+
5
+ [![NPM version][npm-image]][npm-url]
6
+ [![l][l-image]][l-url]
7
+
8
+ [npm-image]: https://img.shields.io/npm/v/mazey
9
+ [npm-url]: https://npmjs.org/package/mazey
10
+ [l-image]: https://img.shields.io/npm/l/mazey
11
+ [l-url]: https://github.com/mazeyqian/mazey
12
+
13
+ Mazey's library for front end.
14
+
15
+ ## Install
16
+
17
+ You can get Mazey via [npm](https://www.npmjs.com/package/mazey).
18
+
19
+ ```
20
+ npm install mazey --save
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ ### Load Resource
26
+
27
+ #### Load JavaScript
28
+
29
+ ```
30
+ import { loadScript } from 'mazey';
31
+
32
+ loadScript({
33
+ url: 'http://example.com/js/plugin/jquery/jquery-2.1.1.min.js',
34
+ id: 'iamid', // Optional, script ID, default none
35
+ timeout: 5000, // Optional, timeout, default `5000`
36
+ isDefer: false, // Optional, defer, default `false`
37
+ })
38
+ .then(
39
+ res => {
40
+ console.log(`Load JavaScript Success: ${res}`);
41
+ }
42
+ )
43
+ .catch(
44
+ err => {
45
+ console.error(`Load JavaScript Fail: ${err}`)
46
+ }
47
+ );
48
+ ```
49
+
50
+ #### Load CSS
51
+
52
+ ```
53
+ import { loadCSS } from 'mazey';
54
+
55
+ loadCSS({
56
+ url: 'http://example.com/css/mazey-base.css',
57
+ id: 'iamid', // Optional, link ID, default none
58
+ })
59
+ .then(
60
+ res => {
61
+ console.log(`Load CSS Success: ${res}`);
62
+ }
63
+ )
64
+ .catch(
65
+ err => {
66
+ console.error(`Load CSS Fail: ${err}`)
67
+ }
68
+ );
69
+ ```
70
+
71
+ #### Check Load
72
+
73
+ Check whether the page is loaded successfully (Keepe the compatibility in case that browser's `load` event has been triggered).
74
+
75
+ ```
76
+ import { windowLoaded } from 'mazey';
77
+
78
+ windowLoaded({ timeout: 30 }) // second
79
+ .then(res => {
80
+ console.log(`Load Success: ${res}`); // Load Success: load
81
+ })
82
+ .catch(err => {
83
+ console.log(`Load Timeout or Fail: ${err}`);
84
+ });
85
+ ```
86
+ ### Function
87
+
88
+ #### Debounce
89
+
90
+ ```
91
+ import { debounce } from 'mazey';
92
+
93
+ const foo = debounce(() => {
94
+ console.log('The debounced function will only be invoked in 1000 milliseconds, the other invoking will disappear during the wait time.');
95
+ }, 1000, { leading: true })
96
+ ```
97
+
98
+ #### Throttle
99
+
100
+ ```
101
+ import { throttle } from 'mazey';
102
+
103
+ const foo = throttle(() => {
104
+ console.log('The function will be invoked at most once per every wait 1000 milliseconds.');
105
+ }, 1000, { leading: true })
106
+ ```
107
+
108
+ #### Check Number
109
+
110
+ Check whether it is a right number.
111
+
112
+ ```
113
+ import { isNumber } from 'mazey';
114
+
115
+ isNumber(123); // true
116
+ isNumber('123'); // false
117
+ // Default: NaN, Infinity is not Number
118
+ isNumber(Infinity); // false
119
+ isNumber(Infinity, { isUnFiniteAsNumber: true }); true
120
+ isNumber(NaN); // false
121
+ isNumber(NaN, { isNaNAsNumber: true, isUnFiniteAsNumber: true }); // true
122
+ ```
123
+
124
+ #### Camel Case
125
+
126
+ Transfer CamelCase to KebabCase.
127
+
128
+ ```
129
+ import { camelCaseToKebabCase } from 'mazey';
130
+
131
+ camelCaseToKebabCase('ABC'); // a-b-c
132
+ camelCaseToKebabCase('aBC'); // a-b-c
133
+ ```
134
+
135
+ Transfer CamelCase to Underscore.
136
+
137
+ ```
138
+ import { camelCase2Underscore } from 'mazey';
139
+
140
+ camelCase2Underscore('ABC'); // a-b-c
141
+ camelCase2Underscore('aBC'); // a-b-c
142
+ ```
143
+
144
+ #### Trim
145
+
146
+ Remove leading and trailing whitespace or specified characters from string.
147
+
148
+ ```
149
+ import { mTrim } from 'mazey';
150
+
151
+ mTrim(' 1 2 3 '); // '1 2 3'
152
+ mTrim('abc '); // 'abc'
153
+ ```
154
+
155
+ #### Deep Clone
156
+
157
+ Clone Object deeply.
158
+
159
+ ```
160
+ import { deepCopyObject } from 'mazey';
161
+
162
+ deepCopyObject(['a', 'b', 'c']); // ['a', 'b', 'c']
163
+ deepCopyObject('abc'); // 'abc'
164
+ ```
165
+
166
+ #### JSON
167
+
168
+ Check whether it is a valid JSON string.
169
+
170
+ ```
171
+ import { isJsonString } from 'mazey';
172
+
173
+ isJsonString(`['a', 'b', 'c']`); // false
174
+ isJsonString(`["a", "b", "c"]`); // true
175
+ ```
176
+
177
+ #### Random
178
+
179
+ Produce a random string of number, `generateRndNum(7)` => '7658495'.
180
+
181
+ ```
182
+ import { generateRndNum } from 'mazey';
183
+
184
+ generateRndNum(4); // '9730'
185
+ generateRndNum(7); // '2262490'
186
+ ```
187
+
188
+ ### DOM
189
+
190
+ #### Class
191
+
192
+ Modify `class`.
193
+
194
+ ```
195
+ import { hasClass, addClass, removeClass } from 'mazey';
196
+
197
+ const dom = document.querySelector('#box');
198
+
199
+ // Determine `class`
200
+ hasClass(dom, 'test');
201
+ // Add `class`
202
+ addClass(dom, 'test');
203
+ // Remove `class`
204
+ removeClass(dom, 'test');
205
+ ```
206
+
207
+ #### Style
208
+
209
+ Add inline-style.
210
+
211
+ Case 1: Add the inline style with `id`, and repeated invoking will update the content instead of adding a new one.
212
+
213
+ ```
214
+ import { addInlineStyle } from 'mazey';
215
+
216
+ addInlineStyle({
217
+ inlineStyle: `
218
+ body {
219
+ background-color: #333;
220
+ }
221
+ `,
222
+ id: 'test',
223
+ });
224
+ // <style id="test">
225
+ // body {
226
+ // background-color: #333;
227
+ // }
228
+ // </style>
229
+ ```
230
+
231
+ Case 2: Add the inline style without `id`, and repeated invoking will adding a new one.
232
+
233
+ ```
234
+ import { addInlineStyle } from 'mazey';
235
+
236
+ addInlineStyle({
237
+ inlineStyle: `
238
+ body {
239
+ background-color: #444;
240
+ }
241
+ `,
242
+ });
243
+ // <style>
244
+ // body {
245
+ // background-color: #444;
246
+ // }
247
+ // </style>
248
+ ```
249
+
250
+ #### Newline
251
+
252
+ Make a newline of HTML.
253
+
254
+ ```
255
+ import { newLine } from 'mazey';
256
+
257
+ newLine('a\nb\nc'); // 'a<br />b<br />c'
258
+ newLine('a\n\nbc'); // 'a<br /><br />bc'
259
+ ```
260
+
261
+ ### URL
262
+
263
+ #### Query Param
264
+
265
+ Get the query param's value of the current Web URL(`location.search`).
266
+
267
+ ```
268
+ import { getQueryParam } from 'mazey';
269
+
270
+ // http://example.com/?t1=1&t2=2&t3=3&t4=4#2333
271
+ // ?t1=1&t2=2&t3=3&t4=4
272
+ getQueryParam('t3'); // 3
273
+ getQueryParam('t4'); // 4
274
+ ```
275
+
276
+ Get the query param's value of the input URL.
277
+
278
+ ```
279
+ import { getUrlParam } from 'mazey';
280
+
281
+ getUrlParam('http://example.com/?t1=1&t2=2&t3=3&t4=4', 't3'); // 3
282
+ getUrlParam('http://example.com/?t1=1&t2=2&t3=3&t4=4', 't4'); // 4
283
+ ```
284
+
285
+ #### Update Param
286
+
287
+ Update the query param's value of the input URL.
288
+
289
+ ```
290
+ import { updateQueryParam } from 'mazey';
291
+
292
+ updateQueryParam('http://example.com/?t1=1&t2=2&t3=3&t4=4', 't3', 'three'); // http://example.com/?t1=1&t2=2&t3=three&t4=4
293
+ updateQueryParam('http://example.com/?t1=1&t2=2&t3=3&t4=4', 't4', 'four'); // http://example.com/?t1=1&t2=2&t3=3&t4=four
294
+ ```
295
+
296
+ #### Hash Param
297
+
298
+ Get the hash query param's value of the current Web URL(`location.hash`).
299
+
300
+ ```
301
+ import { getHashQueryParam } from 'mazey';
302
+
303
+ // http://example.com/?#2333?t1=1&t2=2&t3=3&t4=4
304
+ // #2333?t1=1&t2=2&t3=3&t4=4
305
+ getHashQueryParam('t3'); // 3
306
+ getHashQueryParam('t4'); // 4
307
+ ```
308
+
309
+ #### Domain
310
+
311
+ Get the domain of URL, and other params.
312
+
313
+ ```
314
+ import { getDomain } from 'mazey';
315
+
316
+ getDomain('http://example.com/?t1=1&t2=2&t3=3&t4=4'); // example.com
317
+ getDomain('http://example.com/test/thanks?t1=1&t2=2&t3=3&t4=4', ['hostname', 'pathname']); // example.com/test/thanks
318
+ ```
319
+
320
+ ### Cache Data
321
+
322
+ #### Storage
323
+
324
+ Handle Storage (Keep fit for JSON, it can tansfer format automatically).
325
+
326
+ ```
327
+ import { setSessionStorage, getSessionStorage, setLocalStorage, getLocalStorage } from 'mazey';
328
+
329
+ setSessionStorage('test', '123');
330
+ getSessionStorage('test'); // 123
331
+ setLocalStorage('test', '123');
332
+ getLocalStorage('test'); // 123
333
+
334
+ // or package in usage
335
+ const projectName = 'mazey';
336
+ function mSetLocalStorage (key, value) {
337
+ return setLocalStorage(`${projectName}_${key}`, value);
338
+ }
339
+
340
+ function mGetLocalStorage (key) {
341
+ return getLocalStorage(`${projectName}_${key}`);
342
+ }
343
+ ```
344
+
345
+ #### Cookie
346
+
347
+ Handle Cookie.
348
+
349
+ ```
350
+ import { setCookie, getCookie } from 'mazey';
351
+
352
+ setCookie('test', '123', 30, 'example.com'); // key value day domain
353
+ getCookie('test'); // 123
354
+ ```
355
+
356
+ ### Calculate&Formula
357
+
358
+ #### Rate
359
+
360
+ Hit probability (1% ~ 100%).
361
+
362
+ ```
363
+ import { inRate } from 'mazey';
364
+
365
+ inRate(0.5); // 0.01 ~ 1 true / false
366
+
367
+ // Test
368
+ let trueCount = 0;
369
+ let falseCount = 0;
370
+ new Array(1000000).fill(0).forEach(() => {
371
+ if (inRate(0.5)) {
372
+ trueCount++;
373
+ } else {
374
+ falseCount++;
375
+ }
376
+ });
377
+ console.log(trueCount, falseCount); // 499994 500006
378
+ ```
379
+
380
+ #### Algorithm
381
+
382
+ Computes the longest common substring of two strings.
383
+
384
+ ```
385
+ import { calLongestCommonSubstring } from 'mazey';
386
+
387
+ calLongestCommonSubstring('fish', 'finish'); // 3
388
+ ```
389
+
390
+ Computes the longest common subsequence of two strings.
391
+
392
+ ```
393
+ import { calLongestCommonSubsequence } from 'mazey';
394
+
395
+ calLongestCommonSubsequence('fish', 'finish'); // 4
396
+ ```
397
+
398
+ ### Browser Information
399
+
400
+ ```
401
+ import { getBrowserType } from 'mazey';
402
+
403
+ getBrowserType(); // {"engine":"webkit","engineVs":"537.36","platform":"desktop","supporter":"chrome","supporterVs":"85.0.4183.121","system":"windows","systemVs":"10"}
404
+ // Shell and shell version { shell: 'wechat', shellVs: '20' } shell: wechat qq uc 360 2345 sougou liebao maxthon
405
+ ```
406
+
407
+ ### Web Performance
408
+
409
+ Get page load time(PerformanceTiming).
410
+
411
+ ```
412
+ import { getPerformance } from 'mazey';
413
+
414
+ // `camelCase:true`(Default) Return hump data.
415
+ // `camelCase:false` Return underline data.
416
+ getPerformance({ camelCase: true })
417
+ .then(res => {
418
+ console.log(JSON.stringify(res));
419
+ // {"deviceType":"pc","network":"3g","unloadTime":0,"redirectTime":0,"dnsTime":0,"tcpTime":0,"responseTime":65,"downloadTime":1,"domreadyTime":369,"onloadTime":441,"whiteTime":94,"renderTime":441,"decodedBodySize":210,"encodedBodySize":210}
420
+ })
421
+ .catch(console.error);
422
+ ```
423
+
424
+ | Index | Field | Calculation |
425
+ | --- | --- | --- |
426
+ | * DNS lookup | dns_time | domainLookupEnd - domainLookupStart |
427
+ | * Connection negotiation | tcp_time | connectEnd - connectStart |
428
+ | * Requests and responses | response_time | responseStart - requestStart |
429
+ | * White screen | white_time | responseStart - navigationStart |
430
+ | * DomReady | domready_time | domContentLoadedEventStart - navigationStart |
431
+ | * Onload | onload_time | loadEventStart - navigationStart |
432
+ | * EventEnd | render_time | loadEventEnd -navigationStart |
433
+ | Unload | unload_time | unloadEventEnd - unloadEventStart |
434
+ | Redirect | redirect_time | redirectEnd - redirectStart |
435
+ | SSL | ssl_time | connectEnd - secureConnectionStart |
436
+ | Download | download_time | responseEnd - responseStart |
437
+
438
+ ### Margin of Safety
439
+
440
+ Determine if it is a secure PWA environment that it can run.
441
+
442
+ ```
443
+ import { isSafePWAEnv } from 'mazey';
444
+
445
+ isSafePWAEnv(); // true
446
+ ```
447
+
448
+ ### Debug
449
+
450
+ #### Print
451
+
452
+ Custom console printing (`console`).
453
+
454
+ ```
455
+ import { genCustomConsole } from 'mazey';
456
+
457
+ const myConsole = genCustomConsole({ prefix: 'MazeyLog:' });
458
+ myConsole.log('I am string.'); // MazeyLog: I am string.
459
+ myConsole.info('I am boolean.', true); // MazeyLog: I am boolean. true
460
+ myConsole.info('I am number.', 123, 456); // MazeyLog: I am number. 123 456
461
+ myConsole.info('I am object.', { a: 123, b: 456}); // MazeyLog: I am object. {a: 123, b: 456}
462
+ ```
463
+
464
+ [More API>>](https://mazey.cn/docs/mazey/modules/_index_.html)
465
+
466
+ ## Develop
467
+
468
+ ```
469
+ # dev
470
+ npm run dev
471
+
472
+ # build
473
+ npm run build
474
+
475
+ # documentation
476
+ npm run docs
477
+ ```