@quintype/framework 7.0.2-gtm.0 → 7.0.2-test-worker.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/start.js +83 -25
- package/package.json +1 -1
- package/server/start.js +4 -6
package/client/start.js
CHANGED
|
@@ -7,7 +7,12 @@
|
|
|
7
7
|
* @module start
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
BreakingNews,
|
|
12
|
+
CLIENT_SIDE_RENDERED,
|
|
13
|
+
NAVIGATE_TO_PAGE,
|
|
14
|
+
PAGE_LOADING
|
|
15
|
+
} from "@quintype/components";
|
|
11
16
|
import { createBrowserHistory } from "history";
|
|
12
17
|
import get from "lodash/get";
|
|
13
18
|
import React from "react";
|
|
@@ -16,12 +21,17 @@ import { Provider } from "react-redux";
|
|
|
16
21
|
import { IsomorphicComponent } from "../isomorphic/component";
|
|
17
22
|
import { makePickComponentSync } from "../isomorphic/impl/make-pick-component-sync";
|
|
18
23
|
import { createQtStore } from "../store/create-store";
|
|
19
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
registerPageView,
|
|
26
|
+
registerStoryShare,
|
|
27
|
+
setMemberId,
|
|
28
|
+
startAnalytics
|
|
29
|
+
} from "./analytics";
|
|
20
30
|
import { initializeFCM } from "./impl/fcm";
|
|
21
31
|
import {
|
|
22
32
|
checkForServiceWorkerUpdates,
|
|
23
33
|
registerServiceWorker,
|
|
24
|
-
setupServiceWorkerUpdates
|
|
34
|
+
setupServiceWorkerUpdates
|
|
25
35
|
} from "./impl/load-service-worker";
|
|
26
36
|
|
|
27
37
|
require("../assetify/client")();
|
|
@@ -45,20 +55,28 @@ export const app = {
|
|
|
45
55
|
};
|
|
46
56
|
|
|
47
57
|
function getRouteDataAndPath(path, mountAt) {
|
|
48
|
-
const relativePath = path.startsWith(mountAt)
|
|
58
|
+
const relativePath = path.startsWith(mountAt)
|
|
59
|
+
? path.slice(mountAt.length)
|
|
60
|
+
: path;
|
|
49
61
|
return [`${mountAt || ""}/route-data.json`, relativePath];
|
|
50
62
|
}
|
|
51
63
|
|
|
52
|
-
function getRouteData(
|
|
64
|
+
function getRouteData(
|
|
65
|
+
path,
|
|
66
|
+
{ location = global.location, existingFetch, mountAt = global.qtMountAt }
|
|
67
|
+
) {
|
|
53
68
|
// if mountAt is set, then hit /mountAt/route-data, remove mountAt from path
|
|
54
69
|
|
|
55
70
|
const [routeDataPath, relativePath] = getRouteDataAndPath(path, mountAt);
|
|
56
71
|
const url = new URL(relativePath, location.origin);
|
|
57
72
|
return (
|
|
58
73
|
existingFetch ||
|
|
59
|
-
fetch(
|
|
60
|
-
|
|
61
|
-
|
|
74
|
+
fetch(
|
|
75
|
+
`${routeDataPath}?path=${encodeURIComponent(url.pathname)}${
|
|
76
|
+
url.search ? `&${url.search.slice(1)}` : ""
|
|
77
|
+
}`,
|
|
78
|
+
{ credentials: "same-origin" }
|
|
79
|
+
)
|
|
62
80
|
)
|
|
63
81
|
.then((response) => {
|
|
64
82
|
if (response.status == 404) {
|
|
@@ -81,7 +99,11 @@ function getRouteData(path, { location = global.location, existingFetch, mountAt
|
|
|
81
99
|
}
|
|
82
100
|
|
|
83
101
|
function maybeBypassServiceWorker(e) {
|
|
84
|
-
if (
|
|
102
|
+
if (
|
|
103
|
+
global.qtLoadedFromShell ||
|
|
104
|
+
`${location.pathname}${location.search}${location.hash}` !=
|
|
105
|
+
`${path}#bypass-sw`
|
|
106
|
+
) {
|
|
85
107
|
location.href = `${path}#bypass-sw`;
|
|
86
108
|
location.reload();
|
|
87
109
|
}
|
|
@@ -102,7 +124,8 @@ let pickComponentWrapper = null;
|
|
|
102
124
|
* @returns {void}
|
|
103
125
|
*/
|
|
104
126
|
export function navigateToPage(dispatch, path, doNotPushPath) {
|
|
105
|
-
const pathname =
|
|
127
|
+
const pathname =
|
|
128
|
+
!path || path === "undefined" ? global.location.pathname : path;
|
|
106
129
|
|
|
107
130
|
if (global.disableAjaxNavigation) {
|
|
108
131
|
global.location = pathname;
|
|
@@ -111,7 +134,8 @@ export function navigateToPage(dispatch, path, doNotPushPath) {
|
|
|
111
134
|
dispatch({ type: PAGE_LOADING });
|
|
112
135
|
getRouteData(pathname, {}).then((page) => {
|
|
113
136
|
if (!page) {
|
|
114
|
-
console &&
|
|
137
|
+
console &&
|
|
138
|
+
console.log("Recieved a null page. Expecting the browser to redirect.");
|
|
115
139
|
return;
|
|
116
140
|
}
|
|
117
141
|
|
|
@@ -123,7 +147,8 @@ export function navigateToPage(dispatch, path, doNotPushPath) {
|
|
|
123
147
|
}
|
|
124
148
|
|
|
125
149
|
Promise.resolve(
|
|
126
|
-
pickComponentWrapper &&
|
|
150
|
+
pickComponentWrapper &&
|
|
151
|
+
pickComponentWrapper.preloadComponent(page.pageType, page.subPageType)
|
|
127
152
|
).then(() => {
|
|
128
153
|
dispatch({
|
|
129
154
|
type: NAVIGATE_TO_PAGE,
|
|
@@ -152,7 +177,8 @@ export function navigateToPage(dispatch, path, doNotPushPath) {
|
|
|
152
177
|
* @returns {void}
|
|
153
178
|
*/
|
|
154
179
|
export function maybeNavigateTo(path, store) {
|
|
155
|
-
if (store.getState().qt.currentPath != path)
|
|
180
|
+
if (store.getState().qt.currentPath != path)
|
|
181
|
+
navigateToPage(store.dispatch, path, true);
|
|
156
182
|
}
|
|
157
183
|
|
|
158
184
|
/**
|
|
@@ -179,12 +205,24 @@ export function maybeSetUrl(path, title) {
|
|
|
179
205
|
* @param {callback} callback Callback on completion
|
|
180
206
|
*/
|
|
181
207
|
export function renderComponent(clazz, container, store, props = {}, callback) {
|
|
182
|
-
const component = React.createElement(
|
|
208
|
+
const component = React.createElement(
|
|
209
|
+
Provider,
|
|
210
|
+
{ store },
|
|
211
|
+
React.createElement(clazz, props || {})
|
|
212
|
+
);
|
|
183
213
|
|
|
184
214
|
if (props.hydrate) {
|
|
185
|
-
return ReactDOM.hydrate(
|
|
215
|
+
return ReactDOM.hydrate(
|
|
216
|
+
component,
|
|
217
|
+
document.getElementById(container),
|
|
218
|
+
callback
|
|
219
|
+
);
|
|
186
220
|
}
|
|
187
|
-
return ReactDOM.render(
|
|
221
|
+
return ReactDOM.render(
|
|
222
|
+
component,
|
|
223
|
+
document.getElementById(container),
|
|
224
|
+
callback
|
|
225
|
+
);
|
|
188
226
|
}
|
|
189
227
|
|
|
190
228
|
/**
|
|
@@ -195,11 +233,19 @@ export function renderComponent(clazz, container, store, props = {}, callback) {
|
|
|
195
233
|
* @param {Object} props Properties to bootstrap the component with
|
|
196
234
|
* @param {boolean} props.hydrate Hydrate the component instead of rendering it
|
|
197
235
|
*/
|
|
198
|
-
export function renderIsomorphicComponent(
|
|
236
|
+
export function renderIsomorphicComponent(
|
|
237
|
+
container,
|
|
238
|
+
store,
|
|
239
|
+
pickComponent,
|
|
240
|
+
props
|
|
241
|
+
) {
|
|
199
242
|
if (!store.getState().qt.disableIsomorphicComponent) {
|
|
200
243
|
pickComponentWrapper = makePickComponentSync(pickComponent);
|
|
201
244
|
return pickComponentWrapper
|
|
202
|
-
.preloadComponent(
|
|
245
|
+
.preloadComponent(
|
|
246
|
+
store.getState().qt.pageType,
|
|
247
|
+
store.getState().qt.subPageType
|
|
248
|
+
)
|
|
203
249
|
.then(() =>
|
|
204
250
|
renderComponent(
|
|
205
251
|
IsomorphicComponent,
|
|
@@ -221,7 +267,12 @@ export function renderIsomorphicComponent(container, store, pickComponent, props
|
|
|
221
267
|
* @param {Object} props Properties to bootstrap the component with
|
|
222
268
|
*/
|
|
223
269
|
export function renderBreakingNews(container, store, view, props) {
|
|
224
|
-
return renderComponent(
|
|
270
|
+
return renderComponent(
|
|
271
|
+
BreakingNews,
|
|
272
|
+
container,
|
|
273
|
+
store,
|
|
274
|
+
Object.assign({ view }, props)
|
|
275
|
+
);
|
|
225
276
|
}
|
|
226
277
|
|
|
227
278
|
function getJsonContent(id) {
|
|
@@ -255,7 +306,8 @@ export function startApp(renderApplication, reducers, opts) {
|
|
|
255
306
|
global.app = app;
|
|
256
307
|
const { location } = global;
|
|
257
308
|
const path = `${location.pathname}${location.search || ""}`;
|
|
258
|
-
const staticData =
|
|
309
|
+
const staticData =
|
|
310
|
+
global.staticPageStoreContent || getJsonContent("static-page");
|
|
259
311
|
const dataPromise = staticData
|
|
260
312
|
? Promise.resolve(staticData.qt)
|
|
261
313
|
: getRouteData(path, { existingFetch: global.initialFetch });
|
|
@@ -264,7 +316,10 @@ export function startApp(renderApplication, reducers, opts) {
|
|
|
264
316
|
|
|
265
317
|
const store = createQtStore(
|
|
266
318
|
reducers,
|
|
267
|
-
(staticData && staticData.qt) ||
|
|
319
|
+
(staticData && staticData.qt) ||
|
|
320
|
+
global.initialPage ||
|
|
321
|
+
getJsonContent("initial-page") ||
|
|
322
|
+
{},
|
|
268
323
|
{}
|
|
269
324
|
);
|
|
270
325
|
|
|
@@ -276,7 +331,8 @@ export function startApp(renderApplication, reducers, opts) {
|
|
|
276
331
|
|
|
277
332
|
function doStartApp(page, opts) {
|
|
278
333
|
if (!page) {
|
|
279
|
-
console &&
|
|
334
|
+
console &&
|
|
335
|
+
console.log("Received a null page. Expecting the browser to redirect.");
|
|
280
336
|
return;
|
|
281
337
|
}
|
|
282
338
|
|
|
@@ -289,18 +345,20 @@ export function startApp(renderApplication, reducers, opts) {
|
|
|
289
345
|
const { config: { "theme-attributes": pageThemeAttributes = {} } = {} } = page;
|
|
290
346
|
const version = pageThemeAttributes["cache-burst"] || app.getAppVersion();
|
|
291
347
|
|
|
292
|
-
const serviceWorkerPromise = registerServiceWorker({
|
|
348
|
+
const serviceWorkerPromise = registerServiceWorker({...opts, version});
|
|
293
349
|
|
|
294
350
|
setupServiceWorkerUpdates(serviceWorkerPromise, app, store, page, opts);
|
|
295
351
|
|
|
296
352
|
runWithTiming("qt_render", () => renderApplication(store));
|
|
297
353
|
|
|
298
|
-
history.listen((change) =>
|
|
354
|
+
history.listen((change) =>
|
|
355
|
+
app.maybeNavigateTo(`${change.pathname}${change.search || ""}`, store)
|
|
356
|
+
);
|
|
299
357
|
|
|
300
358
|
registerPageView(store.getState().qt);
|
|
301
359
|
|
|
302
360
|
if (page.title) {
|
|
303
|
-
global.document.title =
|
|
361
|
+
global.document.title = get(
|
|
304
362
|
page,
|
|
305
363
|
["data", "customSeo", "title"],
|
|
306
364
|
get(page, ["data", "story", "seo", "meta-title"], page.title)
|
package/package.json
CHANGED
package/server/start.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// istanbul ignore file
|
|
11
11
|
// This is the start file, to be called from your start.js
|
|
12
12
|
|
|
13
|
-
const chalk = require(
|
|
13
|
+
const chalk = require("chalk");
|
|
14
14
|
const cluster = require("cluster");
|
|
15
15
|
const process = require("process");
|
|
16
16
|
const { initializeAllClients } = require("./api-client");
|
|
@@ -48,9 +48,7 @@ function startMaster({ workers = 4 }) {
|
|
|
48
48
|
|
|
49
49
|
cluster.on("exit", (worker, code, signal) => {
|
|
50
50
|
logger.error(`worker ${worker.process.pid} died`);
|
|
51
|
-
const aliveWorkers = Object.values(cluster.workers).filter(
|
|
52
|
-
(worker) => worker.state !== "dead"
|
|
53
|
-
);
|
|
51
|
+
const aliveWorkers = Object.values(cluster.workers).filter((worker) => worker.state !== "dead");
|
|
54
52
|
|
|
55
53
|
if (terminating) {
|
|
56
54
|
if (aliveWorkers.length == 0) {
|
|
@@ -75,7 +73,7 @@ async function startWorker(appThunk, opts) {
|
|
|
75
73
|
await initializeAllClients();
|
|
76
74
|
const server = app.listen(opts.port || 3000, () => {
|
|
77
75
|
console.log(logSuccess(`||=============================||`));
|
|
78
|
-
console.log(logSuccess(`|| App listening on port ${opts.port || 3000}! ||`))
|
|
76
|
+
console.log(logSuccess(`|| App listening on port ${opts.port || 3000}! ||`));
|
|
79
77
|
console.log(logSuccess(`||=============================||`));
|
|
80
78
|
});
|
|
81
79
|
|
|
@@ -93,7 +91,7 @@ async function startWorker(appThunk, opts) {
|
|
|
93
91
|
|
|
94
92
|
e = e || "";
|
|
95
93
|
const sleep = require("sleep-promise");
|
|
96
|
-
logger.error(`Worker died - ${e.message || e}`);
|
|
94
|
+
logger.error(`Worker died - ${JSON.stringify(e.message) || JSON.stringify(e)}`);
|
|
97
95
|
cluster.worker.disconnect();
|
|
98
96
|
await sleep(opts.sleep || 250);
|
|
99
97
|
process.exit();
|