?
//sink.renderIntoElementById('react-app', content)
@@ -52,6 +61,13 @@ const makePageRenderer = ({ computeContext }) => {
)
sink.appendToBody(serializedApolloState)
+
+ // post render callback
+ runCallbacks({
+ name: 'router.server.postRender',
+ iterator: sink,
+ properties: { context }
+ });
}
return renderPage
}
diff --git a/packages/vulcan-redux/lib/client/main.js b/packages/vulcan-redux/lib/client/main.js
new file mode 100644
index 000000000..b1216bb37
--- /dev/null
+++ b/packages/vulcan-redux/lib/client/main.js
@@ -0,0 +1,4 @@
+import setupRedux from './setupRedux';
+setupRedux();
+
+export * from '../modules/index';
diff --git a/packages/vulcan-redux/lib/client/setupRedux.js b/packages/vulcan-redux/lib/client/setupRedux.js
new file mode 100644
index 000000000..9bba72013
--- /dev/null
+++ b/packages/vulcan-redux/lib/client/setupRedux.js
@@ -0,0 +1,13 @@
+import React from 'react'
+import { Provider } from 'react-redux'
+import { addCallback } from 'meteor/vulcan:core'
+import { initStore } from '../modules/store'
+
+const setupRedux = () => {
+ const store = initStore()
+ addCallback('router.client.wrapper',
+ function ReduxStoreProvider(app) {
+ return
{app}
+ });
+}
+export default setupRedux
\ No newline at end of file
diff --git a/packages/vulcan-redux/lib/modules/index.js b/packages/vulcan-redux/lib/modules/index.js
new file mode 100644
index 000000000..efc4a60c0
--- /dev/null
+++ b/packages/vulcan-redux/lib/modules/index.js
@@ -0,0 +1 @@
+export * from './redux.js';
\ No newline at end of file
diff --git a/packages/vulcan-redux/lib/modules/redux.js b/packages/vulcan-redux/lib/modules/redux.js
new file mode 100644
index 000000000..078dc8266
--- /dev/null
+++ b/packages/vulcan-redux/lib/modules/redux.js
@@ -0,0 +1,96 @@
+import { createStore, applyMiddleware, compose, combineReducers } from 'redux';
+import _isEmpty from 'lodash/isEmpty'
+// TODO: now we should add some callback call to add the store to
+// Apollo SSR + client side too
+
+// create store, and implement reload function
+export const configureStore = (reducers = getReducers, initialState = {}, middlewares = getMiddlewares) => {
+ let getReducers;
+ if (typeof reducers === 'function') {
+ getReducers = reducers;
+ reducers = getReducers();
+ }
+ if (typeof reducers === 'object') {
+ // allow to tolerate empty reducers
+ //@see https://github.com/reduxjs/redux/issues/968
+ reducers = !_isEmpty(reducers) ? combineReducers(reducers) : () => {}
+ }
+ let getMiddlewares;
+ if (typeof middlewares === 'function') {
+ getMiddlewares = middlewares;
+ middlewares = getMiddlewares();
+ }
+ middlewares = Array.isArray(middlewares) ? middlewares : [middlewares];
+ const store = createStore(
+ // reducers
+ reducers,
+ // initial state
+ initialState,
+ // middlewares
+ compose(
+ applyMiddleware(...middlewares),
+ typeof window !== 'undefined' && window.devToolsExtension ? window.devToolsExtension() : f => f,
+ ),
+ );
+ store.reload = function reload(options = {}) {
+ if (typeof options.reducers === 'function') {
+ getReducers = options.reducers;
+ options.reducers = undefined;
+ }
+ if (!options.reducers && getReducers) {
+ options.reducers = getReducers();
+ }
+ if (options.reducers) {
+ reducers = typeof options.reducers === 'object' ? combineReducers(options.reducers) : options.reducers;
+ }
+ this.replaceReducer(reducers);
+ return store;
+ };
+ return store;
+};
+
+// action
+// **Notes: client side, addAction to browser**
+// **Notes: server side, addAction to server share with every req**
+let actions = {};
+export const addAction = (addedAction) => {
+ actions = { ...actions, ...addedAction };
+ return actions;
+};
+export const getActions = () => actions;
+// reducers
+// **Notes: client side, addReducer to browser**
+// **Notes: server side, addReducer to server share with every req**
+let reducers = {};
+
+export const addReducer = (addedReducer) => {
+ reducers = { ...reducers, ...addedReducer };
+ return reducers;
+};
+export const getReducers = () => reducers;
+// middlewares
+// **Notes: client side, addMiddleware to browser**
+// **Notes: server side, addMiddleware to server share with every req**
+let middlewares = [];
+
+export const addMiddleware = (middlewareOrMiddlewareArray, options = {}) => {
+ const addedMiddleware = Array.isArray(middlewareOrMiddlewareArray) ? middlewareOrMiddlewareArray : [middlewareOrMiddlewareArray];
+ if (options.unshift) {
+ middlewares = [...addedMiddleware, ...middlewares];
+ } else {
+ middlewares = [...middlewares, ...addedMiddleware];
+ }
+ return middlewares;
+};
+export const getMiddlewares = () => middlewares;
+
+
+
+let store
+export const initStore = () => {
+ if (!store) {
+ store = configureStore()
+ }
+ return store
+}
+export const getStore = () => store
diff --git a/packages/vulcan-redux/lib/server/main.js b/packages/vulcan-redux/lib/server/main.js
new file mode 100644
index 000000000..b1216bb37
--- /dev/null
+++ b/packages/vulcan-redux/lib/server/main.js
@@ -0,0 +1,4 @@
+import setupRedux from './setupRedux';
+setupRedux();
+
+export * from '../modules/index';
diff --git a/packages/vulcan-redux/lib/server/setupRedux.js b/packages/vulcan-redux/lib/server/setupRedux.js
new file mode 100644
index 000000000..52e9df38d
--- /dev/null
+++ b/packages/vulcan-redux/lib/server/setupRedux.js
@@ -0,0 +1,13 @@
+import React from 'react'
+import { Provider } from 'react-redux'
+import { addCallback } from 'meteor/vulcan:core'
+import { initStore } from '../modules/redux'
+
+const setupRedux = () => {
+ const store = initStore()
+ addCallback('router.server.wrapper',
+ function ReduxStoreProvider(app) {
+ return
{app}
+ });
+}
+export default setupRedux
\ No newline at end of file
diff --git a/packages/vulcan-redux/package.js b/packages/vulcan-redux/package.js
new file mode 100644
index 000000000..c0b010cd4
--- /dev/null
+++ b/packages/vulcan-redux/package.js
@@ -0,0 +1,18 @@
+Package.describe({
+ name: 'vulcan:redux',
+ summary: 'Add Redux to Vulcan.',
+ version: '1.12.8',
+ git: 'https://github.com/VulcanJS/Vulcan.git'
+});
+
+Package.onUse(function(api) {
+ api.versionsFrom('1.6.1');
+
+
+ api.use([
+ 'vulcan:core@1.12.8',
+ ]);
+
+ api.mainModule('lib/server/main.js', 'server');
+ api.mainModule('lib/client/main.js', 'client');
+});
\ No newline at end of file
diff --git a/packages/vulcan-styled-components/lib/client/main.js b/packages/vulcan-styled-components/lib/client/main.js
new file mode 100644
index 000000000..172944a07
--- /dev/null
+++ b/packages/vulcan-styled-components/lib/client/main.js
@@ -0,0 +1 @@
+export * from '../modules/index';
diff --git a/packages/vulcan-styled-components/lib/modules/index.js b/packages/vulcan-styled-components/lib/modules/index.js
new file mode 100644
index 000000000..e69de29bb
diff --git a/packages/vulcan-styled-components/lib/server/main.js b/packages/vulcan-styled-components/lib/server/main.js
new file mode 100644
index 000000000..da2cb405c
--- /dev/null
+++ b/packages/vulcan-styled-components/lib/server/main.js
@@ -0,0 +1,4 @@
+import setupStyledComponents from './setupStyledComponents';
+setupStyledComponents();
+
+export * from '../modules/index';
diff --git a/packages/vulcan-styled-components/lib/server/setupStyledComponents.js b/packages/vulcan-styled-components/lib/server/setupStyledComponents.js
new file mode 100644
index 000000000..24443f75f
--- /dev/null
+++ b/packages/vulcan-styled-components/lib/server/setupStyledComponents.js
@@ -0,0 +1,23 @@
+// Setup SSR
+import { ServerStyleSheet } from 'styled-components'
+import { addCallback } from 'meteor/vulcan:core';
+
+const setupStyledComponents = () => {
+ addCallback('router.server.wrapper', function collectStyles(app, { context }) {
+ const stylesheet = new ServerStyleSheet();
+ // @see https://www.styled-components.com/docs/advanced/#example
+ const wrappedApp = stylesheet.collectStyles(app)
+ // store the stylesheet to reuse it later
+ context.stylesheet = stylesheet
+ return wrappedApp
+
+ })
+
+ addCallback('router.server.postRender', function appendStyleTags(sink, { context }) {
+ sink.appendToHead(context.stylesheet.getStyleTags())
+ return sink
+ })
+}
+
+
+export default setupStyledComponents
\ No newline at end of file
diff --git a/packages/vulcan-styled-components/package.js b/packages/vulcan-styled-components/package.js
new file mode 100644
index 000000000..eeb941acf
--- /dev/null
+++ b/packages/vulcan-styled-components/package.js
@@ -0,0 +1,17 @@
+Package.describe({
+ name: 'vulcan:styled-components',
+ summary: 'Add Styled Components to Vulcan.',
+ version: '1.12.8',
+ git: 'https://github.com/VulcanJS/Vulcan.git'
+});
+
+Package.onUse(function(api) {
+ api.versionsFrom('1.6.1');
+
+ api.use([
+ 'vulcan:core@1.12.8',
+ ]);
+
+ api.mainModule('lib/server/main.js', 'server');
+ api.mainModule('lib/client/main.js', 'client');
+});
\ No newline at end of file