use store in SSR mode

pull/951/head
Rich Harris 7 years ago
parent f64e473d2e
commit be68cd9de2

@ -73,16 +73,22 @@ export default function ssr(
generator.stylesheet.render(options.filename, true); generator.stylesheet.render(options.filename, true);
// generate initial state object // generate initial state object
// TODO this doesn't work, because expectedProperties isn't populated const expectedProperties = Array.from(generator.expectedProperties);
const globals = Array.from(generator.expectedProperties).filter(prop => globalWhitelist.has(prop)); const globals = expectedProperties.filter(prop => globalWhitelist.has(prop));
const storeProps = options.store ? expectedProperties.filter(prop => prop[0] === '$') : [];
const initialState = []; const initialState = [];
if (globals.length > 0) { if (globals.length > 0) {
initialState.push(`{ ${globals.map(prop => `${prop} : ${prop}`).join(', ')} }`); initialState.push(`{ ${globals.map(prop => `${prop} : ${prop}`).join(', ')} }`);
} }
if (storeProps.length > 0) {
initialState.push(`options.store._init([${storeProps.map(prop => `"${prop.slice(1)}"`)}])`);
}
if (templateProperties.data) { if (templateProperties.data) {
initialState.push(`%data()`); initialState.push(`%data()`);
} else if (globals.length === 0) { } else if (globals.length === 0 && storeProps.length === 0) {
initialState.push('{}'); initialState.push('{}');
} }
@ -99,7 +105,7 @@ export default function ssr(
return ${templateProperties.data ? `%data()` : `{}`}; return ${templateProperties.data ? `%data()` : `{}`};
}; };
${name}.render = function(state, options) { ${name}.render = function(state, options = {}) {
state = Object.assign(${initialState.join(', ')}); state = Object.assign(${initialState.join(', ')});
${computations.map( ${computations.map(

@ -79,6 +79,11 @@ export default function visitComponent(
let open = `\${${expression}.render({${props}}`; let open = `\${${expression}.render({${props}}`;
const options = [];
if (generator.options.store) {
options.push(`store: options.store`);
}
if (node.children.length) { if (node.children.length) {
const appendTarget: AppendTarget = { const appendTarget: AppendTarget = {
slots: { default: '' }, slots: { default: '' },
@ -95,11 +100,15 @@ export default function visitComponent(
.map(name => `${name}: () => \`${appendTarget.slots[name]}\``) .map(name => `${name}: () => \`${appendTarget.slots[name]}\``)
.join(', '); .join(', ');
open += `, { slotted: { ${slotted} } }`; options.push(`slotted: { ${slotted} }`);
generator.appendTargets.pop(); generator.appendTargets.pop();
} }
if (options.length) {
open += `, { ${options.join(', ')} }`;
}
generator.append(open); generator.append(open);
generator.append(')}'); generator.append(')}');
} }

@ -2,16 +2,22 @@ import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
import { compile } from '../index.ts'; import { compile } from '../index.ts';
const compileOptions = {};
function capitalise(name) { function capitalise(name) {
return name[0].toUpperCase() + name.slice(1); return name[0].toUpperCase() + name.slice(1);
} }
export default function register(options) { export default function register(options) {
const { extensions } = options; const { extensions } = options;
if (extensions) { if (extensions) {
_deregister('.html'); _deregister('.html');
extensions.forEach(_register); extensions.forEach(_register);
} }
// TODO make this the default and remove in v2
if ('store' in options) compileOptions.store = options.store;
} }
function _deregister(extension) { function _deregister(extension) {
@ -20,13 +26,15 @@ function _deregister(extension) {
function _register(extension) { function _register(extension) {
require.extensions[extension] = function(module, filename) { require.extensions[extension] = function(module, filename) {
const {code} = compile(fs.readFileSync(filename, 'utf-8'), { const options = Object.assign({}, compileOptions, {
filename, filename,
name: capitalise(path.basename(filename) name: capitalise(path.basename(filename)
.replace(new RegExp(`${extension.replace('.', '\\.')}$`), '')), .replace(new RegExp(`${extension.replace('.', '\\.')}$`), '')),
generate: 'ssr', generate: 'ssr'
}); });
const {code} = compile(fs.readFileSync(filename, 'utf-8'), options);
return module._compile(code, filename); return module._compile(code, filename);
}; };
} }

@ -4,7 +4,7 @@ SvelteComponent.data = function() {
return {}; return {};
}; };
SvelteComponent.render = function(state, options) { SvelteComponent.render = function(state, options = {}) {
state = Object.assign({}, state); state = Object.assign({}, state);
return ``.trim(); return ``.trim();

@ -6,7 +6,7 @@ SvelteComponent.data = function() {
return {}; return {};
}; };
SvelteComponent.render = function(state, options) { SvelteComponent.render = function(state, options = {}) {
state = Object.assign({}, state); state = Object.assign({}, state);
return ``.trim(); return ``.trim();

@ -22,7 +22,8 @@ function tryToReadFile(file) {
describe("ssr", () => { describe("ssr", () => {
before(() => { before(() => {
require("../../ssr/register")({ require("../../ssr/register")({
extensions: ['.svelte', '.html'] extensions: ['.svelte', '.html'],
store: true
}); });
return setupHtmlEqual(); return setupHtmlEqual();
@ -98,9 +99,15 @@ describe("ssr", () => {
delete require.cache[resolved]; delete require.cache[resolved];
}); });
require("../../ssr/register")({
store: !!config.store
});
try { try {
const component = require(`../runtime/samples/${dir}/main.html`); const component = require(`../runtime/samples/${dir}/main.html`);
const html = component.render(config.data); const html = component.render(config.data, {
store: config.store
});
if (config.html) { if (config.html) {
assert.htmlEqual(html, config.html); assert.htmlEqual(html, config.html);

Loading…
Cancel
Save