├── .babelrc ├── .editorconfig ├── .eslintrc ├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── package.json └── src └── index.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "airbnb" 4 | ] 5 | } -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | indent_size = 2 3 | indent_style = space -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "airbnb-base" 4 | ], 5 | "rules": { 6 | "import/no-unresolved": 0 7 | } 8 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Directory for instrumented libs generated by jscoverage/JSCover 7 | lib-cov 8 | 9 | # Coverage directory used by tools like istanbul 10 | coverage 11 | 12 | # node-waf configuration 13 | .lock-wscript 14 | 15 | # Compiled binary addons (http://nodejs.org/api/addons.html) 16 | build/Release 17 | 18 | # Dependency directory 19 | node_modules 20 | 21 | # Optional npm cache directory 22 | .npm 23 | 24 | # Optional REPL history 25 | .node_repl_history 26 | 27 | TODO 28 | coverage 29 | lib 30 | 31 | # Only apps should have lockfiles 32 | npm-shrinkwrap.json 33 | yarn.lock 34 | package-lock.json 35 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 Felipe Guizar Diaz 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # hypernova-svelte 2 | 3 | [Svelte](https://github.com/sveltejs/svelte) bindings for [Hypernova](https://github.com/airbnb/hypernova). 4 | 5 | On the server, wraps the component in a function to render it to a HTML string given its props. 6 | 7 | On the client, calling this function with your component scans the DOM for any server-side rendered instances of it. It then resumes those components using the server-specified props. 8 | 9 | ## Install 10 | 11 | ```sh 12 | npm install hypernova-svelte 13 | ``` 14 | 15 | ## Usage 16 | 17 | Here's how to use it in your module: 18 | 19 | ```js 20 | import { renderSvelte } from 'hypernova-svelte' 21 | import HeaderComponent from './components/HeaderComponent.svelte' 22 | 23 | export default renderSvelte('Header', HeaderComponent) 24 | ``` -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hypernova-svelte", 3 | "version": "1.2.0", 4 | "description": "Svelte Bindings for Hypernova", 5 | "main": "lib/index.js", 6 | "author": "Felipe Guizar Diaz ", 7 | "license": "MIT", 8 | "keywords": [ 9 | "svelte", 10 | "hypernova", 11 | "ssr", 12 | "isomorphic" 13 | ], 14 | "repository": { 15 | "type": "git", 16 | "url": "git@github.com:marconi1992/hypernova-svelte.git" 17 | }, 18 | "scripts": { 19 | "prepublish": "npm run build", 20 | "lint": "eslint src", 21 | "build": "babel src -d lib" 22 | }, 23 | "dependencies": { 24 | "hypernova": "^2.5.0", 25 | "nova-helpers": "^1.0.1-alpha.0" 26 | }, 27 | "devDependencies": { 28 | "@babel/cli": "^7.5.5", 29 | "@babel/core": "^7.5.5", 30 | "@babel/runtime": "^7.5.5", 31 | "babel-preset-airbnb": "^4.0.1", 32 | "eslint": "^6.6.0", 33 | "eslint-config-airbnb-base": "^14.0.0", 34 | "eslint-plugin-import": "^2.16.0" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import hypernova, { serialize, load } from 'hypernova'; 2 | import { findNode, getData } from 'nova-helpers'; 3 | 4 | export { load } from 'hypernova'; 5 | 6 | export const loadById = (name, id) => { 7 | const node = findNode(name, id); 8 | const data = getData(name, id); 9 | 10 | if (node && data) { 11 | return { 12 | node, 13 | data, 14 | }; 15 | } 16 | 17 | return null; 18 | }; 19 | 20 | export const mountComponent = (Component, node, data) => new Component({ 21 | target: node, 22 | props: data, 23 | hydrate: true, 24 | }); 25 | 26 | export const renderInPlaceholder = (name, Component, id) => { 27 | const node = findNode(name, id); 28 | const data = getData(name, id); 29 | 30 | if (node && data) { 31 | mountComponent(Component, node, data); 32 | } 33 | }; 34 | 35 | export const renderSvelte = (name, Component) => hypernova({ 36 | server() { 37 | return (propsData) => { 38 | const { html } = Component.render(propsData); 39 | 40 | return serialize(name, html, propsData); 41 | }; 42 | }, 43 | 44 | client() { 45 | const payloads = load(name); 46 | if (payloads) { 47 | payloads.forEach((payload) => { 48 | const { node, data: propsData } = payload; 49 | 50 | return mountComponent(Component, node, propsData); 51 | }); 52 | } 53 | 54 | return Component; 55 | }, 56 | }); 57 | --------------------------------------------------------------------------------