@thoughtbot/superglue 0.54.0 → 1.0.0

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.
@@ -1,33 +1,223 @@
1
1
  import {
2
- BEFORE_FETCH,
3
- BEFORE_REMOTE,
4
- BEFORE_VISIT,
5
- COPY_PAGE,
6
2
  GRAFTING_ERROR,
7
3
  GRAFTING_SUCCESS,
8
- HANDLE_GRAFT,
9
- HISTORY_CHANGE,
10
- KeyPathError,
11
- REMOVE_PAGE,
12
- SAVE_RESPONSE,
13
- SET_CSRF_TOKEN,
14
- UPDATE_FRAGMENTS,
15
- actions_exports,
16
4
  argsForHistory,
5
+ beforeFetch,
6
+ beforeRemote,
7
+ beforeVisit,
17
8
  config,
9
+ copyPage,
18
10
  getIn,
19
- mapDispatchToProps,
20
- mapStateToProps,
11
+ handleGraft,
12
+ historyChange,
13
+ parsePageKey,
21
14
  pathWithoutBZParams,
15
+ removePage,
22
16
  saveAndProcessPage,
17
+ saveResponse,
18
+ setActivePage,
19
+ setCSRFToken,
23
20
  setIn,
24
21
  ujsHandlers,
22
+ updateFragments,
25
23
  urlToPageKey
26
- } from "./chunk-MNVGYKSD.mjs";
24
+ } from "./chunk-LGUVOEZ3.mjs";
27
25
 
28
26
  // lib/index.tsx
29
- import React2 from "react";
27
+ import React2, { useRef, useMemo } from "react";
30
28
  import parse from "url-parse";
