forked from ASOS/web-toggle-point
-
Notifications
You must be signed in to change notification settings - Fork 0
[ASOS#46] parallel folder example #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
TomStrepsil
wants to merge
50
commits into
main
Choose a base branch
from
issue/46-parallel-filesystem-convention-example
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
[ASOS#46] parallel folder example #3
TomStrepsil
wants to merge
50
commits into
main
from
issue/46-parallel-filesystem-convention-example
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
* rename to proper module namespace * update docs links * update versions * web toggle point in readme title * fixup changelog from revised 0.x range * 2.0.0 -> 0.5.0 in oss version scheme * fix broken link syntax in CHANGELOG * consistent quoting * more version history issues * fixup module name in jsdoc * add web remove sdkInstanceProvider * remove SDKInstanceProvider * fixup jsdoc dedupe * tweak * clarity re: ssr package * casing etc
* update workflows * version * typo * update chromium linux snaps * versions for serve update * package.json repository field * update root package.lock * bugs & directories/doc fields * fix changelog --------- Co-authored-by: Tom Pereira <[email protected]>
Co-authored-by: Tom Pereira <[email protected]>
move reducer replacement to a provider, rather than a toggle side-effect
upgrade eslint
…or when unpacking playwright test report
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Issue
resolves ASOS#46
Details
As per ASOS#46 (comment) needs a cross-merge of ASOS#43 to get this working, and for ASOS#55 to be merged
Readme
Express "parallel folder convention" example
This example shows the use of the
react-pointcuts,features,ssrandwebpackpackages, as part of an express application.An inbound header named "feature" can take the following values:
...which is used server side (via a "node request scoped features store") to generate appropriate server-rendered content.
The chosen feature state is serialized to the browser using the
ssrpackage, and loaded into a "global features store", usingvaltiobrowser-side, for reactivity.To demonstrate the reactivity, a drop-down allows changing of the selected feature state.
Filesystem structure
The base / control folder structure is thus:
├── components │ ├── Animal │ │ └── index.tsx │ ├── BottomBox │ │ ├── index.tsx │ │ └── useAnimals.ts │ └── TopBox │ ├── TopBoxChild │ │ ├── TopBoxButton │ │ │ ├── index.module.css │ │ │ ├── index.tsx │ │ │ └── useAddAnimal.ts │ │ └── index.tsx │ └── index.tsx ├── constants │ └── index.ts └── state ├── modules │ ├── animals │ │ └── slice.ts │ └── index.ts └── store.tsVariations
The features comprise the following:
baseline
The base experience. Clicking the dog dispatches a redux action adding a dog to the bottom box
feature1
Varied react components (
TopBox&BottomBox), at various depths in the folder structure. A varied constant for the animal emoji (constants/index.ts) and varied css (background colour of the button) (TopBoxButton/index.module.css).├── components │ ├── BottomBox │ │ └── index.tsx │ └── TopBox │ ├── TopBoxChild │ │ └── TopBoxButton │ │ └── index.module.css │ └── index.tsx └── constants └── index.tsfeature2
Varied constant (
constants/index.ts), react component (TopBoxChild) and redux slice (slice.ts) connecting an additional action creator (useFreeAnimal.ts) to "free" added animals (clears the state collection). Has an alternate "initial state" containing two hamsters, activated during server rendering by afeatureheader containingfeature2.├── components │ └── TopBox │ └── TopBoxChild │ ├── index.tsx │ └── useFreeAnimals.ts └── constants └── index.tsfeature3
Varied constant (
constants/index.ts) & redux slice (slice.ts) with modified reducer action that multiplies rabbits, when added├── constants │ └── index.ts └── state └── modules └── animals └── slice.tsfeature4
Varied constant (
constants/index.ts) & redux slice (slice.ts) with replaced redux selector that carcinizes previously added animals├── constants │ └── index.ts └── state └── modules └── animals └── slice.tsfeature5
Varied component (
TopBox) & redux store (modules/index.ts) that introduces a new "space" slice, with it's own state containing spacey stuff.├── components │ └── TopBox │ ├── index.tsx │ ├── styles.module.css │ └── useSpaceStuff.ts └── state └── modules ├── space │ └── slice.ts └── index.tsExplanation
The webpack plugin is configured with a toggle handler that maps variants to controls based on a parallel root folder. This allows for any file to be replaced at any depth. The example shows both complete replacements, and augmentations (importing of the base, then modifying).
To vary react components, the toggle point from the
react-pointcutspackage is used.To vary CSS files, constants, and
redux"slices", a toggle point is used that utilises an object proxy, to intercept property access. Despite objects not being innately reactive, as long as they are accessed from something that does update with change of state (i.e. react components), their properties will also update based on the new feature.To vary
reduxreducer map, a toggle point that wraps the factory method (getReducerMap) is used.To ensure that the redux store is reactive to feature state, a
StateProviderreact component is used to host the react-redux provider, that subscribes to the valtio state, and calls replaceReducer from the@reduxjs/toolkitwhenever the feature state changes. This ensures a new redux store (but retaining current state) is made available to the react components. Care should be taken to ensure the existing state is compatible with any updated selectors etc.N.B. It is assumed that feature state will not change during a request cycle on the server, so
valtiois only plumbed in to the client-side feature store, via conditional compilation using Webpack'sDefinePlugin.Screenshots
3x button click:

change to "feature 1":

2x button click:

change to "feature 2":

click "⛓️💥"

change to "feature 3":

4x button click:

change to "feature 4":

reload, with "feature2" header, then change to "feature 5":

CheckList
main.