diff --git a/.gitignore b/.gitignore index c80bb4a..3db73ec 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ node_modules cypress/screenshots test/app/.sapper test/app/src/manifest +__sapper__ test/app/export test/app/build sapper diff --git a/index.js b/index.js new file mode 100644 index 0000000..92381ab --- /dev/null +++ b/index.js @@ -0,0 +1 @@ +throw new Error(`As of Sapper 0.22, you should not import 'sapper' directly. See https://sapper.svelte.technology/guide#0-21-to-0-22 for more information`); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 3f914d9..0e9d068 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "sapper", - "version": "0.20.4", + "version": "0.21.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -23,9 +23,9 @@ "dev": true }, "@types/glob": { - "version": "5.0.35", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-5.0.35.tgz", - "integrity": "sha512-wc+VveszMLyMWFvXLkloixT4n0harUIVZjnpzztaZ0nKLuul7Z32iMt2fUFGAaZ4y1XWjFRMtCI5ewvyh4aIeg==", + "version": "5.0.36", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-5.0.36.tgz", + "integrity": "sha512-KEzSKuP2+3oOjYYjujue6Z3Yqis5HKA1BsIC+jZ1v3lrRNdsqyNNtX0rQf6LSuI4DJJ2z5UV//zBZCcvM0xikg==", "dev": true, "requires": { "@types/events": "*", @@ -55,9 +55,9 @@ "dev": true }, "@types/node": { - "version": "10.9.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.9.4.tgz", - "integrity": "sha512-fCHV45gS+m3hH17zgkgADUSi2RR1Vht6wOZ0jyHP8rjiQra9f+mIcgwPQHllmDocYOstIEbKlxbFDYlgrTPYqw==", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.11.3.tgz", + "integrity": "sha512-3AvcEJAh9EMatxs+OxAlvAEs7OTy6AG94mcH1iqyVDwVVndekLxzwkWQ/Z4SDbY6GO2oyUXyWW8tQ4rENSSQVQ==", "dev": true }, "@types/rimraf": { @@ -71,264 +71,189 @@ } }, "@webassemblyjs/ast": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.5.13.tgz", - "integrity": "sha512-49nwvW/Hx9i+OYHg+mRhKZfAlqThr11Dqz8TsrvqGKMhdI2ijy3KBJOun2Z4770TPjrIJhR6KxChQIDaz8clDA==", + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.8.tgz", + "integrity": "sha512-dOrtdtEyB8sInpl75yLPNksY4sRl0j/+t6aHyB/YA+ab9hV3Fo7FmG12FHzP+2MvWVAJtDb+6eXR5EZbZJ+uVg==", "dev": true, "requires": { - "@webassemblyjs/helper-module-context": "1.5.13", - "@webassemblyjs/helper-wasm-bytecode": "1.5.13", - "@webassemblyjs/wast-parser": "1.5.13", - "debug": "^3.1.0", - "mamacro": "^0.0.3" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "@webassemblyjs/helper-module-context": "1.7.8", + "@webassemblyjs/helper-wasm-bytecode": "1.7.8", + "@webassemblyjs/wast-parser": "1.7.8" } }, "@webassemblyjs/floating-point-hex-parser": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.5.13.tgz", - "integrity": "sha512-vrvvB18Kh4uyghSKb0NTv+2WZx871WL2NzwMj61jcq2bXkyhRC+8Q0oD7JGVf0+5i/fKQYQSBCNMMsDMRVAMqA==", + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.8.tgz", + "integrity": "sha512-kn2zNKGsbql5i56VAgRYkpG+VazqHhQQZQycT2uXAazrAEDs23gy+Odkh5VblybjnwX2/BITkDtNmSO76hdIvQ==", "dev": true }, "@webassemblyjs/helper-api-error": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.5.13.tgz", - "integrity": "sha512-dBh2CWYqjaDlvMmRP/kudxpdh30uXjIbpkLj9HQe+qtYlwvYjPRjdQXrq1cTAAOUSMTtzqbXIxEdEZmyKfcwsg==", + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.8.tgz", + "integrity": "sha512-xUwxDXsd1dUKArJEP5wWM5zxgCSwZApSOJyP1XO7M8rNUChUDblcLQ4FpzTpWG2YeylMwMl1MlP5Ztryiz1x4g==", "dev": true }, "@webassemblyjs/helper-buffer": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.5.13.tgz", - "integrity": "sha512-v7igWf1mHcpJNbn4m7e77XOAWXCDT76Xe7Is1VQFXc4K5jRcFrl9D0NrqM4XifQ0bXiuTSkTKMYqDxu5MhNljA==", - "dev": true, - "requires": { - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.8.tgz", + "integrity": "sha512-WXiIMnuvuwlhWvVOm8xEXU9DnHaa3AgAU0ZPfvY8vO1cSsmYb2WbGbHnMLgs43vXnA7XAob9b56zuZaMkxpCBg==", + "dev": true }, "@webassemblyjs/helper-code-frame": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.5.13.tgz", - "integrity": "sha512-yN6ScQQDFCiAXnVctdVO/J5NQRbwyTbQzsGzEgXsAnrxhjp0xihh+nNHQTMrq5UhOqTb5LykpJAvEv9AT0jnAQ==", + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.8.tgz", + "integrity": "sha512-TLQxyD9qGOIdX5LPQOPo0Ernd88U5rHkFb8WAjeMIeA0sPjCHeVPaGqUGGIXjUcblUkjuDAc07bruCcNHUrHDA==", "dev": true, "requires": { - "@webassemblyjs/wast-printer": "1.5.13" + "@webassemblyjs/wast-printer": "1.7.8" } }, "@webassemblyjs/helper-fsm": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.5.13.tgz", - "integrity": "sha512-hSIKzbXjVMRvy3Jzhgu+vDd/aswJ+UMEnLRCkZDdknZO3Z9e6rp1DAs0tdLItjCFqkz9+0BeOPK/mk3eYvVzZg==", + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.8.tgz", + "integrity": "sha512-TjK0CnD8hAPkV5mbSp5aWl6SO1+H3WFcjWtixWoy8EMA99YnNzYhpc/WSYWhf7yrhpzkq5tZB0tvLK3Svr3IXA==", "dev": true }, "@webassemblyjs/helper-module-context": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.5.13.tgz", - "integrity": "sha512-zxJXULGPLB7r+k+wIlvGlXpT4CYppRz8fLUM/xobGHc9Z3T6qlmJD9ySJ2jknuktuuiR9AjnNpKYDECyaiX+QQ==", - "dev": true, - "requires": { - "debug": "^3.1.0", - "mamacro": "^0.0.3" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.8.tgz", + "integrity": "sha512-uCutAKR7Nm0VsFixcvnB4HhAyHouNbj0Dx1p7eRjFjXGGZ+N7ftTaG1ZbWCasAEbtwGj54LP8+lkBZdTCPmLGg==", + "dev": true }, "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.5.13.tgz", - "integrity": "sha512-0n3SoNGLvbJIZPhtMFq0XmmnA/YmQBXaZKQZcW8maGKwLpVcgjNrxpFZHEOLKjXJYVN5Il8vSfG7nRX50Zn+aw==", + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.8.tgz", + "integrity": "sha512-AdCCE3BMW6V34WYaKUmPgVHa88t2Z14P4/0LjLwuGkI0X6pf7nzp0CehzVVk51cKm2ymVXjl9dCG+gR1yhITIQ==", "dev": true }, "@webassemblyjs/helper-wasm-section": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.5.13.tgz", - "integrity": "sha512-IJ/goicOZ5TT1axZFSnlAtz4m8KEjYr12BNOANAwGFPKXM4byEDaMNXYowHMG0yKV9a397eU/NlibFaLwr1fbw==", + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.8.tgz", + "integrity": "sha512-BkBhYQuzyl4hgTGOKo87Vdw6f9nj8HhI7WYpI0MCC5qFa5ahrAPOGgyETVdnRbv+Rjukl9MxxfDmVcVC435lDg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.5.13", - "@webassemblyjs/helper-buffer": "1.5.13", - "@webassemblyjs/helper-wasm-bytecode": "1.5.13", - "@webassemblyjs/wasm-gen": "1.5.13", - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "@webassemblyjs/ast": "1.7.8", + "@webassemblyjs/helper-buffer": "1.7.8", + "@webassemblyjs/helper-wasm-bytecode": "1.7.8", + "@webassemblyjs/wasm-gen": "1.7.8" } }, "@webassemblyjs/ieee754": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.5.13.tgz", - "integrity": "sha512-TseswvXEPpG5TCBKoLx9tT7+/GMACjC1ruo09j46ULRZWYm8XHpDWaosOjTnI7kr4SRJFzA6MWoUkAB+YCGKKg==", + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.8.tgz", + "integrity": "sha512-tOarWChdG1a3y1yqCX0JMDKzrat5tQe4pV6K/TX19BcXsBLYxFQOL1DEDa5KG9syeyvCrvZ+i1+Mv1ExngvktQ==", "dev": true, "requires": { - "ieee754": "^1.1.11" + "@xtuc/ieee754": "^1.2.0" } }, "@webassemblyjs/leb128": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.5.13.tgz", - "integrity": "sha512-0NRMxrL+GG3eISGZBmLBLAVjphbN8Si15s7jzThaw1UE9e5BY1oH49/+MA1xBzxpf1OW5sf9OrPDOclk9wj2yg==", + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.8.tgz", + "integrity": "sha512-GCYeGPgUFWJiZuP4NICbcyUQNxNLJIf476Ei+K+jVuuebtLpfvwkvYT6iTUE7oZYehhkor4Zz2g7SJ/iZaPudQ==", "dev": true, "requires": { - "long": "4.0.0" - }, - "dependencies": { - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - } + "@xtuc/long": "4.2.1" } }, "@webassemblyjs/utf8": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.5.13.tgz", - "integrity": "sha512-Ve1ilU2N48Ew0lVGB8FqY7V7hXjaC4+PeZM+vDYxEd+R2iQ0q+Wb3Rw8v0Ri0+rxhoz6gVGsnQNb4FjRiEH/Ng==", + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.8.tgz", + "integrity": "sha512-9X+f0VV+xNXW2ujfIRSXBJENGE6Qh7bNVKqu3yDjTFB3ar3nsThsGBBKdTG58aXOm2iUH6v28VIf88ymPXODHA==", "dev": true }, "@webassemblyjs/wasm-edit": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.5.13.tgz", - "integrity": "sha512-X7ZNW4+Hga4f2NmqENnHke2V/mGYK/xnybJSIXImt1ulxbCOEs/A+ZK/Km2jgihjyVxp/0z0hwIcxC6PrkWtgw==", + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.8.tgz", + "integrity": "sha512-6D3Hm2gFixrfyx9XjSON4ml1FZTugqpkIz5Awvrou8fnpyprVzcm4X8pyGRtA2Piixjl3DqmX/HB1xdWyE097A==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.5.13", - "@webassemblyjs/helper-buffer": "1.5.13", - "@webassemblyjs/helper-wasm-bytecode": "1.5.13", - "@webassemblyjs/helper-wasm-section": "1.5.13", - "@webassemblyjs/wasm-gen": "1.5.13", - "@webassemblyjs/wasm-opt": "1.5.13", - "@webassemblyjs/wasm-parser": "1.5.13", - "@webassemblyjs/wast-printer": "1.5.13", - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "@webassemblyjs/ast": "1.7.8", + "@webassemblyjs/helper-buffer": "1.7.8", + "@webassemblyjs/helper-wasm-bytecode": "1.7.8", + "@webassemblyjs/helper-wasm-section": "1.7.8", + "@webassemblyjs/wasm-gen": "1.7.8", + "@webassemblyjs/wasm-opt": "1.7.8", + "@webassemblyjs/wasm-parser": "1.7.8", + "@webassemblyjs/wast-printer": "1.7.8" } }, "@webassemblyjs/wasm-gen": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.5.13.tgz", - "integrity": "sha512-yfv94Se8R73zmr8GAYzezFHc3lDwE/lBXQddSiIZEKZFuqy7yWtm3KMwA1uGbv5G1WphimJxboXHR80IgX1hQA==", + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.8.tgz", + "integrity": "sha512-a7O/wE6eBeVKKUYgpMK7NOHmMADD85rSXLe3CqrWRDwWff5y3cSVbzpN6Qv3z6C4hdkpq9qyij1Ga1kemOZGvQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.5.13", - "@webassemblyjs/helper-wasm-bytecode": "1.5.13", - "@webassemblyjs/ieee754": "1.5.13", - "@webassemblyjs/leb128": "1.5.13", - "@webassemblyjs/utf8": "1.5.13" + "@webassemblyjs/ast": "1.7.8", + "@webassemblyjs/helper-wasm-bytecode": "1.7.8", + "@webassemblyjs/ieee754": "1.7.8", + "@webassemblyjs/leb128": "1.7.8", + "@webassemblyjs/utf8": "1.7.8" } }, "@webassemblyjs/wasm-opt": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.5.13.tgz", - "integrity": "sha512-IkXSkgzVhQ0QYAdIayuCWMmXSYx0dHGU8Ah/AxJf1gBvstMWVnzJnBwLsXLyD87VSBIcsqkmZ28dVb0mOC3oBg==", + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.8.tgz", + "integrity": "sha512-3lbQ0PT81NHCdi1sR/7+SNpZadM4qYcTSr62nFFAA7e5lFwJr14M1Gi+A/Y3PgcDWOHYjsaNGPpPU0H03N6Blg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.5.13", - "@webassemblyjs/helper-buffer": "1.5.13", - "@webassemblyjs/wasm-gen": "1.5.13", - "@webassemblyjs/wasm-parser": "1.5.13", - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "@webassemblyjs/ast": "1.7.8", + "@webassemblyjs/helper-buffer": "1.7.8", + "@webassemblyjs/wasm-gen": "1.7.8", + "@webassemblyjs/wasm-parser": "1.7.8" } }, "@webassemblyjs/wasm-parser": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.5.13.tgz", - "integrity": "sha512-XnYoIcu2iqq8/LrtmdnN3T+bRjqYFjRHqWbqK3osD/0r/Fcv4d9ecRzjVtC29ENEuNTK4mQ9yyxCBCbK8S/cpg==", + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.8.tgz", + "integrity": "sha512-rZ/zlhp9DHR/05zh1MbAjT2t624sjrPP/OkJCjXqzm7ynH+nIdNcn9Ixc+qzPMFXhIrk0rBoQ3to6sEIvHh9jQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.5.13", - "@webassemblyjs/helper-api-error": "1.5.13", - "@webassemblyjs/helper-wasm-bytecode": "1.5.13", - "@webassemblyjs/ieee754": "1.5.13", - "@webassemblyjs/leb128": "1.5.13", - "@webassemblyjs/utf8": "1.5.13" + "@webassemblyjs/ast": "1.7.8", + "@webassemblyjs/helper-api-error": "1.7.8", + "@webassemblyjs/helper-wasm-bytecode": "1.7.8", + "@webassemblyjs/ieee754": "1.7.8", + "@webassemblyjs/leb128": "1.7.8", + "@webassemblyjs/utf8": "1.7.8" } }, "@webassemblyjs/wast-parser": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.5.13.tgz", - "integrity": "sha512-Lbz65T0LQ1LgzKiUytl34CwuhMNhaCLgrh0JW4rJBN6INnBB8NMwUfQM+FxTnLY9qJ+lHJL/gCM5xYhB9oWi4A==", + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.8.tgz", + "integrity": "sha512-Q/zrvtUvzWuSiJMcSp90fi6gp2nraiHXjTV2VgAluVdVapM4gy1MQn7akja2p6eSBDQpKJPJ6P4TxRkghRS5dg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.5.13", - "@webassemblyjs/floating-point-hex-parser": "1.5.13", - "@webassemblyjs/helper-api-error": "1.5.13", - "@webassemblyjs/helper-code-frame": "1.5.13", - "@webassemblyjs/helper-fsm": "1.5.13", - "long": "^3.2.0", - "mamacro": "^0.0.3" + "@webassemblyjs/ast": "1.7.8", + "@webassemblyjs/floating-point-hex-parser": "1.7.8", + "@webassemblyjs/helper-api-error": "1.7.8", + "@webassemblyjs/helper-code-frame": "1.7.8", + "@webassemblyjs/helper-fsm": "1.7.8", + "@xtuc/long": "4.2.1" } }, "@webassemblyjs/wast-printer": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.5.13.tgz", - "integrity": "sha512-QcwogrdqcBh8Z+eUF8SG+ag5iwQSXxQJELBEHmLkk790wgQgnIMmntT2sMAMw53GiFNckArf5X0bsCA44j3lWQ==", + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.8.tgz", + "integrity": "sha512-GllIthRtwTxRDAURRNXscu7Napzmdf1jt1gpiZiK/QN4fH0lSGs3OTmvdfsMNP7tqI4B3ZtfaaWRlNIQug6Xyg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.5.13", - "@webassemblyjs/wast-parser": "1.5.13", - "long": "^3.2.0" + "@webassemblyjs/ast": "1.7.8", + "@webassemblyjs/wast-parser": "1.7.8", + "@xtuc/long": "4.2.1" } }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", + "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", + "dev": true + }, "accepts": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", @@ -340,9 +265,9 @@ } }, "acorn": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.2.tgz", - "integrity": "sha512-cJrKCNcr2kv8dlDnbw+JPUGjHZzo4myaxOLmpOX8a+rgX94YeTcTMv/LFJUSByRpc+i4GgVnnhLxvMu/2Y+rqw==", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", "dev": true }, "acorn-dynamic-import": { @@ -356,7 +281,7 @@ }, "acorn-jsx": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", "dev": true, "requires": { @@ -365,12 +290,34 @@ "dependencies": { "acorn": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "resolved": "http://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", "dev": true } } }, + "agadoo": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/agadoo/-/agadoo-1.0.1.tgz", + "integrity": "sha512-rEOSqXQ3ABoxmgvxqEvUfS7mcMJBqRhcMbmJq4j+EpCXN0P1cFHYQT66V7rYSu0C+3jialSk58yHTBqzY0m+Sw==", + "dev": true, + "requires": { + "rollup": "^0.64.1", + "rollup-plugin-virtual": "^1.0.1" + }, + "dependencies": { + "rollup": { + "version": "0.64.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.64.1.tgz", + "integrity": "sha512-+ThdVXrvonJdOTzyybMBipP0uz605Z8AnzWVY3rf+cSGnLO7uNkJBlN+9jXqWOomkvumXfm/esmBpA5d53qm7g==", + "dev": true, + "requires": { + "@types/estree": "0.0.39", + "@types/node": "*" + } + } + } + }, "ajv": { "version": "5.5.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", @@ -900,7 +847,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -1005,15 +952,15 @@ "dev": true }, "binary-extensions": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", - "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", + "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", "dev": true }, "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.2.tgz", + "integrity": "sha512-dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg==", "dev": true }, "bn.js": { @@ -1083,7 +1030,7 @@ }, "browserify-aes": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": { @@ -1120,7 +1067,7 @@ }, "browserify-rsa": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "dev": true, "requires": { @@ -1447,9 +1394,9 @@ } }, "chownr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", - "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", + "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", "dev": true }, "chrome-trace-event": { @@ -1573,9 +1520,9 @@ "dev": true }, "combined-stream": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", "dev": true, "requires": { "delayed-stream": "~1.0.0" @@ -1605,12 +1552,12 @@ "dev": true }, "compressible": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.14.tgz", - "integrity": "sha1-MmxfUH+7BV9UEWeCuWmoG2einac=", + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.15.tgz", + "integrity": "sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw==", "dev": true, "requires": { - "mime-db": ">= 1.34.0 < 2" + "mime-db": ">= 1.36.0 < 2" } }, "compression": { @@ -1729,7 +1676,7 @@ }, "create-hash": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "requires": { @@ -1742,7 +1689,7 @@ }, "create-hmac": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "requires": { @@ -1836,20 +1783,12 @@ "dev": true }, "deep-defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/deep-defaults/-/deep-defaults-1.0.4.tgz", - "integrity": "sha1-Gpdi4rbI1qTpkxuO5/+M3O4dF1A=", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/deep-defaults/-/deep-defaults-1.0.5.tgz", + "integrity": "sha512-5ev/sNkiHTmeTqbDJEDgdQa/Ub0eOMQNix9l+dLLGbwOos7/in5HdvHXI014wqxsET4YeJG9Eq4qj0PJRL8rSw==", "dev": true, "requires": { - "lodash": "3.0.x" - }, - "dependencies": { - "lodash": { - "version": "3.0.1", - "resolved": "http://registry.npmjs.org/lodash/-/lodash-3.0.1.tgz", - "integrity": "sha1-FNSQKKOLx0AkHRHi7NV+wG1zwZo=", - "dev": true - } + "lodash": "^4.17.5" } }, "deep-extend": { @@ -2000,7 +1939,7 @@ }, "diffie-hellman": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "requires": { @@ -2026,7 +1965,7 @@ }, "duplexer": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", "dev": true }, @@ -2071,9 +2010,9 @@ }, "dependencies": { "@types/node": { - "version": "8.10.29", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.29.tgz", - "integrity": "sha512-zbteaWZ2mdduacm0byELwtRyhYE40aK+pAanQk415gr1eRuu67x7QGOLmn8jz5zI8LDK7d0WI/oT6r5Trz4rzQ==", + "version": "8.10.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.30.tgz", + "integrity": "sha512-Le8HGMI5gjFSBqcCuKP/wfHC19oURzkU2D+ERIescUoJd+CmNEMYBib9LQ4zj1HHEZOJQWhw2ZTnbD8weASh/Q==", "dev": true } } @@ -2205,20 +2144,20 @@ } }, "es-to-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", - "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", "dev": true, "requires": { - "is-callable": "^1.1.1", + "is-callable": "^1.1.4", "is-date-object": "^1.0.1", - "is-symbol": "^1.0.1" + "is-symbol": "^1.0.2" } }, "es6-promise": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", - "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==", + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz", + "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==", "dev": true }, "escape-html": { @@ -2280,13 +2219,19 @@ }, "dependencies": { "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.5.tgz", + "integrity": "sha512-D61LaDQPQkxJ5AUM2mbSJRbPkNs/TmdmOeLAi1hgDkpDfIfetSrjmWhccwtuResSwMbACjx/xXQofvM9CE/aeg==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true } } }, @@ -2415,23 +2360,24 @@ "dev": true }, "event-stream": { - "version": "3.3.4", - "resolved": "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", - "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.6.tgz", + "integrity": "sha512-dGXNg4F/FgVzlApjzItL+7naHutA3fDqbV/zAZqDDlXTjiMnQmZKu+prImWKszeBM5UQeGvAl3u1wBiKeDh61g==", "dev": true, "requires": { - "duplexer": "~0.1.1", - "from": "~0", - "map-stream": "~0.1.0", - "pause-stream": "0.0.11", - "split": "0.3", - "stream-combiner": "~0.0.4", - "through": "~2.3.1" + "duplexer": "^0.1.1", + "flatmap-stream": "^0.1.0", + "from": "^0.1.7", + "map-stream": "0.0.7", + "pause-stream": "^0.0.11", + "split": "^1.0.1", + "stream-combiner": "^0.2.2", + "through": "^2.3.8" } }, "events": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/events/-/events-1.1.1.tgz", "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", "dev": true }, @@ -2465,7 +2411,7 @@ }, "express": { "version": "4.16.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", + "resolved": "http://registry.npmjs.org/express/-/express-4.16.3.tgz", "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", "dev": true, "requires": { @@ -2641,7 +2587,7 @@ }, "finalhandler": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", "dev": true, "requires": { @@ -2707,6 +2653,12 @@ "write": "^0.2.1" } }, + "flatmap-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/flatmap-stream/-/flatmap-stream-0.1.0.tgz", + "integrity": "sha512-Nlic4ZRYxikqnK5rj3YoxDVKGGtUjcNDUtvQ7XsdGLZmMwdUYnXf10o1zcXtzEZTBgc6GxeRpQxV/Wu3WPIIHA==", + "dev": true + }, "flush-write-stream": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", @@ -2747,6 +2699,17 @@ "asynckit": "^0.4.0", "combined-stream": "1.0.6", "mime-types": "^2.1.12" + }, + "dependencies": { + "combined-stream": { + "version": "1.0.6", + "resolved": "http://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", + "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + } } }, "forwarded": { @@ -3502,6 +3465,12 @@ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -3626,7 +3595,7 @@ }, "http-errors": { "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, "requires": { @@ -3783,7 +3752,7 @@ }, "is-builtin-module": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, "requires": { @@ -3971,10 +3940,13 @@ "dev": true }, "is-symbol": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", - "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", - "dev": true + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } }, "is-typedarray": { "version": "1.0.0", @@ -4082,13 +4054,13 @@ }, "json5": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz", "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", "dev": true }, "jsonfile": { "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "dev": true, "requires": { @@ -4155,7 +4127,7 @@ }, "load-json-file": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "dev": true, "requires": { @@ -4166,9 +4138,9 @@ } }, "loader-runner": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz", - "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.1.tgz", + "integrity": "sha512-By6ZFY7ETWOc9RFaAIb23IjJVcM4dvJC/N57nmdz9RSkMXvAXGI7SyVlAw3v8vjtDRlqThgVDVmTnr9fqMlxkw==", "dev": true }, "loader-utils": { @@ -4201,9 +4173,9 @@ } }, "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", "dev": true }, "lodash.debounce": { @@ -4212,12 +4184,6 @@ "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", "dev": true }, - "long": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", - "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=", - "dev": true - }, "loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", @@ -4245,7 +4211,7 @@ }, "magic-string": { "version": "0.22.5", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", + "resolved": "http://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", "integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==", "dev": true, "requires": { @@ -4275,12 +4241,6 @@ "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", "dev": true }, - "mamacro": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", - "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==", - "dev": true - }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", @@ -4294,9 +4254,9 @@ "dev": true }, "map-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", + "integrity": "sha1-ih8HiW2CsQkmvTdEokIACfiJdKg=", "dev": true }, "map-visit": { @@ -4384,7 +4344,7 @@ "dependencies": { "load-json-file": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { @@ -4552,7 +4512,7 @@ "dependencies": { "commander": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/commander/-/commander-1.0.4.tgz", + "resolved": "http://registry.npmjs.org/commander/-/commander-1.0.4.tgz", "integrity": "sha1-Xt6xruI8T7VBprcNaSq+8ZZpotM=", "dev": true, "requires": { @@ -4648,7 +4608,7 @@ "dependencies": { "commander": { "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz", "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", "dev": true }, @@ -4728,9 +4688,9 @@ "dev": true }, "nan": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.0.tgz", - "integrity": "sha512-F4miItu2rGnV2ySkXOQoA8FKz/SR2Q2sWP0sbTxNxz/tuokeC8WxOhPMcwi0qIyGtVn/rrSeLbvVkznqCdwYnw==", + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", + "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==", "dev": true, "optional": true }, @@ -5216,7 +5176,7 @@ }, "parse-asn1": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", + "resolved": "http://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", "dev": true, "requires": { @@ -5328,7 +5288,7 @@ }, "pause-stream": { "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "resolved": "http://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", "dev": true, "requires": { @@ -5336,9 +5296,9 @@ } }, "pbkdf2": { - "version": "3.0.16", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", - "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==", + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", "dev": true, "requires": { "create-hash": "^1.1.2", @@ -5518,7 +5478,7 @@ }, "public-encrypt": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", + "resolved": "http://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", "dev": true, "requires": { @@ -5722,7 +5682,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { @@ -5736,15 +5696,290 @@ } }, "readdirp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", - "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", - "readable-stream": "^2.0.2", - "set-immediate-shim": "^1.0.1" + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + } } }, "redent": { @@ -5923,9 +6158,9 @@ } }, "rollup": { - "version": "0.65.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.65.0.tgz", - "integrity": "sha512-en95i7zwW5IiWay6DR/6QV8TxO2LvWuCjHYDcgP96oVG/gPnWWzsxNViObhoJUs17bAj2RgB67WuBuGmysZZcw==", + "version": "0.65.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.65.2.tgz", + "integrity": "sha512-BbXOrpxVbx0MpElI6vVLR2B6vnWHvYU/QAMw3GcEXvs601bvgrozuaW30cnvt43B96a6DeoYA0i9T5THanN+Rw==", "dev": true, "requires": { "@types/estree": "0.0.39", @@ -5933,9 +6168,9 @@ } }, "rollup-plugin-commonjs": { - "version": "9.1.6", - "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-9.1.6.tgz", - "integrity": "sha512-J7GOJm9uzEeLqkVxYSgjyoieh34hATWpa9G2M1ilGzWOLYGfQx5IDQ9ewG8QUj/Z2dzgV+d0/AyloAzElkABAA==", + "version": "9.1.8", + "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-9.1.8.tgz", + "integrity": "sha512-c3nAfVVyEwbq9OohIeQudfQQdGV9Cl1RE8MUc90fH9UdtCiWAYpI+au3HxGwNf1DdV51HfBjCDbT4fwjsZEUUg==", "dev": true, "requires": { "estree-walker": "^0.5.1", @@ -5945,18 +6180,18 @@ } }, "rollup-plugin-json": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-json/-/rollup-plugin-json-3.0.0.tgz", - "integrity": "sha512-WUAV9/I/uFWvHhyRTqFb+3SIapjISFJS7R1xN/cXxWESrfYo9I8ncHI7AxJHflKRXhBVSv7revBVJh2wvhWh5w==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-json/-/rollup-plugin-json-3.1.0.tgz", + "integrity": "sha512-BlYk5VspvGpjz7lAwArVzBXR60JK+4EKtPkCHouAWg39obk9S61hZYJDBfMK+oitPdoe11i69TlxKlMQNFC/Uw==", "dev": true, "requires": { - "rollup-pluginutils": "^2.2.0" + "rollup-pluginutils": "^2.3.1" } }, "rollup-plugin-node-resolve": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.3.0.tgz", - "integrity": "sha512-9zHGr3oUJq6G+X0oRMYlzid9fXicBdiydhwGChdyeNRGPcN/majtegApRKHLR5drboUvEWU+QeUmGTyEZQs3WA==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.4.0.tgz", + "integrity": "sha512-PJcd85dxfSBWih84ozRtBkB731OjXk0KnzN0oGp7WOWcarAFkVa71cV5hTJg2qpVsV2U8EUwrzHP3tvy9vS3qg==", "dev": true, "requires": { "builtin-modules": "^2.0.0", @@ -5989,7 +6224,7 @@ }, "rollup-pluginutils": { "version": "1.5.2", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz", + "resolved": "http://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz", "integrity": "sha1-HhVud4+UtyVb+hs9AXi+j1xVJAg=", "dev": true, "requires": { @@ -6001,7 +6236,7 @@ }, "rollup-plugin-typescript": { "version": "0.8.1", - "resolved": "https://registry.npmjs.org/rollup-plugin-typescript/-/rollup-plugin-typescript-0.8.1.tgz", + "resolved": "http://registry.npmjs.org/rollup-plugin-typescript/-/rollup-plugin-typescript-0.8.1.tgz", "integrity": "sha1-L/fuzCHPa7K0P8J+W2iJUs5xkko=", "dev": true, "requires": { @@ -6020,7 +6255,7 @@ }, "rollup-pluginutils": { "version": "1.5.2", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz", + "resolved": "http://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz", "integrity": "sha1-HhVud4+UtyVb+hs9AXi+j1xVJAg=", "dev": true, "requires": { @@ -6036,10 +6271,16 @@ } } }, + "rollup-plugin-virtual": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-virtual/-/rollup-plugin-virtual-1.0.1.tgz", + "integrity": "sha512-HCTBpV8MwP5lNzZrHD2moVxHIToHU1EkzkKGVj6Z0DcgUfxrxrZmeQirQeLz2yhnkJqRjwiVywK9CS8jDYakrw==", + "dev": true + }, "rollup-pluginutils": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.3.1.tgz", - "integrity": "sha512-JZS8aJMHEHhqmY2QVPMXwKP6lsD1ShkrcGYjhAIvqKKdXQyPHw/9NF0tl3On/xOJ4ACkxfeG7AF+chfCN1NpBg==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.3.3.tgz", + "integrity": "sha512-2XZwja7b6P5q4RZ5FhyX1+f46xi1Z3qBKigLRZ6VTZjwbN0K1IFGMlwm06Uu0Emcre2Z63l77nq/pzn+KxIEoA==", "dev": true, "requires": { "estree-walker": "^0.5.2", @@ -6132,9 +6373,9 @@ }, "dependencies": { "ajv": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.3.tgz", - "integrity": "sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.4.tgz", + "integrity": "sha512-4Wyjt8+t6YszqaXnLDfMmG/8AlO5Zbcsy3ATHncCzjW/NoPzAId8AK6749Ybjmdt+kUY1gP60fCu46oDxPv/mg==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -6208,12 +6449,6 @@ "send": "0.16.2" } }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true - }, "set-value": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", @@ -6251,7 +6486,7 @@ }, "sha.js": { "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dev": true, "requires": { @@ -6328,7 +6563,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -6506,14 +6741,14 @@ "dev": true }, "sourcemap-codec": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.1.tgz", - "integrity": "sha512-hX1eNBNuilj8yfFnECh0DzLgwKpBLMIvmhgEhixXNui8lMLBInTI8Kyxt++RwJnMNu7cAUo635L2+N1TxMJCzA==" + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.3.tgz", + "integrity": "sha512-vFrY/x/NdsD7Yc8mpTJXuao9S8lq08Z/kOITHz6b7YbfI9xL8Spe5EvSQUHOI7SbpY8bRPr0U3kKSsPuqEGSfA==" }, "spdx-correct": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", - "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.1.tgz", + "integrity": "sha512-hxSPZbRZvSDuOvADntOElzJpenIR7wXJkuoUcUtS0erbgt2fgeaoPIYretfKpslMhfFDY4k0MZ2F5CUzhBsSvQ==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", @@ -6537,9 +6772,9 @@ } }, "spdx-license-ids": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", - "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.1.tgz", + "integrity": "sha512-TfOfPcYGBB5sDuPn3deByxPhmfegAhpDYKSOXZQN81Oyrrif8ZCodOLzK3AesELnCx03kikhyDwh0pfvvQvF8w==", "dev": true }, "speedometer": { @@ -6549,9 +6784,9 @@ "dev": true }, "split": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", - "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", "dev": true, "requires": { "through": "2" @@ -6663,12 +6898,13 @@ } }, "stream-combiner": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", + "version": "0.2.2", + "resolved": "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", + "integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=", "dev": true, "requires": { - "duplexer": "~0.1.1" + "duplexer": "~0.1.1", + "through": "~2.3.4" } }, "stream-each": { @@ -6798,9 +7034,9 @@ "dev": true }, "svelte": { - "version": "2.13.2", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-2.13.2.tgz", - "integrity": "sha512-b27mBrxCR3CK06iiNdwynq34WV9I9VBBoeO+Rg9lTuRiaYmbN1eG1+6llxvn1VjPt6PGm3EskYOfR85piiCUfA==", + "version": "2.13.5", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-2.13.5.tgz", + "integrity": "sha512-Mg4+vRwAT1IMR4FAH3cOmMaVVrJ35xUI1qsTW+WoJvRpeBDx7aLZUbgBXnctxdfEJQ4BuP2MCuhYKy8917Au1A==", "dev": true }, "svelte-dev-helper": { @@ -6835,9 +7071,9 @@ } }, "tapable": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.0.0.tgz", - "integrity": "sha512-dQRhbNQkRnaqauC7WqSJ21EEksgT0fYZX2lqXzGkpo8JNig9zGZTYoMGvyI2nWmXlE2VSVXVDu7wLVGu/mQEsg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.0.tgz", + "integrity": "sha512-IlqtmLVaZA2qab8epUXbVWRn3aB1imbDMJtjB3nu4X0NqPkcY/JH9ZtCBWKHWPxs8Svi9tyo8w2dBoi07qZbBA==", "dev": true }, "text-table": { @@ -6854,7 +7090,7 @@ }, "through": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, @@ -6876,7 +7112,7 @@ }, "readable-stream": { "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, "requires": { @@ -7162,18 +7398,18 @@ } }, "unique-filename": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.0.tgz", - "integrity": "sha1-0F8v5AMlYIcfMOk8vnNe6iAVFPM=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", "dev": true, "requires": { "unique-slug": "^2.0.0" } }, "unique-slug": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.0.tgz", - "integrity": "sha1-22Z258fMBimHj/GWCXx4hVrp9Ks=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz", + "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==", "dev": true, "requires": { "imurmurhash": "^0.1.4" @@ -7380,16 +7616,15 @@ } }, "webpack": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.17.1.tgz", - "integrity": "sha512-vdPYogljzWPhFKDj3Gcp01Vqgu7K3IQlybc3XIdKSQHelK1C3eIQuysEUR7MxKJmdandZlQB/9BG2Jb1leJHaw==", + "version": "4.20.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.20.2.tgz", + "integrity": "sha512-75WFUMblcWYcocjSLlXCb71QuGyH7egdBZu50FtBGl2Nso8CK3Ej+J7bTZz2FPFq5l6fzCisD9modB7t30ikuA==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.5.13", - "@webassemblyjs/helper-module-context": "1.5.13", - "@webassemblyjs/wasm-edit": "1.5.13", - "@webassemblyjs/wasm-opt": "1.5.13", - "@webassemblyjs/wasm-parser": "1.5.13", + "@webassemblyjs/ast": "1.7.8", + "@webassemblyjs/helper-module-context": "1.7.8", + "@webassemblyjs/wasm-edit": "1.7.8", + "@webassemblyjs/wasm-parser": "1.7.8", "acorn": "^5.6.2", "acorn-dynamic-import": "^3.0.0", "ajv": "^6.1.0", @@ -7406,16 +7641,16 @@ "neo-async": "^2.5.0", "node-libs-browser": "^2.0.0", "schema-utils": "^0.4.4", - "tapable": "^1.0.0", + "tapable": "^1.1.0", "uglifyjs-webpack-plugin": "^1.2.4", "watchpack": "^1.5.0", - "webpack-sources": "^1.0.1" + "webpack-sources": "^1.3.0" }, "dependencies": { "ajv": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.3.tgz", - "integrity": "sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.4.tgz", + "integrity": "sha512-4Wyjt8+t6YszqaXnLDfMmG/8AlO5Zbcsy3ATHncCzjW/NoPzAId8AK6749Ybjmdt+kUY1gP60fCu46oDxPv/mg==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -7738,9 +7973,9 @@ } }, "webpack-sources": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.2.0.tgz", - "integrity": "sha512-9BZwxR85dNsjWz3blyxdOhTgtnQvv3OEs5xofI0wPYTwu5kaWxS08UuD1oI7WLBLpRO+ylf0ofnXLXWmGb2WMw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz", + "integrity": "sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==", "dev": true, "requires": { "source-list-map": "^2.0.0", diff --git a/package.json b/package.json index 1cd808f..9790ca5 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,6 @@ "name": "sapper", "version": "0.21.1", "description": "Military-grade apps, engineered by Svelte", - "main": "dist/middleware.js", "bin": { "sapper": "./sapper" }, @@ -32,6 +31,7 @@ "@types/mocha": "^5.2.5", "@types/node": "^10.7.1", "@types/rimraf": "^2.0.2", + "agadoo": "^1.0.1", "cheap-watch": "^0.3.0", "compression": "^1.7.1", "cookie": "^0.3.1", diff --git a/rollup.config.js b/rollup.config.js index c74d63d..90e1f45 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -4,6 +4,7 @@ import json from 'rollup-plugin-json'; import resolve from 'rollup-plugin-node-resolve'; import commonjs from 'rollup-plugin-commonjs'; import pkg from './package.json'; +import { builtinModules } from 'module'; const external = [].concat( Object.keys(pkg.dependencies), @@ -11,27 +12,37 @@ const external = [].concat( 'sapper/core.js' ); -export default [ - { - input: `src/runtime/index.ts`, +function template(kind, external) { + return { + input: `templates/src/${kind}/index.ts`, output: { - file: `runtime.js`, + file: `templates/dist/${kind}.js`, format: 'es' }, + external, plugins: [ + resolve(), + commonjs(), + string({ + include: '**/*.md' + }), typescript({ typescript: require('typescript'), target: "ES2017" }) ] - }, + }; +} + +export default [ + template('client', ['__ROOT__', '__ERROR__']), + template('server', builtinModules), { input: [ `src/api.ts`, `src/cli.ts`, `src/core.ts`, - `src/middleware.ts`, `src/rollup.ts`, `src/webpack.ts` ], @@ -42,9 +53,6 @@ export default [ }, external, plugins: [ - string({ - include: '**/*.md' - }), json(), resolve(), commonjs(), diff --git a/runtime/README.md b/runtime/README.md deleted file mode 100644 index 7b650d6..0000000 --- a/runtime/README.md +++ /dev/null @@ -1 +0,0 @@ -This directory exists for legacy reasons and should be deleted before releasing version 1. \ No newline at end of file diff --git a/runtime/app.js b/runtime/app.js deleted file mode 100644 index 43ebb81..0000000 --- a/runtime/app.js +++ /dev/null @@ -1,2 +0,0 @@ -console.error('sapper/runtime/app.js has been deprecated in favour of sapper/runtime.js'); -export * from '../runtime.js'; \ No newline at end of file diff --git a/src/api/build.ts b/src/api/build.ts index ec2e1d3..c9d93f4 100644 --- a/src/api/build.ts +++ b/src/api/build.ts @@ -3,19 +3,16 @@ import * as path from 'path'; import mkdirp from 'mkdirp'; import rimraf from 'rimraf'; import { EventEmitter } from 'events'; -import * as codec from 'sourcemap-codec'; -import hash from 'string-hash'; import minify_html from './utils/minify_html'; import { create_compilers, create_main_manifests, create_manifest_data, create_serviceworker_manifest } from '../core'; import * as events from './interfaces'; import { copy_shimport } from './utils/copy_shimport'; -import { Dirs, PageComponent } from '../interfaces'; -import { CompileResult } from '../core/create_compilers/interfaces'; +import { Dirs } from '../interfaces'; import read_template from '../core/read_template'; type Opts = { legacy: boolean; - bundler: string; + bundler: 'rollup' | 'webpack'; }; export function build(opts: Opts, dirs: Dirs) { @@ -58,7 +55,7 @@ async function execute(emitter: EventEmitter, opts: Opts, dirs: Dirs) { // create src/manifest/client.js and src/manifest/server.js create_main_manifests({ bundler: opts.bundler, manifest_data }); - const { client, server, serviceworker } = await create_compilers(opts.bundler, dirs); + const { client, server, serviceworker } = await create_compilers(opts.bundler); const client_result = await client.compile(); emitter.emit('build', { @@ -71,7 +68,7 @@ async function execute(emitter: EventEmitter, opts: Opts, dirs: Dirs) { if (opts.legacy) { process.env.SAPPER_LEGACY_BUILD = 'true'; - const { client } = await create_compilers(opts.bundler, dirs); + const { client } = await create_compilers(opts.bundler); const client_result = await client.compile(); diff --git a/src/cli.ts b/src/cli.ts index 96cd811..de702b7 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -33,7 +33,7 @@ prog.command('build [dest]') .option('--bundler', 'Specify a bundler (rollup or webpack, blank for auto)') .option('--legacy', 'Create separate legacy build') .example(`build custom-dir -p 4567`) - .action(async (dest = 'build', opts: { + .action(async (dest = '__sapper__/build', opts: { port: string, legacy: boolean, bundler?: string @@ -80,12 +80,12 @@ prog.command('start [dir]') prog.command('export [dest]') .describe('Export your app as static files (if possible)') .option('--build', '(Re)build app before exporting', true) - .option('--build-dir', 'Specify a custom temporary build directory', '.sapper/prod') + .option('--build-dir', 'Specify a custom temporary build directory', '__sapper__/build') .option('--basepath', 'Specify a base path') .option('--timeout', 'Milliseconds to wait for a page (--no-timeout to disable)', 5000) .option('--legacy', 'Create separate legacy build') .option('--bundler', 'Specify a bundler (rollup or webpack, blank for auto)') - .action(async (dest = 'export', opts: { + .action(async (dest = '__sapper__/export', opts: { build: boolean, legacy: boolean, bundler?: string, diff --git a/src/config.ts b/src/config.ts index 37074a4..6ee9941 100644 --- a/src/config.ts +++ b/src/config.ts @@ -7,5 +7,5 @@ export const locations = { src: () => path.resolve(process.env.SAPPER_BASE || '', process.env.SAPPER_SRC || 'src'), static: () => path.resolve(process.env.SAPPER_BASE || '', process.env.SAPPER_STATIC || 'static'), routes: () => path.resolve(process.env.SAPPER_BASE || '', process.env.SAPPER_ROUTES || 'src/routes'), - dest: () => path.resolve(process.env.SAPPER_BASE || '', process.env.SAPPER_DEST || `.sapper/${dev() ? 'dev' : 'prod'}`) + dest: () => path.resolve(process.env.SAPPER_BASE || '', process.env.SAPPER_DEST || `__sapper__/${dev() ? 'dev' : 'build'}`) }; \ No newline at end of file diff --git a/src/core/create_manifests.ts b/src/core/create_manifests.ts index c7c52d1..f3d9441 100644 --- a/src/core/create_manifests.ts +++ b/src/core/create_manifests.ts @@ -10,7 +10,7 @@ export function create_main_manifests({ bundler, manifest_data, dev_port }: { manifest_data: ManifestData; dev_port?: number; }) { - const manifest_dir = path.join(locations.src(), 'manifest'); + const manifest_dir = '__sapper__'; if (!fs.existsSync(manifest_dir)) fs.mkdirSync(manifest_dir); const path_to_routes = path.relative(manifest_dir, locations.routes()); @@ -55,7 +55,7 @@ export function create_serviceworker_manifest({ manifest_data, client_files }: { export const routes = [\n\t${manifest_data.pages.map((r: Page) => `{ pattern: ${r.pattern} }`).join(',\n\t')}\n]; `.replace(/^\t\t/gm, '').trim(); - write_if_changed(`${locations.src()}/manifest/service-worker.js`, code); + write_if_changed(`__sapper__/service-worker.js`, code); } function generate_client( @@ -64,92 +64,100 @@ function generate_client( bundler: string, dev_port?: number ) { + const template_file = path.resolve(__dirname, '../templates/dist/client.js'); + const template = fs.readFileSync(template_file, 'utf-8'); + const page_ids = new Set(manifest_data.pages.map(page => page.pattern.toString())); const server_routes_to_ignore = manifest_data.server_routes.filter(route => !page_ids.has(route.pattern.toString())); - let code = ` - // This file is generated by Sapper — do not edit it! - import root from ${stringify(get_file(path_to_routes, manifest_data.root))}; - import error from ${stringify(posixify(`${path_to_routes}/_error.html`))}; + const component_indexes: Record = {}; - const d = decodeURIComponent; - - ${manifest_data.components.map(component => { + const components = `[ + ${manifest_data.components.map((component, i) => { const annotation = bundler === 'webpack' ? `/* webpackChunkName: "${component.name}" */ ` : ''; const source = get_file(path_to_routes, component); - return `const ${component.name} = { + component_indexes[component.name] = i; + + return `{ js: () => import(${annotation}${stringify(source)}), css: "__SAPPER_CSS_PLACEHOLDER:${stringify(component.file, false)}__" - };`; - }).join('\n')} + }`; + }).join(',\n\t\t')} + ]`.replace(/^\t/gm, '').trim(); - export const manifest = { - ignore: [${server_routes_to_ignore.map(route => route.pattern).join(', ')}], + let needs_decode = false; - pages: [ - ${manifest_data.pages.map(page => `{ - // ${page.parts[page.parts.length - 1].component.file} - pattern: ${page.pattern}, - parts: [ - ${page.parts.map(part => { - if (part === null) return 'null'; + let pages = `[ + ${manifest_data.pages.map(page => `{ + // ${page.parts[page.parts.length - 1].component.file} + pattern: ${page.pattern}, + parts: [ + ${page.parts.map(part => { + if (part === null) return 'null'; - if (part.params.length > 0) { - const props = part.params.map((param, i) => `${param}: d(match[${i + 1}])`); - return `{ component: ${part.component.name}, params: match => ({ ${props.join(', ')} }) }`; - } + if (part.params.length > 0) { + needs_decode = true; + const props = part.params.map((param, i) => `${param}: d(match[${i + 1}])`); + return `{ i: ${component_indexes[part.component.name]}, params: match => ({ ${props.join(', ')} }) }`; + } - return `{ component: ${part.component.name} }`; - }).join(',\n\t\t\t\t\t\t')} - ] - }`).join(',\n\n\t\t\t\t')} - ], + return `{ i: ${component_indexes[part.component.name]} }`; + }).join(',\n\t\t\t\t')} + ] + }`).join(',\n\n\t\t')} + ]`.replace(/^\t/gm, '').trim(); - root, + if (needs_decode) { + pages = `(d => ${pages})(decodeURIComponent)` + } - error - }; - - // this is included for legacy reasons - export const routes = {};`.replace(/^\t\t/gm, '').trim(); + let footer = ''; if (dev()) { const sapper_dev_client = posixify( path.resolve(__dirname, '../sapper-dev-client.js') ); - code += ` + footer = ` import(${stringify(sapper_dev_client)}).then(client => { client.connect(${dev_port}); });`.replace(/^\t{3}/gm, ''); } - return code; + return `// This file is generated by Sapper — do not edit it!\n` + template + .replace('__ROOT__', stringify(get_file(path_to_routes, manifest_data.root), false)) + .replace('__ERROR__', stringify(posixify(`${path_to_routes}/_error.html`), false)) + .replace('__IGNORE__', `[${server_routes_to_ignore.map(route => route.pattern).join(', ')}]`) + .replace('__COMPONENTS__', components) + .replace('__PAGES__', pages) + + footer; } function generate_server( manifest_data: ManifestData, path_to_routes: string ) { + const template_file = path.resolve(__dirname, '../templates/dist/server.js'); + const template = fs.readFileSync(template_file, 'utf-8'); + const imports = [].concat( manifest_data.server_routes.map(route => - `import * as ${route.name} from ${stringify(posixify(`${path_to_routes}/${route.file}`))};`), + `import * as __${route.name} from ${stringify(posixify(`${path_to_routes}/${route.file}`))};`), manifest_data.components.map(component => - `import ${component.name} from ${stringify(get_file(path_to_routes, component))};`), + `import __${component.name} from ${stringify(get_file(path_to_routes, component))};`), `import root from ${stringify(get_file(path_to_routes, manifest_data.root))};`, `import error from ${stringify(posixify(`${path_to_routes}/_error.html`))};` ); let code = ` - // This file is generated by Sapper — do not edit it! ${imports.join('\n')} const d = decodeURIComponent; @@ -159,7 +167,7 @@ function generate_server( ${manifest_data.server_routes.map(route => `{ // ${route.file} pattern: ${route.pattern}, - handlers: ${route.name}, + handlers: __${route.name}, params: ${route.params.length > 0 ? `match => ({ ${route.params.map((param, i) => `${param}: d(match[${i + 1}])`).join(', ')} })` : `() => ({})`} @@ -177,7 +185,7 @@ function generate_server( const props = [ `name: "${part.component.name}"`, `file: ${stringify(part.component.file)}`, - `component: ${part.component.name}` + `component: __${part.component.name}` ]; if (part.params.length > 0) { @@ -194,12 +202,13 @@ function generate_server( root, error - }; + };`.replace(/^\t\t/gm, '').trim(); - // this is included for legacy reasons - export const routes = {};`.replace(/^\t\t/gm, '').trim(); - - return code; + return `// This file is generated by Sapper — do not edit it!\n` + template + .replace('__BUILD__DIR__', JSON.stringify(locations.dest())) + .replace('__SRC__DIR__', JSON.stringify(locations.src())) + .replace('__DEV__', dev() ? 'true' : 'false') + .replace(/const manifest = __MANIFEST__;/, code); } function get_file(path_to_routes: string, component: PageComponent) { diff --git a/src/runtime/index.ts b/src/runtime/index.ts deleted file mode 100644 index 9e07bad..0000000 --- a/src/runtime/index.ts +++ /dev/null @@ -1,504 +0,0 @@ -import { detach, findAnchor, scroll_state, which } from './utils'; -import { Component, ComponentConstructor, Params, Query, Redirect, Manifest, RouteData, ScrollPosition, Store, Target, ComponentLoader } from './interfaces'; - -const initial_data = typeof window !== 'undefined' && window.__SAPPER__; - -export let root: Component; -let target: Node; -let store: Store; -let manifest: Manifest; -let segments: string[] = []; - -type RootProps = { - path: string; - params: Record; - query: Record; - child: Child; -}; - -type Child = { - segment?: string; - props?: any; - component?: Component; -}; - -const root_props: RootProps = { - path: null, - params: null, - query: null, - child: { - segment: null, - component: null, - props: {} - } -}; - -export { root as component }; // legacy reasons — drop in a future version - -const history = typeof window !== 'undefined' ? window.history : { - pushState: (state: any, title: string, href: string) => {}, - replaceState: (state: any, title: string, href: string) => {}, - scrollRestoration: '' -}; - -const scroll_history: Record = {}; -let uid = 1; -let cid: number; - -if ('scrollRestoration' in history) { - history.scrollRestoration = 'manual'; -} - -function select_route(url: URL): Target { - if (url.origin !== window.location.origin) return null; - if (!url.pathname.startsWith(initial_data.baseUrl)) return null; - - const path = url.pathname.slice(initial_data.baseUrl.length); - - // avoid accidental clashes between server routes and pages - if (manifest.ignore.some(pattern => pattern.test(path))) return; - - for (let i = 0; i < manifest.pages.length; i += 1) { - const page = manifest.pages[i]; - - const match = page.pattern.exec(path); - if (match) { - const query: Record = {}; - if (url.search.length > 0) { - url.search.slice(1).split('&').forEach(searchParam => { - const [, key, value] = /([^=]+)(?:=(.*))?/.exec(searchParam); - query[key] = decodeURIComponent((value || '').replace(/\+/g, ' ')); - }); - } - return { url, path, page, match, query }; - } - } -} - -let current_token: {}; - -function render(data: any, nullable_depth: number, scroll: ScrollPosition, token: {}) { - if (current_token !== token) return; - - if (root) { - // first, clear out highest-level root component - let level = data.child; - for (let i = 0; i < nullable_depth; i += 1) { - if (i === nullable_depth) break; - level = level.props.child; - } - - const { component } = level; - level.component = null; - root.set({ child: data.child }); - - // then render new stuff - level.component = component; - root.set(data); - } else { - // first load — remove SSR'd contents - const start = document.querySelector('#sapper-head-start'); - const end = document.querySelector('#sapper-head-end'); - - if (start && end) { - while (start.nextSibling !== end) detach(start.nextSibling); - detach(start); - detach(end); - } - - Object.assign(data, root_data); - - root = new manifest.root({ - target, - data, - store, - hydrate: true - }); - } - - if (scroll) { - window.scrollTo(scroll.x, scroll.y); - } - - Object.assign(root_props, data); - ready = true; -} - -function changed(a: Record, b: Record) { - return JSON.stringify(a) !== JSON.stringify(b); -} - -let root_preload: Promise; -let root_data: any; - -function load_css(chunk: string) { - const href = `${initial_data.baseUrl}client/${chunk}`; - if (document.querySelector(`link[href="${href}"]`)) return; - - return new Promise((fulfil, reject) => { - const link = document.createElement('link'); - link.rel = 'stylesheet'; - link.href = href; - - link.onload = () => fulfil(); - link.onerror = reject; - - document.head.appendChild(link); - }); -} - -function load_component(component: ComponentLoader): Promise { - // TODO this is temporary — once placeholders are - // always rewritten, scratch the ternary - const promises: Array> = (typeof component.css === 'string' ? [] : component.css.map(load_css)); - promises.unshift(component.js()); - return Promise.all(promises).then(values => values[0].default); -} - -function prepare_page(target: Target): Promise<{ - redirect?: Redirect; - data?: any; - nullable_depth?: number; -}> { - const { page, path, query } = target; - const new_segments = path.split('/').filter(Boolean); - let changed_from = 0; - - while ( - segments[changed_from] && - new_segments[changed_from] && - segments[changed_from] === new_segments[changed_from] - ) changed_from += 1; - - let redirect: Redirect = null; - let error: { statusCode: number, message: Error | string } = null; - - const preload_context = { - store, - fetch: (url: string, opts?: any) => window.fetch(url, opts), - redirect: (statusCode: number, location: string) => { - if (redirect && (redirect.statusCode !== statusCode || redirect.location !== location)) { - throw new Error(`Conflicting redirects`); - } - redirect = { statusCode, location }; - }, - error: (statusCode: number, message: Error | string) => { - error = { statusCode, message }; - } - }; - - if (!root_preload) { - root_preload = manifest.root.preload - ? initial_data.preloaded[0] || manifest.root.preload.call(preload_context, { - path, - query, - params: {} - }) - : {}; - } - - return Promise.all(page.parts.map(async (part, i) => { - if (i < changed_from) return null; - if (!part) return null; - - const Component = await load_component(part.component); - - const req = { - path, - query, - params: part.params ? part.params(target.match) : {} - }; - - const preloaded = ready || !initial_data.preloaded[i + 1] - ? Component.preload ? await Component.preload.call(preload_context, req) : {} - : initial_data.preloaded[i + 1]; - - return { Component, preloaded }; - })).catch(err => { - error = { statusCode: 500, message: err }; - return []; - }).then(async results => { - if (!root_data) root_data = await root_preload; - - if (redirect) { - return { redirect }; - } - - segments = new_segments; - - const get_params = page.parts[page.parts.length - 1].params || (() => ({})); - const params = get_params(target.match); - - if (error) { - const props = { - path, - query, - params, - error: typeof error.message === 'string' ? new Error(error.message) : error.message, - status: error.statusCode - }; - - return { - data: Object.assign({}, props, { - preloading: false, - child: { - component: manifest.error, - props - } - }) - }; - } - - const props = { path, query }; - const data = { - path, - preloading: false, - child: Object.assign({}, root_props.child, { - segment: segments[0] - }) - }; - if (changed(query, root_props.query)) data.query = query; - if (changed(params, root_props.params)) data.params = params; - - let level = data.child; - let nullable_depth = 0; - - for (let i = 0; i < page.parts.length; i += 1) { - const part = page.parts[i]; - if (!part) continue; - - const get_params = part.params || (() => ({})); - - if (i < changed_from) { - level.props.path = path; - level.props.query = query; - level.props.child = Object.assign({}, level.props.child); - - nullable_depth += 1; - } else { - level.component = results[i].Component; - level.props = Object.assign({}, level.props, props, { - params: get_params(target.match), - }, results[i].preloaded); - - level.props.child = {}; - } - - level = level.props.child; - level.segment = segments[i + 1]; - } - - return { data, nullable_depth }; - }); -} - -async function navigate(target: Target, id: number): Promise { - if (id) { - // popstate or initial navigation - cid = id; - } else { - // clicked on a link. preserve scroll state - scroll_history[cid] = scroll_state(); - - id = cid = ++uid; - scroll_history[cid] = { x: 0, y: 0 }; - } - - cid = id; - - if (root) { - root.set({ preloading: true }); - } - const loaded = prefetching && prefetching.href === target.url.href ? - prefetching.promise : - prepare_page(target); - - prefetching = null; - - const token = current_token = {}; - const { redirect, data, nullable_depth } = await loaded; - - if (redirect) { - await goto(redirect.location, { replaceState: true }); - } else { - render(data, nullable_depth, scroll_history[id], token); - if (document.activeElement) document.activeElement.blur(); - } -} - -function handle_click(event: MouseEvent) { - // Adapted from https://github.com/visionmedia/page.js - // MIT license https://github.com/visionmedia/page.js#license - if (which(event) !== 1) return; - if (event.metaKey || event.ctrlKey || event.shiftKey) return; - if (event.defaultPrevented) return; - - const a: HTMLAnchorElement | SVGAElement = findAnchor(event.target); - if (!a) return; - - if (!a.href) return; - - // check if link is inside an svg - // in this case, both href and target are always inside an object - const svg = typeof a.href === 'object' && a.href.constructor.name === 'SVGAnimatedString'; - const href = String(svg ? (a).href.baseVal : a.href); - - if (href === window.location.href) { - event.preventDefault(); - return; - } - - // Ignore if tag has - // 1. 'download' attribute - // 2. rel='external' attribute - if (a.hasAttribute('download') || a.getAttribute('rel') === 'external') return; - - // Ignore if has a target - if (svg ? (a).target.baseVal : a.target) return; - - const url = new URL(href); - - // Don't handle hash changes - if (url.pathname === window.location.pathname && url.search === window.location.search) return; - - const target = select_route(url); - if (target) { - navigate(target, null); - event.preventDefault(); - history.pushState({ id: cid }, '', url.href); - } -} - -function handle_popstate(event: PopStateEvent) { - scroll_history[cid] = scroll_state(); - - if (event.state) { - const url = new URL(window.location.href); - const target = select_route(url); - if (target) { - navigate(target, event.state.id); - } else { - window.location.href = window.location.href; - } - } else { - // hashchange - cid = ++uid; - history.replaceState({ id: cid }, '', window.location.href); - } -} - -let prefetching: { - href: string; - promise: Promise<{ redirect?: Redirect, data?: any, nullable_depth?: number }>; -} = null; - -export function prefetch(href: string) { - const target: Target = select_route(new URL(href, document.baseURI)); - - if (target && (!prefetching || href !== prefetching.href)) { - prefetching = { - href, - promise: prepare_page(target) - }; - } -} - -let mousemove_timeout: NodeJS.Timer; - -function handle_mousemove(event: MouseEvent) { - clearTimeout(mousemove_timeout); - mousemove_timeout = setTimeout(() => { - trigger_prefetch(event); - }, 20); -} - -function trigger_prefetch(event: MouseEvent | TouchEvent) { - const a: HTMLAnchorElement = findAnchor(event.target); - if (!a || a.rel !== 'prefetch') return; - - prefetch(a.href); -} - -let inited: boolean; -let ready = false; - -export function init(opts: { - App: ComponentConstructor, - target: Node, - manifest: Manifest, - store?: (data: any) => Store, - routes?: any // legacy -}) { - if (opts instanceof HTMLElement) { - throw new Error(`The signature of init(...) has changed — see https://sapper.svelte.technology/guide#0-11-to-0-12 for more information`); - } - - if (opts.routes) { - throw new Error(`As of Sapper 0.15, opts.routes should be opts.manifest`); - } - - target = opts.target; - manifest = opts.manifest; - - if (opts && opts.store) { - store = opts.store(initial_data.store); - } - - if (!inited) { // this check makes HMR possible - window.addEventListener('click', handle_click); - window.addEventListener('popstate', handle_popstate); - - // prefetch - window.addEventListener('touchstart', trigger_prefetch); - window.addEventListener('mousemove', handle_mousemove); - - inited = true; - } - - return Promise.resolve().then(() => { - const { hash, href } = window.location; - - const deep_linked = hash && document.getElementById(hash.slice(1)); - scroll_history[uid] = deep_linked ? - { x: 0, y: deep_linked.getBoundingClientRect().top } : - scroll_state(); - - history.replaceState({ id: uid }, '', href); - - if (!initial_data.error) { - const target = select_route(new URL(window.location.href)); - if (target) return navigate(target, uid); - } - }); -} - -export function goto(href: string, opts = { replaceState: false }) { - const target = select_route(new URL(href, document.baseURI)); - let promise; - - if (target) { - promise = navigate(target, null); - if (history) history[opts.replaceState ? 'replaceState' : 'pushState']({ id: cid }, '', href); - } else { - window.location.href = href; - promise = new Promise(f => {}); // never resolves - } - - return promise; -} - -export function prefetchRoutes(pathnames: string[]) { - if (!manifest) throw new Error(`You must call init() first`); - - return manifest.pages - .filter(route => { - if (!pathnames) return true; - return pathnames.some(pathname => route.pattern.test(pathname)); - }) - .reduce((promise: Promise, route) => promise.then(() => { - return Promise.all(route.parts.map(part => part && load_component(part.component))); - }), Promise.resolve()); -} - -// remove this in 0.9 -export { prefetchRoutes as preloadRoutes }; \ No newline at end of file diff --git a/src/runtime/utils.ts b/src/runtime/utils.ts deleted file mode 100644 index cec5f69..0000000 --- a/src/runtime/utils.ts +++ /dev/null @@ -1,19 +0,0 @@ -export function detach(node: Node) { - node.parentNode.removeChild(node); -} - -export function findAnchor(node: Node) { - while (node && node.nodeName.toUpperCase() !== 'A') node = node.parentNode; // SVG elements have a lowercase name - return node; -} - -export function which(event: MouseEvent) { - return event.which === null ? event.button : event.which; -} - -export function scroll_state() { - return { - x: window.scrollX, - y: window.scrollY - }; -} \ No newline at end of file diff --git a/templates/src/client/app.ts b/templates/src/client/app.ts new file mode 100644 index 0000000..9456a63 --- /dev/null +++ b/templates/src/client/app.ts @@ -0,0 +1,372 @@ +import RootComponent from '__ROOT__'; +import ErrorComponent from '__ERROR__'; +import { + Target, + ScrollPosition, + Component, + Redirect, + ComponentLoader, + ComponentConstructor, + RootProps, + Page +} from './types'; +import goto from './goto'; + +const ignore = __IGNORE__; +export const components: ComponentLoader[] = __COMPONENTS__; +export const pages: Page[] = __PAGES__; + +let ready = false; +let root_component: Component; +let segments: string[] = []; +let current_token: {}; +let root_preload: Promise; +let root_data: any; + +const root_props: RootProps = { + path: null, + params: null, + query: null, + child: { + segment: null, + component: null, + props: {} + } +}; + +export let prefetching: { + href: string; + promise: Promise<{ redirect?: Redirect, data?: any, nullable_depth?: number }>; +} = null; +export function set_prefetching(href, promise) { + prefetching = { href, promise }; +} + +export let store; +export function set_store(fn) { + store = fn(initial_data.store); +} + +export let target: Node; +export function set_target(element) { + target = element; +} + +export let uid = 1; +export function set_uid(n) { + uid = n; +} + +export let cid: number; +export function set_cid(n) { + cid = n; +} + +export const initial_data = typeof __SAPPER__ !== 'undefined' && __SAPPER__; + +const _history = typeof history !== 'undefined' ? history : { + pushState: (state: any, title: string, href: string) => {}, + replaceState: (state: any, title: string, href: string) => {}, + scrollRestoration: '' +}; +export { _history as history }; + +export const scroll_history: Record = {}; + +export function select_route(url: URL): Target { + if (url.origin !== location.origin) return null; + if (!url.pathname.startsWith(initial_data.baseUrl)) return null; + + const path = url.pathname.slice(initial_data.baseUrl.length); + + // avoid accidental clashes between server routes and pages + if (ignore.some(pattern => pattern.test(path))) return; + + for (let i = 0; i < pages.length; i += 1) { + const page = pages[i]; + + const match = page.pattern.exec(path); + if (match) { + const query: Record = {}; + if (url.search.length > 0) { + url.search.slice(1).split('&').forEach(searchParam => { + const [, key, value] = /([^=]+)(?:=(.*))?/.exec(searchParam); + query[key] = decodeURIComponent((value || '').replace(/\+/g, ' ')); + }); + } + return { url, path, page, match, query }; + } + } +} + +export function scroll_state() { + return { + x: scrollX, + y: scrollY + }; +} + +export function navigate(target: Target, id: number): Promise { + if (id) { + // popstate or initial navigation + cid = id; + } else { + // clicked on a link. preserve scroll state + scroll_history[cid] = scroll_state(); + + id = cid = ++uid; + scroll_history[cid] = { x: 0, y: 0 }; + } + + cid = id; + + if (root_component) { + root_component.set({ preloading: true }); + } + const loaded = prefetching && prefetching.href === target.url.href ? + prefetching.promise : + prepare_page(target); + + prefetching = null; + + const token = current_token = {}; + + return loaded.then(({ redirect, data, nullable_depth }) => { + if (redirect) { + return goto(redirect.location, { replaceState: true }); + } + + render(data, nullable_depth, scroll_history[id], token); + if (document.activeElement) document.activeElement.blur(); + }); +} + +function render(data: any, nullable_depth: number, scroll: ScrollPosition, token: {}) { + if (current_token !== token) return; + + if (root_component) { + // first, clear out highest-level root component + let level = data.child; + for (let i = 0; i < nullable_depth; i += 1) { + if (i === nullable_depth) break; + level = level.props.child; + } + + const { component } = level; + level.component = null; + root_component.set({ child: data.child }); + + // then render new stuff + level.component = component; + root_component.set(data); + } else { + // first load — remove SSR'd contents + const start = document.querySelector('#sapper-head-start'); + const end = document.querySelector('#sapper-head-end'); + + if (start && end) { + while (start.nextSibling !== end) detach(start.nextSibling); + detach(start); + detach(end); + } + + Object.assign(data, root_data); + + root_component = new RootComponent({ + target, + data, + store, + hydrate: true + }); + } + + if (scroll) { + scrollTo(scroll.x, scroll.y); + } + + Object.assign(root_props, data); + ready = true; +} + +export function prepare_page(target: Target): Promise<{ + redirect?: Redirect; + data?: any; + nullable_depth?: number; +}> { + const { page, path, query } = target; + const new_segments = path.split('/').filter(Boolean); + let changed_from = 0; + + while ( + segments[changed_from] && + new_segments[changed_from] && + segments[changed_from] === new_segments[changed_from] + ) changed_from += 1; + + let redirect: Redirect = null; + let error: { statusCode: number, message: Error | string } = null; + + const preload_context = { + store, + fetch: (url: string, opts?: any) => fetch(url, opts), + redirect: (statusCode: number, location: string) => { + if (redirect && (redirect.statusCode !== statusCode || redirect.location !== location)) { + throw new Error(`Conflicting redirects`); + } + redirect = { statusCode, location }; + }, + error: (statusCode: number, message: Error | string) => { + error = { statusCode, message }; + } + }; + + if (!root_preload) { + root_preload = RootComponent.preload + ? initial_data.preloaded[0] || RootComponent.preload.call(preload_context, { + path, + query, + params: {} + }) + : {}; + } + + return Promise.all(page.parts.map((part, i) => { + if (i < changed_from) return null; + if (!part) return null; + + return load_component(components[part.i]).then(Component => { + const req = { + path, + query, + params: part.params ? part.params(target.match) : {} + }; + + let preloaded; + if (ready || !initial_data.preloaded[i + 1]) { + preloaded = Component.preload + ? Component.preload.call(preload_context, req) + : {}; + } else { + preloaded = initial_data.preloaded[i + 1]; + } + + return Promise.resolve(preloaded).then(preloaded => { + return { Component, preloaded }; + }); + }); + })).catch(err => { + error = { statusCode: 500, message: err }; + return []; + }).then(results => { + if (root_data) { + return results; + } else { + return Promise.resolve(root_preload).then(value => { + root_data = value; + return results; + }); + } + }).then(results => { + if (redirect) { + return { redirect }; + } + + segments = new_segments; + + const get_params = page.parts[page.parts.length - 1].params || (() => ({})); + const params = get_params(target.match); + + if (error) { + const props = { + path, + query, + params, + error: typeof error.message === 'string' ? new Error(error.message) : error.message, + status: error.statusCode + }; + + return { + data: Object.assign({}, props, { + preloading: false, + child: { + component: ErrorComponent, + props + } + }) + }; + } + + const props = { path, query }; + const data = { + path, + preloading: false, + child: Object.assign({}, root_props.child, { + segment: segments[0] + }) + }; + if (changed(query, root_props.query)) data.query = query; + if (changed(params, root_props.params)) data.params = params; + + let level = data.child; + let nullable_depth = 0; + + for (let i = 0; i < page.parts.length; i += 1) { + const part = page.parts[i]; + if (!part) continue; + + const get_params = part.params || (() => ({})); + + if (i < changed_from) { + level.props.path = path; + level.props.query = query; + level.props.child = Object.assign({}, level.props.child); + + nullable_depth += 1; + } else { + level.component = results[i].Component; + level.props = Object.assign({}, level.props, props, { + params: get_params(target.match), + }, results[i].preloaded); + + level.props.child = {}; + } + + level = level.props.child; + level.segment = segments[i + 1]; + } + + return { data, nullable_depth }; + }); +} + +function load_css(chunk: string) { + const href = `${initial_data.baseUrl}client/${chunk}`; + if (document.querySelector(`link[href="${href}"]`)) return; + + return new Promise((fulfil, reject) => { + const link = document.createElement('link'); + link.rel = 'stylesheet'; + link.href = href; + + link.onload = () => fulfil(); + link.onerror = reject; + + document.head.appendChild(link); + }); +} + +export function load_component(component: ComponentLoader): Promise { + // TODO this is temporary — once placeholders are + // always rewritten, scratch the ternary + const promises: Array> = (typeof component.css === 'string' ? [] : component.css.map(load_css)); + promises.unshift(component.js()); + return Promise.all(promises).then(values => values[0].default); +} + +function detach(node: Node) { + node.parentNode.removeChild(node); +} + +function changed(a: Record, b: Record) { + return JSON.stringify(a) !== JSON.stringify(b); +} \ No newline at end of file diff --git a/templates/src/client/goto/index.ts b/templates/src/client/goto/index.ts new file mode 100644 index 0000000..29757ed --- /dev/null +++ b/templates/src/client/goto/index.ts @@ -0,0 +1,13 @@ +import { history, select_route, navigate, cid } from '../app'; + +export default function goto(href: string, opts = { replaceState: false }) { + const target = select_route(new URL(href, document.baseURI)); + + if (target) { + history[opts.replaceState ? 'replaceState' : 'pushState']({ id: cid }, '', href); + return navigate(target, null).then(() => {}); + } + + location.href = href; + return new Promise(f => {}); // never resolves +} \ No newline at end of file diff --git a/templates/src/client/index.ts b/templates/src/client/index.ts new file mode 100644 index 0000000..f171109 --- /dev/null +++ b/templates/src/client/index.ts @@ -0,0 +1,4 @@ +export { default as start } from './start/index'; +export { default as goto } from './goto/index'; +export { default as prefetch } from './prefetch/index'; +export { default as prefetchRoutes } from './prefetchRoutes/index'; \ No newline at end of file diff --git a/templates/src/client/prefetch/index.ts b/templates/src/client/prefetch/index.ts new file mode 100644 index 0000000..4b601d2 --- /dev/null +++ b/templates/src/client/prefetch/index.ts @@ -0,0 +1,10 @@ +import { select_route, prefetching, set_prefetching, prepare_page } from '../app'; +import { Target } from '../types'; + +export default function prefetch(href: string) { + const target: Target = select_route(new URL(href, document.baseURI)); + + if (target && (!prefetching || href !== prefetching.href)) { + set_prefetching(href, prepare_page(target)); + } +} \ No newline at end of file diff --git a/templates/src/client/prefetchRoutes/index.ts b/templates/src/client/prefetchRoutes/index.ts new file mode 100644 index 0000000..b3c2f3c --- /dev/null +++ b/templates/src/client/prefetchRoutes/index.ts @@ -0,0 +1,12 @@ +import { components, pages, load_component } from "../app"; + +export default function prefetchRoutes(pathnames: string[]) { + return pages + .filter(route => { + if (!pathnames) return true; + return pathnames.some(pathname => route.pattern.test(pathname)); + }) + .reduce((promise: Promise, route) => promise.then(() => { + return Promise.all(route.parts.map(part => part && load_component(components[part.i]))); + }), Promise.resolve()); +} \ No newline at end of file diff --git a/templates/src/client/start/index.ts b/templates/src/client/start/index.ts new file mode 100644 index 0000000..240fdd8 --- /dev/null +++ b/templates/src/client/start/index.ts @@ -0,0 +1,138 @@ +import { + cid, + history, + initial_data, + navigate, + scroll_history, + scroll_state, + select_route, + set_store, + set_target, + uid, + set_uid, + set_cid +} from '../app'; +import prefetch from '../prefetch/index'; +import { Store } from '../types'; + +export default function start(opts: { + target: Node, + store?: (data: any) => Store +}) { + if ('scrollRestoration' in history) { + history.scrollRestoration = 'manual'; + } + + set_target(opts.target); + if (opts.store) set_store(opts.store); + + addEventListener('click', handle_click); + addEventListener('popstate', handle_popstate); + + // prefetch + addEventListener('touchstart', trigger_prefetch); + addEventListener('mousemove', handle_mousemove); + + return Promise.resolve().then(() => { + const { hash, href } = location; + + const deep_linked = hash && document.getElementById(hash.slice(1)); + scroll_history[uid] = deep_linked ? + { x: 0, y: deep_linked.getBoundingClientRect().top } : + scroll_state(); + + history.replaceState({ id: uid }, '', href); + + if (!initial_data.error) { + const target = select_route(new URL(location.href)); + if (target) return navigate(target, uid); + } + }); +} + +let mousemove_timeout: NodeJS.Timer; + +function handle_mousemove(event: MouseEvent) { + clearTimeout(mousemove_timeout); + mousemove_timeout = setTimeout(() => { + trigger_prefetch(event); + }, 20); +} + +function trigger_prefetch(event: MouseEvent | TouchEvent) { + const a: HTMLAnchorElement = find_anchor(event.target); + if (!a || a.rel !== 'prefetch') return; + + prefetch(a.href); +} + +function handle_click(event: MouseEvent) { + // Adapted from https://github.com/visionmedia/page.js + // MIT license https://github.com/visionmedia/page.js#license + if (which(event) !== 1) return; + if (event.metaKey || event.ctrlKey || event.shiftKey) return; + if (event.defaultPrevented) return; + + const a: HTMLAnchorElement | SVGAElement = find_anchor(event.target); + if (!a) return; + + if (!a.href) return; + + // check if link is inside an svg + // in this case, both href and target are always inside an object + const svg = typeof a.href === 'object' && a.href.constructor.name === 'SVGAnimatedString'; + const href = String(svg ? (a).href.baseVal : a.href); + + if (href === location.href) { + event.preventDefault(); + return; + } + + // Ignore if tag has + // 1. 'download' attribute + // 2. rel='external' attribute + if (a.hasAttribute('download') || a.getAttribute('rel') === 'external') return; + + // Ignore if has a target + if (svg ? (a).target.baseVal : a.target) return; + + const url = new URL(href); + + // Don't handle hash changes + if (url.pathname === location.pathname && url.search === location.search) return; + + const target = select_route(url); + if (target) { + navigate(target, null); + event.preventDefault(); + history.pushState({ id: cid }, '', url.href); + } +} + +function which(event: MouseEvent) { + return event.which === null ? event.button : event.which; +} + +function find_anchor(node: Node) { + while (node && node.nodeName.toUpperCase() !== 'A') node = node.parentNode; // SVG elements have a lowercase name + return node; +} + +function handle_popstate(event: PopStateEvent) { + scroll_history[cid] = scroll_state(); + + if (event.state) { + const url = new URL(location.href); + const target = select_route(url); + if (target) { + navigate(target, event.state.id); + } else { + location.href = location.href; + } + } else { + // hashchange + set_uid(uid + 1); + set_cid(uid); + history.replaceState({ id: cid }, '', location.href); + } +} \ No newline at end of file diff --git a/src/runtime/interfaces.ts b/templates/src/client/types.ts similarity index 80% rename from src/runtime/interfaces.ts rename to templates/src/client/types.ts index 457d667..08e7a04 100644 --- a/src/runtime/interfaces.ts +++ b/templates/src/client/types.ts @@ -1,10 +1,20 @@ -import { Store } from '../interfaces'; - -export { Store }; export type Params = Record; export type Query = Record; export type RouteData = { params: Params, query: Query, path: string }; +type Child = { + segment?: string; + props?: any; + component?: Component; +}; + +export type RootProps = { + path: string; + params: Record; + query: Record; + child: Child; +}; + export interface ComponentConstructor { new (options: { target: Node, data: any, store: Store, hydrate: boolean }): Component; preload: (props: { params: Params, query: Query }) => Promise; @@ -23,7 +33,7 @@ export type ComponentLoader = { export type Page = { pattern: RegExp; parts: Array<{ - component: ComponentLoader; + i: number; params?: (match: RegExpExecArray) => Record; }>; }; @@ -51,4 +61,8 @@ export type Target = { export type Redirect = { statusCode: number; location: string; -}; \ No newline at end of file +}; + +export type Store = { + get: () => any; +} \ No newline at end of file diff --git a/templates/src/server/index.ts b/templates/src/server/index.ts new file mode 100644 index 0000000..f6706ca --- /dev/null +++ b/templates/src/server/index.ts @@ -0,0 +1 @@ +export { default as middleware } from './middleware/index'; \ No newline at end of file diff --git a/src/middleware.ts b/templates/src/server/middleware/get_page_handler.ts similarity index 52% rename from src/middleware.ts rename to templates/src/server/middleware/get_page_handler.ts index 582d423..654e4b8 100644 --- a/src/middleware.ts +++ b/templates/src/server/middleware/get_page_handler.ts @@ -1,301 +1,30 @@ import * as fs from 'fs'; import * as path from 'path'; -import { URL } from 'url'; -import { ClientRequest, ServerResponse } from 'http'; import cookie from 'cookie'; import devalue from 'devalue'; import fetch from 'node-fetch'; -import { lookup } from './middleware/mime'; -import { locations, dev } from './config'; -import sourceMapSupport from 'source-map-support'; -import read_template from './core/read_template'; +import { URL } from 'url'; +import { build_dir, dev, src_dir, IGNORE } from '../placeholders'; +import { Manifest, Page, Props, Req, Res, Store } from './types'; -sourceMapSupport.install(); - -type ServerRoute = { - pattern: RegExp; - handlers: Record; - params: (match: RegExpMatchArray) => Record; -}; - -type Page = { - pattern: RegExp; - parts: Array<{ - name: string; - component: Component; - params?: (match: RegExpMatchArray) => Record; - }> -}; - -type Manifest = { - server_routes: ServerRoute[]; - pages: Page[]; - root: Component; - error: Component; -} - -type Handler = (req: Req, res: ServerResponse, next: () => void) => void; - -type Store = { - get: () => any -}; - -type Props = { - path: string; - query: Record; - params: Record; - error?: { message: string }; - status?: number; - child: { - segment: string; - component: Component; - props: Props; - }; - [key: string]: any; -}; - -interface Req extends ClientRequest { - url: string; - baseUrl: string; - originalUrl: string; - method: string; - path: string; - params: Record; - query: Record; - headers: Record; -} - -interface Component { - render: (data: any, opts: { store: Store }) => { - head: string; - css: { code: string, map: any }; - html: string - }, - preload: (data: any) => any | Promise -} - -const IGNORE = '__SAPPER__IGNORE__'; -function toIgnore(uri: string, val: any) { - if (Array.isArray(val)) return val.some(x => toIgnore(uri, x)); - if (val instanceof RegExp) return val.test(uri); - if (typeof val === 'function') return val(uri); - return uri.startsWith(val.charCodeAt(0) === 47 ? val : `/${val}`); -} - -export default function middleware(opts: { +export function get_page_handler( manifest: Manifest, - store: (req: Req, res: ServerResponse) => Store, - ignore?: any, - routes?: any // legacy -}) { - if (opts.routes) { - throw new Error(`As of Sapper 0.15, opts.routes should be opts.manifest`); - } - - const output = locations.dest(); - - const { manifest, store, ignore } = opts; - - let emitted_basepath = false; - - const middleware = compose_handlers([ - ignore && ((req: Req, res: ServerResponse, next: () => void) => { - req[IGNORE] = toIgnore(req.path, ignore); - next(); - }), - - (req: Req, res: ServerResponse, next: () => void) => { - if (req[IGNORE]) return next(); - - if (req.baseUrl === undefined) { - let { originalUrl } = req; - if (req.url === '/' && originalUrl[originalUrl.length - 1] !== '/') { - originalUrl += '/'; - } - - req.baseUrl = originalUrl - ? originalUrl.slice(0, -req.url.length) - : ''; - } - - if (!emitted_basepath && process.send) { - process.send({ - __sapper__: true, - event: 'basepath', - basepath: req.baseUrl - }); - - emitted_basepath = true; - } - - if (req.path === undefined) { - req.path = req.url.replace(/\?.*/, ''); - } - - next(); - }, - - fs.existsSync(path.join(output, 'index.html')) && serve({ - pathname: '/index.html', - cache_control: dev() ? 'no-cache' : 'max-age=600' - }), - - fs.existsSync(path.join(output, 'service-worker.js')) && serve({ - pathname: '/service-worker.js', - cache_control: 'no-cache, no-store, must-revalidate' - }), - - fs.existsSync(path.join(output, 'service-worker.js.map')) && serve({ - pathname: '/service-worker.js.map', - cache_control: 'no-cache, no-store, must-revalidate' - }), - - serve({ - prefix: '/client/', - cache_control: dev() ? 'no-cache' : 'max-age=31536000, immutable' - }), - - get_server_route_handler(manifest.server_routes), - get_page_handler(manifest, store) - ].filter(Boolean)); - - return middleware; -} - -function serve({ prefix, pathname, cache_control }: { - prefix?: string, - pathname?: string, - cache_control: string -}) { - const filter = pathname - ? (req: Req) => req.path === pathname - : (req: Req) => req.path.startsWith(prefix); - - const output = locations.dest(); - - const cache: Map = new Map(); - - const read = dev() - ? (file: string) => fs.readFileSync(path.resolve(output, file)) - : (file: string) => (cache.has(file) ? cache : cache.set(file, fs.readFileSync(path.resolve(output, file)))).get(file) - - return (req: Req, res: ServerResponse, next: () => void) => { - if (req[IGNORE]) return next(); - - if (filter(req)) { - const type = lookup(req.path); - - try { - const file = decodeURIComponent(req.path.slice(1)); - const data = read(file); - - res.setHeader('Content-Type', type); - res.setHeader('Cache-Control', cache_control); - res.end(data); - } catch (err) { - res.statusCode = 404; - res.end('not found'); - } - } else { - next(); - } - }; -} - -function get_server_route_handler(routes: ServerRoute[]) { - function handle_route(route: ServerRoute, req: Req, res: ServerResponse, next: () => void) { - req.params = route.params(route.pattern.exec(req.path)); - - const method = req.method.toLowerCase(); - // 'delete' cannot be exported from a module because it is a keyword, - // so check for 'del' instead - const method_export = method === 'delete' ? 'del' : method; - const handle_method = route.handlers[method_export]; - if (handle_method) { - if (process.env.SAPPER_EXPORT) { - const { write, end, setHeader } = res; - const chunks: any[] = []; - const headers: Record = {}; - - // intercept data so that it can be exported - res.write = function(chunk: any) { - chunks.push(Buffer.from(chunk)); - write.apply(res, arguments); - }; - - res.setHeader = function(name: string, value: string) { - headers[name.toLowerCase()] = value; - setHeader.apply(res, arguments); - }; - - res.end = function(chunk?: any) { - if (chunk) chunks.push(Buffer.from(chunk)); - end.apply(res, arguments); - - process.send({ - __sapper__: true, - event: 'file', - url: req.url, - method: req.method, - status: res.statusCode, - type: headers['content-type'], - body: Buffer.concat(chunks).toString() - }); - }; - } - - const handle_next = (err?: Error) => { - if (err) { - res.statusCode = 500; - res.end(err.message); - } else { - process.nextTick(next); - } - }; - - try { - handle_method(req, res, handle_next); - } catch (err) { - handle_next(err); - } - } else { - // no matching handler for method - process.nextTick(next); - } - } - - return function find_route(req: Req, res: ServerResponse, next: () => void) { - if (req[IGNORE]) return next(); - - for (const route of routes) { - if (route.pattern.test(req.path)) { - handle_route(route, req, res, next); - return; - } - } - - next(); - }; -} - -function get_page_handler( - manifest: Manifest, - store_getter: (req: Req, res: ServerResponse) => Store + store_getter: (req: Req, res: Res) => Store ) { - const output = locations.dest(); + const get_build_info = dev + ? () => JSON.parse(fs.readFileSync(path.join(build_dir, 'build.json'), 'utf-8')) + : (assets => () => assets)(JSON.parse(fs.readFileSync(path.join(build_dir, 'build.json'), 'utf-8'))); - const get_build_info = dev() - ? () => JSON.parse(fs.readFileSync(path.join(output, 'build.json'), 'utf-8')) - : (assets => () => assets)(JSON.parse(fs.readFileSync(path.join(output, 'build.json'), 'utf-8'))); + const template = dev + ? () => read_template(src_dir) + : (str => () => str)(read_template(build_dir)); - const template = dev() - ? () => read_template() - : (str => () => str)(read_template(output)); + const has_service_worker = fs.existsSync(path.join(build_dir, 'service-worker.js')); const { server_routes, pages } = manifest; const error_route = manifest.error; - function handle_error(req: Req, res: ServerResponse, statusCode: number, error: Error | string) { + function handle_error(req: Req, res: Res, statusCode: number, error: Error | string) { handle_page({ pattern: null, parts: [ @@ -304,7 +33,7 @@ function get_page_handler( }, req, res, statusCode, error || new Error('Unknown error in preload function')); } - function handle_page(page: Page, req: Req, res: ServerResponse, status = 200, error: Error | string = null) { + function handle_page(page: Page, req: Req, res: Res, status = 200, error: Error | string = null) { const build_info: { bundler: 'rollup' | 'webpack', shimport: string | null, @@ -313,7 +42,7 @@ function get_page_handler( } = get_build_info(); res.setHeader('Content-Type', 'text/html'); - res.setHeader('Cache-Control', dev() ? 'no-cache' : 'max-age=600'); + res.setHeader('Cache-Control', dev ? 'no-cache' : 'max-age=600'); // preload main.js and current route // TODO detect other stuff we can preload? images, CSS, fonts? @@ -483,7 +212,6 @@ function get_page_handler( serialized.store && `store:${serialized.store}` ].filter(Boolean).join(',')}};`; - const has_service_worker = fs.existsSync(path.join(locations.dest(), 'service-worker.js')); if (has_service_worker) { script += `if('serviceWorker' in navigator)navigator.serviceWorker.register('${req.baseUrl}/service-worker.js');`; } @@ -505,6 +233,7 @@ function get_page_handler( let styles: string; // TODO make this consistent across apps + // TODO embed build_info in placeholder.ts if (build_info.css && build_info.css.main) { const css_chunks = new Set(); if (build_info.css.main) css_chunks.add(build_info.css.main); @@ -549,7 +278,7 @@ function get_page_handler( }); } - return function find_route(req: Req, res: ServerResponse, next: () => void) { + return function find_route(req: Req, res: Res, next: () => void) { if (req[IGNORE]) return next(); if (!server_routes.some(route => route.pattern.test(req.path))) { @@ -565,24 +294,8 @@ function get_page_handler( }; } -function compose_handlers(handlers: Handler[]) { - return (req: Req, res: ServerResponse, next: () => void) => { - let i = 0; - function go() { - const handler = handlers[i]; - - if (handler) { - handler(req, res, () => { - i += 1; - go(); - }); - } else { - next(); - } - } - - go(); - }; +function read_template(dir = build_dir) { + return fs.readFileSync(`${dir}/template.html`, 'utf-8'); } function try_serialize(data: any) { @@ -603,4 +316,4 @@ function escape_html(html: string) { }; return html.replace(/["'&<>]/g, c => `&${chars[c]};`); -} +} \ No newline at end of file diff --git a/templates/src/server/middleware/get_server_route_handler.ts b/templates/src/server/middleware/get_server_route_handler.ts new file mode 100644 index 0000000..c788f4d --- /dev/null +++ b/templates/src/server/middleware/get_server_route_handler.ts @@ -0,0 +1,78 @@ +import { IGNORE } from '../placeholders'; +import { Req, Res, ServerRoute } from './types'; + +export function get_server_route_handler(routes: ServerRoute[]) { + function handle_route(route: ServerRoute, req: Req, res: Res, next: () => void) { + req.params = route.params(route.pattern.exec(req.path)); + + const method = req.method.toLowerCase(); + // 'delete' cannot be exported from a module because it is a keyword, + // so check for 'del' instead + const method_export = method === 'delete' ? 'del' : method; + const handle_method = route.handlers[method_export]; + if (handle_method) { + if (process.env.SAPPER_EXPORT) { + const { write, end, setHeader } = res; + const chunks: any[] = []; + const headers: Record = {}; + + // intercept data so that it can be exported + res.write = function(chunk: any) { + chunks.push(Buffer.from(chunk)); + write.apply(res, arguments); + }; + + res.setHeader = function(name: string, value: string) { + headers[name.toLowerCase()] = value; + setHeader.apply(res, arguments); + }; + + res.end = function(chunk?: any) { + if (chunk) chunks.push(Buffer.from(chunk)); + end.apply(res, arguments); + + process.send({ + __sapper__: true, + event: 'file', + url: req.url, + method: req.method, + status: res.statusCode, + type: headers['content-type'], + body: Buffer.concat(chunks).toString() + }); + }; + } + + const handle_next = (err?: Error) => { + if (err) { + res.statusCode = 500; + res.end(err.message); + } else { + process.nextTick(next); + } + }; + + try { + handle_method(req, res, handle_next); + } catch (err) { + handle_next(err); + } + } else { + // no matching handler for method + process.nextTick(next); + } + } + + return function find_route(req: Req, res: Res, next: () => void) { + if (req[IGNORE]) return next(); + + for (const route of routes) { + if (route.pattern.test(req.path)) { + handle_route(route, req, res, next); + return; + } + } + + next(); + }; +} \ No newline at end of file diff --git a/templates/src/server/middleware/index.ts b/templates/src/server/middleware/index.ts new file mode 100644 index 0000000..f06942c --- /dev/null +++ b/templates/src/server/middleware/index.ts @@ -0,0 +1,143 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import { build_dir, dev, manifest, IGNORE } from '../placeholders'; +import { Handler, Req, Res, Store } from './types'; +import { get_server_route_handler } from './get_server_route_handler'; +import { get_page_handler } from './get_page_handler'; +import { lookup } from './mime'; + +export default function middleware(opts: { + store?: (req: Req, res: Res) => Store, + ignore?: any +} = {}) { + const { store, ignore } = opts; + + let emitted_basepath = false; + + return compose_handlers([ + ignore && ((req: Req, res: Res, next: () => void) => { + req[IGNORE] = should_ignore(req.path, ignore); + next(); + }), + + (req: Req, res: Res, next: () => void) => { + if (req[IGNORE]) return next(); + + if (req.baseUrl === undefined) { + let { originalUrl } = req; + if (req.url === '/' && originalUrl[originalUrl.length - 1] !== '/') { + originalUrl += '/'; + } + + req.baseUrl = originalUrl + ? originalUrl.slice(0, -req.url.length) + : ''; + } + + if (!emitted_basepath && process.send) { + process.send({ + __sapper__: true, + event: 'basepath', + basepath: req.baseUrl + }); + + emitted_basepath = true; + } + + if (req.path === undefined) { + req.path = req.url.replace(/\?.*/, ''); + } + + next(); + }, + + fs.existsSync(path.join(build_dir, 'index.html')) && serve({ + pathname: '/index.html', + cache_control: dev ? 'no-cache' : 'max-age=600' + }), + + fs.existsSync(path.join(build_dir, 'service-worker.js')) && serve({ + pathname: '/service-worker.js', + cache_control: 'no-cache, no-store, must-revalidate' + }), + + fs.existsSync(path.join(build_dir, 'service-worker.js.map')) && serve({ + pathname: '/service-worker.js.map', + cache_control: 'no-cache, no-store, must-revalidate' + }), + + serve({ + prefix: '/client/', + cache_control: dev ? 'no-cache' : 'max-age=31536000, immutable' + }), + + get_server_route_handler(manifest.server_routes), + + get_page_handler(manifest, store) + ].filter(Boolean)); +} + +export function compose_handlers(handlers: Handler[]) { + return (req: Req, res: Res, next: () => void) => { + let i = 0; + function go() { + const handler = handlers[i]; + + if (handler) { + handler(req, res, () => { + i += 1; + go(); + }); + } else { + next(); + } + } + + go(); + }; +} + +export function should_ignore(uri: string, val: any) { + if (Array.isArray(val)) return val.some(x => should_ignore(uri, x)); + if (val instanceof RegExp) return val.test(uri); + if (typeof val === 'function') return val(uri); + return uri.startsWith(val.charCodeAt(0) === 47 ? val : `/${val}`); +} + +export function serve({ prefix, pathname, cache_control }: { + prefix?: string, + pathname?: string, + cache_control: string +}) { + const filter = pathname + ? (req: Req) => req.path === pathname + : (req: Req) => req.path.startsWith(prefix); + + const cache: Map = new Map(); + + const read = dev + ? (file: string) => fs.readFileSync(path.resolve(build_dir, file)) + : (file: string) => (cache.has(file) ? cache : cache.set(file, fs.readFileSync(path.resolve(build_dir, file)))).get(file) + + return (req: Req, res: Res, next: () => void) => { + if (req[IGNORE]) return next(); + + if (filter(req)) { + const type = lookup(req.path); + + try { + const file = decodeURIComponent(req.path.slice(1)); + const data = read(file); + + res.setHeader('Content-Type', type); + res.setHeader('Cache-Control', cache_control); + res.end(data); + } catch (err) { + res.statusCode = 404; + res.end('not found'); + } + } else { + next(); + } + }; +} \ No newline at end of file diff --git a/src/middleware/mime-types.md b/templates/src/server/middleware/mime-types.md similarity index 100% rename from src/middleware/mime-types.md rename to templates/src/server/middleware/mime-types.md diff --git a/src/middleware/mime.ts b/templates/src/server/middleware/mime.ts similarity index 100% rename from src/middleware/mime.ts rename to templates/src/server/middleware/mime.ts diff --git a/templates/src/server/middleware/types.ts b/templates/src/server/middleware/types.ts new file mode 100644 index 0000000..6d7597f --- /dev/null +++ b/templates/src/server/middleware/types.ts @@ -0,0 +1,69 @@ +import { ClientRequest, ServerResponse } from 'http'; + +export type ServerRoute = { + pattern: RegExp; + handlers: Record; + params: (match: RegExpMatchArray) => Record; +}; + +export type Page = { + pattern: RegExp; + parts: Array<{ + name: string; + component: Component; + params?: (match: RegExpMatchArray) => Record; + }> +}; + +export type Manifest = { + server_routes: ServerRoute[]; + pages: Page[]; + root: Component; + error: Component; +} + +export type Handler = (req: Req, res: Res, next: () => void) => void; + +export type Store = { + get: () => any +}; + +export type Props = { + path: string; + query: Record; + params: Record; + error?: { message: string }; + status?: number; + child: { + segment: string; + component: Component; + props: Props; + }; + [key: string]: any; +}; + +export interface Req extends ClientRequest { + url: string; + baseUrl: string; + originalUrl: string; + method: string; + path: string; + params: Record; + query: Record; + headers: Record; +} + +export interface Res extends ServerResponse { + write: (data: any) => void; +} + +export { ServerResponse }; + +interface Component { + render: (data: any, opts: { store: Store }) => { + head: string; + css: { code: string, map: any }; + html: string + }, + preload: (data: any) => any | Promise +} \ No newline at end of file diff --git a/templates/src/server/placeholders.ts b/templates/src/server/placeholders.ts new file mode 100644 index 0000000..b95b5ea --- /dev/null +++ b/templates/src/server/placeholders.ts @@ -0,0 +1,11 @@ +import { Manifest } from './types'; + +export const manifest: Manifest = __MANIFEST__; + +export const build_dir = __BUILD__DIR__; + +export const src_dir = __SRC__DIR__; + +export const dev = __DEV__; + +export const IGNORE = '__SAPPER__IGNORE__'; \ No newline at end of file diff --git a/test/app/src/client.js b/test/app/src/client.js index d1c2e96..39aeea7 100644 --- a/test/app/src/client.js +++ b/test/app/src/client.js @@ -1,14 +1,12 @@ -import { init, goto, prefetchRoutes } from '../../../runtime.js'; import { Store } from 'svelte/store.js'; -import { manifest } from './manifest/client.js'; +import * as sapper from '../__sapper__/client.js'; window.init = () => { - return init({ + return sapper.start({ target: document.querySelector('#sapper'), - manifest, store: data => new Store(data) }); }; -window.prefetchRoutes = prefetchRoutes; -window.goto = goto; \ No newline at end of file +window.prefetchRoutes = sapper.prefetchRoutes; +window.goto = sapper.goto; \ No newline at end of file diff --git a/test/app/src/routes/about.html b/test/app/src/routes/about.html index 949ad84..af0dd1d 100644 --- a/test/app/src/routes/about.html +++ b/test/app/src/routes/about.html @@ -9,17 +9,9 @@