29
+ import { Provider } from "react-redux";
30
+ import { createBrowserHistory, createMemoryHistory } from "history";
31
+
32
+ // lib/components/Navigation.tsx
33
+ import React, {
34
+ createContext,
35
+ useEffect,
36
+ forwardRef,
37
+ useImperativeHandle
38
+ } from "react";
39
+ import { useDispatch, useSelector, useStore } from "react-redux";
40
+ var NavigationContext = createContext(
41
+ {}
42
+ );
43
+ var hasWindow = typeof window !== "undefined";
44
+ var setWindowScroll = (posX, posY) => {
45
+ hasWindow && window.scrollTo(posX, posY);
46
+ };
47
+ var notFound = (identifier) => {
48
+ let reminder = "";
49
+ if (!identifier) {
50
+ reminder = "Did you forget to add `json.componentIdentifier` in your application.json.props layout?";
51
+ }
52
+ const error = new Error(
53
+ `Superglue Nav component was looking for ${identifier} but could not find it in your mapping. ${reminder}`
54
+ );
55
+ throw error;
56
+ };
57
+ var NavigationProvider = forwardRef(function NavigationProvider2({ history, visit, remote, mapping }, ref) {
58
+ const dispatch = useDispatch();
59
+ const pages = useSelector((state) => state.pages);
60
+ const superglue = useSelector(
61
+ (state) => state.superglue
62
+ );
63
+ const store = useStore();
64
+ useEffect(() => {
65
+ return history.listen(onHistoryChange);
66
+ }, []);
67
+ useImperativeHandle(
68
+ ref,
69
+ () => {
70
+ return {
71
+ navigateTo
72
+ };
73
+ },
74
+ []
75
+ );
76
+ const visitAndRestore = (pageKey, posX, posY) => {
77
+ return visit(pageKey, { revisit: true }).then((meta) => {
78
+ if (meta) {
79
+ if (meta.navigationAction === "none") {
80
+ dispatch(setActivePage({ pageKey }));
81
+ setWindowScroll(posX, posY);
82
+ }
83
+ } else {
84
+ console.warn(
85
+ `scoll restoration was skipped. Your visit's then funtion
86
+ should return the meta object it recieved if you want your
87
+ application to restore the page's previous scroll.`
88
+ );
89
+ }
90
+ });
91
+ };
92
+ const onHistoryChange = ({ location, action }) => {
93
+ const state = location.state;
94
+ if (!state && location.hash !== "" && action === "POP") {
95
+ const nextPageKey = urlToPageKey(location.pathname + location.search);
96
+ const containsKey = !!pages[nextPageKey];
97
+ if (containsKey) {
98
+ history.replace(
99
+ {
100
+ pathname: location.pathname,
101
+ search: location.search,
102
+ hash: location.hash
103
+ },
104
+ {
105
+ pageKey: nextPageKey,
106
+ superglue: true,
107
+ posY: window.pageYOffset,
108
+ posX: window.pageXOffset
109
+ }
110
+ );
111
+ }
112
+ }
113
+ if (state && "superglue" in state) {
114
+ dispatch(
115
+ historyChange({
116
+ pageKey: state.pageKey
117
+ })
118
+ );
119
+ if (action !== "POP") {
120
+ return;
121
+ }
122
+ const { pageKey, posX, posY } = state;
123
+ const containsKey = !!pages[pageKey];
124
+ if (containsKey) {
125
+ const { restoreStrategy } = pages[pageKey];
126
+ switch (restoreStrategy) {
127
+ case "fromCacheOnly":
128
+ dispatch(setActivePage({ pageKey }));
129
+ setWindowScroll(posX, posY);
130
+ break;
131
+ case "fromCacheAndRevisitInBackground":
132
+ dispatch(setActivePage({ pageKey }));
133
+ setWindowScroll(posX, posY);
134
+ visit(pageKey, { revisit: true });
135
+ break;
136
+ case "revisitOnly":
137
+ default:
138
+ visitAndRestore(pageKey, posX, posY);
139
+ }
140
+ } else {
141
+ visitAndRestore(pageKey, posX, posY);
142
+ }
143
+ }
144
+ };
145
+ const navigateTo = (path, { action } = {
146
+ action: "push"
147
+ }) => {
148
+ if (action === "none") {
149
+ return false;
150
+ }
151
+ path = pathWithoutBZParams(path);
152
+ const nextPageKey = urlToPageKey(path);
153
+ const hasPage = Object.prototype.hasOwnProperty.call(
154
+ store.getState().pages,
155
+ nextPageKey
156
+ );
157
+ if (hasPage) {
158
+ const location = history.location;
159
+ const state = location.state;
160
+ const prevPageKey = state.pageKey;
161
+ const historyArgs = [
162
+ path,
163
+ {
164
+ pageKey: nextPageKey,
165
+ superglue: true,
166
+ posY: 0,
167
+ posX: 0
168
+ }
169
+ ];
170
+ if (action === "push") {
171
+ if (hasWindow) {
172
+ history.replace(
173
+ {
174
+ pathname: location.pathname,
175
+ search: location.search,
176
+ hash: location.hash
177
+ },
178
+ {
179
+ ...state,
180
+ posY: window.pageYOffset,
181
+ posX: window.pageXOffset
182
+ }
183
+ );
184
+ }
185
+ history.push(...historyArgs);
186
+ }
187
+ if (action === "replace") {
188
+ history.replace(...historyArgs);
189
+ }
190
+ setActivePage({ pageKey: nextPageKey });
191
+ setWindowScroll(0, 0);
192
+ if (action === "replace" && prevPageKey && prevPageKey !== nextPageKey) {
193
+ dispatch(removePage({ pageKey: prevPageKey }));
194
+ }
195
+ return true;
196
+ } else {
197
+ console.warn(
198
+ `\`navigateTo\` was called , but could not find
199
+ the pageKey in the store. This may happen when the wrong
200
+ content_location was set in your non-get controller action.
201
+ No navigation will take place`
202
+ );
203
+ return false;
204
+ }
205
+ };
206
+ const { currentPageKey, search } = superglue;
207
+ const { componentIdentifier } = pages[currentPageKey];
208
+ const Component = mapping[componentIdentifier];
209
+ if (Component) {
210
+ return /* @__PURE__ */ React.createElement(
211
+ NavigationContext.Provider,
212
+ {
213
+ value: { pageKey: currentPageKey, search, navigateTo, visit, remote }
214
+ },
215
+ /* @__PURE__ */ React.createElement(Component, null)
216
+ );
217
+ } else {
218
+ notFound(componentIdentifier);
219
+ }
220
+ });
31
221
 
32
222
  // lib/reducers/index.ts
33
223
  function addPlaceholdersToDeferredNodes(existingPage, page) {
@@ -51,10 +241,9 @@ function constrainPagesSize(state) {
51
241
  }
52
242
  }
53
243
  }
54
- function saveResponse(state, pageKey, page) {
244
+ function handleSaveResponse(state, pageKey, page) {
55
245
  state = { ...state };
56
246
  let nextPage = {
57
- pageKey,
58
247
  ...page,
59
248
  savedAt: Date.now()
60
249
  };
@@ -104,7 +293,7 @@ function graftNodeOntoPage(state, pageKey, node, pathToNode) {
104
293
  const fullPathToNode = [pageKey, pathToNode].join(".");
105
294
  return setIn(state, fullPathToNode, node);
106
295
  }
107
- function handleGraft(state, pageKey, page) {
296
+ function handleGraftResponse(state, pageKey, page) {
108
297
  const currentPage = state[pageKey];
109
298
  if (!currentPage) {
110
299
  const error = new Error(
@@ -123,491 +312,188 @@ function handleGraft(state, pageKey, page) {
123
312
  ].reduce((memo, fn) => fn(memo), state);
124
313
  }
125
314
  function pageReducer(state = {}, action) {
126
- switch (action.type) {
127
- case SAVE_RESPONSE: {
128
- const { pageKey, page } = action.payload;
129
- return saveResponse(state, pageKey, page);
130
- }
131
- case HANDLE_GRAFT: {
132
- const { pageKey, page } = action.payload;
133
- return handleGraft(state, pageKey, page);
134
- }
135
- case UPDATE_FRAGMENTS: {
136
- const { changedFragments } = action.payload;
137
- let nextState = state;
138
- Object.entries(state).forEach(([pageKey, page]) => {
139
- page.fragments.forEach((fragment) => {
140
- const { type, path } = fragment;
141
- const changedNode = changedFragments[type];
142
- const currentNode = getIn(nextState, `${pageKey}.${path}`);
143
- if (type in changedFragments && changedNode !== currentNode) {
144
- const nextNode = JSON.parse(JSON.stringify(changedNode));
145
- nextState = setIn(nextState, `${pageKey}.${path}`, nextNode);
146
- }
147
- });
148
- });
149
- return nextState;
150
- }
151
- case COPY_PAGE: {
152
- const nextState = { ...state };
153
- const { from, to } = action.payload;
154
- nextState[urlToPageKey(to)] = JSON.parse(JSON.stringify(nextState[from]));
155
- return nextState;
156
- }
157
- case REMOVE_PAGE: {
158
- const { pageKey } = action.payload;
159
- const nextState = { ...state };
160
- delete nextState[pageKey];
161
- return nextState;
162
- }
163
- default:
164
- return state;
315
+ if (removePage.match(action)) {
316
+ const { pageKey } = action.payload;
317
+ const nextState = { ...state };
318
+ delete nextState[pageKey];
319
+ return nextState;
320
+ }
321
+ if (copyPage.match(action)) {
322
+ const nextState = { ...state };
323
+ const { from, to } = action.payload;
324
+ nextState[urlToPageKey(to)] = JSON.parse(JSON.stringify(nextState[from]));
325
+ return nextState;
165
326
  }
327
+ if (handleGraft.match(action)) {
328
+ const { pageKey, page } = action.payload;
329
+ return handleGraftResponse(state, pageKey, page);
330
+ }
331
+ if (saveResponse.match(action)) {
332
+ const { pageKey, page } = action.payload;
333
+ const nextState = handleSaveResponse(state, pageKey, page);
334
+ return nextState;
335
+ }
336
+ return state;
166
337
  }
167
- function superglueReducer(state = {}, action) {
168
- switch (action.type) {
169
- case HISTORY_CHANGE: {
170
- const { pathname, search, hash } = action.payload;
171
- const currentPageKey = urlToPageKey(pathname + search);
172
- return {
173
- ...state,
174
- currentPageKey,
175
- pathname,
176
- search,
177
- hash
178
- };
179
- }
180
- case SAVE_RESPONSE: {
181
- const {
182
- page: { csrfToken, assets }
183
- } = action.payload;
184
- return { ...state, csrfToken, assets };
185
- }
186
- case SET_CSRF_TOKEN: {
187
- const { csrfToken } = action.payload;
188
- return { ...state, csrfToken };
189
- }
190
- default:
191
- return state;
338
+ function superglueReducer(state = {
339
+ currentPageKey: "",
340
+ search: {},
341
+ assets: []
342
+ }, action) {
343
+ if (setCSRFToken.match(action)) {
344
+ const { csrfToken } = action.payload;
345
+ return { ...state, csrfToken };
192
346
  }
347
+ if (setActivePage.match(action)) {
348
+ const { pageKey } = action.payload;
349
+ const { search } = parsePageKey(pageKey);
350
+ return {
351
+ ...state,
352
+ search,
353
+ currentPageKey: pageKey
354
+ };
355
+ }
356
+ if (historyChange.match(action)) {
357
+ const { pageKey } = action.payload;
358
+ const { search } = parsePageKey(pageKey);
359
+ return {
360
+ ...state,
361
+ currentPageKey: pageKey,
362
+ search
363
+ };
364
+ }
365
+ if (saveResponse.match(action)) {
366
+ const {
367
+ page: { csrfToken, assets }
368
+ } = action.payload;
369
+ return { ...state, csrfToken, assets };
370
+ }
371
+ return state;
193
372
  }
194
373
  var rootReducer = {
195
374
  superglue: superglueReducer,
196
375
  pages: pageReducer
197
376
  };
198
377
 
199
- // lib/index.tsx
200
- import { Provider, connect } from "react-redux";
201
- import {
202
- createBrowserHistory,
203
- createMemoryHistory
204
- } from "history";
378
+ // lib/hooks/index.ts
379
+ import { useSelector as useSelector2 } from "react-redux";
380
+ function useSuperglue() {
381
+ return useSelector2((state) => state.superglue);
382
+ }
383
+ function useContent() {
384
+ const superglueState = useSuperglue();
385
+ const currentPageKey = superglueState.currentPageKey;
386
+ return useSelector2(
387
+ (state) => state.pages[currentPageKey]
388
+ ).data;
389
+ }
205
390
 
206
- // lib/components/Nav.tsx
207
- import React from "react";
208
- var Nav = class extends React.Component {
209
- /**
210
- * @ignore
211
- */
212
- constructor(props) {
213
- super(props);
214
- const { history, initialPageKey } = this.props;
215
- this.history = history;
216
- this.navigateTo = this.navigateTo.bind(this);
217
- this.scrollTo = this.scrollTo.bind(this);
218
- this.onHistoryChange = this.onHistoryChange.bind(this);
219
- this.state = {
220
- pageKey: initialPageKey,
221
- ownProps: {}
222
- };
223
- this.hasWindow = typeof window !== "undefined";
224
- }
225
- /**
226
- * @ignore
227
- */
228
- componentDidMount() {
229
- this.unsubscribeHistory = this.history.listen(this.onHistoryChange);
230
- }
231
- /**
232
- * @ignore
233
- */
234
- componentWillUnmount() {
235
- this.unsubscribeHistory();
236
- }
237
- /**
238
- * Passed to every page component. Manually navigate using pages that exists
239
- * in the store and restores scroll position. This is what {@link Visit} in
240
- * your `application_visit.js` ultimately calls.
241
- *
242
- * If there is an existing page in your store `navigateTo` will restore the props,
243
- * render the correct component, and return `true`. Otherwise, it will return
244
- * `false`. This is useful if you want to restore an existing page before making a
245
- * call to `visit` or `remote`.
246
- *
247
- * @param path
248
- * @param options when `none`, immediately returns `false`
249
- * @returns `true` if the navigation was a success, `false` if the page was not found in the
250
- * store.
251
- */
252
- navigateTo(path, {
253
- action,
254
- ownProps
255
- } = {
256
- action: "push",
257
- ownProps: {}
258
- }) {
259
- if (action === "none") {
260
- return false;
261
- }
262
- path = pathWithoutBZParams(path);
263
- const nextPageKey = urlToPageKey(path);
264
- const { store } = this.props;
265
- const hasPage = !!store.getState().pages[nextPageKey];
266
- if (hasPage) {
267
- const location = this.history.location;
268
- const state = location.state;
269
- const prevPageKey = state.pageKey;
270
- const historyArgs = [
271
- path,
272
- {
273
- pageKey: nextPageKey,
274
- superglue: true,
275
- posY: 0,
276
- posX: 0
277
- }
278
- ];
279
- if (action === "push") {
280
- if (this.hasWindow) {
281
- this.history.replace(
282
- {
283
- pathname: location.pathname,
284
- search: location.search,
285
- hash: location.hash
286
- },
287
- {
288
- ...state,
289
- posY: window.pageYOffset,
290
- posX: window.pageXOffset
291
- }
292
- );
293
- }
294
- this.history.push(...historyArgs);
295
- }
296
- if (action === "replace") {
297
- this.history.replace(...historyArgs);
298
- }
299
- this.setState({ pageKey: nextPageKey, ownProps });
300
- this.scrollTo(0, 0);
301
- if (action === "replace" && prevPageKey && prevPageKey !== nextPageKey) {
302
- store.dispatch({
303
- type: REMOVE_PAGE,
304
- payload: {
305
- pageKey: prevPageKey
306
- }
307
- });
308
- }
309
- return true;
310
- } else {
311
- console.warn(
312
- `\`navigateTo\` was called , but could not find.
313
- the pageKey in the store. This may happen when the wrong
314
- content_location was set in your non-get controller action.
315
- No navigation will take place`
316
- );
317
- return false;
318
- }
319
- }
320
- /**
321
- * @ignore
322
- */
323
- scrollTo(posX, posY) {
324
- this.hasWindow && window.scrollTo(posX, posY);
325
- }
326
- /**
327
- * @ignore
328
- */
329
- onHistoryChange({ location, action }) {
330
- const { store, visit } = this.props;
331
- const { pathname, search, hash } = location;
332
- const state = location.state;
333
- if (state && "superglue" in state) {
334
- store.dispatch({
335
- type: HISTORY_CHANGE,
336
- payload: { pathname, search, hash }
337
- });
338
- if (action !== "POP") {
339
- return;
340
- }
341
- const { pageKey, posX, posY } = state;
342
- const containsKey = !!store.getState().pages[pageKey];
343
- if (containsKey) {
344
- const { restoreStrategy } = store.getState().pages[pageKey];
345
- switch (restoreStrategy) {
346
- case "fromCacheOnly":
347
- this.setState({ pageKey });
348
- this.scrollTo(posX, posY);
349
- break;
350
- case "fromCacheAndRevisitInBackground":
351
- this.setState({ pageKey });
352
- this.scrollTo(posX, posY);
353
- visit(pageKey, { revisit: true });
354
- break;
355
- case "revisitOnly":
356
- default:
357
- visit(pageKey, { revisit: true }).then((meta) => {
358
- if (meta === void 0) {
359
- console.warn(
360
- `scoll restoration was skipped. Your visit's then funtion
361
- should return the meta object it recieved if you want your
362
- application to restore the page's previous scroll.`
363
- );
364
- }
365
- if (!!meta && meta.suggestedAction === "none") {
366
- this.setState({ pageKey });
367
- this.scrollTo(posX, posY);
368
- }
369
- });
370
- }
371
- } else {
372
- visit(pageKey, { revisit: true }).then((meta) => {
373
- if (meta === void 0) {
374
- console.warn(
375
- `scoll restoration was skipped. Your visit's then funtion
376
- should return the meta object it recieved if you want your
377
- application to restore the page's previous scroll.`
378
- );
379
- }
380
- if (!!meta && meta.suggestedAction === "none") {
381
- this.setState({ pageKey });
382
- this.scrollTo(posX, posY);
383
- }
384
- });
385
- }
386
- }
387
- }
388
- /**
389
- * @ignore
390
- */
391
- notFound(identifier) {
392
- let reminder = "";
393
- if (!identifier) {
394
- reminder = "Did you forget to add `json.componentIdentifier` in your application.json.props layout?";
395
- }
396
- const error = new Error(
397
- `Superglue Nav component was looking for ${identifier} but could not find it in your mapping. ${reminder}`
398
- );
399
- throw error;
400
- }
401
- /**
402
- * @ignore
403
- */
404
- render() {
405
- const { store, visit, remote } = this.props;
406
- const { pageKey, ownProps } = this.state;
407
- const { componentIdentifier } = store.getState().pages[pageKey];
408
- const Component = this.props.mapping[componentIdentifier];
409
- if (Component) {
410
- return /* @__PURE__ */ React.createElement(
411
- Component,
412
- {
413
- pageKey,
414
- navigateTo: this.navigateTo,
415
- visit,
416
- remote,
417
- ...ownProps
418
- }
419
- );
420
- } else {
421
- this.notFound(componentIdentifier);
422
- }
391
+ // lib/index.tsx
392
+ var hasWindow2 = typeof window !== "undefined";
393
+ var createHistory = () => {
394
+ if (hasWindow2) {
395
+ return createBrowserHistory({});
396
+ } else {
397
+ return createMemoryHistory({});
423
398
  }
424
399
  };
425
- var Nav_default = Nav;
426
-
427
- // lib/middleware.ts
428
- var actionValues = Object.values(actions_exports).map((action) => action.toString());
429
- var fragmentMiddleware = (store) => (next) => (action) => {
430
- const prevState = store.getState();
431
- const nextAction = next(action);
432
- const nextState = store.getState();
433
- if (!(action instanceof Object && "type" in action && typeof action.type === "string")) {
434
- return nextAction;
435
- }
436
- const type = action.type;
437
- if (actionValues.includes(type)) {
438
- return nextAction;
439
- }
440
- if (prevState.pages === nextState.pages) {
441
- return nextAction;
442
- }
443
- const changedFragments = {};
444
- const changedKeys = Object.keys(nextState.pages).filter((key) => {
445
- return prevState.pages[key] !== nextState.pages[key];
446
- });
447
- if (changedKeys.length === 0) {
448
- return nextAction;
449
- }
450
- changedKeys.forEach((key) => {
451
- nextState.pages[key].fragments.forEach((fragment) => {
452
- const { type: type2, path } = fragment;
453
- const nextPage = nextState.pages[key];
454
- const prevPage = prevState.pages[key];
455
- let nextFragment, prevFragment;
456
- try {
457
- prevFragment = getIn(prevPage, path);
458
- nextFragment = getIn(nextPage, path);
459
- } catch (err) {
460
- if (err instanceof KeyPathError) {
461
- console.warn(err.message);
462
- } else {
463
- throw err;
464
- }
465
- }
466
- if (nextFragment !== void 0 && prevFragment !== void 0 && nextFragment !== prevFragment && nextFragment) {
467
- changedFragments[type2] = nextFragment;
468
- }
469
- });
470
- });
471
- if (Object.keys(changedFragments).length === 0) {
472
- return nextAction;
473
- }
474
- store.dispatch({
475
- type: UPDATE_FRAGMENTS,
476
- payload: {
477
- changedFragments
478
- }
479
- });
480
- return nextAction;
400
+ var prepareStore = (store, initialPage, path) => {
401
+ const location = parse(path);
402
+ const initialPageKey = urlToPageKey(location.href);
403
+ const { csrfToken } = initialPage;
404
+ store.dispatch(
405
+ historyChange({
406
+ pageKey: initialPageKey
407
+ })
408
+ );
409
+ store.dispatch(saveAndProcessPage(initialPageKey, initialPage));
410
+ store.dispatch(setCSRFToken({ csrfToken }));
481
411
  };
482
-
483
- // lib/index.tsx
484
- function pageToInitialState(key, page) {
485
- const slices = page.slices || {};
486
- const nextPage = {
487
- ...page,
488
- pageKey: key,
489
- //TODO remove this
490
- savedAt: Date.now()
491
- };
492
- return {
493
- pages: { [key]: nextPage },
494
- ...slices
495
- };
496
- }
497
- function start({
412
+ var setup = ({
498
413
  initialPage,
499
- baseUrl = config.baseUrl,
500
- maxPages = config.maxPages,
501
- path
502
- }) {
503
- const initialPageKey = urlToPageKey(parse(path).href);
504
- const { csrfToken } = initialPage;
505
- const location = parse(path);
414
+ baseUrl,
415
+ path,
416
+ store,
417
+ buildVisitAndRemote,
418
+ history,
419
+ navigatorRef
420
+ }) => {
506
421
  config.baseUrl = baseUrl;
507
- config.maxPages = maxPages;
422
+ const { visit, remote } = buildVisitAndRemote(navigatorRef, store);
423
+ const initialPageKey = urlToPageKey(parse(path).href);
424
+ const nextHistory = history || createHistory();
425
+ nextHistory.replace(...argsForHistory(path));
426
+ prepareStore(store, initialPage, path);
427
+ const handlers = ujsHandlers({
428
+ visit,
429
+ remote,
430
+ ujsAttributePrefix: "data-sg",
431
+ store
432
+ });
508
433
  return {
509
- reducer: rootReducer,
510
- prepareStore: function(store) {
511
- store.dispatch({
512
- type: HISTORY_CHANGE,
513
- payload: {
514
- pathname: location.pathname,
515
- search: location.query,
516
- hash: location.hash
517
- }
518
- });
519
- store.dispatch(saveAndProcessPage(initialPageKey, initialPage));
520
- store.dispatch({ type: SET_CSRF_TOKEN, payload: { csrfToken } });
521
- },
522
- initialState: pageToInitialState(initialPageKey, initialPage),
523
- initialPageKey
434
+ visit,
435
+ remote,
436
+ nextHistory,
437
+ initialPageKey,
438
+ ujs: handlers
524
439
  };
525
- }
526
- var ApplicationBase = class extends React2.Component {
527
- /**
528
- * The constructor of the `ApplicationBase` class.
529
- * @param props
530
- */
531
- constructor(props) {
532
- super(props);
533
- this.hasWindow = typeof window !== "undefined";
534
- this.navigatorRef = React2.createRef();
535
- const { prepareStore, initialState, initialPageKey, reducer } = start({
536
- initialPage: this.props.initialPage,
537
- baseUrl: this.props.baseUrl,
538
- path: this.props.path
539
- // The max number of pages to keep in the store. Default is 20
540
- // maxPages: 20
541
- });
542
- this.initialPageKey = initialPageKey;
543
- this.store = this.buildStore(initialState, reducer);
544
- prepareStore(this.store);
545
- this.history = this.createHistory();
546
- this.history.replace(...argsForHistory(this.props.path));
547
- const unconnectedMapping = this.mapping();
548
- const nextMapping = {};
549
- for (const key in unconnectedMapping) {
550
- const component = unconnectedMapping[key];
551
- nextMapping[key] = connect(mapStateToProps, mapDispatchToProps)(component);
552
- }
553
- this.connectedMapping = nextMapping;
554
- const { visit, remote } = this.visitAndRemote(this.navigatorRef, this.store);
555
- this.visit = visit;
556
- this.remote = remote;
557
- }
558
- componentDidMount() {
559
- const { appEl } = this.props;
560
- this.ujsHandlers = ujsHandlers({
561
- visit: this.visit,
562
- remote: this.remote,
563
- ujsAttributePrefix: "data-sg"
440
+ };
441
+ function Application({
442
+ initialPage,
443
+ baseUrl,
444
+ path,
445
+ store,
446
+ buildVisitAndRemote,
447
+ history,
448
+ mapping,
449
+ ...rest
450
+ }) {
451
+ const navigatorRef = useRef(null);
452
+ const { visit, remote, nextHistory, initialPageKey, ujs } = useMemo(() => {
453
+ return setup({
454
+ initialPage,
455
+ baseUrl,
456
+ path,
457
+ store,
458
+ buildVisitAndRemote,
459
+ history,
460
+ navigatorRef
564
461
  });
565
- const { onClick, onSubmit } = this.ujsHandlers;
566
- appEl.addEventListener("click", onClick);
567
- appEl.addEventListener("submit", onSubmit);
568
- }
569
- componentWillUnmount() {
570
- const { appEl } = this.props;
571
- const { onClick, onSubmit } = this.ujsHandlers;
572
- appEl.removeEventListener("click", onClick);
573
- appEl.removeEventListener("submit", onSubmit);
574
- }
575
- createHistory() {
576
- if (this.hasWindow) {
577
- return createBrowserHistory({});
578
- } else {
579
- return createMemoryHistory({});
462
+ }, []);
463
+ return /* @__PURE__ */ React2.createElement("div", { onClick: ujs.onClick, onSubmit: ujs.onSubmit, ...rest }, /* @__PURE__ */ React2.createElement(Provider, { store }, /* @__PURE__ */ React2.createElement(
464
+ NavigationProvider,
465
+ {
466
+ ref: navigatorRef,
467
+ visit,
468
+ remote,
469
+ mapping,
470
+ history: nextHistory,
471
+ initialPageKey
580
472
  }
581
- }
582
- render() {
583
- return /* @__PURE__ */ React2.createElement(Provider, { store: this.store }, /* @__PURE__ */ React2.createElement(
584
- Nav_default,
585
- {
586
- store: this.store,
587
- ref: this.navigatorRef,
588
- visit: this.visit,
589
- remote: this.remote,
590
- mapping: this.connectedMapping,
591
- history: this.history,
592
- initialPageKey: this.initialPageKey
593
- }
594
- ));
595
- }
596
- };
473
+ )));
474
+ }
597
475
  export {
598
- ApplicationBase,
599
- BEFORE_FETCH,
600
- BEFORE_REMOTE,
601
- BEFORE_VISIT,
602
- COPY_PAGE,
476
+ Application,
603
477
  GRAFTING_ERROR,
604
478
  GRAFTING_SUCCESS,
605
- HISTORY_CHANGE,
606
- REMOVE_PAGE,
607
- SAVE_RESPONSE,
608
- UPDATE_FRAGMENTS,
609
- fragmentMiddleware,
479
+ NavigationContext,
480
+ NavigationProvider,
481
+ beforeFetch,
482
+ beforeRemote,
483
+ beforeVisit,
484
+ copyPage,
610
485
  getIn,
611
- urlToPageKey
486
+ pageReducer,
487
+ prepareStore,
488
+ removePage,
489
+ rootReducer,
490
+ saveAndProcessPage,
491
+ saveResponse,
492
+ setup,
493
+ superglueReducer,
494
+ updateFragments,
495
+ urlToPageKey,
496
+ useContent,
497
+ useSuperglue
612
498
  };
613
499
  //# sourceMappingURL=superglue.mjs.map