vite-plugin-blocklet 0.8.2 → 0.8.3

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/dist/index.cjs CHANGED
@@ -14,6 +14,7 @@ var getPort = require('get-port');
14
14
  var mri = require('mri');
15
15
  var httpProxyMiddleware = require('http-proxy-middleware');
16
16
 
17
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
17
18
  const { types } = Mcrypto;
18
19
 
19
20
  function toBlockletDid(name) {
@@ -26,12 +27,15 @@ function toBlockletDid(name) {
26
27
  }
27
28
 
28
29
  const isInBlocklet = !!process.env.BLOCKLET_PORT;
30
+ const blockletPort = process.env.BLOCKLET_PORT;
31
+ const blockletPrefix = process.env.BLOCKLET_DEV_MOUNT_POINT || '/';
29
32
 
30
33
  /**
31
34
  * Creates a HMR plugin with the given options.
32
35
  *
33
36
  * @param {Object} options - The options for the HMR plugin.
34
37
  * @param {string} options.version - The version of the vite version.
38
+ * @param {'middleware'|'client'} options.hmrMode - The version of the vite version.
35
39
  * @return {Object} The HMR plugin object.
36
40
  */
37
41
  function createHmrPlugin(options = {}) {
@@ -39,7 +43,7 @@ function createHmrPlugin(options = {}) {
39
43
  return {
40
44
  name: 'blocklet:hmr',
41
45
  apply: 'serve',
42
- async transform(code, id) {
46
+ transform(code, id) {
43
47
  if (isInBlocklet && id.endsWith('/vite/dist/client/client.mjs')) {
44
48
  const pureVersion = semver.major(version);
45
49
  let replacedCode = code;
@@ -52,29 +56,35 @@ function createHmrPlugin(options = {}) {
52
56
  return replacedCode;
53
57
  }
54
58
 
55
- // 根据页面的协议自动判断端口
56
- replacedCode = replacedCode.replace(
57
- /__HMR_PORT__/g,
58
- 'location.port || (location.protocol === "https:" ? 443 : 80);',
59
- );
60
-
61
- // 在页面加载时,触发一次 upgrade
62
- replacedCode = replacedCode.replace(
63
- 'function setupWebSocket(protocol, hostAndPath, onCloseWithoutOpen) {',
64
- 'async function setupWebSocket(protocol, hostAndPath, onCloseWithoutOpen) {\nawait waitForSuccessfulPing(protocol, hostAndPath);\n',
65
- );
66
- replacedCode = replacedCode.replace('fallback = () => {', 'fallback = async () => {');
67
- replacedCode = replacedCode.replace(/socket = setupWebSocket\(/g, 'socket = await setupWebSocket(');
68
-
69
- if ([4, 5].includes(pureVersion)) {
70
- // 改变刷新页面的判断
59
+ replacedCode = replacedCode.replace(/__HMR_BASE__/g, `"${blockletPrefix}"+__HMR_BASE__`);
60
+
61
+ if (process.env.VITE_HMR_MODE === 'middleware') {
62
+ // 根据页面的协议自动判断端口
63
+ replacedCode = replacedCode.replace(
64
+ /__HMR_PORT__/g,
65
+ 'location.port || (location.protocol === "https:" ? 443 : 80);',
66
+ );
67
+
68
+ // 在页面加载时,触发一次 upgrade
71
69
  replacedCode = replacedCode.replace(
72
- 'const ping =',
73
- "const ping = async () => {\ntry {\nawait fetch(`${pingHostProtocol}://${hostAndPath}`, {\nmode: 'no-cors',\nheaders: {\nAccept: 'text/x-vite-ping'\n}\n}).then(res => {\nif ([404, 502].includes(res.status)) {\nthrow new Error('waiting for server to restart...');\n}\n});\nreturn true;\n} catch {}\nreturn false;\n}\nconst pingBak =",
70
+ 'function setupWebSocket(protocol, hostAndPath, onCloseWithoutOpen) {',
71
+ 'async function setupWebSocket(protocol, hostAndPath, onCloseWithoutOpen) {\nawait waitForSuccessfulPing(protocol, hostAndPath);\n',
74
72
  );
73
+ replacedCode = replacedCode.replace('fallback = () => {', 'fallback = async () => {');
74
+ replacedCode = replacedCode.replace(/socket = setupWebSocket\(/g, 'socket = await setupWebSocket(');
75
+
76
+ if ([4, 5].includes(pureVersion)) {
77
+ // 改变刷新页面的判断
78
+ replacedCode = replacedCode.replace(
79
+ 'const ping =',
80
+ "const ping = async () => {\ntry {\nawait fetch(`${pingHostProtocol}://${hostAndPath}`, {\nmode: 'no-cors',\nheaders: {\nAccept: 'text/x-vite-ping'\n}\n}).then(res => {\nif ([404, 502].includes(res.status)) {\nthrow new Error('waiting for server to restart...');\n}\n});\nreturn true;\n} catch {}\nreturn false;\n}\nconst pingBak =",
81
+ );
82
+ }
75
83
  }
84
+
76
85
  return replacedCode;
77
86
  }
87
+ return code;
78
88
  },
79
89
  };
80
90
  }
@@ -85,10 +95,9 @@ function createConfigPlugin$1() {
85
95
  configureServer(server) {
86
96
  if (isInBlocklet) {
87
97
  server.middlewares.use((req, res, next) => {
88
- const prefix = req.headers['x-path-prefix'] || '/';
89
98
  // blocklet server 会把设置的 base 从请求 url 中移除,所以需要再加回 base
90
- if (!req.url.startsWith(prefix)) {
91
- req.url = path.join(prefix || '/', req.url);
99
+ if (!req.url.startsWith(blockletPrefix)) {
100
+ req.url = path.join(blockletPrefix || '/', req.url);
92
101
  }
93
102
  return next();
94
103
  });
@@ -97,21 +106,9 @@ function createConfigPlugin$1() {
97
106
  config(config, { command }) {
98
107
  if (command === 'serve') {
99
108
  const targetConfig = {};
100
- if (!config.base) {
101
- let base = process.env.BLOCKLET_DEV_MOUNT_POINT || '';
102
-
103
- if (base) {
104
- if (!base.startsWith('/')) {
105
- base = `/${base}`;
106
- }
107
- if (!base.endsWith('/')) {
108
- base = `${base}/`;
109
- }
110
- }
111
- targetConfig.base = base;
112
- }
109
+ targetConfig.base = path.join('/', config.base || blockletPrefix, '/');
113
110
  if (!(config.server && config.server.port)) {
114
- const port = process.env.BLOCKLET_PORT || 3000;
111
+ const port = blockletPort || 3000;
115
112
  targetConfig.server = {
116
113
  port,
117
114
  };
@@ -404,6 +401,53 @@ function createConfigPlugin(options) {
404
401
  };
405
402
  }
406
403
 
404
+ /**
405
+ * Creates a config plugin for Vite development server.
406
+ *
407
+ * @param {object} options - The options for the plugin.
408
+ * @param {string} options.entryPath - The entry path of the Express app.
409
+ * @return {object} The Vite config plugin.
410
+ */
411
+ function createExpressPlugin({ entryPath }) {
412
+ // 此处需要解构 import.meta 对象,才能拿到 vite.config 的地址,否则拿到的地址会是 express.js 文件的地址
413
+ const { dirname } = { ...({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)) }) };
414
+ const fullPath = path.join(dirname, entryPath);
415
+ const folderPath = path.dirname(fullPath);
416
+ return {
417
+ name: 'blocklet:express',
418
+ apply: 'serve',
419
+ configureServer(server) {
420
+ server.middlewares.use(async (req, res, next) => {
421
+ process.env.VITE = 'true';
422
+ try {
423
+ const { app } = await server.ssrLoadModule(entryPath);
424
+ app(req, res, next);
425
+ } catch (err) {
426
+ console.error(err);
427
+ }
428
+ });
429
+ },
430
+ handleHotUpdate({ server, modules, timestamp }) {
431
+ const validatedModules = [];
432
+ const invalidatedModules = [];
433
+
434
+ for (const mod of modules) {
435
+ if (mod.file.includes(folderPath)) {
436
+ invalidatedModules.push(mod);
437
+ } else {
438
+ validatedModules.push(mod);
439
+ }
440
+ }
441
+ // 手动使模块失效
442
+ const mods = new Set();
443
+ for (const mod of invalidatedModules) {
444
+ server.moduleGraph.invalidateModule(mod, mods, timestamp, true);
445
+ }
446
+ return validatedModules;
447
+ },
448
+ };
449
+ }
450
+
407
451
  const argv = process.argv.slice(2);
408
452
  const isProduction = process.env.NODE_ENV === 'production' || process.env.ABT_NODE_SERVICE_ENV === 'production';
409
453
 
@@ -433,7 +477,8 @@ async function setupClient(app, options = {}) {
433
477
  target: `ws://127.0.0.1:${port}`,
434
478
  ws: true,
435
479
  });
436
- app.use('/__vite_hmr__', wsProxy);
480
+ process.env.VITE_HMR_MODE = 'middleware';
481
+ app.use(path.join(blockletPrefix, '/__vite_hmr__'), wsProxy);
437
482
 
438
483
  // 以中间件模式创建 Vite 服务器
439
484
  const vite$1 = await vite.createServer({
@@ -442,7 +487,6 @@ async function setupClient(app, options = {}) {
442
487
  middlewareMode: true,
443
488
  hmr: {
444
489
  port,
445
- clientPort: 80,
446
490
  path: '/__vite_hmr__',
447
491
  },
448
492
  },
@@ -464,12 +508,14 @@ async function setupClient(app, options = {}) {
464
508
  * @property {boolean} [disableHmr=false] - Disable hmr plugin.
465
509
  * @property {boolean} [disableLoading=false] - Disable loading plugin.
466
510
  * @property {boolean} [disableDebug=false] - Disable debug plugin.
511
+ * @property {import('vite-plugin-node-polyfills').PolyfillOptions} [nodePolyfillsOptions]
467
512
  *
468
513
  * @property {string} [loadingElementId]
469
514
  * @property {string} [loadingColor]
470
515
  * @property {string} [loadingImage]
471
516
  * @property {'all'|'mobile'|'desktop'} [debugPlatform='mobile']
472
517
  * @property {string} [debugScript]
518
+ * @property {'middleware'|'client'} [hmrMode='middleware']
473
519
  */
474
520
 
475
521
  /**
@@ -488,6 +534,7 @@ function createBlockletPlugin(options = {}) {
488
534
  disableHmr = false,
489
535
  disableLoading = false,
490
536
  disableDebug = false,
537
+ nodePolyfillsOptions,
491
538
  ...restOptions
492
539
  } = options;
493
540
 
@@ -504,7 +551,7 @@ function createBlockletPlugin(options = {}) {
504
551
  plugins.push(createHmrPlugin(restOptions));
505
552
  }
506
553
  if (!disableNodePolyfills) {
507
- plugins.push(vitePluginNodePolyfills.nodePolyfills({ protocolImports: true }));
554
+ plugins.push(vitePluginNodePolyfills.nodePolyfills(nodePolyfillsOptions));
508
555
  }
509
556
  if (!disableLoading) {
510
557
  plugins.push(createLoadingPlugin(restOptions));
@@ -522,6 +569,7 @@ Object.defineProperty(exports, "nodePolyfills", {
522
569
  });
523
570
  exports.createBlockletConfig = createConfigPlugin$1;
524
571
  exports.createBlockletDebug = createConfigPlugin;
572
+ exports.createBlockletExpress = createExpressPlugin;
525
573
  exports.createBlockletHmr = createHmrPlugin;
526
574
  exports.createBlockletLoading = createLoadingPlugin;
527
575
  exports.createBlockletMeta = createMetaPlugin;
package/index.js CHANGED
@@ -4,6 +4,7 @@ import createConfigPlugin from './libs/config.js';
4
4
  import createMetaPlugin from './libs/meta.js';
5
5
  import createLoadingPlugin from './libs/loading.js';
6
6
  import createDebugPlugin from './libs/debug.js';
7
+ import createExpressPlugin from './libs/express.js';
7
8
  import setupClient from './libs/client.js';
8
9
 
9
10
  /**
@@ -16,12 +17,14 @@ import setupClient from './libs/client.js';
16
17
  * @property {boolean} [disableHmr=false] - Disable hmr plugin.
17
18
  * @property {boolean} [disableLoading=false] - Disable loading plugin.
18
19
  * @property {boolean} [disableDebug=false] - Disable debug plugin.
20
+ * @property {import('vite-plugin-node-polyfills').PolyfillOptions} [nodePolyfillsOptions]
19
21
  *
20
22
  * @property {string} [loadingElementId]
21
23
  * @property {string} [loadingColor]
22
24
  * @property {string} [loadingImage]
23
25
  * @property {'all'|'mobile'|'desktop'} [debugPlatform='mobile']
24
26
  * @property {string} [debugScript]
27
+ * @property {'middleware'|'client'} [hmrMode='middleware']
25
28
  */
26
29
 
27
30
  /**
@@ -40,6 +43,7 @@ export function createBlockletPlugin(options = {}) {
40
43
  disableHmr = false,
41
44
  disableLoading = false,
42
45
  disableDebug = false,
46
+ nodePolyfillsOptions,
43
47
  ...restOptions
44
48
  } = options;
45
49
 
@@ -56,7 +60,7 @@ export function createBlockletPlugin(options = {}) {
56
60
  plugins.push(createHmrPlugin(restOptions));
57
61
  }
58
62
  if (!disableNodePolyfills) {
59
- plugins.push(nodePolyfills({ protocolImports: true }));
63
+ plugins.push(nodePolyfills(nodePolyfillsOptions));
60
64
  }
61
65
  if (!disableLoading) {
62
66
  plugins.push(createLoadingPlugin(restOptions));
@@ -75,5 +79,6 @@ export {
75
79
  createMetaPlugin as createBlockletMeta,
76
80
  createLoadingPlugin as createBlockletLoading,
77
81
  createDebugPlugin as createBlockletDebug,
82
+ createExpressPlugin as createBlockletExpress,
78
83
  nodePolyfills,
79
84
  };
package/libs/client.js CHANGED
@@ -1,7 +1,9 @@
1
+ import path from 'node:path';
1
2
  import getPort from 'get-port';
2
3
  import { createServer } from 'vite';
3
4
  import mri from 'mri';
4
5
  import { createProxyMiddleware } from 'http-proxy-middleware';
6
+ import { blockletPrefix } from './utils';
5
7
 
6
8
  const argv = process.argv.slice(2);
7
9
  const isProduction = process.env.NODE_ENV === 'production' || process.env.ABT_NODE_SERVICE_ENV === 'production';
@@ -32,7 +34,8 @@ export default async function setupClient(app, options = {}) {
32
34
  target: `ws://127.0.0.1:${port}`,
33
35
  ws: true,
34
36
  });
35
- app.use('/__vite_hmr__', wsProxy);
37
+ process.env.VITE_HMR_MODE = 'middleware';
38
+ app.use(path.join(blockletPrefix, '/__vite_hmr__'), wsProxy);
36
39
 
37
40
  // 以中间件模式创建 Vite 服务器
38
41
  const vite = await createServer({
@@ -41,7 +44,6 @@ export default async function setupClient(app, options = {}) {
41
44
  middlewareMode: true,
42
45
  hmr: {
43
46
  port,
44
- clientPort: 80,
45
47
  path: '/__vite_hmr__',
46
48
  },
47
49
  },
package/libs/config.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import YAML from 'yaml';
4
- import { toBlockletDid, isInBlocklet } from './utils.js';
4
+ import { toBlockletDid, isInBlocklet, blockletPort, blockletPrefix } from './utils.js';
5
5
 
6
6
  export default function createConfigPlugin() {
7
7
  return {
@@ -9,10 +9,9 @@ export default function createConfigPlugin() {
9
9
  configureServer(server) {
10
10
  if (isInBlocklet) {
11
11
  server.middlewares.use((req, res, next) => {
12
- const prefix = req.headers['x-path-prefix'] || '/';
13
12
  // blocklet server 会把设置的 base 从请求 url 中移除,所以需要再加回 base
14
- if (!req.url.startsWith(prefix)) {
15
- req.url = path.join(prefix || '/', req.url);
13
+ if (!req.url.startsWith(blockletPrefix)) {
14
+ req.url = path.join(blockletPrefix || '/', req.url);
16
15
  }
17
16
  return next();
18
17
  });
@@ -21,21 +20,9 @@ export default function createConfigPlugin() {
21
20
  config(config, { command }) {
22
21
  if (command === 'serve') {
23
22
  const targetConfig = {};
24
- if (!config.base) {
25
- let base = process.env.BLOCKLET_DEV_MOUNT_POINT || '';
26
-
27
- if (base) {
28
- if (!base.startsWith('/')) {
29
- base = `/${base}`;
30
- }
31
- if (!base.endsWith('/')) {
32
- base = `${base}/`;
33
- }
34
- }
35
- targetConfig.base = base;
36
- }
23
+ targetConfig.base = path.join('/', config.base || blockletPrefix, '/');
37
24
  if (!(config.server && config.server.port)) {
38
- const port = process.env.BLOCKLET_PORT || 3000;
25
+ const port = blockletPort || 3000;
39
26
  targetConfig.server = {
40
27
  port,
41
28
  };
@@ -0,0 +1,47 @@
1
+ import path from 'node:path';
2
+ /**
3
+ * Creates a config plugin for Vite development server.
4
+ *
5
+ * @param {object} options - The options for the plugin.
6
+ * @param {string} options.entryPath - The entry path of the Express app.
7
+ * @return {object} The Vite config plugin.
8
+ */
9
+ export default function createExpressPlugin({ entryPath }) {
10
+ // 此处需要解构 import.meta 对象,才能拿到 vite.config 的地址,否则拿到的地址会是 express.js 文件的地址
11
+ const { dirname } = { ...import.meta };
12
+ const fullPath = path.join(dirname, entryPath);
13
+ const folderPath = path.dirname(fullPath);
14
+ return {
15
+ name: 'blocklet:express',
16
+ apply: 'serve',
17
+ configureServer(server) {
18
+ server.middlewares.use(async (req, res, next) => {
19
+ process.env.VITE = 'true';
20
+ try {
21
+ const { app } = await server.ssrLoadModule(entryPath);
22
+ app(req, res, next);
23
+ } catch (err) {
24
+ console.error(err);
25
+ }
26
+ });
27
+ },
28
+ handleHotUpdate({ server, modules, timestamp }) {
29
+ const validatedModules = [];
30
+ const invalidatedModules = [];
31
+
32
+ for (const mod of modules) {
33
+ if (mod.file.includes(folderPath)) {
34
+ invalidatedModules.push(mod);
35
+ } else {
36
+ validatedModules.push(mod);
37
+ }
38
+ }
39
+ // 手动使模块失效
40
+ const mods = new Set();
41
+ for (const mod of invalidatedModules) {
42
+ server.moduleGraph.invalidateModule(mod, mods, timestamp, true);
43
+ }
44
+ return validatedModules;
45
+ },
46
+ };
47
+ }
package/libs/hmr.js CHANGED
@@ -1,12 +1,13 @@
1
1
  import { version as viteVersion } from 'vite';
2
2
  import semver from 'semver';
3
- import { isInBlocklet } from './utils.js';
3
+ import { blockletPrefix, isInBlocklet } from './utils.js';
4
4
 
5
5
  /**
6
6
  * Creates a HMR plugin with the given options.
7
7
  *
8
8
  * @param {Object} options - The options for the HMR plugin.
9
9
  * @param {string} options.version - The version of the vite version.
10
+ * @param {'middleware'|'client'} options.hmrMode - The version of the vite version.
10
11
  * @return {Object} The HMR plugin object.
11
12
  */
12
13
  export default function createHmrPlugin(options = {}) {
@@ -14,7 +15,7 @@ export default function createHmrPlugin(options = {}) {
14
15
  return {
15
16
  name: 'blocklet:hmr',
16
17
  apply: 'serve',
17
- async transform(code, id) {
18
+ transform(code, id) {
18
19
  if (isInBlocklet && id.endsWith('/vite/dist/client/client.mjs')) {
19
20
  const pureVersion = semver.major(version);
20
21
  let replacedCode = code;
@@ -27,29 +28,35 @@ export default function createHmrPlugin(options = {}) {
27
28
  return replacedCode;
28
29
  }
29
30
 
30
- // 根据页面的协议自动判断端口
31
- replacedCode = replacedCode.replace(
32
- /__HMR_PORT__/g,
33
- 'location.port || (location.protocol === "https:" ? 443 : 80);',
34
- );
31
+ replacedCode = replacedCode.replace(/__HMR_BASE__/g, `"${blockletPrefix}"+__HMR_BASE__`);
35
32
 
36
- // 在页面加载时,触发一次 upgrade
37
- replacedCode = replacedCode.replace(
38
- 'function setupWebSocket(protocol, hostAndPath, onCloseWithoutOpen) {',
39
- 'async function setupWebSocket(protocol, hostAndPath, onCloseWithoutOpen) {\nawait waitForSuccessfulPing(protocol, hostAndPath);\n',
40
- );
41
- replacedCode = replacedCode.replace('fallback = () => {', 'fallback = async () => {');
42
- replacedCode = replacedCode.replace(/socket = setupWebSocket\(/g, 'socket = await setupWebSocket(');
33
+ if (process.env.VITE_HMR_MODE === 'middleware') {
34
+ // 根据页面的协议自动判断端口
35
+ replacedCode = replacedCode.replace(
36
+ /__HMR_PORT__/g,
37
+ 'location.port || (location.protocol === "https:" ? 443 : 80);',
38
+ );
43
39
 
44
- if ([4, 5].includes(pureVersion)) {
45
- // 改变刷新页面的判断
40
+ // 在页面加载时,触发一次 upgrade
46
41
  replacedCode = replacedCode.replace(
47
- 'const ping =',
48
- "const ping = async () => {\ntry {\nawait fetch(`${pingHostProtocol}://${hostAndPath}`, {\nmode: 'no-cors',\nheaders: {\nAccept: 'text/x-vite-ping'\n}\n}).then(res => {\nif ([404, 502].includes(res.status)) {\nthrow new Error('waiting for server to restart...');\n}\n});\nreturn true;\n} catch {}\nreturn false;\n}\nconst pingBak =",
42
+ 'function setupWebSocket(protocol, hostAndPath, onCloseWithoutOpen) {',
43
+ 'async function setupWebSocket(protocol, hostAndPath, onCloseWithoutOpen) {\nawait waitForSuccessfulPing(protocol, hostAndPath);\n',
49
44
  );
45
+ replacedCode = replacedCode.replace('fallback = () => {', 'fallback = async () => {');
46
+ replacedCode = replacedCode.replace(/socket = setupWebSocket\(/g, 'socket = await setupWebSocket(');
47
+
48
+ if ([4, 5].includes(pureVersion)) {
49
+ // 改变刷新页面的判断
50
+ replacedCode = replacedCode.replace(
51
+ 'const ping =',
52
+ "const ping = async () => {\ntry {\nawait fetch(`${pingHostProtocol}://${hostAndPath}`, {\nmode: 'no-cors',\nheaders: {\nAccept: 'text/x-vite-ping'\n}\n}).then(res => {\nif ([404, 502].includes(res.status)) {\nthrow new Error('waiting for server to restart...');\n}\n});\nreturn true;\n} catch {}\nreturn false;\n}\nconst pingBak =",
53
+ );
54
+ }
50
55
  }
56
+
51
57
  return replacedCode;
52
58
  }
59
+ return code;
53
60
  },
54
61
  };
55
62
  }
package/libs/utils.js CHANGED
@@ -13,6 +13,6 @@ export function toBlockletDid(name) {
13
13
  return fromPublicKey(pk, { role: types.RoleType.ROLE_ANY });
14
14
  }
15
15
 
16
- const isInBlocklet = !!process.env.BLOCKLET_PORT;
17
-
18
- export { isInBlocklet };
16
+ export const isInBlocklet = !!process.env.BLOCKLET_PORT;
17
+ export const blockletPort = process.env.BLOCKLET_PORT;
18
+ export const blockletPrefix = process.env.BLOCKLET_DEV_MOUNT_POINT || '/';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vite-plugin-blocklet",
3
3
  "type": "module",
4
- "version": "0.8.2",
4
+ "version": "0.8.3",
5
5
  "description": "",
6
6
  "main": "index.js",
7
7
  "files": [