├── .gitattributes ├── .gitignore ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── LICENSE ├── main.mjs ├── package-lock.json ├── package.json ├── pom.xml └── src ├── main ├── java │ └── net │ │ └── razshare │ │ └── svelte3jssr │ │ ├── core │ │ ├── models │ │ │ └── SvelteComponentResult.java │ │ └── proxies │ │ │ ├── NodeProxy.java │ │ │ └── SvelteProxy.java │ │ └── starter │ │ ├── Entry.java │ │ ├── callbacks │ │ └── HttpRequestCallback.java │ │ ├── proxies │ │ └── JavaProxy.java │ │ └── tools │ │ └── TestClass.java └── svelte │ ├── App.svelte │ ├── SomeComponent.svelte │ └── scripts │ └── test.mjs └── test └── java └── net └── razshare └── svelte3jssr └── AppTest.java /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | /public/build/ 3 | 4 | .DS_Store 5 | 6 | #Maven 7 | target/ 8 | pom.xml.tag 9 | pom.xml.releaseBackup 10 | pom.xml.versionsBackup 11 | release.properties 12 | 13 | # Eclipse 14 | .project 15 | .classpath 16 | .settings/ 17 | bin/ 18 | 19 | # IntelliJ 20 | .idea 21 | *.ipr 22 | *.iml 23 | *.iws 24 | 25 | # NetBeans 26 | nb-configuration.xml 27 | 28 | # Visual Studio Code 29 | .factorypath 30 | 31 | # OSX 32 | .DS_Store 33 | 34 | # Vim 35 | *.swp 36 | *.swo 37 | 38 | # patch 39 | *.orig 40 | *.rej 41 | 42 | # Local environment 43 | .env 44 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "graalvm", 9 | "request": "launch", 10 | "name": "Launch Node App", 11 | "outputCapture": "std", 12 | "program": "${workspaceFolder}/main.mjs", 13 | "runtimeArgs": [ 14 | "--polyglot", 15 | "--jvm", 16 | "--inspect", 17 | "--vm.cp=./target/classes" 18 | ], 19 | "preLaunchTask": "compile" 20 | } 21 | 22 | ] 23 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "java.configuration.updateBuildConfiguration": "automatic", 3 | "java.completion.enabled": false, 4 | "java.debug.settings.enableRunDebugCodeLens": false, 5 | "java.test.editor.enableShortcuts": false, 6 | "recommendations": [ 7 | "oracle-labs-graalvm.graalvm", 8 | "oracle-labs-graalvm.micronaut", 9 | "oracle-labs-graalvm.graalvm-pack", 10 | "gabrielbb.vscode-lombok" 11 | ] 12 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "type": "shell", 6 | "command": "mvn compile", 7 | "group": "build", 8 | "problemMatcher": [], 9 | "label": "compile", 10 | "detail": "mvn compile" 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Razvan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /main.mjs: -------------------------------------------------------------------------------- 1 | import svelte from 'rollup-plugin-svelte' 2 | import resolve from '@rollup/plugin-node-resolve' 3 | import http from "http" 4 | import { rollup } from 'rollup'; 5 | 6 | 7 | const NodeProxy = Java.type("net.razshare.svelte3jssr.core.proxies.NodeProxy") 8 | const SvelteProxy = Java.type("net.razshare.svelte3jssr.core.proxies.SvelteProxy") 9 | const Entry = Java.type("net.razshare.svelte3jssr.starter.Entry") 10 | const JavaProxy = Java.type("net.razshare.svelte3jssr.starter.proxies.JavaProxy") 11 | 12 | // FLAGS START 13 | //////////////////////////////////////////////////// 14 | //If this is enabled the server will cache in compiled ".svelte" files, making it faster to serve. 15 | const USE_CACHE = true 16 | //If this is enabled, the server will include props in the prerendered version of the component. 17 | //This will make it easier to SEO. 18 | //Make no mistake the JS bundle will still contain your data and render it properly if this flag is disabled. 19 | const PREPRENDER_PROPS = true 20 | //////////////////////////////////////////////////// 21 | // FLAGS END 22 | 23 | const compiledComponents = {} 24 | 25 | // This following instructions give Java access to some NodeJS functions and their context. 26 | // API STARTS 27 | //////////////////////////////////////////////////// 28 | NodeProxy.setRequire((url)=>{ 29 | return importScripts(url) 30 | }) 31 | 32 | NodeProxy.setJson(JSON) 33 | 34 | SvelteProxy.setCompiler(async (source,generate)=>{ 35 | if(USE_CACHE && compiledComponents[`${source}::${generate}`]) return compiledComponents[`${source}::${generate}`] 36 | 37 | const bundle = await rollup({ 38 | input:source, 39 | plugins:[ 40 | svelte({ 41 | // By default, all ".svelte" files are compiled 42 | //extensions: ['.my-custom-extension'], 43 | 44 | // You can restrict which files are compiled 45 | // using `include` and `exclude` 46 | include: 'src/main/svelte/**/*.svelte', 47 | 48 | // Optionally, preprocess components with svelte.preprocess: 49 | // https://svelte.dev/docs#svelte_preprocess 50 | preprocess: { 51 | style: ({ content }) => { 52 | return transformStyles(content); 53 | } 54 | }, 55 | 56 | // Emit CSS as "files" for other plugins to process. default is true 57 | emitCss: false, 58 | 59 | // Warnings are normally passed straight to Rollup. You can 60 | // optionally handle them here, for example to squelch 61 | // warnings with a particular code 62 | onwarn: (warning, handler) => { 63 | // e.g. don't warn on elements, cos they're cool 64 | if (warning.code === 'a11y-distracting-elements') return; 65 | 66 | // let Rollup handle all other warnings normally 67 | handler(warning); 68 | }, 69 | 70 | // You can pass any of the Svelte compiler options 71 | compilerOptions: { 72 | 73 | // By default, the client-side compiler is used. You 74 | // can also use the server-side rendering compiler 75 | generate, 76 | 77 | // ensure that extra attributes are added to head 78 | // elements for hydration (used with generate: 'ssr') 79 | hydratable: true, 80 | 81 | // You can optionally set 'customElement' to 'true' to compile 82 | // your components to custom elements (aka web elements) 83 | customElement: false 84 | } 85 | }), 86 | // see NOTICE below 87 | resolve({ browser: true }), 88 | // ... 89 | ] 90 | }) 91 | 92 | const { output } = await bundle.generate({ 93 | format:'iife' 94 | }) 95 | compiledComponents[`${source}::${generate}`] = output[0].code 96 | return output[0].code 97 | }) 98 | 99 | SvelteProxy.setRender((code,props)=>{ 100 | const Component = eval(code) 101 | return Component.render(PREPRENDER_PROPS?props:{}) 102 | }) 103 | //////////////////////////////////////////////////// 104 | // API ENDS 105 | 106 | 107 | 108 | /** 109 | * I'm running a node js server here but you can just initialize your 110 | * own Java server inside src/main/java/Entry.java instead. 111 | * 112 | * It will probably be hard to spin off a Spring Boot server because Spring Boot does some code transformations that are not possible in GraalVM, at least not with the default Spring Boot project setup. 113 | * However since then this came out: https://spring.io/blog/2020/04/16/spring-tips-the-graalvm-native-image-builder-feature 114 | * 115 | * That being said you should be perfectly able to run a Quarkus web server using the same familiar Spring API. 116 | * For more information refer to: https://quarkus.io/ 117 | */ 118 | 119 | new Entry() //initialize Java app. 120 | 121 | http 122 | .createServer((request, response)=>{ 123 | JavaProxy.requestCallback(request, response) 124 | }) 125 | .listen(8000, ()=>console.log("Graal.js server running at http://127.0.0.1:8000/")) -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svelte-app", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@rollup/plugin-commonjs": { 8 | "version": "20.0.0", 9 | "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-20.0.0.tgz", 10 | "integrity": "sha512-5K0g5W2Ol8hAcTHqcTBHiA7M58tfmYi1o9KxeJuuRNpGaTa5iLjcyemBitCBcKXaHamOBBEH2dGom6v6Unmqjg==", 11 | "dev": true, 12 | "requires": { 13 | "@rollup/pluginutils": "^3.1.0", 14 | "commondir": "^1.0.1", 15 | "estree-walker": "^2.0.1", 16 | "glob": "^7.1.6", 17 | "is-reference": "^1.2.1", 18 | "magic-string": "^0.25.7", 19 | "resolve": "^1.17.0" 20 | }, 21 | "dependencies": { 22 | "estree-walker": { 23 | "version": "2.0.2", 24 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", 25 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", 26 | "dev": true 27 | } 28 | } 29 | }, 30 | "@rollup/plugin-node-resolve": { 31 | "version": "13.0.4", 32 | "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.4.tgz", 33 | "integrity": "sha512-eYq4TFy40O8hjeDs+sIxEH/jc9lyuI2k9DM557WN6rO5OpnC2qXMBNj4IKH1oHrnAazL49C5p0tgP0/VpqJ+/w==", 34 | "dev": true, 35 | "requires": { 36 | "@rollup/pluginutils": "^3.1.0", 37 | "@types/resolve": "1.17.1", 38 | "builtin-modules": "^3.1.0", 39 | "deepmerge": "^4.2.2", 40 | "is-module": "^1.0.0", 41 | "resolve": "^1.19.0" 42 | }, 43 | "dependencies": { 44 | "@types/resolve": { 45 | "version": "1.17.1", 46 | "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", 47 | "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", 48 | "dev": true, 49 | "requires": { 50 | "@types/node": "*" 51 | } 52 | } 53 | } 54 | }, 55 | "@rollup/pluginutils": { 56 | "version": "3.1.0", 57 | "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", 58 | "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", 59 | "dev": true, 60 | "requires": { 61 | "@types/estree": "0.0.39", 62 | "estree-walker": "^1.0.1", 63 | "picomatch": "^2.2.2" 64 | }, 65 | "dependencies": { 66 | "estree-walker": { 67 | "version": "1.0.1", 68 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", 69 | "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", 70 | "dev": true 71 | } 72 | } 73 | }, 74 | "@types/estree": { 75 | "version": "0.0.39", 76 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", 77 | "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", 78 | "dev": true 79 | }, 80 | "@types/node": { 81 | "version": "16.6.2", 82 | "resolved": "https://registry.npmjs.org/@types/node/-/node-16.6.2.tgz", 83 | "integrity": "sha512-LSw8TZt12ZudbpHc6EkIyDM3nHVWKYrAvGy6EAJfNfjusbwnThqjqxUKKRwuV3iWYeW/LYMzNgaq3MaLffQ2xA==", 84 | "dev": true 85 | }, 86 | "@types/resolve": { 87 | "version": "0.0.8", 88 | "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", 89 | "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", 90 | "dev": true, 91 | "requires": { 92 | "@types/node": "*" 93 | } 94 | }, 95 | "accepts": { 96 | "version": "1.3.8", 97 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 98 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 99 | "requires": { 100 | "mime-types": "~2.1.34", 101 | "negotiator": "0.6.3" 102 | } 103 | }, 104 | "ansi-styles": { 105 | "version": "4.3.0", 106 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 107 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 108 | "dev": true, 109 | "requires": { 110 | "color-convert": "^2.0.1" 111 | } 112 | }, 113 | "array-flatten": { 114 | "version": "1.1.1", 115 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 116 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 117 | }, 118 | "async": { 119 | "version": "3.2.4", 120 | "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", 121 | "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", 122 | "dev": true 123 | }, 124 | "balanced-match": { 125 | "version": "1.0.2", 126 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 127 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 128 | "dev": true 129 | }, 130 | "body-parser": { 131 | "version": "1.20.1", 132 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", 133 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", 134 | "requires": { 135 | "bytes": "3.1.2", 136 | "content-type": "~1.0.4", 137 | "debug": "2.6.9", 138 | "depd": "2.0.0", 139 | "destroy": "1.2.0", 140 | "http-errors": "2.0.0", 141 | "iconv-lite": "0.4.24", 142 | "on-finished": "2.4.1", 143 | "qs": "6.11.0", 144 | "raw-body": "2.5.1", 145 | "type-is": "~1.6.18", 146 | "unpipe": "1.0.0" 147 | } 148 | }, 149 | "brace-expansion": { 150 | "version": "1.1.11", 151 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 152 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 153 | "dev": true, 154 | "requires": { 155 | "balanced-match": "^1.0.0", 156 | "concat-map": "0.0.1" 157 | } 158 | }, 159 | "builtin-modules": { 160 | "version": "3.2.0", 161 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", 162 | "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", 163 | "dev": true 164 | }, 165 | "bytes": { 166 | "version": "3.1.2", 167 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 168 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" 169 | }, 170 | "call-bind": { 171 | "version": "1.0.2", 172 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 173 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 174 | "requires": { 175 | "function-bind": "^1.1.1", 176 | "get-intrinsic": "^1.0.2" 177 | } 178 | }, 179 | "chalk": { 180 | "version": "4.1.2", 181 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 182 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 183 | "dev": true, 184 | "requires": { 185 | "ansi-styles": "^4.1.0", 186 | "supports-color": "^7.1.0" 187 | } 188 | }, 189 | "color-convert": { 190 | "version": "2.0.1", 191 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 192 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 193 | "dev": true, 194 | "requires": { 195 | "color-name": "~1.1.4" 196 | } 197 | }, 198 | "color-name": { 199 | "version": "1.1.4", 200 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 201 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 202 | "dev": true 203 | }, 204 | "commondir": { 205 | "version": "1.0.1", 206 | "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", 207 | "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", 208 | "dev": true 209 | }, 210 | "concat-map": { 211 | "version": "0.0.1", 212 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 213 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 214 | "dev": true 215 | }, 216 | "content-disposition": { 217 | "version": "0.5.4", 218 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 219 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 220 | "requires": { 221 | "safe-buffer": "5.2.1" 222 | } 223 | }, 224 | "content-type": { 225 | "version": "1.0.5", 226 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 227 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" 228 | }, 229 | "cookie": { 230 | "version": "0.5.0", 231 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", 232 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" 233 | }, 234 | "cookie-signature": { 235 | "version": "1.0.6", 236 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 237 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 238 | }, 239 | "debug": { 240 | "version": "2.6.9", 241 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 242 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 243 | "requires": { 244 | "ms": "2.0.0" 245 | } 246 | }, 247 | "deepmerge": { 248 | "version": "4.2.2", 249 | "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", 250 | "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", 251 | "dev": true 252 | }, 253 | "depd": { 254 | "version": "2.0.0", 255 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 256 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" 257 | }, 258 | "destroy": { 259 | "version": "1.2.0", 260 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 261 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" 262 | }, 263 | "ee-first": { 264 | "version": "1.1.1", 265 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 266 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 267 | }, 268 | "ejs": { 269 | "version": "3.1.7", 270 | "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.7.tgz", 271 | "integrity": "sha512-BIar7R6abbUxDA3bfXrO4DSgwo8I+fB5/1zgujl3HLLjwd6+9iOnrT+t3grn2qbk9vOgBubXOFwX2m9axoFaGw==", 272 | "dev": true, 273 | "requires": { 274 | "jake": "^10.8.5" 275 | } 276 | }, 277 | "encodeurl": { 278 | "version": "1.0.2", 279 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 280 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" 281 | }, 282 | "escape-html": { 283 | "version": "1.0.3", 284 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 285 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 286 | }, 287 | "estree-walker": { 288 | "version": "0.6.1", 289 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", 290 | "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", 291 | "dev": true 292 | }, 293 | "etag": { 294 | "version": "1.8.1", 295 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 296 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" 297 | }, 298 | "express": { 299 | "version": "4.18.2", 300 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", 301 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", 302 | "requires": { 303 | "accepts": "~1.3.8", 304 | "array-flatten": "1.1.1", 305 | "body-parser": "1.20.1", 306 | "content-disposition": "0.5.4", 307 | "content-type": "~1.0.4", 308 | "cookie": "0.5.0", 309 | "cookie-signature": "1.0.6", 310 | "debug": "2.6.9", 311 | "depd": "2.0.0", 312 | "encodeurl": "~1.0.2", 313 | "escape-html": "~1.0.3", 314 | "etag": "~1.8.1", 315 | "finalhandler": "1.2.0", 316 | "fresh": "0.5.2", 317 | "http-errors": "2.0.0", 318 | "merge-descriptors": "1.0.1", 319 | "methods": "~1.1.2", 320 | "on-finished": "2.4.1", 321 | "parseurl": "~1.3.3", 322 | "path-to-regexp": "0.1.7", 323 | "proxy-addr": "~2.0.7", 324 | "qs": "6.11.0", 325 | "range-parser": "~1.2.1", 326 | "safe-buffer": "5.2.1", 327 | "send": "0.18.0", 328 | "serve-static": "1.15.0", 329 | "setprototypeof": "1.2.0", 330 | "statuses": "2.0.1", 331 | "type-is": "~1.6.18", 332 | "utils-merge": "1.0.1", 333 | "vary": "~1.1.2" 334 | } 335 | }, 336 | "filelist": { 337 | "version": "1.0.4", 338 | "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", 339 | "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", 340 | "dev": true, 341 | "requires": { 342 | "minimatch": "^5.0.1" 343 | }, 344 | "dependencies": { 345 | "brace-expansion": { 346 | "version": "2.0.1", 347 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 348 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 349 | "dev": true, 350 | "requires": { 351 | "balanced-match": "^1.0.0" 352 | } 353 | }, 354 | "minimatch": { 355 | "version": "5.1.6", 356 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", 357 | "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", 358 | "dev": true, 359 | "requires": { 360 | "brace-expansion": "^2.0.1" 361 | } 362 | } 363 | } 364 | }, 365 | "finalhandler": { 366 | "version": "1.2.0", 367 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", 368 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 369 | "requires": { 370 | "debug": "2.6.9", 371 | "encodeurl": "~1.0.2", 372 | "escape-html": "~1.0.3", 373 | "on-finished": "2.4.1", 374 | "parseurl": "~1.3.3", 375 | "statuses": "2.0.1", 376 | "unpipe": "~1.0.0" 377 | } 378 | }, 379 | "forwarded": { 380 | "version": "0.2.0", 381 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 382 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" 383 | }, 384 | "fresh": { 385 | "version": "0.5.2", 386 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 387 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" 388 | }, 389 | "fs.realpath": { 390 | "version": "1.0.0", 391 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 392 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 393 | "dev": true 394 | }, 395 | "fsevents": { 396 | "version": "2.3.2", 397 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 398 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 399 | "dev": true, 400 | "optional": true 401 | }, 402 | "function-bind": { 403 | "version": "1.1.1", 404 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 405 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 406 | }, 407 | "get-intrinsic": { 408 | "version": "1.2.0", 409 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", 410 | "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", 411 | "requires": { 412 | "function-bind": "^1.1.1", 413 | "has": "^1.0.3", 414 | "has-symbols": "^1.0.3" 415 | } 416 | }, 417 | "glob": { 418 | "version": "7.1.7", 419 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", 420 | "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", 421 | "dev": true, 422 | "requires": { 423 | "fs.realpath": "^1.0.0", 424 | "inflight": "^1.0.4", 425 | "inherits": "2", 426 | "minimatch": "^3.0.4", 427 | "once": "^1.3.0", 428 | "path-is-absolute": "^1.0.0" 429 | } 430 | }, 431 | "has": { 432 | "version": "1.0.3", 433 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 434 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 435 | "requires": { 436 | "function-bind": "^1.1.1" 437 | } 438 | }, 439 | "has-flag": { 440 | "version": "4.0.0", 441 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 442 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 443 | "dev": true 444 | }, 445 | "has-symbols": { 446 | "version": "1.0.3", 447 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 448 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" 449 | }, 450 | "http-errors": { 451 | "version": "2.0.0", 452 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 453 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 454 | "requires": { 455 | "depd": "2.0.0", 456 | "inherits": "2.0.4", 457 | "setprototypeof": "1.2.0", 458 | "statuses": "2.0.1", 459 | "toidentifier": "1.0.1" 460 | }, 461 | "dependencies": { 462 | "inherits": { 463 | "version": "2.0.4", 464 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 465 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 466 | } 467 | } 468 | }, 469 | "iconv-lite": { 470 | "version": "0.4.24", 471 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 472 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 473 | "requires": { 474 | "safer-buffer": ">= 2.1.2 < 3" 475 | } 476 | }, 477 | "inflight": { 478 | "version": "1.0.6", 479 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 480 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 481 | "dev": true, 482 | "requires": { 483 | "once": "^1.3.0", 484 | "wrappy": "1" 485 | } 486 | }, 487 | "inherits": { 488 | "version": "2.0.3", 489 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 490 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", 491 | "dev": true 492 | }, 493 | "ipaddr.js": { 494 | "version": "1.9.1", 495 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 496 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 497 | }, 498 | "is-core-module": { 499 | "version": "2.6.0", 500 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz", 501 | "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==", 502 | "dev": true, 503 | "requires": { 504 | "has": "^1.0.3" 505 | } 506 | }, 507 | "is-module": { 508 | "version": "1.0.0", 509 | "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", 510 | "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", 511 | "dev": true 512 | }, 513 | "is-reference": { 514 | "version": "1.2.1", 515 | "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", 516 | "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", 517 | "dev": true, 518 | "requires": { 519 | "@types/estree": "*" 520 | } 521 | }, 522 | "jake": { 523 | "version": "10.8.5", 524 | "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", 525 | "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", 526 | "dev": true, 527 | "requires": { 528 | "async": "^3.2.3", 529 | "chalk": "^4.0.2", 530 | "filelist": "^1.0.1", 531 | "minimatch": "^3.0.4" 532 | } 533 | }, 534 | "magic-string": { 535 | "version": "0.25.7", 536 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", 537 | "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", 538 | "dev": true, 539 | "requires": { 540 | "sourcemap-codec": "^1.4.4" 541 | } 542 | }, 543 | "media-typer": { 544 | "version": "0.3.0", 545 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 546 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" 547 | }, 548 | "merge-descriptors": { 549 | "version": "1.0.1", 550 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 551 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 552 | }, 553 | "methods": { 554 | "version": "1.1.2", 555 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 556 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" 557 | }, 558 | "mime": { 559 | "version": "1.6.0", 560 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 561 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 562 | }, 563 | "mime-db": { 564 | "version": "1.52.0", 565 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 566 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" 567 | }, 568 | "mime-types": { 569 | "version": "2.1.35", 570 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 571 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 572 | "requires": { 573 | "mime-db": "1.52.0" 574 | } 575 | }, 576 | "minimatch": { 577 | "version": "3.1.2", 578 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 579 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 580 | "dev": true, 581 | "requires": { 582 | "brace-expansion": "^1.1.7" 583 | } 584 | }, 585 | "ms": { 586 | "version": "2.0.0", 587 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 588 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 589 | }, 590 | "negotiator": { 591 | "version": "0.6.3", 592 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 593 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" 594 | }, 595 | "object-inspect": { 596 | "version": "1.12.3", 597 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", 598 | "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==" 599 | }, 600 | "on-finished": { 601 | "version": "2.4.1", 602 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 603 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 604 | "requires": { 605 | "ee-first": "1.1.1" 606 | } 607 | }, 608 | "once": { 609 | "version": "1.4.0", 610 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 611 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 612 | "dev": true, 613 | "requires": { 614 | "wrappy": "1" 615 | } 616 | }, 617 | "parseurl": { 618 | "version": "1.3.3", 619 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 620 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 621 | }, 622 | "path-is-absolute": { 623 | "version": "1.0.1", 624 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 625 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 626 | "dev": true 627 | }, 628 | "path-parse": { 629 | "version": "1.0.7", 630 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 631 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 632 | "dev": true 633 | }, 634 | "path-to-regexp": { 635 | "version": "0.1.7", 636 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 637 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 638 | }, 639 | "picomatch": { 640 | "version": "2.3.0", 641 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", 642 | "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", 643 | "dev": true 644 | }, 645 | "proxy-addr": { 646 | "version": "2.0.7", 647 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 648 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 649 | "requires": { 650 | "forwarded": "0.2.0", 651 | "ipaddr.js": "1.9.1" 652 | } 653 | }, 654 | "qs": { 655 | "version": "6.11.0", 656 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", 657 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", 658 | "requires": { 659 | "side-channel": "^1.0.4" 660 | } 661 | }, 662 | "range-parser": { 663 | "version": "1.2.1", 664 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 665 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 666 | }, 667 | "raw-body": { 668 | "version": "2.5.1", 669 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", 670 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", 671 | "requires": { 672 | "bytes": "3.1.2", 673 | "http-errors": "2.0.0", 674 | "iconv-lite": "0.4.24", 675 | "unpipe": "1.0.0" 676 | } 677 | }, 678 | "require-relative": { 679 | "version": "0.8.7", 680 | "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz", 681 | "integrity": "sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=", 682 | "dev": true 683 | }, 684 | "resolve": { 685 | "version": "1.20.0", 686 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", 687 | "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", 688 | "dev": true, 689 | "requires": { 690 | "is-core-module": "^2.2.0", 691 | "path-parse": "^1.0.6" 692 | } 693 | }, 694 | "rollup": { 695 | "version": "2.56.2", 696 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.56.2.tgz", 697 | "integrity": "sha512-s8H00ZsRi29M2/lGdm1u8DJpJ9ML8SUOpVVBd33XNeEeL3NVaTiUcSBHzBdF3eAyR0l7VSpsuoVUGrRHq7aPwQ==", 698 | "dev": true, 699 | "requires": { 700 | "fsevents": "~2.3.2" 701 | } 702 | }, 703 | "rollup-plugin-node-resolve": { 704 | "version": "5.2.0", 705 | "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz", 706 | "integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==", 707 | "dev": true, 708 | "requires": { 709 | "@types/resolve": "0.0.8", 710 | "builtin-modules": "^3.1.0", 711 | "is-module": "^1.0.0", 712 | "resolve": "^1.11.1", 713 | "rollup-pluginutils": "^2.8.1" 714 | } 715 | }, 716 | "rollup-plugin-svelte": { 717 | "version": "7.1.0", 718 | "resolved": "https://registry.npmjs.org/rollup-plugin-svelte/-/rollup-plugin-svelte-7.1.0.tgz", 719 | "integrity": "sha512-vopCUq3G+25sKjwF5VilIbiY6KCuMNHP1PFvx2Vr3REBNMDllKHFZN2B9jwwC+MqNc3UPKkjXnceLPEjTjXGXg==", 720 | "dev": true, 721 | "requires": { 722 | "require-relative": "^0.8.7", 723 | "rollup-pluginutils": "^2.8.2" 724 | } 725 | }, 726 | "rollup-pluginutils": { 727 | "version": "2.8.2", 728 | "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", 729 | "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", 730 | "dev": true, 731 | "requires": { 732 | "estree-walker": "^0.6.1" 733 | } 734 | }, 735 | "safe-buffer": { 736 | "version": "5.2.1", 737 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 738 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 739 | }, 740 | "safer-buffer": { 741 | "version": "2.1.2", 742 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 743 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 744 | }, 745 | "send": { 746 | "version": "0.18.0", 747 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", 748 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 749 | "requires": { 750 | "debug": "2.6.9", 751 | "depd": "2.0.0", 752 | "destroy": "1.2.0", 753 | "encodeurl": "~1.0.2", 754 | "escape-html": "~1.0.3", 755 | "etag": "~1.8.1", 756 | "fresh": "0.5.2", 757 | "http-errors": "2.0.0", 758 | "mime": "1.6.0", 759 | "ms": "2.1.3", 760 | "on-finished": "2.4.1", 761 | "range-parser": "~1.2.1", 762 | "statuses": "2.0.1" 763 | }, 764 | "dependencies": { 765 | "ms": { 766 | "version": "2.1.3", 767 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 768 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 769 | } 770 | } 771 | }, 772 | "serve-static": { 773 | "version": "1.15.0", 774 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", 775 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 776 | "requires": { 777 | "encodeurl": "~1.0.2", 778 | "escape-html": "~1.0.3", 779 | "parseurl": "~1.3.3", 780 | "send": "0.18.0" 781 | } 782 | }, 783 | "setprototypeof": { 784 | "version": "1.2.0", 785 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 786 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 787 | }, 788 | "side-channel": { 789 | "version": "1.0.4", 790 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 791 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 792 | "requires": { 793 | "call-bind": "^1.0.0", 794 | "get-intrinsic": "^1.0.2", 795 | "object-inspect": "^1.9.0" 796 | } 797 | }, 798 | "sourcemap-codec": { 799 | "version": "1.4.8", 800 | "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", 801 | "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", 802 | "dev": true 803 | }, 804 | "statuses": { 805 | "version": "2.0.1", 806 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 807 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" 808 | }, 809 | "supports-color": { 810 | "version": "7.2.0", 811 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 812 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 813 | "dev": true, 814 | "requires": { 815 | "has-flag": "^4.0.0" 816 | } 817 | }, 818 | "svelte": { 819 | "version": "3.49.0", 820 | "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.49.0.tgz", 821 | "integrity": "sha512-+lmjic1pApJWDfPCpUUTc1m8azDqYCG1JN9YEngrx/hUyIcFJo6VZhj0A1Ai0wqoHcEIuQy+e9tk+4uDgdtsFA==", 822 | "dev": true 823 | }, 824 | "toidentifier": { 825 | "version": "1.0.1", 826 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 827 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" 828 | }, 829 | "type-is": { 830 | "version": "1.6.18", 831 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 832 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 833 | "requires": { 834 | "media-typer": "0.3.0", 835 | "mime-types": "~2.1.24" 836 | } 837 | }, 838 | "unpipe": { 839 | "version": "1.0.0", 840 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 841 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" 842 | }, 843 | "utils-merge": { 844 | "version": "1.0.1", 845 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 846 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" 847 | }, 848 | "vary": { 849 | "version": "1.1.2", 850 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 851 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" 852 | }, 853 | "wrappy": { 854 | "version": "1.0.2", 855 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 856 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 857 | "dev": true 858 | } 859 | } 860 | } 861 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svelte-app", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "mvn compile & node --polyglot --jvm --inspect --vm.cp=./target/classes ./main.mjs" 7 | }, 8 | "devDependencies": { 9 | "@rollup/plugin-commonjs": "^20.0.0", 10 | "@rollup/plugin-node-resolve": "^13.0.4", 11 | "ejs": "^3.1.7", 12 | "rollup": "^2.56.2", 13 | "rollup-plugin-node-resolve": "^5.2.0", 14 | "rollup-plugin-svelte": "^7.1.0", 15 | "svelte": "^3.49.0" 16 | }, 17 | "dependencies": { 18 | "express": "^4.18.2" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 4.0.0 6 | 7 | net.razshare.svelte3jssr 8 | starter 9 | 1.0-SNAPSHOT 10 | 11 | starter 12 | 13 | https://github.com/tncrazvan/svelte-3-jssr-starter 14 | 15 | 16 | UTF-8 17 | 11 18 | 11 19 | 20 | 21 | 22 | 23 | junit 24 | junit 25 | 4.13.1 26 | test 27 | 28 | 29 | org.projectlombok 30 | lombok 31 | 1.18.20 32 | provided 33 | 34 | 35 | org.thymeleaf 36 | thymeleaf 37 | 3.0.12.RELEASE 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | maven-clean-plugin 47 | 3.1.0 48 | 49 | 50 | 51 | maven-resources-plugin 52 | 3.0.2 53 | 54 | 55 | maven-compiler-plugin 56 | 3.8.0 57 | 58 | 59 | maven-surefire-plugin 60 | 2.22.1 61 | 62 | 63 | maven-jar-plugin 64 | 3.0.2 65 | 66 | 67 | maven-install-plugin 68 | 2.5.2 69 | 70 | 71 | maven-deploy-plugin 72 | 2.8.2 73 | 74 | 75 | 76 | maven-site-plugin 77 | 3.7.1 78 | 79 | 80 | maven-project-info-reports-plugin 81 | 3.0.0 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/main/java/net/razshare/svelte3jssr/core/models/SvelteComponentResult.java: -------------------------------------------------------------------------------- 1 | package net.razshare.svelte3jssr.core.models; 2 | 3 | import lombok.Getter; 4 | 5 | public class SvelteComponentResult { 6 | 7 | @Getter private final String jsCode; 8 | @Getter private final String cssCode; 9 | @Getter private final String head; 10 | @Getter private final String html; 11 | 12 | /** 13 | * Represents a Svelte object in its html, js and css forms. 14 | * @param jsCode raw javascript code. 15 | * @param cssCode raw css code. 16 | * @param head head html. 17 | * @param html component html. 18 | */ 19 | public SvelteComponentResult( 20 | String jsCode, 21 | String cssCode, 22 | String head, 23 | String html 24 | ){ 25 | this.jsCode = jsCode; 26 | this.cssCode = cssCode; 27 | this.head = head; 28 | this.html = html; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/net/razshare/svelte3jssr/core/proxies/NodeProxy.java: -------------------------------------------------------------------------------- 1 | package net.razshare.svelte3jssr.core.proxies; 2 | 3 | import java.nio.file.Paths; 4 | import java.util.HashMap; 5 | import org.graalvm.polyglot.Value; 6 | import org.graalvm.polyglot.proxy.ProxyObject; 7 | 8 | public class NodeProxy { 9 | private static Value require; 10 | private static Value json; 11 | 12 | private static final String WD = Paths.get("").toAbsolutePath().toString()+"/"; 13 | 14 | /** 15 | * Require a file using the NodeJS api. 16 | * @param filename Name of the file you want to require, by default this name is relative to the project working directory. 17 | * @return The required file as a Value. 18 | */ 19 | public static Value require(String filename){ 20 | return require(filename,true); 21 | } 22 | 23 | /** 24 | * Require a file using the NodeJS api. 25 | * @param filename Name of the file you want to require. 26 | * @param scopedToProject if true will require the filename relative to 27 | * the working directory of the project (aka location of pom.xml and package.json), 28 | * otherwise filename will be relative to the Java entry point class (App.java). 29 | * @return The required file as a Value. 30 | */ 31 | public static Value require(String filename, boolean scopedToProject){ 32 | Value object = require.execute(String.format("%s%s", scopedToProject?WD:"/",filename)); 33 | return object; 34 | } 35 | 36 | /** 37 | * Parse a JSON string to an java Object. 38 | * @param input 39 | * @return The parsed Object. 40 | */ 41 | public static Object JSONParse(String input){ 42 | return json.invokeMember("parse", input).asHostObject(); 43 | } 44 | 45 | /** 46 | * Serialize a java HashMap of Objects into a string. 47 | * @param object 48 | * @return the serialized result. 49 | */ 50 | public static String JSONStringify(HashMap object){ 51 | return json.invokeMember("stringify", ProxyObject.fromMap(object)).asString(); 52 | } 53 | 54 | /** 55 | * Set the proxy for the "require" function.
56 | * This should be set to the NodeJS "require" function. 57 | * @param f the "require" function as Value 58 | */ 59 | public static void setRequire(Value f){ 60 | require = f; 61 | } 62 | 63 | /** 64 | * Set the proxy for the "JSON" javascript object. 65 | * @param o the "JSON" object. 66 | */ 67 | public static void setJson(Value o){ 68 | json = o; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/net/razshare/svelte3jssr/core/proxies/SvelteProxy.java: -------------------------------------------------------------------------------- 1 | package net.razshare.svelte3jssr.core.proxies; 2 | 3 | import java.util.HashMap; 4 | import java.util.function.Consumer; 5 | import net.razshare.svelte3jssr.core.models.SvelteComponentResult; 6 | import org.graalvm.polyglot.Value; 7 | import org.graalvm.polyglot.proxy.ProxyObject; 8 | 9 | public class SvelteProxy { 10 | private static Value compiler; 11 | private static Value render; 12 | 13 | /** 14 | * Parse a svelte input source code into a SvelteComponentResult object. 15 | * @param compiledSource The compiled svelte source code.
16 | * This is not the raw svelte source code, you must first pass your raw svelte code through the compiler. 17 | * @return The parsed SvelteComponentResult. 18 | */ 19 | public static SvelteComponentResult render(String compiledSource){ 20 | return render(compiledSource, new HashMap<>()); 21 | } 22 | 23 | /** 24 | * Parse a compiled svelte input source code into a SvelteComponentResult object. 25 | * @param compiledSource The compiled svelte source code.
26 | * This is not the raw svelte source code, you must first pass your raw svelte code through the compiler. 27 | * @param props Properties to pass to the svelte component. 28 | * @return The parsed SvelteComponentResult. 29 | */ 30 | public static SvelteComponentResult render(String compiledSource, HashMap props){ 31 | Value component = render.execute(compiledSource, ProxyObject.fromMap(props)); 32 | String jsCode = component.hasMember("js")?component.getMember("js").getMember("code").asString():""; 33 | String cssCode = component.hasMember("css")?component.getMember("css").getMember("code").asString():""; 34 | String head = component.getMember("head").asString(); 35 | String html = component.getMember("html").asString(); 36 | return new SvelteComponentResult(jsCode,cssCode,head,html); 37 | } 38 | 39 | /** 40 | * Compile a raw svelte input source code into it's javascript form.
41 | * The compilation is executed asynchronously. 42 | * @param rawSourceFileName The raw svelte source code. 43 | * @param generate Type of compilation.
44 | * This should be either "dom" or "ssr". 45 | * @param callback The callback that will be invoked when the compilation is completed. 46 | */ 47 | public static void compile(String rawSourceFileName, String generate, Consumer callback){ 48 | Value compiled = compiler.execute(rawSourceFileName, generate); 49 | compiled 50 | .invokeMember("then", (Consumer) (result)->{ 51 | callback.accept(result); 52 | }).invokeMember("catch", (Consumer) (result)->{ 53 | System.out.println("Some error occoured:\n"+result.toString()); 54 | }); 55 | 56 | } 57 | 58 | 59 | public static void ssr(String rawSourceFileName, Consumer callback) { 60 | ssr(rawSourceFileName,new HashMap<>(),callback); 61 | } 62 | 63 | 64 | public static void ssr(String rawSourceFileName, HashMap props, Consumer callback) { 65 | SvelteProxy.compile(rawSourceFileName, "ssr", (sourceSSR)->{ 66 | 67 | SvelteComponentResult result = SvelteProxy.render(sourceSSR,props); 68 | String head = result.getHead(); 69 | String body = result.getHtml(); 70 | String css = result.getCssCode(); 71 | 72 | SvelteProxy.compile(rawSourceFileName, "dom", (sourceDOM)->{ 73 | 74 | callback.accept(String.format( 75 | "" 76 | +"" 77 | +"" 78 | +"%s" 79 | +"" 80 | +"" 81 | +"" 82 | +"%s
" 83 | +"" 84 | +"" 85 | +"", 86 | head, 87 | css, 88 | body, 89 | String.format("((props)=>{window.Java={};const App = %s\ndocument.body.innerHTML = '';new App({target:document.body,props});})(%s)", sourceDOM, NodeProxy.JSONStringify(props).replaceAll("\"", "\\\"")) 90 | )); 91 | }); 92 | }); 93 | } 94 | 95 | public static void setCompiler(Value c){ 96 | compiler = c; 97 | } 98 | 99 | public static void setRender(Value f){ 100 | render = f; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/net/razshare/svelte3jssr/starter/Entry.java: -------------------------------------------------------------------------------- 1 | package net.razshare.svelte3jssr.starter; 2 | 3 | public class Entry { 4 | /** 5 | * Entry point of your Java application. 6 | */ 7 | public Entry(){ 8 | System.out.println("Java context started."); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/net/razshare/svelte3jssr/starter/callbacks/HttpRequestCallback.java: -------------------------------------------------------------------------------- 1 | package net.razshare.svelte3jssr.starter.callbacks; 2 | 3 | import java.nio.file.Paths; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | import net.razshare.svelte3jssr.core.proxies.SvelteProxy; 7 | import org.graalvm.polyglot.Value; 8 | import org.graalvm.polyglot.proxy.ProxyObject; 9 | 10 | public class HttpRequestCallback { 11 | 12 | 13 | private static final String WD = Paths.get("").toAbsolutePath().toString(); 14 | 15 | private static class Response{ 16 | private final Value res; 17 | public Response(Value response){ 18 | this.res = response; 19 | } 20 | 21 | public void end(String contents){ 22 | res.getMember("end").execute(contents); 23 | } 24 | 25 | public void writeHead(int statusCode, String reasonPhrase){ 26 | writeHead(statusCode, reasonPhrase, new HashMap<>()); 27 | } 28 | public void writeHead(int statusCode, String reasonPhrase, Map headerFields){ 29 | res.getMember("writeHead").execute(statusCode, reasonPhrase, ProxyObject.fromMap(headerFields)); 30 | } 31 | } 32 | 33 | private static class Request{ 34 | private final Value req; 35 | private String url; 36 | public Request(Value request){ 37 | this.req = request; 38 | url = request.getMember("url").asString(); 39 | 40 | if(url.endsWith("/") || "".equals(url)) 41 | url = "/index.html"; 42 | } 43 | 44 | public String getUrl(){ 45 | return url; 46 | } 47 | } 48 | 49 | public static void run(Value request, Value response){ 50 | Request req = new Request(request); 51 | Response res = new Response(response); 52 | 53 | res.writeHead(200,"OK", new HashMap<>(){{ 54 | put("Content-Type","text/html"); 55 | }}); 56 | 57 | SvelteProxy.ssr(String.format("%s/src/main/svelte/App.svelte", WD), new HashMap<>(){{ 58 | put("name", "world!"); 59 | }},(result)->{ 60 | res.end(result); 61 | }); 62 | } 63 | } -------------------------------------------------------------------------------- /src/main/java/net/razshare/svelte3jssr/starter/proxies/JavaProxy.java: -------------------------------------------------------------------------------- 1 | package net.razshare.svelte3jssr.starter.proxies; 2 | 3 | import java.io.IOException; 4 | import net.razshare.svelte3jssr.starter.callbacks.HttpRequestCallback; 5 | import org.graalvm.polyglot.Value; 6 | 7 | public class JavaProxy { 8 | public static void requestCallback(Value request, Value response) throws IOException{ 9 | HttpRequestCallback.run(request, response); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/net/razshare/svelte3jssr/starter/tools/TestClass.java: -------------------------------------------------------------------------------- 1 | package net.razshare.svelte3jssr.starter.tools; 2 | 3 | public class TestClass{ 4 | public String getMessage(){ 5 | return "This is a message from java"; 6 | } 7 | } -------------------------------------------------------------------------------- /src/main/svelte/App.svelte: -------------------------------------------------------------------------------- 1 | 14 | 24 |

hello {name}!

25 | -------------------------------------------------------------------------------- /src/main/svelte/SomeComponent.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 | This is a secondary component imported using "import". 6 | 7 | Counter: {counter} 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/main/svelte/scripts/test.mjs: -------------------------------------------------------------------------------- 1 | export default function test(){ 2 | console.log("test") 3 | } -------------------------------------------------------------------------------- /src/test/java/net/razshare/svelte3jssr/AppTest.java: -------------------------------------------------------------------------------- 1 | package net.razshare.svelte3jssr; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest 11 | { 12 | /** 13 | * Rigorous Test :-) 14 | */ 15 | @Test 16 | public void shouldAnswerWithTrue() 17 | { 18 | assertTrue( true ); 19 | } 20 | } 21 | --------------------------------------------------------------------------------