Repository files navigation

CIRelease Version

Vlow

A simple library for unidirectional dataflow architecture inspired by Reflux



Installation

Using npm:

$ npm i vlow

In your project:

importVlowfrom'vlow';// Exposes:// - Vlow.version// - Vlow.createActions// - Vlow.factoryActions// - Vlow.Store// - Vlow.Component// - Vlow.withVlow

Or... download the latest release from here and load the file in inside your project. For example:

<!-- Add this line to expose `window.vlow.default` --><!-- WARN: Make sure React is loaded before this line --><scriptsrc="vlow.min.js"></script>

Overview

Vlow uses actions to update one or more stores which updates the state of all components who are mapped to the store(s). In turn, a component triggers an action. Vlow can be used for keeping a global state.

There are three steps which need to be understood to use Vlow:

  1. Create Actions
  2. Create Stores
  3. Map store(s) to Components

Create actions

Actions can be created using the Vlow.createActions function:

// this example creates an add and remove actionconstItemActions=Vlow.createActions(['add','remove',]);

Invoking an action is as simple as calling the function, for example:

ItemsActions.add(item);

Create a store

A Vlow Store is an object which holds a global state which can be shared across components.

Creating a store can be done by creating a subclass of Vlow.Store and call the Store constructor with an actions object, for example:

classItemStoreextendsVlow.Store{constructor(){// Call super with the actions to which this store should// listen too.// Note: multiple actions instances are possible,// for example super(Actions1, Actions2);super(ItemActions);// Create the initial statethis.state={items: []};}// Implement onAction functions for each action defined by actions.// It is not required to create functions for all actions but usually// this is what you want and Vlow logs a warning in `development` mode// when actions are not implemented.onAdd(item){// Update the state like you would do with React.// Just like react the first argument can also be a function.//// An optional second argument can be used. When given it must be// a callback function() which will be called once when all// components which are mapped to the store are rendered.this.setState({items: [...this.state.items,item]});}onRemove(itemId){this.setState({items: this.state.filter(i=>i.id!==itemId)});}}

Map stores to Components

Now that the actions and stores are created, it is time to map them to a component.

This can be done either by using Vlow.withVlow which is the preferred method as of version 1.1.0, or it can be done by extending the Vlow.Component class.

Using withVlow

By using withVlow the store will be mapped to the component props. The function withVlow requires a Vlow Store or an array with multiple stores and returns a new function which accepts a component you want to wrap.

Here are some valid examples:

// Just parse the storewithVlow(SomeStore)(MyComponent);// Multiple storeswithVlow([SomeStore,SomeOtherStore])(MyComponent);// Map only specific store keyswithVlow({store: ItemStore,keys: ['items']// listen only to 'items' changes})(MyComponent);

And this is an example of how withVlow can be used:

import{withVlow}from'vlow';importItemStorefrom'../Stores/ItemStore';constItemComponent=({items})=>(<ul>{items.map(i=><likey={i.id}>{i.text}</li>)}</ul>)exportdefaultwithVlow(ItemStore)(ItemComponent);

Note: It is still ok to use PropTypes for checking the props from a store, for example:

ItemComponent.propTypes={items: PropTypes.arrayOf(PropTypes.shape({id: PropTypes.number,text: PropTypes.string})).isRequired};

Using Vlow Component

It is recommended to use withVlow instead of Vlow.Component but in some cases you might prefer to extend your component directly with a Vlow.Component instead of React.Component. The main difference is that the state from the store will be merged with your components state, instead of receiving the state by props.

Inside the constructor you should use the mapStore() or mapStores() function to map the state to the store.

Here is an example of how to use Vlow.Component:

classItemComponentextendsVlow.Component{constructor(props){super(props);// In case you want to set state in the constructor, make// sure to do this before calling mapStore() since you// otherwise would overwrite the state defined by the store.this.state={some: 'state'};// Function mapStore() accepts a store in which case the// complete store state will be mapped to the components state.// There are two more options://// - Using a keys filter in which case a component only listens// to certain store changes.//// this.mapStore({// store: ItemStore,// keys: ['items'] // listen only to 'items' changes,// // other store state will be ignored// });//// - Using an altState function which allows you to modify state// before it will be applied. (more info on altState() can be// found later in this documentation)this.mapStore(ItemStore);// The state now looks like:// {some: 'state', items: []}// It's ok to modify the state as long as you do not// overwrite `this.state` with a new Object, for example:this.state.hasItems=this.state.items.length>0;}render(){return(<ul>{this.state.items.map(i=><likey={i.id}>{i.text}</li>)}</ul>);}}

In case you need multiple stores, the function this.mapStores([]) can be used which accepts an Array of stores. Each store may be defined in a different way.

this.mapStores([StoreOne,{store: StoreTwo},{store: StoreThree,keys: ['foo','status']},{store: StoreFour,altState: storeState, state,props=> storeState
}]);

Alternative super class

By default the Vlow.Component class extends the React.Component class but you might want Vlow.Component to extend your own custom class. This is possible by using Vlow.Component.extend().

// In this example we create a Vlow Component which extends// React.PureComponent instead of the default React.ComponentclassMyComponentextendsVlow.Component.extend(React.PureComponent){
...
}

Using altState

Sometimes you want to listen to state changes in a store but then do something with this state instead of just applying the state to a component. This can be done by using an altState(storeState, state, props) hook which will be triggered on state changes in the store but before the component state is changed. The altState function should return the state changes you want to make or null in case you don't want to update the state of the component.

functionaltState(storeState,state,props){// This function should return the state// you want to apply on the component. The function can// also return `null` in which case the components state// will not be changed.if(props.status==='error'){// the components state will not be changedreturnnull;}// Return some alternative state for `this` component.// Other components still receive the `original` state// from the store.return{items: storeState.items.filter(i=>i.age>state.minAge)};}// Use the altState functionconststores={store: MyStore,
altState,};

No more listeners

If there are no components left who listen to the store, the store function listenersEmpty() is called. By default, this function does nothing but you might implement it yourself and overwrite the default behavior. For example, you might want to unregister the store if no more components are listening to clean-up memory:

importVlowfrom'vlow';// define the state on the store, e.g. this.state.todosexportinterfaceIMyStore{
todos: string[];}classMyStoreextendsVlow.Store<IMyStore>{listenersEmpty(){this.unregisterStore();// the store will unregister itself from the// actions until a new store is created}}

Use TypeScript

With Vlow, it is possible to use TypeScript and have both the state in your store and the actions typed.

Example:

importVlowfrom'vlow';// define the state on the store, e.g. this.state.todosexportinterfaceIMyStore{
todos: string[];}classMyStoreextendsVlow.Store<IMyStore>{onFetch(limit: number){/* fetch todo's... */}}constactions=['fetch',]asconst;constMyActions=Vlow.factoryActions<MyStore>()(actions);// MyActions.fetch(10); understands the arguments of the `onFetch` defined in the store

About

A simple library for unidirectional dataflow architecture inspired by Reflux

Resources

Stars

5 stars

Watchers

4 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

CIRelease Version

Vlow

A simple library for unidirectional dataflow architecture inspired by Reflux



Installation

Using npm:

$ npm i vlow

In your project:

importVlowfrom'vlow';// Exposes:// - Vlow.version// - Vlow.createActions// - Vlow.factoryActions// - Vlow.Store// - Vlow.Component// - Vlow.withVlow

Or... download the latest release from here and load the file in inside your project. For example:

<!-- Add this line to expose `window.vlow.default` --><!-- WARN: Make sure React is loaded before this line --><scriptsrc="vlow.min.js"></script>

Overview

Vlow uses actions to update one or more stores which updates the state of all components who are mapped to the store(s). In turn, a component triggers an action. Vlow can be used for keeping a global state.

There are three steps which need to be understood to use Vlow:

  1. Create Actions
  2. Create Stores
  3. Map store(s) to Components

Create actions

Actions can be created using the Vlow.createActions function:

// this example creates an add and remove actionconstItemActions=Vlow.createActions(['add','remove',]);

Invoking an action is as simple as calling the function, for example:

ItemsActions.add(item);

Create a store

A Vlow Store is an object which holds a global state which can be shared across components.

Creating a store can be done by creating a subclass of Vlow.Store and call the Store constructor with an actions object, for example:

classItemStoreextendsVlow.Store{constructor(){// Call super with the actions to which this store should// listen too.// Note: multiple actions instances are possible,// for example super(Actions1, Actions2);super(ItemActions);// Create the initial statethis.state={items: []};}// Implement onAction functions for each action defined by actions.// It is not required to create functions for all actions but usually// this is what you want and Vlow logs a warning in `development` mode// when actions are not implemented.onAdd(item){// Update the state like you would do with React.// Just like react the first argument can also be a function.//// An optional second argument can be used. When given it must be// a callback function() which will be called once when all// components which are mapped to the store are rendered.this.setState({items: [...this.state.items,item]});}onRemove(itemId){this.setState({items: this.state.filter(i=>i.id!==itemId)});}}

Map stores to Components

Now that the actions and stores are created, it is time to map them to a component.

This can be done either by using Vlow.withVlow which is the preferred method as of version 1.1.0, or it can be done by extending the Vlow.Component class.

Using withVlow

By using withVlow the store will be mapped to the component props. The function withVlow requires a Vlow Store or an array with multiple stores and returns a new function which accepts a component you want to wrap.

Here are some valid examples:

// Just parse the storewithVlow(SomeStore)(MyComponent);// Multiple storeswithVlow([SomeStore,SomeOtherStore])(MyComponent);// Map only specific store keyswithVlow({store: ItemStore,keys: ['items']// listen only to 'items' changes})(MyComponent);

And this is an example of how withVlow can be used:

import{withVlow}from'vlow';importItemStorefrom'../Stores/ItemStore';constItemComponent=({items})=>(<ul>{items.map(i=><likey={i.id}>{i.text}</li>)}</ul>)exportdefaultwithVlow(ItemStore)(ItemComponent);

Note: It is still ok to use PropTypes for checking the props from a store, for example:

ItemComponent.propTypes={items: PropTypes.arrayOf(PropTypes.shape({id: PropTypes.number,text: PropTypes.string})).isRequired};

Using Vlow Component

It is recommended to use withVlow instead of Vlow.Component but in some cases you might prefer to extend your component directly with a Vlow.Component instead of React.Component. The main difference is that the state from the store will be merged with your components state, instead of receiving the state by props.

Inside the constructor you should use the mapStore() or mapStores() function to map the state to the store.

Here is an example of how to use Vlow.Component:

classItemComponentextendsVlow.Component{constructor(props){super(props);// In case you want to set state in the constructor, make// sure to do this before calling mapStore() since you// otherwise would overwrite the state defined by the store.this.state={some: 'state'};// Function mapStore() accepts a store in which case the// complete store state will be mapped to the components state.// There are two more options://// - Using a keys filter in which case a component only listens// to certain store changes.//// this.mapStore({// store: ItemStore,// keys: ['items'] // listen only to 'items' changes,// // other store state will be ignored// });//// - Using an altState function which allows you to modify state// before it will be applied. (more info on altState() can be// found later in this documentation)this.mapStore(ItemStore);// The state now looks like:// {some: 'state', items: []}// It's ok to modify the state as long as you do not// overwrite `this.state` with a new Object, for example:this.state.hasItems=this.state.items.length>0;}render(){return(<ul>{this.state.items.map(i=><likey={i.id}>{i.text}</li>)}</ul>);}}

In case you need multiple stores, the function this.mapStores([]) can be used which accepts an Array of stores. Each store may be defined in a different way.

this.mapStores([StoreOne,{store: StoreTwo},{store: StoreThree,keys: ['foo','status']},{store: StoreFour,altState: storeState, state,props=> storeState
}]);

Alternative super class

By default the Vlow.Component class extends the React.Component class but you might want Vlow.Component to extend your own custom class. This is possible by using Vlow.Component.extend().

// In this example we create a Vlow Component which extends// React.PureComponent instead of the default React.ComponentclassMyComponentextendsVlow.Component.extend(React.PureComponent){
...
}

Using altState

Sometimes you want to listen to state changes in a store but then do something with this state instead of just applying the state to a component. This can be done by using an altState(storeState, state, props) hook which will be triggered on state changes in the store but before the component state is changed. The altState function should return the state changes you want to make or null in case you don't want to update the state of the component.

functionaltState(storeState,state,props){// This function should return the state// you want to apply on the component. The function can// also return `null` in which case the components state// will not be changed.if(props.status==='error'){// the components state will not be changedreturnnull;}// Return some alternative state for `this` component.// Other components still receive the `original` state// from the store.return{items: storeState.items.filter(i=>i.age>state.minAge)};}// Use the altState functionconststores={store: MyStore,
altState,};

No more listeners

If there are no components left who listen to the store, the store function listenersEmpty() is called. By default, this function does nothing but you might implement it yourself and overwrite the default behavior. For example, you might want to unregister the store if no more components are listening to clean-up memory:

importVlowfrom'vlow';// define the state on the store, e.g. this.state.todosexportinterfaceIMyStore{
todos: string[];}classMyStoreextendsVlow.Store<IMyStore>{listenersEmpty(){this.unregisterStore();// the store will unregister itself from the// actions until a new store is created}}

Use TypeScript

With Vlow, it is possible to use TypeScript and have both the state in your store and the actions typed.

Example:

importVlowfrom'vlow';// define the state on the store, e.g. this.state.todosexportinterfaceIMyStore{
todos: string[];}classMyStoreextendsVlow.Store<IMyStore>{onFetch(limit: number){/* fetch todo's... */}}constactions=['fetch',]asconst;constMyActions=Vlow.factoryActions<MyStore>()(actions);// MyActions.fetch(10); understands the arguments of the `onFetch` defined in the store

About

A simple library for unidirectional dataflow architecture inspired by Reflux

Resources

Stars

5 stars

Watchers

4 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

CIRelease Version

Vlow

A simple library for unidirectional dataflow architecture inspired by Reflux



Installation

Using npm:

$ npm i vlow

In your project:

importVlowfrom'vlow';// Exposes:// - Vlow.version// - Vlow.createActions// - Vlow.factoryActions// - Vlow.Store// - Vlow.Component// - Vlow.withVlow

Or... download the latest release from here and load the file in inside your project. For example:

<!-- Add this line to expose `window.vlow.default` --><!-- WARN: Make sure React is loaded before this line --><scriptsrc="vlow.min.js"></script>

Overview

Vlow uses actions to update one or more stores which updates the state of all components who are mapped to the store(s). In turn, a component triggers an action. Vlow can be used for keeping a global state.

There are three steps which need to be understood to use Vlow:

  1. Create Actions
  2. Create Stores
  3. Map store(s) to Components

Create actions

Actions can be created using the Vlow.createActions function:

// this example creates an add and remove actionconstItemActions=Vlow.createActions(['add','remove',]);

Invoking an action is as simple as calling the function, for example:

ItemsActions.add(item);

Create a store

A Vlow Store is an object which holds a global state which can be shared across components.

Creating a store can be done by creating a subclass of Vlow.Store and call the Store constructor with an actions object, for example:

classItemStoreextendsVlow.Store{constructor(){// Call super with the actions to which this store should// listen too.// Note: multiple actions instances are possible,// for example super(Actions1, Actions2);super(ItemActions);// Create the initial statethis.state={items: []};}// Implement onAction functions for each action defined by actions.// It is not required to create functions for all actions but usually// this is what you want and Vlow logs a warning in `development` mode// when actions are not implemented.onAdd(item){// Update the state like you would do with React.// Just like react the first argument can also be a function.//// An optional second argument can be used. When given it must be// a callback function() which will be called once when all// components which are mapped to the store are rendered.this.setState({items: [...this.state.items,item]});}onRemove(itemId){this.setState({items: this.state.filter(i=>i.id!==itemId)});}}

Map stores to Components

Now that the actions and stores are created, it is time to map them to a component.

This can be done either by using Vlow.withVlow which is the preferred method as of version 1.1.0, or it can be done by extending the Vlow.Component class.

Using withVlow

By using withVlow the store will be mapped to the component props. The function withVlow requires a Vlow Store or an array with multiple stores and returns a new function which accepts a component you want to wrap.

Here are some valid examples:

// Just parse the storewithVlow(SomeStore)(MyComponent);// Multiple storeswithVlow([SomeStore,SomeOtherStore])(MyComponent);// Map only specific store keyswithVlow({store: ItemStore,keys: ['items']// listen only to 'items' changes})(MyComponent);

And this is an example of how withVlow can be used:

import{withVlow}from'vlow';importItemStorefrom'../Stores/ItemStore';constItemComponent=({items})=>(<ul>{items.map(i=><likey={i.id}>{i.text}</li>)}</ul>)exportdefaultwithVlow(ItemStore)(ItemComponent);

Note: It is still ok to use PropTypes for checking the props from a store, for example:

ItemComponent.propTypes={items: PropTypes.arrayOf(PropTypes.shape({id: PropTypes.number,text: PropTypes.string})).isRequired};

Using Vlow Component

It is recommended to use withVlow instead of Vlow.Component but in some cases you might prefer to extend your component directly with a Vlow.Component instead of React.Component. The main difference is that the state from the store will be merged with your components state, instead of receiving the state by props.

Inside the constructor you should use the mapStore() or mapStores() function to map the state to the store.

Here is an example of how to use Vlow.Component:

classItemComponentextendsVlow.Component{constructor(props){super(props);// In case you want to set state in the constructor, make// sure to do this before calling mapStore() since you// otherwise would overwrite the state defined by the store.this.state={some: 'state'};// Function mapStore() accepts a store in which case the// complete store state will be mapped to the components state.// There are two more options://// - Using a keys filter in which case a component only listens// to certain store changes.//// this.mapStore({// store: ItemStore,// keys: ['items'] // listen only to 'items' changes,// // other store state will be ignored// });//// - Using an altState function which allows you to modify state// before it will be applied. (more info on altState() can be// found later in this documentation)this.mapStore(ItemStore);// The state now looks like:// {some: 'state', items: []}// It's ok to modify the state as long as you do not// overwrite `this.state` with a new Object, for example:this.state.hasItems=this.state.items.length>0;}render(){return(<ul>{this.state.items.map(i=><likey={i.id}>{i.text}</li>)}</ul>);}}

In case you need multiple stores, the function this.mapStores([]) can be used which accepts an Array of stores. Each store may be defined in a different way.

this.mapStores([StoreOne,{store: StoreTwo},{store: StoreThree,keys: ['foo','status']},{store: StoreFour,altState: storeState, state,props=> storeState
}]);

Alternative super class

By default the Vlow.Component class extends the React.Component class but you might want Vlow.Component to extend your own custom class. This is possible by using Vlow.Component.extend().

// In this example we create a Vlow Component which extends// React.PureComponent instead of the default React.ComponentclassMyComponentextendsVlow.Component.extend(React.PureComponent){
...
}

Using altState

Sometimes you want to listen to state changes in a store but then do something with this state instead of just applying the state to a component. This can be done by using an altState(storeState, state, props) hook which will be triggered on state changes in the store but before the component state is changed. The altState function should return the state changes you want to make or null in case you don't want to update the state of the component.

functionaltState(storeState,state,props){// This function should return the state// you want to apply on the component. The function can// also return `null` in which case the components state// will not be changed.if(props.status==='error'){// the components state will not be changedreturnnull;}// Return some alternative state for `this` component.// Other components still receive the `original` state// from the store.return{items: storeState.items.filter(i=>i.age>state.minAge)};}// Use the altState functionconststores={store: MyStore,
altState,};

No more listeners

If there are no components left who listen to the store, the store function listenersEmpty() is called. By default, this function does nothing but you might implement it yourself and overwrite the default behavior. For example, you might want to unregister the store if no more components are listening to clean-up memory:

importVlowfrom'vlow';// define the state on the store, e.g. this.state.todosexportinterfaceIMyStore{
todos: string[];}classMyStoreextendsVlow.Store<IMyStore>{listenersEmpty(){this.unregisterStore();// the store will unregister itself from the// actions until a new store is created}}

Use TypeScript

With Vlow, it is possible to use TypeScript and have both the state in your store and the actions typed.

Example:

importVlowfrom'vlow';// define the state on the store, e.g. this.state.todosexportinterfaceIMyStore{
todos: string[];}classMyStoreextendsVlow.Store<IMyStore>{onFetch(limit: number){/* fetch todo's... */}}constactions=['fetch',]asconst;constMyActions=Vlow.factoryActions<MyStore>()(actions);// MyActions.fetch(10); understands the arguments of the `onFetch` defined in the store

About

A simple library for unidirectional dataflow architecture inspired by Reflux

Resources

Stars

5 stars

Watchers

4 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

CIRelease Version

Vlow

A simple library for unidirectional dataflow architecture inspired by Reflux



Installation

Using npm:

$ npm i vlow

In your project:

importVlowfrom'vlow';// Exposes:// - Vlow.version// - Vlow.createActions// - Vlow.factoryActions// - Vlow.Store// - Vlow.Component// - Vlow.withVlow

Or... download the latest release from here and load the file in inside your project. For example:

<!-- Add this line to expose `window.vlow.default` --><!-- WARN: Make sure React is loaded before this line --><scriptsrc="vlow.min.js"></script>

Overview

Vlow uses actions to update one or more stores which updates the state of all components who are mapped to the store(s). In turn, a component triggers an action. Vlow can be used for keeping a global state.

There are three steps which need to be understood to use Vlow:

  1. Create Actions
  2. Create Stores
  3. Map store(s) to Components

Create actions

Actions can be created using the Vlow.createActions function:

// this example creates an add and remove actionconstItemActions=Vlow.createActions(['add','remove',]);

Invoking an action is as simple as calling the function, for example:

ItemsActions.add(item);

Create a store

A Vlow Store is an object which holds a global state which can be shared across components.

Creating a store can be done by creating a subclass of Vlow.Store and call the Store constructor with an actions object, for example:

classItemStoreextendsVlow.Store{constructor(){// Call super with the actions to which this store should// listen too.// Note: multiple actions instances are possible,// for example super(Actions1, Actions2);super(ItemActions);// Create the initial statethis.state={items: []};}// Implement onAction functions for each action defined by actions.// It is not required to create functions for all actions but usually// this is what you want and Vlow logs a warning in `development` mode// when actions are not implemented.onAdd(item){// Update the state like you would do with React.// Just like react the first argument can also be a function.//// An optional second argument can be used. When given it must be// a callback function() which will be called once when all// components which are mapped to the store are rendered.this.setState({items: [...this.state.items,item]});}onRemove(itemId){this.setState({items: this.state.filter(i=>i.id!==itemId)});}}

Map stores to Components

Now that the actions and stores are created, it is time to map them to a component.

This can be done either by using Vlow.withVlow which is the preferred method as of version 1.1.0, or it can be done by extending the Vlow.Component class.

Using withVlow

By using withVlow the store will be mapped to the component props. The function withVlow requires a Vlow Store or an array with multiple stores and returns a new function which accepts a component you want to wrap.

Here are some valid examples:

// Just parse the storewithVlow(SomeStore)(MyComponent);// Multiple storeswithVlow([SomeStore,SomeOtherStore])(MyComponent);// Map only specific store keyswithVlow({store: ItemStore,keys: ['items']// listen only to 'items' changes})(MyComponent);

And this is an example of how withVlow can be used:

import{withVlow}from'vlow';importItemStorefrom'../Stores/ItemStore';constItemComponent=({items})=>(<ul>{items.map(i=><likey={i.id}>{i.text}</li>)}</ul>)exportdefaultwithVlow(ItemStore)(ItemComponent);

Note: It is still ok to use PropTypes for checking the props from a store, for example:

ItemComponent.propTypes={items: PropTypes.arrayOf(PropTypes.shape({id: PropTypes.number,text: PropTypes.string})).isRequired};

Using Vlow Component

It is recommended to use withVlow instead of Vlow.Component but in some cases you might prefer to extend your component directly with a Vlow.Component instead of React.Component. The main difference is that the state from the store will be merged with your components state, instead of receiving the state by props.

Inside the constructor you should use the mapStore() or mapStores() function to map the state to the store.

Here is an example of how to use Vlow.Component:

classItemComponentextendsVlow.Component{constructor(props){super(props);// In case you want to set state in the constructor, make// sure to do this before calling mapStore() since you// otherwise would overwrite the state defined by the store.this.state={some: 'state'};// Function mapStore() accepts a store in which case the// complete store state will be mapped to the components state.// There are two more options://// - Using a keys filter in which case a component only listens// to certain store changes.//// this.mapStore({// store: ItemStore,// keys: ['items'] // listen only to 'items' changes,// // other store state will be ignored// });//// - Using an altState function which allows you to modify state// before it will be applied. (more info on altState() can be// found later in this documentation)this.mapStore(ItemStore);// The state now looks like:// {some: 'state', items: []}// It's ok to modify the state as long as you do not// overwrite `this.state` with a new Object, for example:this.state.hasItems=this.state.items.length>0;}render(){return(<ul>{this.state.items.map(i=><likey={i.id}>{i.text}</li>)}</ul>);}}

In case you need multiple stores, the function this.mapStores([]) can be used which accepts an Array of stores. Each store may be defined in a different way.

this.mapStores([StoreOne,{store: StoreTwo},{store: StoreThree,keys: ['foo','status']},{store: StoreFour,altState: storeState, state,props=> storeState
}]);

Alternative super class

By default the Vlow.Component class extends the React.Component class but you might want Vlow.Component to extend your own custom class. This is possible by using Vlow.Component.extend().

// In this example we create a Vlow Component which extends// React.PureComponent instead of the default React.ComponentclassMyComponentextendsVlow.Component.extend(React.PureComponent){
...
}

Using altState

Sometimes you want to listen to state changes in a store but then do something with this state instead of just applying the state to a component. This can be done by using an altState(storeState, state, props) hook which will be triggered on state changes in the store but before the component state is changed. The altState function should return the state changes you want to make or null in case you don't want to update the state of the component.

functionaltState(storeState,state,props){// This function should return the state// you want to apply on the component. The function can// also return `null` in which case the components state// will not be changed.if(props.status==='error'){// the components state will not be changedreturnnull;}// Return some alternative state for `this` component.// Other components still receive the `original` state// from the store.return{items: storeState.items.filter(i=>i.age>state.minAge)};}// Use the altState functionconststores={store: MyStore,
altState,};

No more listeners

If there are no components left who listen to the store, the store function listenersEmpty() is called. By default, this function does nothing but you might implement it yourself and overwrite the default behavior. For example, you might want to unregister the store if no more components are listening to clean-up memory:

importVlowfrom'vlow';// define the state on the store, e.g. this.state.todosexportinterfaceIMyStore{
todos: string[];}classMyStoreextendsVlow.Store<IMyStore>{listenersEmpty(){this.unregisterStore();// the store will unregister itself from the// actions until a new store is created}}

Use TypeScript

With Vlow, it is possible to use TypeScript and have both the state in your store and the actions typed.

Example:

importVlowfrom'vlow';// define the state on the store, e.g. this.state.todosexportinterfaceIMyStore{
todos: string[];}classMyStoreextendsVlow.Store<IMyStore>{onFetch(limit: number){/* fetch todo's... */}}constactions=['fetch',]asconst;constMyActions=Vlow.factoryActions<MyStore>()(actions);// MyActions.fetch(10); understands the arguments of the `onFetch` defined in the store

About

A simple library for unidirectional dataflow architecture inspired by Reflux

Resources

Stars

5 stars

Watchers

4 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

CIRelease Version

Vlow

A simple library for unidirectional dataflow architecture inspired by Reflux



Installation

Using npm:

$ npm i vlow

In your project:

importVlowfrom'vlow';// Exposes:// - Vlow.version// - Vlow.createActions// - Vlow.factoryActions// - Vlow.Store// - Vlow.Component// - Vlow.withVlow

Or... download the latest release from here and load the file in inside your project. For example:

<!-- Add this line to expose `window.vlow.default` --><!-- WARN: Make sure React is loaded before this line --><scriptsrc="vlow.min.js"></script>

Overview

Vlow uses actions to update one or more stores which updates the state of all components who are mapped to the store(s). In turn, a component triggers an action. Vlow can be used for keeping a global state.

There are three steps which need to be understood to use Vlow:

  1. Create Actions
  2. Create Stores
  3. Map store(s) to Components

Create actions

Actions can be created using the Vlow.createActions function:

// this example creates an add and remove actionconstItemActions=Vlow.createActions(['add','remove',]);

Invoking an action is as simple as calling the function, for example:

ItemsActions.add(item);

Create a store

A Vlow Store is an object which holds a global state which can be shared across components.

Creating a store can be done by creating a subclass of Vlow.Store and call the Store constructor with an actions object, for example:

classItemStoreextendsVlow.Store{constructor(){// Call super with the actions to which this store should// listen too.// Note: multiple actions instances are possible,// for example super(Actions1, Actions2);super(ItemActions);// Create the initial statethis.state={items: []};}// Implement onAction functions for each action defined by actions.// It is not required to create functions for all actions but usually// this is what you want and Vlow logs a warning in `development` mode// when actions are not implemented.onAdd(item){// Update the state like you would do with React.// Just like react the first argument can also be a function.//// An optional second argument can be used. When given it must be// a callback function() which will be called once when all// components which are mapped to the store are rendered.this.setState({items: [...this.state.items,item]});}onRemove(itemId){this.setState({items: this.state.filter(i=>i.id!==itemId)});}}

Map stores to Components

Now that the actions and stores are created, it is time to map them to a component.

This can be done either by using Vlow.withVlow which is the preferred method as of version 1.1.0, or it can be done by extending the Vlow.Component class.

Using withVlow

By using withVlow the store will be mapped to the component props. The function withVlow requires a Vlow Store or an array with multiple stores and returns a new function which accepts a component you want to wrap.

Here are some valid examples:

// Just parse the storewithVlow(SomeStore)(MyComponent);// Multiple storeswithVlow([SomeStore,SomeOtherStore])(MyComponent);// Map only specific store keyswithVlow({store: ItemStore,keys: ['items']// listen only to 'items' changes})(MyComponent);

And this is an example of how withVlow can be used:

import{withVlow}from'vlow';importItemStorefrom'../Stores/ItemStore';constItemComponent=({items})=>(<ul>{items.map(i=><likey={i.id}>{i.text}</li>)}</ul>)exportdefaultwithVlow(ItemStore)(ItemComponent);

Note: It is still ok to use PropTypes for checking the props from a store, for example:

ItemComponent.propTypes={items: PropTypes.arrayOf(PropTypes.shape({id: PropTypes.number,text: PropTypes.string})).isRequired};

Using Vlow Component

It is recommended to use withVlow instead of Vlow.Component but in some cases you might prefer to extend your component directly with a Vlow.Component instead of React.Component. The main difference is that the state from the store will be merged with your components state, instead of receiving the state by props.

Inside the constructor you should use the mapStore() or mapStores() function to map the state to the store.

Here is an example of how to use Vlow.Component:

classItemComponentextendsVlow.Component{constructor(props){super(props);// In case you want to set state in the constructor, make// sure to do this before calling mapStore() since you// otherwise would overwrite the state defined by the store.this.state={some: 'state'};// Function mapStore() accepts a store in which case the// complete store state will be mapped to the components state.// There are two more options://// - Using a keys filter in which case a component only listens// to certain store changes.//// this.mapStore({// store: ItemStore,// keys: ['items'] // listen only to 'items' changes,// // other store state will be ignored// });//// - Using an altState function which allows you to modify state// before it will be applied. (more info on altState() can be// found later in this documentation)this.mapStore(ItemStore);// The state now looks like:// {some: 'state', items: []}// It's ok to modify the state as long as you do not// overwrite `this.state` with a new Object, for example:this.state.hasItems=this.state.items.length>0;}render(){return(<ul>{this.state.items.map(i=><likey={i.id}>{i.text}</li>)}</ul>);}}

In case you need multiple stores, the function this.mapStores([]) can be used which accepts an Array of stores. Each store may be defined in a different way.

this.mapStores([StoreOne,{store: StoreTwo},{store: StoreThree,keys: ['foo','status']},{store: StoreFour,altState: storeState, state,props=> storeState
}]);

Alternative super class

By default the Vlow.Component class extends the React.Component class but you might want Vlow.Component to extend your own custom class. This is possible by using Vlow.Component.extend().

// In this example we create a Vlow Component which extends// React.PureComponent instead of the default React.ComponentclassMyComponentextendsVlow.Component.extend(React.PureComponent){
...
}

Using altState

Sometimes you want to listen to state changes in a store but then do something with this state instead of just applying the state to a component. This can be done by using an altState(storeState, state, props) hook which will be triggered on state changes in the store but before the component state is changed. The altState function should return the state changes you want to make or null in case you don't want to update the state of the component.

functionaltState(storeState,state,props){// This function should return the state// you want to apply on the component. The function can// also return `null` in which case the components state// will not be changed.if(props.status==='error'){// the components state will not be changedreturnnull;}// Return some alternative state for `this` component.// Other components still receive the `original` state// from the store.return{items: storeState.items.filter(i=>i.age>state.minAge)};}// Use the altState functionconststores={store: MyStore,
altState,};

No more listeners

If there are no components left who listen to the store, the store function listenersEmpty() is called. By default, this function does nothing but you might implement it yourself and overwrite the default behavior. For example, you might want to unregister the store if no more components are listening to clean-up memory:

importVlowfrom'vlow';// define the state on the store, e.g. this.state.todosexportinterfaceIMyStore{
todos: string[];}classMyStoreextendsVlow.Store<IMyStore>{listenersEmpty(){this.unregisterStore();// the store will unregister itself from the// actions until a new store is created}}

Use TypeScript

With Vlow, it is possible to use TypeScript and have both the state in your store and the actions typed.

Example:

importVlowfrom'vlow';// define the state on the store, e.g. this.state.todosexportinterfaceIMyStore{
todos: string[];}classMyStoreextendsVlow.Store<IMyStore>{onFetch(limit: number){/* fetch todo's... */}}constactions=['fetch',]asconst;constMyActions=Vlow.factoryActions<MyStore>()(actions);// MyActions.fetch(10); understands the arguments of the `onFetch` defined in the store

About

A simple library for unidirectional dataflow architecture inspired by Reflux

Resources

Stars

5 stars

Watchers

4 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

CIRelease Version

Vlow

A simple library for unidirectional dataflow architecture inspired by Reflux



Installation

Using npm:

$ npm i vlow

In your project:

importVlowfrom'vlow';// Exposes:// - Vlow.version// - Vlow.createActions// - Vlow.factoryActions// - Vlow.Store// - Vlow.Component// - Vlow.withVlow

Or... download the latest release from here and load the file in inside your project. For example:

<!-- Add this line to expose `window.vlow.default` --><!-- WARN: Make sure React is loaded before this line --><scriptsrc="vlow.min.js"></script>

Overview

Vlow uses actions to update one or more stores which updates the state of all components who are mapped to the store(s). In turn, a component triggers an action. Vlow can be used for keeping a global state.

There are three steps which need to be understood to use Vlow:

  1. Create Actions
  2. Create Stores
  3. Map store(s) to Components

Create actions

Actions can be created using the Vlow.createActions function:

// this example creates an add and remove actionconstItemActions=Vlow.createActions(['add','remove',]);

Invoking an action is as simple as calling the function, for example:

ItemsActions.add(item);

Create a store

A Vlow Store is an object which holds a global state which can be shared across components.

Creating a store can be done by creating a subclass of Vlow.Store and call the Store constructor with an actions object, for example:

classItemStoreextendsVlow.Store{constructor(){// Call super with the actions to which this store should// listen too.// Note: multiple actions instances are possible,// for example super(Actions1, Actions2);super(ItemActions);// Create the initial statethis.state={items: []};}// Implement onAction functions for each action defined by actions.// It is not required to create functions for all actions but usually// this is what you want and Vlow logs a warning in `development` mode// when actions are not implemented.onAdd(item){// Update the state like you would do with React.// Just like react the first argument can also be a function.//// An optional second argument can be used. When given it must be// a callback function() which will be called once when all// components which are mapped to the store are rendered.this.setState({items: [...this.state.items,item]});}onRemove(itemId){this.setState({items: this.state.filter(i=>i.id!==itemId)});}}

Map stores to Components

Now that the actions and stores are created, it is time to map them to a component.

This can be done either by using Vlow.withVlow which is the preferred method as of version 1.1.0, or it can be done by extending the Vlow.Component class.

Using withVlow

By using withVlow the store will be mapped to the component props. The function withVlow requires a Vlow Store or an array with multiple stores and returns a new function which accepts a component you want to wrap.

Here are some valid examples:

// Just parse the storewithVlow(SomeStore)(MyComponent);// Multiple storeswithVlow([SomeStore,SomeOtherStore])(MyComponent);// Map only specific store keyswithVlow({store: ItemStore,keys: ['items']// listen only to 'items' changes})(MyComponent);

And this is an example of how withVlow can be used:

import{withVlow}from'vlow';importItemStorefrom'../Stores/ItemStore';constItemComponent=({items})=>(<ul>{items.map(i=><likey={i.id}>{i.text}</li>)}</ul>)exportdefaultwithVlow(ItemStore)(ItemComponent);

Note: It is still ok to use PropTypes for checking the props from a store, for example:

ItemComponent.propTypes={items: PropTypes.arrayOf(PropTypes.shape({id: PropTypes.number,text: PropTypes.string})).isRequired};

Using Vlow Component

It is recommended to use withVlow instead of Vlow.Component but in some cases you might prefer to extend your component directly with a Vlow.Component instead of React.Component. The main difference is that the state from the store will be merged with your components state, instead of receiving the state by props.

Inside the constructor you should use the mapStore() or mapStores() function to map the state to the store.

Here is an example of how to use Vlow.Component:

classItemComponentextendsVlow.Component{constructor(props){super(props);// In case you want to set state in the constructor, make// sure to do this before calling mapStore() since you// otherwise would overwrite the state defined by the store.this.state={some: 'state'};// Function mapStore() accepts a store in which case the// complete store state will be mapped to the components state.// There are two more options://// - Using a keys filter in which case a component only listens// to certain store changes.//// this.mapStore({// store: ItemStore,// keys: ['items'] // listen only to 'items' changes,// // other store state will be ignored// });//// - Using an altState function which allows you to modify state// before it will be applied. (more info on altState() can be// found later in this documentation)this.mapStore(ItemStore);// The state now looks like:// {some: 'state', items: []}// It's ok to modify the state as long as you do not// overwrite `this.state` with a new Object, for example:this.state.hasItems=this.state.items.length>0;}render(){return(<ul>{this.state.items.map(i=><likey={i.id}>{i.text}</li>)}</ul>);}}

In case you need multiple stores, the function this.mapStores([]) can be used which accepts an Array of stores. Each store may be defined in a different way.

this.mapStores([StoreOne,{store: StoreTwo},{store: StoreThree,keys: ['foo','status']},{store: StoreFour,altState: storeState, state,props=> storeState
}]);

Alternative super class

By default the Vlow.Component class extends the React.Component class but you might want Vlow.Component to extend your own custom class. This is possible by using Vlow.Component.extend().

// In this example we create a Vlow Component which extends// React.PureComponent instead of the default React.ComponentclassMyComponentextendsVlow.Component.extend(React.PureComponent){
...
}

Using altState

Sometimes you want to listen to state changes in a store but then do something with this state instead of just applying the state to a component. This can be done by using an altState(storeState, state, props) hook which will be triggered on state changes in the store but before the component state is changed. The altState function should return the state changes you want to make or null in case you don't want to update the state of the component.

functionaltState(storeState,state,props){// This function should return the state// you want to apply on the component. The function can// also return `null` in which case the components state// will not be changed.if(props.status==='error'){// the components state will not be changedreturnnull;}// Return some alternative state for `this` component.// Other components still receive the `original` state// from the store.return{items: storeState.items.filter(i=>i.age>state.minAge)};}// Use the altState functionconststores={store: MyStore,
altState,};

No more listeners

If there are no components left who listen to the store, the store function listenersEmpty() is called. By default, this function does nothing but you might implement it yourself and overwrite the default behavior. For example, you might want to unregister the store if no more components are listening to clean-up memory:

importVlowfrom'vlow';// define the state on the store, e.g. this.state.todosexportinterfaceIMyStore{
todos: string[];}classMyStoreextendsVlow.Store<IMyStore>{listenersEmpty(){this.unregisterStore();// the store will unregister itself from the// actions until a new store is created}}

Use TypeScript

With Vlow, it is possible to use TypeScript and have both the state in your store and the actions typed.

Example:

importVlowfrom'vlow';// define the state on the store, e.g. this.state.todosexportinterfaceIMyStore{
todos: string[];}classMyStoreextendsVlow.Store<IMyStore>{onFetch(limit: number){/* fetch todo's... */}}constactions=['fetch',]asconst;constMyActions=Vlow.factoryActions<MyStore>()(actions);// MyActions.fetch(10); understands the arguments of the `onFetch` defined in the store

About

A simple library for unidirectional dataflow architecture inspired by Reflux

Resources

Stars

5 stars

Watchers

4 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

CIRelease Version

Vlow

A simple library for unidirectional dataflow architecture inspired by Reflux



Installation

Using npm:

$ npm i vlow

In your project:

importVlowfrom'vlow';// Exposes:// - Vlow.version// - Vlow.createActions// - Vlow.factoryActions// - Vlow.Store// - Vlow.Component// - Vlow.withVlow

Or... download the latest release from here and load the file in inside your project. For example:

<!-- Add this line to expose `window.vlow.default` --><!-- WARN: Make sure React is loaded before this line --><scriptsrc="vlow.min.js"></script>

Overview

Vlow uses actions to update one or more stores which updates the state of all components who are mapped to the store(s). In turn, a component triggers an action. Vlow can be used for keeping a global state.

There are three steps which need to be understood to use Vlow:

  1. Create Actions
  2. Create Stores
  3. Map store(s) to Components

Create actions

Actions can be created using the Vlow.createActions function:

// this example creates an add and remove actionconstItemActions=Vlow.createActions(['add','remove',]);

Invoking an action is as simple as calling the function, for example:

ItemsActions.add(item);

Create a store

A Vlow Store is an object which holds a global state which can be shared across components.

Creating a store can be done by creating a subclass of Vlow.Store and call the Store constructor with an actions object, for example:

classItemStoreextendsVlow.Store{constructor(){// Call super with the actions to which this store should// listen too.// Note: multiple actions instances are possible,// for example super(Actions1, Actions2);super(ItemActions);// Create the initial statethis.state={items: []};}// Implement onAction functions for each action defined by actions.// It is not required to create functions for all actions but usually// this is what you want and Vlow logs a warning in `development` mode// when actions are not implemented.onAdd(item){// Update the state like you would do with React.// Just like react the first argument can also be a function.//// An optional second argument can be used. When given it must be// a callback function() which will be called once when all// components which are mapped to the store are rendered.this.setState({items: [...this.state.items,item]});}onRemove(itemId){this.setState({items: this.state.filter(i=>i.id!==itemId)});}}

Map stores to Components

Now that the actions and stores are created, it is time to map them to a component.

This can be done either by using Vlow.withVlow which is the preferred method as of version 1.1.0, or it can be done by extending the Vlow.Component class.

Using withVlow

By using withVlow the store will be mapped to the component props. The function withVlow requires a Vlow Store or an array with multiple stores and returns a new function which accepts a component you want to wrap.

Here are some valid examples:

// Just parse the storewithVlow(SomeStore)(MyComponent);// Multiple storeswithVlow([SomeStore,SomeOtherStore])(MyComponent);// Map only specific store keyswithVlow({store: ItemStore,keys: ['items']// listen only to 'items' changes})(MyComponent);

And this is an example of how withVlow can be used:

import{withVlow}from'vlow';importItemStorefrom'../Stores/ItemStore';constItemComponent=({items})=>(<ul>{items.map(i=><likey={i.id}>{i.text}</li>)}</ul>)exportdefaultwithVlow(ItemStore)(ItemComponent);

Note: It is still ok to use PropTypes for checking the props from a store, for example:

ItemComponent.propTypes={items: PropTypes.arrayOf(PropTypes.shape({id: PropTypes.number,text: PropTypes.string})).isRequired};

Using Vlow Component

It is recommended to use withVlow instead of Vlow.Component but in some cases you might prefer to extend your component directly with a Vlow.Component instead of React.Component. The main difference is that the state from the store will be merged with your components state, instead of receiving the state by props.

Inside the constructor you should use the mapStore() or mapStores() function to map the state to the store.

Here is an example of how to use Vlow.Component:

classItemComponentextendsVlow.Component{constructor(props){super(props);// In case you want to set state in the constructor, make// sure to do this before calling mapStore() since you// otherwise would overwrite the state defined by the store.this.state={some: 'state'};// Function mapStore() accepts a store in which case the// complete store state will be mapped to the components state.// There are two more options://// - Using a keys filter in which case a component only listens// to certain store changes.//// this.mapStore({// store: ItemStore,// keys: ['items'] // listen only to 'items' changes,// // other store state will be ignored// });//// - Using an altState function which allows you to modify state// before it will be applied. (more info on altState() can be// found later in this documentation)this.mapStore(ItemStore);// The state now looks like:// {some: 'state', items: []}// It's ok to modify the state as long as you do not// overwrite `this.state` with a new Object, for example:this.state.hasItems=this.state.items.length>0;}render(){return(<ul>{this.state.items.map(i=><likey={i.id}>{i.text}</li>)}</ul>);}}

In case you need multiple stores, the function this.mapStores([]) can be used which accepts an Array of stores. Each store may be defined in a different way.

this.mapStores([StoreOne,{store: StoreTwo},{store: StoreThree,keys: ['foo','status']},{store: StoreFour,altState: storeState, state,props=> storeState
}]);

Alternative super class

By default the Vlow.Component class extends the React.Component class but you might want Vlow.Component to extend your own custom class. This is possible by using Vlow.Component.extend().

// In this example we create a Vlow Component which extends// React.PureComponent instead of the default React.ComponentclassMyComponentextendsVlow.Component.extend(React.PureComponent){
...
}

Using altState

Sometimes you want to listen to state changes in a store but then do something with this state instead of just applying the state to a component. This can be done by using an altState(storeState, state, props) hook which will be triggered on state changes in the store but before the component state is changed. The altState function should return the state changes you want to make or null in case you don't want to update the state of the component.

functionaltState(storeState,state,props){// This function should return the state// you want to apply on the component. The function can// also return `null` in which case the components state// will not be changed.if(props.status==='error'){// the components state will not be changedreturnnull;}// Return some alternative state for `this` component.// Other components still receive the `original` state// from the store.return{items: storeState.items.filter(i=>i.age>state.minAge)};}// Use the altState functionconststores={store: MyStore,
altState,};

No more listeners

If there are no components left who listen to the store, the store function listenersEmpty() is called. By default, this function does nothing but you might implement it yourself and overwrite the default behavior. For example, you might want to unregister the store if no more components are listening to clean-up memory:

importVlowfrom'vlow';// define the state on the store, e.g. this.state.todosexportinterfaceIMyStore{
todos: string[];}classMyStoreextendsVlow.Store<IMyStore>{listenersEmpty(){this.unregisterStore();// the store will unregister itself from the// actions until a new store is created}}

Use TypeScript

With Vlow, it is possible to use TypeScript and have both the state in your store and the actions typed.

Example:

importVlowfrom'vlow';// define the state on the store, e.g. this.state.todosexportinterfaceIMyStore{
todos: string[];}classMyStoreextendsVlow.Store<IMyStore>{onFetch(limit: number){/* fetch todo's... */}}constactions=['fetch',]asconst;constMyActions=Vlow.factoryActions<MyStore>()(actions);// MyActions.fetch(10); understands the arguments of the `onFetch` defined in the store

About

A simple library for unidirectional dataflow architecture inspired by Reflux

Resources

Stars

5 stars

Watchers

4 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

CIRelease Version

Vlow

A simple library for unidirectional dataflow architecture inspired by Reflux



Installation

Using npm:

$ npm i vlow

In your project:

importVlowfrom'vlow';// Exposes:// - Vlow.version// - Vlow.createActions// - Vlow.factoryActions// - Vlow.Store// - Vlow.Component// - Vlow.withVlow

Or... download the latest release from here and load the file in inside your project. For example:

<!-- Add this line to expose `window.vlow.default` --><!-- WARN: Make sure React is loaded before this line --><scriptsrc="vlow.min.js"></script>

Overview

Vlow uses actions to update one or more stores which updates the state of all components who are mapped to the store(s). In turn, a component triggers an action. Vlow can be used for keeping a global state.

There are three steps which need to be understood to use Vlow:

  1. Create Actions
  2. Create Stores
  3. Map store(s) to Components

Create actions

Actions can be created using the Vlow.createActions function:

// this example creates an add and remove actionconstItemActions=Vlow.createActions(['add','remove',]);

Invoking an action is as simple as calling the function, for example:

ItemsActions.add(item);

Create a store

A Vlow Store is an object which holds a global state which can be shared across components.

Creating a store can be done by creating a subclass of Vlow.Store and call the Store constructor with an actions object, for example:

classItemStoreextendsVlow.Store{constructor(){// Call super with the actions to which this store should// listen too.// Note: multiple actions instances are possible,// for example super(Actions1, Actions2);super(ItemActions);// Create the initial statethis.state={items: []};}// Implement onAction functions for each action defined by actions.// It is not required to create functions for all actions but usually// this is what you want and Vlow logs a warning in `development` mode// when actions are not implemented.onAdd(item){// Update the state like you would do with React.// Just like react the first argument can also be a function.//// An optional second argument can be used. When given it must be// a callback function() which will be called once when all// components which are mapped to the store are rendered.this.setState({items: [...this.state.items,item]});}onRemove(itemId){this.setState({items: this.state.filter(i=>i.id!==itemId)});}}

Map stores to Components

Now that the actions and stores are created, it is time to map them to a component.

This can be done either by using Vlow.withVlow which is the preferred method as of version 1.1.0, or it can be done by extending the Vlow.Component class.

Using withVlow

By using withVlow the store will be mapped to the component props. The function withVlow requires a Vlow Store or an array with multiple stores and returns a new function which accepts a component you want to wrap.

Here are some valid examples:

// Just parse the storewithVlow(SomeStore)(MyComponent);// Multiple storeswithVlow([SomeStore,SomeOtherStore])(MyComponent);// Map only specific store keyswithVlow({store: ItemStore,keys: ['items']// listen only to 'items' changes})(MyComponent);

And this is an example of how withVlow can be used:

import{withVlow}from'vlow';importItemStorefrom'../Stores/ItemStore';constItemComponent=({items})=>(<ul>{items.map(i=><likey={i.id}>{i.text}</li>)}</ul>)exportdefaultwithVlow(ItemStore)(ItemComponent);

Note: It is still ok to use PropTypes for checking the props from a store, for example:

ItemComponent.propTypes={items: PropTypes.arrayOf(PropTypes.shape({id: PropTypes.number,text: PropTypes.string})).isRequired};

Using Vlow Component

It is recommended to use withVlow instead of Vlow.Component but in some cases you might prefer to extend your component directly with a Vlow.Component instead of React.Component. The main difference is that the state from the store will be merged with your components state, instead of receiving the state by props.

Inside the constructor you should use the mapStore() or mapStores() function to map the state to the store.

Here is an example of how to use Vlow.Component:

classItemComponentextendsVlow.Component{constructor(props){super(props);// In case you want to set state in the constructor, make// sure to do this before calling mapStore() since you// otherwise would overwrite the state defined by the store.this.state={some: 'state'};// Function mapStore() accepts a store in which case the// complete store state will be mapped to the components state.// There are two more options://// - Using a keys filter in which case a component only listens// to certain store changes.//// this.mapStore({// store: ItemStore,// keys: ['items'] // listen only to 'items' changes,// // other store state will be ignored// });//// - Using an altState function which allows you to modify state// before it will be applied. (more info on altState() can be// found later in this documentation)this.mapStore(ItemStore);// The state now looks like:// {some: 'state', items: []}// It's ok to modify the state as long as you do not// overwrite `this.state` with a new Object, for example:this.state.hasItems=this.state.items.length>0;}render(){return(<ul>{this.state.items.map(i=><likey={i.id}>{i.text}</li>)}</ul>);}}

In case you need multiple stores, the function this.mapStores([]) can be used which accepts an Array of stores. Each store may be defined in a different way.

this.mapStores([StoreOne,{store: StoreTwo},{store: StoreThree,keys: ['foo','status']},{store: StoreFour,altState: storeState, state,props=> storeState
}]);

Alternative super class

By default the Vlow.Component class extends the React.Component class but you might want Vlow.Component to extend your own custom class. This is possible by using Vlow.Component.extend().

// In this example we create a Vlow Component which extends// React.PureComponent instead of the default React.ComponentclassMyComponentextendsVlow.Component.extend(React.PureComponent){
...
}

Using altState

Sometimes you want to listen to state changes in a store but then do something with this state instead of just applying the state to a component. This can be done by using an altState(storeState, state, props) hook which will be triggered on state changes in the store but before the component state is changed. The altState function should return the state changes you want to make or null in case you don't want to update the state of the component.

functionaltState(storeState,state,props){// This function should return the state// you want to apply on the component. The function can// also return `null` in which case the components state// will not be changed.if(props.status==='error'){// the components state will not be changedreturnnull;}// Return some alternative state for `this` component.// Other components still receive the `original` state// from the store.return{items: storeState.items.filter(i=>i.age>state.minAge)};}// Use the altState functionconststores={store: MyStore,
altState,};

No more listeners

If there are no components left who listen to the store, the store function listenersEmpty() is called. By default, this function does nothing but you might implement it yourself and overwrite the default behavior. For example, you might want to unregister the store if no more components are listening to clean-up memory:

importVlowfrom'vlow';// define the state on the store, e.g. this.state.todosexportinterfaceIMyStore{
todos: string[];}classMyStoreextendsVlow.Store<IMyStore>{listenersEmpty(){this.unregisterStore();// the store will unregister itself from the// actions until a new store is created}}

Use TypeScript

With Vlow, it is possible to use TypeScript and have both the state in your store and the actions typed.

Example:

importVlowfrom'vlow';// define the state on the store, e.g. this.state.todosexportinterfaceIMyStore{
todos: string[];}classMyStoreextendsVlow.Store<IMyStore>{onFetch(limit: number){/* fetch todo's... */}}constactions=['fetch',]asconst;constMyActions=Vlow.factoryActions<MyStore>()(actions);// MyActions.fetch(10); understands the arguments of the `onFetch` defined in the store

About

A simple library for unidirectional dataflow architecture inspired by Reflux

Resources

Stars

5 stars

Watchers

4 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages