superglue 0.41.0 → 0.50.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 20e7f46b274beaffe44eb96b704678e4eb2ebb43c85607a6b4170974525db452
4
- data.tar.gz: 4e4280233e4e9ed82664aafb9fde2f176471c605142bba3af3326282431e0278
3
+ metadata.gz: '0586b4b5e16fbae55b29d0b9b56fb421fec1f5e0841bea7cb8ed2ee661ad6642'
4
+ data.tar.gz: 01fe043eadc91fb4efe74b96e4e1ce35d01bcb895514d701b6a924ce8c7ed994
5
5
  SHA512:
6
- metadata.gz: ba6cd0dabf868452a22e88533df3b2d76f324078e7d7559917a1b5d5aa181cf3e060ceee6f1ea9271f8a8478fde127636639493914eb38ba6eba583026edeabd
7
- data.tar.gz: 7ebb6ade8ba3a240013f9c55f2b6527423773d8655be5292aedab05e01af089884f8e6f7e93bbb0e45f27c785aebd20c4153e20e93796da3c88e3f0804bb775a
6
+ metadata.gz: dab5eef3eff758a64408a2d239e47d0107b60952cb4eb0dfec97a241f39eeeea644ff67741022550d6ca2847a5773098c72379c2b48a2fafb86f0f0ba6d46980
7
+ data.tar.gz: 10340fee27529540353885d343bd5202a35db8bbd5a403156b53c38e960e1b299dd34d5b8955e831cf0791f0f3ebed35908d3189a828fed3605e51eb4be640c8
@@ -1,10 +1,10 @@
1
- require 'rails/generators'
2
- require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator'
1
+ require "rails/generators"
2
+ require "rails/generators/rails/scaffold_controller/scaffold_controller_generator"
3
3
 
4
4
  module Rails
5
5
  module Generators
6
6
  class ScaffoldControllerGenerator
7
- source_paths << File.expand_path('../templates', __FILE__)
7
+ source_paths << File.expand_path("../templates", __FILE__)
8
8
 
9
9
  hook_for :superglue, type: :boolean, default: true
10
10
  end
@@ -1,109 +1,98 @@
1
- require 'rails/generators/named_base'
2
- require 'rails/generators/resource_helpers'
3
- require 'rails/version'
1
+ require "rails/generators/named_base"
2
+ require "rails/generators/resource_helpers"
4
3
 
5
4
  module Rails
6
5
  module Generators
7
6
  class SuperglueGenerator < NamedBase
8
7
  include Rails::Generators::ResourceHelpers
9
8
 
10
- source_root File.expand_path('../templates', __FILE__)
9
+ source_root File.expand_path("../templates", __FILE__)
11
10
 
12
- argument :attributes, type: :array, default: [], banner: 'field:type field:type'
11
+ argument :attributes, type: :array, default: [], banner: "field:type field:type"
13
12
 
14
13
  def create_root_folder
15
- path = File.join('app/views', controller_file_path)
14
+ path = File.join("app/views", controller_file_path)
16
15
  empty_directory path unless File.directory?(path)
17
16
  end
18
17
 
19
18
  def copy_view_files
20
- %w(index show new edit).each do |view|
19
+ %w[index show new edit].each do |view|
21
20
  @action_name = view
22
21
  filename = filename_with_extensions(view)
23
- template filename, File.join('app/views', controller_file_path, filename)
22
+ template filename, File.join("app/views", controller_file_path, filename)
24
23
  end
25
- template '_form.json.props', File.join('app/views', controller_file_path, '_form.json.props')
24
+ template "_form.json.props", File.join("app/views", controller_file_path, "_form.json.props")
26
25
 
27
- %w(index show new edit).each do |view|
26
+ %w[index show new edit].each do |view|
28
27
  @action_name = view
29
28
  filename = filename_with_js_extensions(view)
30
- template 'web/' + filename, File.join('app/views', controller_file_path, filename)
29
+ template "web/" + filename, File.join("app/views", controller_file_path, filename)
31
30
  end
32
31
 
33
- %w(index show new edit).each do |view|
32
+ %w[index show new edit].each do |view|
34
33
  @action_name = view
35
34
  filename = filename_with_html_extensions(view)
36
- template 'web/' + filename, File.join('app/views', controller_file_path, filename)
35
+ template "web/" + filename, File.join("app/views", controller_file_path, filename)
37
36
  end
38
37
 
39
- %w(index show new edit).each do |view|
38
+ %w[index show new edit].each do |view|
40
39
  append_mapping(view)
41
40
  end
42
41
  end
43
42
 
44
-
45
43
  protected
46
- def view_path
47
- if Rails.version >= "7"
48
- "../views"
49
- else
50
- "../../views"
51
- end
52
- end
53
44
 
54
- def app_js_path
55
- if Rails.version >= "7"
56
- "app/javascript/"
57
- else
58
- "app/javascript/packs"
59
- end
60
- end
45
+ def view_path
46
+ "../views"
47
+ end
61
48
 
62
- def append_mapping(action)
63
- app_js = "#{app_js_path}/application.js"
49
+ def app_js_path
50
+ "app/javascript/"
51
+ end
64
52
 
65
- component_name = [plural_table_name, action].map(&:camelcase).join
53
+ def append_mapping(action)
54
+ app_js = "#{app_js_path}/page_to_page_mapping.js"
66
55
 
67
- inject_into_file app_js, after: "from '@thoughtbot/superglue'" do
68
- "\nimport #{component_name} from '#{view_path}/#{controller_file_path}/#{action}'"
69
- end
56
+ component_name = [plural_table_name, action].map(&:camelcase).join
70
57
 
71
- inject_into_file app_js, after: 'identifierToComponentMapping = {' do
72
- "\n '#{[controller_file_path, action].join('/')}': #{component_name},"
73
- end
58
+ prepend_to_file app_js do
59
+ "\nimport #{component_name} from '#{view_path}/#{controller_file_path}/#{action}'"
74
60
  end
75
61
 
76
- def action_name
77
- @action_name
62
+ inject_into_file app_js, after: "pageIdentifierToPageComponent = {" do
63
+ "\n '#{[controller_file_path, action].join("/")}': #{component_name},"
78
64
  end
65
+ end
79
66
 
80
- def attributes_names
81
- [:id] + super
82
- end
67
+ attr_reader :action_name
83
68
 
84
- def filename_with_extensions(name)
85
- [name, :json, :props] * '.'
86
- end
69
+ def attributes_names
70
+ [:id] + super
71
+ end
87
72
 
88
- def filename_with_js_extensions(name)
89
- [name, :js] * '.'
90
- end
73
+ def filename_with_extensions(name)
74
+ [name, :json, :props].join(".")
75
+ end
91
76
 
92
- def filename_with_html_extensions(name)
93
- [name, :html, :erb] * '.'
94
- end
77
+ def filename_with_js_extensions(name)
78
+ [name, :js].join(".")
79
+ end
95
80
 
96
- def attributes_list_with_timestamps
97
- attributes_list(attributes_names + %w(created_at updated_at))
98
- end
81
+ def filename_with_html_extensions(name)
82
+ [name, :html, :erb].join(".")
83
+ end
99
84
 
100
- def attributes_list(attributes = attributes_names)
101
- if self.attributes.any? {|attr| attr.name == 'password' && attr.type == :digest}
102
- attributes = attributes.reject {|name| %w(password password_confirmation).include? name}
103
- end
85
+ def attributes_list_with_timestamps
86
+ attributes_list(attributes_names + %w[created_at updated_at])
87
+ end
104
88
 
105
- attributes
89
+ def attributes_list(attributes = attributes_names)
90
+ if self.attributes.any? { |attr| attr.name == "password" && attr.type == :digest }
91
+ attributes = attributes.reject { |name| %w[password password_confirmation].include? name }
106
92
  end
93
+
94
+ attributes
95
+ end
107
96
  end
108
97
  end
109
98
  end
@@ -1,13 +1,6 @@
1
- html = form_with(model: @<%= model_resource_name %>, local: true) do |form|
2
- inner = "".html_safe
3
-
1
+ form_props(model: @<%= model_resource_name %>) do |f|
4
2
  <%- attributes.each do |attr| -%>
5
- inner << form.label(:<%= attr.column_name %>)
6
- inner << form.<%= attr.field_type %>(:<%= attr.column_name %>)
3
+ f.<%= attr.field_type %>(:<%= attr.column_name %>)
7
4
  <%- end -%>
8
- inner << form.submit
9
-
10
- inner
5
+ f.submit
11
6
  end
12
-
13
- json.html html
@@ -1,10 +1,8 @@
1
1
  if @post.errors.any?
2
- content = {
2
+ json.errors({
3
3
  explanation: "#{pluralize(@<%= singular_table_name %>.errors.count, "error")} prohibited this post from being saved:",
4
4
  messages: @<%= singular_table_name %>.errors.full_messages.map{|msg| {body: msg}}
5
- }
6
-
7
- flash.now[:form_error] = content
5
+ })
8
6
  end
9
7
 
10
8
  json.form(partial: 'form') do
@@ -5,7 +5,9 @@ json.<%= plural_table_name %> do
5
5
  <%- end -%>
6
6
  json.edit_<%=singular_table_name%>_path edit_<%=singular_table_name%>_path(<%=singular_table_name%>)
7
7
  json.<%=singular_table_name%>_path <%=singular_table_name%>_path(<%=singular_table_name%>)
8
- json.delete_<%=singular_table_name%>_path <%=singular_table_name%>_path(<%=singular_table_name%>)
8
+ json.delete_form do
9
+ form_props(model: <%=singular_table_name%>, method: :delete)
10
+ end
9
11
  end
10
12
  end
11
13
 
@@ -1,10 +1,8 @@
1
1
  if @post.errors.any?
2
- content = {
2
+ json.errors({
3
3
  explanation: "#{pluralize(@<%= singular_table_name %>.errors.count, "error")} prohibited this post from being saved:",
4
4
  messages: @<%= singular_table_name %>.errors.full_messages.map{|msg| {body: msg}}
5
- }
6
-
7
- flash.now[:form_error] = content
5
+ })
8
6
  end
9
7
 
10
8
  json.form(partial: 'form') do
@@ -1,18 +1,14 @@
1
1
  import React from 'react'
2
- import RailsTag from '@thoughtbot/superglue/components/RailsTag'
3
- // import * as actionCreators from 'javascript/packs/action_creators'
4
- // import {useDispatch} from 'react-redux'
2
+ // import { useSelector } from 'react-redux'
5
3
 
