├── index.html
├── package.json
├── LICENSE
├── README.md
├── .gitignore
├── index.js
└── yarn.lock
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dirty-check",
3 | "version": "0.0.0",
4 | "description": "reactivity system with dirty checking",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "start": "serve ."
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+https://github.com/yisar/dirty-checking.git"
13 | },
14 | "keywords": [],
15 | "author": "",
16 | "license": "ISC",
17 | "bugs": {
18 | "url": "https://github.com/yisar/dirty-checking/issues"
19 | },
20 | "homepage": "https://github.com/yisar/dirty-checking#readme",
21 | "devDependencies": {
22 | "serve": "^11.3.2"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 伊撒尔
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.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # dirty-check
2 |
3 | Tiny reactivity system with dirty checking.
4 |
5 | ### Motivation
6 |
7 | [点我](https://zhuanlan.zhihu.com/p/278238753)
8 |
9 | 由于基于`对象劫持`的响应式方案存在 ref 的缺陷,不利于组合……我们企图找到一种替代方案
10 |
11 | 这个仓库提供了一种脏检查的思路,它没有 ref 的缺陷,没有 hooks 的限制,对组合更有利
12 |
13 | ### Usage
14 |
15 | ```js
16 | import { ref, computed, invalidate } from './index.js'
17 | const count = ref(0)
18 | const double = computed(() => count() * 2)
19 | count(1)
20 | count(2)
21 |
22 | invalidate() // 开始脏检查
23 | console.log(double()) // 4
24 | ```
25 |
26 | ### Implement
27 |
28 | 脏检查也是一种依赖收集,每调用一次 invalidate 则开启一轮的脏检查,此时 computed 会重新计算
29 |
30 | 和 angularjs 不同,这个仓库使用了`有向图`的数据结构,约定脏检查是单向的,性能显著提升
31 |
32 | - vs setState
33 |
34 | 脏检查和 setState 是类似的,只是 setState 必须利用闭包缓存组件实例,而脏检查的响应式不需要和组件强绑定
35 |
36 | ```js
37 | const double = computed(() => count() * 2)
38 |
39 | const stateLessComponent = () =>
40 | ```
41 |
42 | - vs Proxy
43 |
44 | 脏检查和对象劫持也是类似的,一般来讲,脏检查性能会稍差,API 也低级些,但是没有 ref 的限制
45 |
46 | ### Compiler
47 |
48 | 建议和编译手段结合使用,脏检查的思路非常适合走编译路线
49 |
50 | ```html
51 |
59 |
60 |
61 | ```
62 |
63 | 大约编译成这个样子:
64 |
65 | ```html
66 |
74 |
75 |
76 | ```
77 |
78 | 不需要改变语义,不需要任何语法糖,runtime 也非常轻量
79 |
80 | p.s.
81 |
82 | 俺不开倒车,不同的机制有不同的优势,在 vue composition API 和 hooks API 都出现了限制的前提下
83 |
84 | 脏检查恰好可以规避这些限制,可以说最适合组合的方案了
85 |
86 | ### License
87 |
88 | MIT @132
89 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 |
9 | # Diagnostic reports (https://nodejs.org/api/report.html)
10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 | *.lcov
24 |
25 | # nyc test coverage
26 | .nyc_output
27 |
28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29 | .grunt
30 |
31 | # Bower dependency directory (https://bower.io/)
32 | bower_components
33 |
34 | # node-waf configuration
35 | .lock-wscript
36 |
37 | # Compiled binary addons (https://nodejs.org/api/addons.html)
38 | build/Release
39 |
40 | # Dependency directories
41 | node_modules/
42 | jspm_packages/
43 |
44 | # TypeScript v1 declaration files
45 | typings/
46 |
47 | # TypeScript cache
48 | *.tsbuildinfo
49 |
50 | # Optional npm cache directory
51 | .npm
52 |
53 | # Optional eslint cache
54 | .eslintcache
55 |
56 | # Microbundle cache
57 | .rpt2_cache/
58 | .rts2_cache_cjs/
59 | .rts2_cache_es/
60 | .rts2_cache_umd/
61 |
62 | # Optional REPL history
63 | .node_repl_history
64 |
65 | # Output of 'npm pack'
66 | *.tgz
67 |
68 | # Yarn Integrity file
69 | .yarn-integrity
70 |
71 | # dotenv environment variables file
72 | .env
73 | .env.test
74 |
75 | # parcel-bundler cache (https://parceljs.org/)
76 | .cache
77 |
78 | # Next.js build output
79 | .next
80 |
81 | # Nuxt.js build / generate output
82 | .nuxt
83 | dist
84 |
85 | # Gatsby files
86 | .cache/
87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js
88 | # https://nextjs.org/blog/next-9-1#public-directory-support
89 | # public
90 |
91 | # vuepress build output
92 | .vuepress/dist
93 |
94 | # Serverless directories
95 | .serverless/
96 |
97 | # FuseBox cache
98 | .fusebox/
99 |
100 | # DynamoDB Local files
101 | .dynamodb/
102 |
103 | # TernJS port file
104 | .tern-port
105 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | let count = 1
2 | let activeDeps = null
3 |
4 | export function clock() {
5 | return count
6 | }
7 |
8 | export function advanceClock() {
9 | count++
10 | }
11 |
12 | export const ref = (v) => {
13 | let value = { t: clock(), v }
14 | return (n) => {
15 | return n ? set(value, n) : get(value)
16 | }
17 | }
18 |
19 | export function restore(deps) {
20 | activeDeps = deps
21 | }
22 |
23 | export function set(v, n) {
24 | v.t = clock()
25 | v.v = n
26 | return v.v
27 | }
28 |
29 | export function get(v) {
30 | if (activeDeps === null) {
31 | activeDeps = [clock(), v]
32 | } else {
33 | activeDeps.push(v)
34 | }
35 | return typeof v === 'function' ? v : v.v
36 | }
37 |
38 | export function dirtyCheck(deps) {
39 | if (deps == null) return true
40 | const t = deps[0]
41 | for (let i = 1; i < deps.length; i++) {
42 | const v = deps[i]
43 | if (typeof v === 'object') {
44 | if (v.t > t) {
45 | return true
46 | }
47 | } else if (v(true, t) === true) {
48 | return true
49 | }
50 | }
51 | return false
52 | }
53 |
54 | export function save() {
55 | const deps = activeDeps
56 | activeDeps = null
57 | return deps
58 | }
59 |
60 | export function computed(fn) {
61 | let lastdirtyCheck = 0
62 | let lastUpdate = 0
63 | let value = void 0
64 | let deps = null
65 | return (token, time) => {
66 | const now = clock()
67 | if (lastdirtyCheck < now) {
68 | lastdirtyCheck = now
69 | if (dirtyCheck(deps) === true) {
70 | const prevDeps = save()
71 | const nextValue = fn(value)
72 | deps = save()
73 | restore(prevDeps)
74 | if (value !== nextValue) {
75 | value = nextValue
76 | lastUpdate = now
77 | }
78 | }
79 | }
80 | return token ? lastUpdate > time : value
81 | }
82 | }
83 |
84 | export function selector(fn) {
85 | let lastdirtyCheck = 0
86 | let lastUpdate = 0
87 | let value = void 0
88 | return () => {
89 | const now = clock()
90 | if (lastdirtyCheck < now) {
91 | lastdirtyCheck = now
92 | const nextValue = fn(value)
93 | if (value !== nextValue) {
94 | value = nextValue
95 | lastUpdate = now
96 | }
97 | }
98 | return token ? lastUpdate > time : value
99 | }
100 | }
101 |
102 | const defer =
103 | typeof Promise === 'function'
104 | ? function (cb) {
105 | Promise.resolve().then(cb)
106 | }
107 | : setTimeout
108 |
109 | export function invalidate(render) {
110 | try {
111 | defer(render)
112 | } finally {
113 | advanceClock()
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@zeit/schemas@2.6.0":
6 | version "2.6.0"
7 | resolved "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.6.0.tgz#004e8e553b4cd53d538bd38eac7bcbf58a867fe3"
8 | integrity sha512-uUrgZ8AxS+Lio0fZKAipJjAh415JyrOZowliZAzmnJSsf7piVL5w+G0+gFJ0KSu3QRhvui/7zuvpLz03YjXAhg==
9 |
10 | accepts@~1.3.5:
11 | version "1.3.7"
12 | resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
13 | integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==
14 | dependencies:
15 | mime-types "~2.1.24"
16 | negotiator "0.6.2"
17 |
18 | ajv@6.5.3:
19 | version "6.5.3"
20 | resolved "https://registry.npmjs.org/ajv/-/ajv-6.5.3.tgz#71a569d189ecf4f4f321224fecb166f071dd90f9"
21 | integrity sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==
22 | dependencies:
23 | fast-deep-equal "^2.0.1"
24 | fast-json-stable-stringify "^2.0.0"
25 | json-schema-traverse "^0.4.1"
26 | uri-js "^4.2.2"
27 |
28 | ansi-align@^2.0.0:
29 | version "2.0.0"
30 | resolved "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f"
31 | integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=
32 | dependencies:
33 | string-width "^2.0.0"
34 |
35 | ansi-regex@^3.0.0:
36 | version "3.0.0"
37 | resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
38 | integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
39 |
40 | ansi-styles@^3.2.1:
41 | version "3.2.1"
42 | resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
43 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
44 | dependencies:
45 | color-convert "^1.9.0"
46 |
47 | arch@^2.1.0:
48 | version "2.2.0"
49 | resolved "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11"
50 | integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==
51 |
52 | arg@2.0.0:
53 | version "2.0.0"
54 | resolved "https://registry.npmjs.org/arg/-/arg-2.0.0.tgz#c06e7ff69ab05b3a4a03ebe0407fac4cba657545"
55 | integrity sha512-XxNTUzKnz1ctK3ZIcI2XUPlD96wbHP2nGqkPKpvk/HNRlPveYrXIVSTk9m3LcqOgDPg3B1nMvdV/K8wZd7PG4w==
56 |
57 | balanced-match@^1.0.0:
58 | version "1.0.0"
59 | resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
60 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
61 |
62 | boxen@1.3.0:
63 | version "1.3.0"
64 | resolved "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b"
65 | integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==
66 | dependencies:
67 | ansi-align "^2.0.0"
68 | camelcase "^4.0.0"
69 | chalk "^2.0.1"
70 | cli-boxes "^1.0.0"
71 | string-width "^2.0.0"
72 | term-size "^1.2.0"
73 | widest-line "^2.0.0"
74 |
75 | brace-expansion@^1.1.7:
76 | version "1.1.11"
77 | resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
78 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
79 | dependencies:
80 | balanced-match "^1.0.0"
81 | concat-map "0.0.1"
82 |
83 | bytes@3.0.0:
84 | version "3.0.0"
85 | resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
86 | integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=
87 |
88 | camelcase@^4.0.0:
89 | version "4.1.0"
90 | resolved "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
91 | integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=
92 |
93 | chalk@2.4.1:
94 | version "2.4.1"
95 | resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
96 | integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==
97 | dependencies:
98 | ansi-styles "^3.2.1"
99 | escape-string-regexp "^1.0.5"
100 | supports-color "^5.3.0"
101 |
102 | chalk@^2.0.1:
103 | version "2.4.2"
104 | resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
105 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
106 | dependencies:
107 | ansi-styles "^3.2.1"
108 | escape-string-regexp "^1.0.5"
109 | supports-color "^5.3.0"
110 |
111 | cli-boxes@^1.0.0:
112 | version "1.0.0"
113 | resolved "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143"
114 | integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM=
115 |
116 | clipboardy@1.2.3:
117 | version "1.2.3"
118 | resolved "https://registry.npmjs.org/clipboardy/-/clipboardy-1.2.3.tgz#0526361bf78724c1f20be248d428e365433c07ef"
119 | integrity sha512-2WNImOvCRe6r63Gk9pShfkwXsVtKCroMAevIbiae021mS850UkWPbevxsBz3tnvjZIEGvlwaqCPsw+4ulzNgJA==
120 | dependencies:
121 | arch "^2.1.0"
122 | execa "^0.8.0"
123 |
124 | color-convert@^1.9.0:
125 | version "1.9.3"
126 | resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
127 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
128 | dependencies:
129 | color-name "1.1.3"
130 |
131 | color-name@1.1.3:
132 | version "1.1.3"
133 | resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
134 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
135 |
136 | compressible@~2.0.14:
137 | version "2.0.18"
138 | resolved "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba"
139 | integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==
140 | dependencies:
141 | mime-db ">= 1.43.0 < 2"
142 |
143 | compression@1.7.3:
144 | version "1.7.3"
145 | resolved "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz#27e0e176aaf260f7f2c2813c3e440adb9f1993db"
146 | integrity sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==
147 | dependencies:
148 | accepts "~1.3.5"
149 | bytes "3.0.0"
150 | compressible "~2.0.14"
151 | debug "2.6.9"
152 | on-headers "~1.0.1"
153 | safe-buffer "5.1.2"
154 | vary "~1.1.2"
155 |
156 | concat-map@0.0.1:
157 | version "0.0.1"
158 | resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
159 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
160 |
161 | content-disposition@0.5.2:
162 | version "0.5.2"
163 | resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4"
164 | integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ=
165 |
166 | cross-spawn@^5.0.1:
167 | version "5.1.0"
168 | resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
169 | integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=
170 | dependencies:
171 | lru-cache "^4.0.1"
172 | shebang-command "^1.2.0"
173 | which "^1.2.9"
174 |
175 | debug@2.6.9:
176 | version "2.6.9"
177 | resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
178 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
179 | dependencies:
180 | ms "2.0.0"
181 |
182 | deep-extend@^0.6.0:
183 | version "0.6.0"
184 | resolved "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
185 | integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
186 |
187 | escape-string-regexp@^1.0.5:
188 | version "1.0.5"
189 | resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
190 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
191 |
192 | execa@^0.7.0:
193 | version "0.7.0"
194 | resolved "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
195 | integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=
196 | dependencies:
197 | cross-spawn "^5.0.1"
198 | get-stream "^3.0.0"
199 | is-stream "^1.1.0"
200 | npm-run-path "^2.0.0"
201 | p-finally "^1.0.0"
202 | signal-exit "^3.0.0"
203 | strip-eof "^1.0.0"
204 |
205 | execa@^0.8.0:
206 | version "0.8.0"
207 | resolved "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da"
208 | integrity sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=
209 | dependencies:
210 | cross-spawn "^5.0.1"
211 | get-stream "^3.0.0"
212 | is-stream "^1.1.0"
213 | npm-run-path "^2.0.0"
214 | p-finally "^1.0.0"
215 | signal-exit "^3.0.0"
216 | strip-eof "^1.0.0"
217 |
218 | fast-deep-equal@^2.0.1:
219 | version "2.0.1"
220 | resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
221 | integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=
222 |
223 | fast-json-stable-stringify@^2.0.0:
224 | version "2.1.0"
225 | resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
226 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
227 |
228 | fast-url-parser@1.1.3:
229 | version "1.1.3"
230 | resolved "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d"
231 | integrity sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0=
232 | dependencies:
233 | punycode "^1.3.2"
234 |
235 | get-stream@^3.0.0:
236 | version "3.0.0"
237 | resolved "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
238 | integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=
239 |
240 | has-flag@^3.0.0:
241 | version "3.0.0"
242 | resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
243 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
244 |
245 | ini@~1.3.0:
246 | version "1.3.5"
247 | resolved "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
248 | integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
249 |
250 | is-fullwidth-code-point@^2.0.0:
251 | version "2.0.0"
252 | resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
253 | integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
254 |
255 | is-stream@^1.1.0:
256 | version "1.1.0"
257 | resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
258 | integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
259 |
260 | isexe@^2.0.0:
261 | version "2.0.0"
262 | resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
263 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
264 |
265 | json-schema-traverse@^0.4.1:
266 | version "0.4.1"
267 | resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
268 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
269 |
270 | lru-cache@^4.0.1:
271 | version "4.1.5"
272 | resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd"
273 | integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==
274 | dependencies:
275 | pseudomap "^1.0.2"
276 | yallist "^2.1.2"
277 |
278 | mime-db@1.44.0:
279 | version "1.44.0"
280 | resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92"
281 | integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==
282 |
283 | "mime-db@>= 1.43.0 < 2":
284 | version "1.45.0"
285 | resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz#cceeda21ccd7c3a745eba2decd55d4b73e7879ea"
286 | integrity sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==
287 |
288 | mime-db@~1.33.0:
289 | version "1.33.0"
290 | resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db"
291 | integrity sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==
292 |
293 | mime-types@2.1.18:
294 | version "2.1.18"
295 | resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8"
296 | integrity sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==
297 | dependencies:
298 | mime-db "~1.33.0"
299 |
300 | mime-types@~2.1.24:
301 | version "2.1.27"
302 | resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f"
303 | integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==
304 | dependencies:
305 | mime-db "1.44.0"
306 |
307 | minimatch@3.0.4:
308 | version "3.0.4"
309 | resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
310 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
311 | dependencies:
312 | brace-expansion "^1.1.7"
313 |
314 | minimist@^1.2.0:
315 | version "1.2.5"
316 | resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
317 | integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
318 |
319 | ms@2.0.0:
320 | version "2.0.0"
321 | resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
322 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
323 |
324 | negotiator@0.6.2:
325 | version "0.6.2"
326 | resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
327 | integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==
328 |
329 | npm-run-path@^2.0.0:
330 | version "2.0.2"
331 | resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
332 | integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=
333 | dependencies:
334 | path-key "^2.0.0"
335 |
336 | on-headers@~1.0.1:
337 | version "1.0.2"
338 | resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f"
339 | integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==
340 |
341 | p-finally@^1.0.0:
342 | version "1.0.0"
343 | resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
344 | integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=
345 |
346 | path-is-inside@1.0.2:
347 | version "1.0.2"
348 | resolved "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
349 | integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=
350 |
351 | path-key@^2.0.0:
352 | version "2.0.1"
353 | resolved "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
354 | integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
355 |
356 | path-to-regexp@2.2.1:
357 | version "2.2.1"
358 | resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz#90b617025a16381a879bc82a38d4e8bdeb2bcf45"
359 | integrity sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==
360 |
361 | pseudomap@^1.0.2:
362 | version "1.0.2"
363 | resolved "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
364 | integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM=
365 |
366 | punycode@^1.3.2:
367 | version "1.4.1"
368 | resolved "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
369 | integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
370 |
371 | punycode@^2.1.0:
372 | version "2.1.1"
373 | resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
374 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
375 |
376 | range-parser@1.2.0:
377 | version "1.2.0"
378 | resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"
379 | integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=
380 |
381 | rc@^1.0.1, rc@^1.1.6:
382 | version "1.2.8"
383 | resolved "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
384 | integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
385 | dependencies:
386 | deep-extend "^0.6.0"
387 | ini "~1.3.0"
388 | minimist "^1.2.0"
389 | strip-json-comments "~2.0.1"
390 |
391 | registry-auth-token@3.3.2:
392 | version "3.3.2"
393 | resolved "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20"
394 | integrity sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==
395 | dependencies:
396 | rc "^1.1.6"
397 | safe-buffer "^5.0.1"
398 |
399 | registry-url@3.1.0:
400 | version "3.1.0"
401 | resolved "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942"
402 | integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI=
403 | dependencies:
404 | rc "^1.0.1"
405 |
406 | safe-buffer@5.1.2:
407 | version "5.1.2"
408 | resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
409 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
410 |
411 | safe-buffer@^5.0.1:
412 | version "5.2.1"
413 | resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
414 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
415 |
416 | serve-handler@6.1.3:
417 | version "6.1.3"
418 | resolved "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.3.tgz#1bf8c5ae138712af55c758477533b9117f6435e8"
419 | integrity sha512-FosMqFBNrLyeiIDvP1zgO6YoTzFYHxLDEIavhlmQ+knB2Z7l1t+kGLHkZIDN7UVWqQAmKI3D20A6F6jo3nDd4w==
420 | dependencies:
421 | bytes "3.0.0"
422 | content-disposition "0.5.2"
423 | fast-url-parser "1.1.3"
424 | mime-types "2.1.18"
425 | minimatch "3.0.4"
426 | path-is-inside "1.0.2"
427 | path-to-regexp "2.2.1"
428 | range-parser "1.2.0"
429 |
430 | serve@^11.3.2:
431 | version "11.3.2"
432 | resolved "https://registry.npmjs.org/serve/-/serve-11.3.2.tgz#b905e980616feecd170e51c8f979a7b2374098f5"
433 | integrity sha512-yKWQfI3xbj/f7X1lTBg91fXBP0FqjJ4TEi+ilES5yzH0iKJpN5LjNb1YzIfQg9Rqn4ECUS2SOf2+Kmepogoa5w==
434 | dependencies:
435 | "@zeit/schemas" "2.6.0"
436 | ajv "6.5.3"
437 | arg "2.0.0"
438 | boxen "1.3.0"
439 | chalk "2.4.1"
440 | clipboardy "1.2.3"
441 | compression "1.7.3"
442 | serve-handler "6.1.3"
443 | update-check "1.5.2"
444 |
445 | shebang-command@^1.2.0:
446 | version "1.2.0"
447 | resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
448 | integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=
449 | dependencies:
450 | shebang-regex "^1.0.0"
451 |
452 | shebang-regex@^1.0.0:
453 | version "1.0.0"
454 | resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
455 | integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
456 |
457 | signal-exit@^3.0.0:
458 | version "3.0.3"
459 | resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
460 | integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
461 |
462 | string-width@^2.0.0, string-width@^2.1.1:
463 | version "2.1.1"
464 | resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
465 | integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
466 | dependencies:
467 | is-fullwidth-code-point "^2.0.0"
468 | strip-ansi "^4.0.0"
469 |
470 | strip-ansi@^4.0.0:
471 | version "4.0.0"
472 | resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
473 | integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8=
474 | dependencies:
475 | ansi-regex "^3.0.0"
476 |
477 | strip-eof@^1.0.0:
478 | version "1.0.0"
479 | resolved "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
480 | integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=
481 |
482 | strip-json-comments@~2.0.1:
483 | version "2.0.1"
484 | resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
485 | integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
486 |
487 | supports-color@^5.3.0:
488 | version "5.5.0"
489 | resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
490 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
491 | dependencies:
492 | has-flag "^3.0.0"
493 |
494 | term-size@^1.2.0:
495 | version "1.2.0"
496 | resolved "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69"
497 | integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=
498 | dependencies:
499 | execa "^0.7.0"
500 |
501 | update-check@1.5.2:
502 | version "1.5.2"
503 | resolved "https://registry.npmjs.org/update-check/-/update-check-1.5.2.tgz#2fe09f725c543440b3d7dabe8971f2d5caaedc28"
504 | integrity sha512-1TrmYLuLj/5ZovwUS7fFd1jMH3NnFDN1y1A8dboedIDt7zs/zJMo6TwwlhYKkSeEwzleeiSBV5/3c9ufAQWDaQ==
505 | dependencies:
506 | registry-auth-token "3.3.2"
507 | registry-url "3.1.0"
508 |
509 | uri-js@^4.2.2:
510 | version "4.4.0"
511 | resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz#aa714261de793e8a82347a7bcc9ce74e86f28602"
512 | integrity sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==
513 | dependencies:
514 | punycode "^2.1.0"
515 |
516 | vary@~1.1.2:
517 | version "1.1.2"
518 | resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
519 | integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
520 |
521 | which@^1.2.9:
522 | version "1.3.1"
523 | resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
524 | integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
525 | dependencies:
526 | isexe "^2.0.0"
527 |
528 | widest-line@^2.0.0:
529 | version "2.0.1"
530 | resolved "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc"
531 | integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==
532 | dependencies:
533 | string-width "^2.1.1"
534 |
535 | yallist@^2.1.2:
536 | version "2.1.2"
537 | resolved "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
538 | integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=
539 |
--------------------------------------------------------------------------------