6
4
  export default function <%= plural_table_name.camelize %>Edit ({
7
5
  // visit,
8
6
  // remote,
9
7
  form,
10
- flash,
8
+ error,
11
9
  <%= singular_table_name.camelize(:lower) %>Path,
12
10
  <%= plural_table_name.camelize(:lower) %>Path,
13
11
  }) {
14
- const error = flash.form_error
15
-
16
12
  const messagesEl = error && (
17
13
  <div id="error_explanation">
18
14
  <h2>{ error.explanation }</h2>
@@ -23,7 +19,15 @@ export default function <%= plural_table_name.camelize %>Edit ({
23
19
  return (
24
20
  <div>
25
21
  {messagesEl}
26
- <RailsTag {...form} data-sg-visit={true}/>
22
+ <form {...form.props} data-sg-visit={true}>
23
+ {Object.values(form.extras).map((hiddenProps) => (<input {...hiddenProps} key={hiddenProps.id} type="hidden"/>))}
24
+ <%- attributes.each do |attr| -%>
25
+ <input {...form.inputs.<%= attr.column_name %>} type="text"/>
26
+ <label htmlFor={form.inputs.<%= attr.column_name %>.id}><%= attr.column_name %></label>
27
+ <%- end -%>
28
+ <button {...form.inputs.submit} type="submit"> {...form.inputs.submit.text} </button>
29
+ </form>
30
+
27
31
  <a href={<%= singular_table_name.camelize(:lower) %>Path} data-sg-visit={true}>Show</a>
28
32
  <a href={<%= plural_table_name.camelize(:lower) %>Path} data-sg-visit={true}>Back</a>
29
33
  </div>
@@ -1,15 +1,17 @@
1
1
  import React from 'react'
2
- // import * as actionCreators from 'javascript/packs/action_creators'
3
- // import {useDispatch} from 'react-redux'
2
+ import { useSelector } from 'react-redux'
4
3
 
5
4
  export default function <%= plural_table_name.camelize %>Index({
6
5
  // visit,
7
6
  // remote,
8
- flash,
9
7
  new<%= singular_table_name.camelize %>Path,
10
8
  <%= plural_table_name.camelize(:lower) %> = [],
11
9
  }) {
10
+ const flash = useSelector((state) => state.flash)
11
+
12
12
  const <%= singular_table_name.camelize(:lower) %>Items = <%= plural_table_name.camelize(:lower) %>.map((<%= singular_table_name.camelize(:lower) %>, key) => {
13
+ const deleteForm = <%=singular_table_name.camelize(:lower)%>.deleteForm;
14
+
13
15
  return (
14
16
  <tr key={<%= singular_table_name.camelize(:lower) %>.id}>
15
17
  <%- attributes_list.select{|attr| attr != :id }.each do |attr| -%>
@@ -17,14 +19,19 @@ export default function <%= plural_table_name.camelize %>Index({
17
19
  <%- end -%>
18
20
  <td><a href={ <%=singular_table_name%>.<%=singular_table_name.camelize(:lower)%>Path } data-sg-visit={true}>Show</a></td>
19
21
  <td><a href={ <%=singular_table_name%>.edit<%=singular_table_name.camelize%>Path } data-sg-visit={true}>Edit</a></td>
20
- <td><a href={ <%=singular_table_name%>.delete<%=singular_table_name.camelize%>Path }data-sg-visit={true} data-sg-method={"DELETE"}>Delete</a></td>
22
+ <td>
23
+ <form {...deleteForm.props} data-sg-visit={true}>
24
+ {Object.values(deleteForm.extras).map((hiddenProps) => (<input {...hiddenProps} key={hiddenProps.id} type="hidden"/>))}
25
+ <button type="submit">Delete</button>
26
+ </form>
27
+ </td>
21
28
  </tr>
22
29
  )
23
30
  })
24
31
 
25
32
  return (
26
33
  <div>
27
- <p id="notice">{flash.notice}</p>
34
+ <p id="notice">{flash && flash.notice}</p>
28
35
 
29
36
  <h1><%= plural_table_name.capitalize %></h1>
30
37
 
@@ -1,17 +1,13 @@
1
1
  import React from 'react'
2
- import RailsTag from '@thoughtbot/superglue/components/RailsTag'
3
- // import * as actionCreators from 'javascript/packs/action_creators'
4
- // import { useDispatch } from 'react-redux'
2
+ // import { useSelector } from 'react-redux'
5
3
 
6
4
  export default function <%= plural_table_name.camelize %>New({
7
5
  // visit,
8
6
  // remote
9
7
  form,
10
- flash,
8
+ error,
11
9
  <%= plural_table_name.camelize(:lower) %>Path,
12
10
  }) {
13
- const error = flash.form_error
14
-
15
11
  const messagesEl = error && (
16
12
  <div id="error_explanation">
17
13
  <h2>{ error.explanation }</h2>
@@ -22,7 +18,15 @@ export default function <%= plural_table_name.camelize %>New({
22
18
  return (
23
19
  <div>
24
20
  {messagesEl}
25
- <RailsTag {...form} data-sg-visit={true}/>
21
+ <form {...form.props} data-sg-visit={true}>
22
+ {Object.values(form.extras).map((hiddenProps) => (<input {...hiddenProps} key={hiddenProps.id} type="hidden"/>))}
23
+ <%- attributes.each do |attr| -%>
24
+ <input {...form.inputs.<%= attr.column_name %>} type="text"/>
25
+ <label htmlFor={form.inputs.<%= attr.column_name %>.id}><%= attr.column_name %></label>
26
+ <%- end -%>
27
+ <button {...form.inputs.submit} type="submit"> {...form.inputs.submit.text} </button>
28
+ </form>
29
+
26
30
  <a href={<%= plural_table_name.camelize(:lower) %>Path} data-sg-visit={true}>Back</a>
27
31
  </div>
28
32
  )
@@ -1,17 +1,17 @@
1
1
  import React from 'react'
2
- // import * as actionCreators from 'javascript/packs/action_creators'
3
- // import {useDispatch} from 'react-redux'
2
+ import { useSelector } from 'react-redux'
4
3
 
5
4
  export default function <%= plural_table_name.camelize %>Show({
6
5
  // visit,
7
6
  // remote,
8
- flash,
9
7
  <%- attributes_list_with_timestamps.select{|attr| attr != :id }.each do |attr| -%>
10
8
  <%=attr.camelize(:lower)%>,
11
9
  <%- end -%>
12
10
  edit<%= singular_table_name.camelize %>Path,
13
11
  <%= plural_table_name.camelize(:lower) %>Path
14
12
  }) {
13
+ const flash = useSelector((state) => state.flash)
14
+
15
15
  return (
16
16
  <div>
17
17
  <p id="notice">{flash && flash.notice}</p>
@@ -1,3 +1,6 @@
1
- // Example:
2
- //
3
- // export const CLEAR_FORM_ERRORS = 'CLEAR_FORM_ERRORS'
1
+ import { createAction } from '@reduxjs/toolkit'
2
+ import { SAVE_RESPONSE, BEFORE_VISIT, UPDATE_FRAGMENTS } from '@thoughtbot/superglue'
3
+
4
+ export const saveResponse = createAction(SAVE_RESPONSE)
5
+ export const beforeVisit = createAction(BEFORE_VISIT)
6
+ export const updateFragments = createAction(UPDATE_FRAGMENTS)
@@ -1,20 +1,25 @@
1
1
  import React from 'react';
2
- import { combineReducers, createStore, applyMiddleware, compose } from 'redux';
3
- import reduceReducers from 'reduce-reducers';
4
2
  import thunk from 'redux-thunk';
5
3
  import { Provider } from 'react-redux';
6
- import { render } from 'react-dom';
7
- import { ApplicationBase, fragmentMiddleware } from '@thoughtbot/superglue';
8
- import { applicationRootReducer, applicationPagesReducer } from './reducer';
4
+ import { createRoot } from 'react-dom/client';
5
+ import { ApplicationBase } from '@thoughtbot/superglue';
9
6
  import { buildVisitAndRemote } from './application_visit';
7
+ import { pageIdentifierToPageComponent } from './page_to_page_mapping';
8
+ import { buildStore } from './store'
10
9
 
11
- // Mapping between your props template to Component, you must add to this
12
- // to register any new page level component you create. If you are using the
13
- // scaffold, it will auto append the identifers for you.
14
- //
15
- // e.g {'posts/new': PostNew}
16
- const identifierToComponentMapping = {
17
- };
10
+ class Application extends ApplicationBase {
11
+ mapping() {
12
+ return pageIdentifierToPageComponent;
13
+ }
14
+
15
+ visitAndRemote(navRef, store) {
16
+ return buildVisitAndRemote(navRef, store);
17
+ }
18
+
19
+ buildStore(initialState, { superglue, pages}) {
20
+ return buildStore(initialState, superglue, pages);
21
+ }
22
+ }
18
23
 
19
24
  if (typeof window !== "undefined") {
20
25
  document.addEventListener("DOMContentLoaded", function () {
@@ -22,7 +27,8 @@ if (typeof window !== "undefined") {
22
27
  const location = window.location;
23
28
 
24
29
  if (appEl) {
25
- render(
30
+ const root = createRoot(appEl);
31
+ root.render(
26
32
  <Application
27
33
  appEl={appEl}
28
34
  // The base url prefixed to all calls made by the `visit`
@@ -33,43 +39,10 @@ if (typeof window !== "undefined") {
33
39
  initialPage={window.SUPERGLUE_INITIAL_PAGE_STATE}
34
40
  // The initial path of the page, e.g., /foobar
35
41
  path={location.pathname + location.search + location.hash}
36
- buildVisitAndRemote={buildVisitAndRemote}
37
- />,
38
- appEl
42
+ />
39
43
  );
40
44
  }
41
45
  });
42
46
  }
43
47
 
44
- export default class Application extends ApplicationBase {
45
- mapping() {
46
- return identifierToComponentMapping;
47
- }
48
-
49
- visitAndRemote(navRef, store) {
50
- return buildVisitAndRemote(navRef, store);
51
- }
52
48
 
53
- buildStore(initialState, { superglue: superglueReducer, pages: pagesReducer }) {
54
- // Create the store
55
- // See `./reducer.js` for an explaination of the two included reducers
56
- const composeEnhancers =
57
- (this.hasWindow && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) ||
58
- compose;
59
- const reducer = reduceReducers(
60
- combineReducers({
61
- superglue: superglueReducer,
62
- pages: reduceReducers(pagesReducer, applicationPagesReducer),
63
- }),
64
- applicationRootReducer
65
- );
66
-
67
- const store = createStore(
68
- reducer,
69
- initialState,
70
- composeEnhancers(applyMiddleware(thunk, fragmentMiddleware))
71
- );
72
-
73
- return store;
74
- }
75
- }
@@ -7,11 +7,7 @@ end
7
7
  json.component_identifier local_assigns[:virtual_path_of_template]
8
8
  json.defers json.deferred!
9
9
  json.fragments json.fragments!
10
- json.assets [
11
- # Uncomment for webpacker support
12
- # asset_pack_path('application.js'),
13
- asset_path('application.css')
14
- ]
10
+ json.assets [ asset_path('application.js') ]
15
11
 
16
12
  if protect_against_forgery?
17
13
  json.csrf_token form_authenticity_token
@@ -25,4 +21,7 @@ end
25
21
  json.restore_strategy 'fromCacheAndRevisitInBackground'
26
22
 
27
23
  json.rendered_at Time.now.to_i
28
- json.flash flash.to_h
24
+
25
+ json.slices do
26
+ json.flash flash.to_h
27
+ end
@@ -0,0 +1,19 @@
1
+ import { createSlice } from '@reduxjs/toolkit'
2
+ import { saveResponse, beforeVisit } from '../actions'
3
+
4
+ export const flashSlice = createSlice({
5
+ name: 'flash',
6
+ initialState: {},
7
+ extraReducers: (builder) => {
8
+ builder.addCase(beforeVisit, (state, action) => {
9
+ return {}
10
+ })
11
+ builder.addCase(saveResponse, (state, action) => {
12
+ const { page } = action.payload;
13
+
14
+ return {
15
+ ...state, ...page.slices.flash
16
+ }
17
+ })
18
+ }
19
+ })
@@ -1 +1 @@
1
- require 'props_template/core_ext'
1
+ require "props_template/core_ext"
@@ -0,0 +1,12 @@
1
+ // import your page component
2
+ // e.g import PostsEdit from '../views/posts/edit'
3
+
4
+
5
+ // Mapping between your props template to Component, you must add to this
6
+ // to register any new page level component you create. If you are using the
7
+ // scaffold, it will auto append the identifers for you.
8
+ //
9
+ // e.g {'posts/new': PostNew}
10
+ export const pageIdentifierToPageComponent = {
11
+ };
12
+
@@ -0,0 +1,15 @@
1
+ import { createSlice } from '@reduxjs/toolkit'
2
+ import { saveResponse, beforeVisit } from '../actions'
3
+
4
+ export const pagesSlice = createSlice({
5
+ name: 'pages',
6
+ // extraReducers: (builder) => {
7
+ // builder.addCase(beforeVisit, (state, action) => {
8
+ // const {currentPageKey} = action.payload
9
+ //
10
+ // const currentPage = draft[currentPageKey]
11
+ // delete currentPage.error
12
+ // })
13
+ // }
14
+ })
15
+
@@ -0,0 +1,32 @@
1
+ import { configureStore } from '@reduxjs/toolkit'
2
+ import { pagesSlice } from "./slices/pages"
3
+ import { flashSlice } from "./slices/flash"
4
+ import {
5
+ BEFORE_VISIT,
6
+ BEFORE_FETCH,
7
+ BEFORE_REMOTE,
8
+ fragmentMiddleware
9
+ } from '@thoughtbot/superglue'
10
+
11
+ export const buildStore = (initialState, superglueReducer, supergluePagesReducer) => {
12
+
13
+ return configureStore({
14
+ preloadedState: initialState,
15
+ devTools: process.env.NODE_ENV !== 'production',
16
+ middleware: (getDefaultMiddleware) =>
17
+ getDefaultMiddleware({
18
+ serializableCheck: {
19
+ ignoredActions: [BEFORE_VISIT, BEFORE_FETCH, BEFORE_REMOTE],
20
+ },
21
+ }).concat(fragmentMiddleware),
22
+ reducer: {
23
+ superglue: superglueReducer,
24
+ pages: (state, action) => {
25
+ const nextState = supergluePagesReducer(state, action)
26
+ return pagesSlice.reducer(nextState, action)
27
+ },
28
+ flash: flashSlice.reducer
29
+ },
30
+ });
31
+ };
32
+