mquan / cortex Goto Github PK
View Code? Open in Web Editor NEWAn immutable data store for managing deeply nested structure with React
License: MIT License
An immutable data store for managing deeply nested structure with React
License: MIT License
These following cases yield double changes where as there should be no change:
Changes should be merge and reflect the final state
Hi! Thanks for the awesome project!
I decided to use it in my company!
Can I know what is the browser compatibility of this project?
The same as ReactJS?
Thank you very much!
Really sorry for annoyance... just tried updating to 0.4.5 and noticed it wasn't published.
Brief code:
var model = new Cortex({username: 'abc'}, function(updatedBody) { });
JSON.stringify(model);
Result: TypeError: Converting circular structure to JSON
Some libraries (like react-async) are stringifying most of the async data and sending it over to the client. It would not be possible to use Cortex in such cases.
var cortex = Cortex(data, function() {
//trigger your React component to update props
});
This may be out of scope here but I thought I'd ask. I'm trying to react-router with cortex. One is not in control of calling render function. Is there a way of using cortex in such a fashion? The best I can come up with is a wrapper component that stores the cortex object as state and passes it down as a prop but at least one weird render problem occurs (cursor position gets lost in text fields).
Thanks
I noticed Cortex can tell you what changed since the last update cycle. This is cool and all, but what I really want to do is find out what changed since the last time I saved data to the server.
Here's how it'd work. When you start editing a record in your browser, I'd like to copy the relevant cortex subtree to remember what it used to look like. Then, when you hit Save, I'd like to diff the current state of the subtree with the saved copy, getting something much like the result of getChanges()
. Now I know what to send to the server to get things in sync!
Btw I want to say I just started using Cortex and I love it! Calling mutators on Cortex is way less work than writing a bunch of action handlers for a Flux app. It even fixes "the dot rule" problem in Angular apps where you can only really mutate a value if you have access to its parent object. Working with Cortex actually feels a lot like working with FireBase. In fact, I think Cortex's API is better than FireBase's, and it'd be cool if there was a cortex-firebase library that let you use FireBase via Cortex. But that's for a different issue, and may be a silly idea. Cortex also feels kind of like using mutable "reference" values in oCaml, since you can assign them in place without knowing about other places they are referenced. And it seems very similar to Functional Reactive Programming stuff like ELM, only you don't have to write any actions.
Calling unshift
results in every single property of every single item being flagged as changed, since all of the keys are now one increment off. This is, of course, the expected result.
Would there be a way to fine-tune this a bit so that Cortex is a bit smarter about these operations? In practice, I really only want to know that one change was made -- a new item at the beginning of the list.
Any thoughts?
I don't understand this message. It might not be important.
Running "webpack:development" (webpack) task
Version: webpack 1.1.11
Asset Size Chunks Chunk Names
main.js 657020 0 [emitted] main
WARNING in ./bower_components/bower-cortex/build/cortex.js
Critical dependencies:
1:104-105 require function is used in a way, in which dependencies cannot be statically extracted
1:113-114 require function is used in a way, in which dependencies cannot be statically extracted
@ ./bower_components/bower-cortex/build/cortex.js 1:104-105 1:113-114
WARNING in ./bower_components/bower-cortex/build/cortex.min.js
Critical dependencies:
1:104-105 require function is used in a way, in which dependencies cannot be statically extracted
1:113-114 require function is used in a way, in which dependencies cannot be statically extracted
@ ./bower_components/bower-cortex/build/cortex.min.js 1:104-105 1:113-114
So we can use on server-side as well.
How would you approach reordering an array in-place? Outside of calling .set() with the mutated node is there a way to edit the childrens' paths? Or is that even worth doing?
This is a pretty sweet project!
Was wondering if it would be possible to come up with an API that doesn't need constant strings. If you can get away without any strings then closure compiler can do a better job minifying, optimizing and it's easier to lint.
First, I wanted to express my thanks for building Cortex. It has made my life much easier.
I do have two problems, however:
version
key in package.json
and bower.json
hasn't been updated since 2b80a5f (add a filter
method). I'll make a pull request for this.gulpfile.js
; the minified library isn't getting updated properly. For instance, it still doesn't have the filter
method, even on master.Thanks again for building Cortex!
Is this intentional?
var obj = new Cortex({a: 0})
obj.on('update', function() { console.log('works'); })
obj.a.on('update', function() { console.log('not working'); }) <-- not working
The documentation made it sound like nested objects acts just like top level elements.
Could you add this file for component(1) compability? I made an attempt at repo gnimmelf/component-cortex
, but I just grabbed your src
-dir for testing. Here is the file, not sure if "it's all there"...
{
"name": "cortexjs",
"description": "A Javascript framework for building brilliant applications",
"keywords": [
"mvc",
"framework"
],
"repository": "mquan/cortex",
"main": "src/cortex.js",
"scripts": [
"src/cortex.js",
"src/pubsub.js",
"src/data_wrapper.js",
"src/wrappers/hash.js",
"src/wrappers/array.js"
],
"version": "0.1.12",
"license": "MIT"
}
I'm using cortex alongside webpack, and apparently it's not too happy about the way cortex.js looks like. I tried googling for a while, but couldn't find any suggestions on how to fix this.
WARNING in /home/manveru/~/cortexjs/build/cortex.js
Critical dependencies:
1:479-486 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results.
@ /home/manveru/~/cortexjs/build/cortex.js 1:479-486
Hi!
I've been using Cortex in my company for a while.
Recently I want to create tests for my React components.
But it's not easy since all the props are wrapped in Cortex.
Any ideas about how to do this?
Thanks!
Currently every react component that receive access to cortex object, can change it value.
I what to have ability to restrict their access to read only.
This would help to keep code base more clean.
P.S. I can achive this with code-guide/reviews, but it can be an issue for distributed team across the globe.
Do they both serve the same purpose? Thanks.
Hello and thanks for creating this library! Passing callbacks all the way down into child components to update root-level props is a pain, so I find the concept behind Cortex quite intriguing. However, I am confused about the following from the example:
orderCortex.on("update", function(updatedOrder) {
orderComponent.setProps({order: updatedOrder});
});
My understanding is the Cortex object we create and provide to the React component is used in place of properties, as it is in your example:
var orderCortex = new Cortex(orderData);
var orderComponent = React.renderComponent(
<Order order={orderCortex} />, document.getElementById("order")
);
Properties are never passed into the component, so why would we call setProps? Would forceUpdate() make more sense in order to re-render components based on the new values of the Cortex object? Perhaps I am missing something, but I thought Cortex replaces properties being passed into components.
Thanks,
-Jesse
Hello.
I started to use Cortex today. It's amazing!
I have one question, set() doesn't work with objects?
Here is what I've tried:
var Cortex = require('cortexjs');
var data = { a: { b: 2 } };
var cortex = new Cortex(data);
cortex.a.set({
c: 3
});
console.log(cortex.a.getValue()); // output: { b: 2 }, expected: { c: 3 }
Am I doing something wrong?
Is there a reason why sort()
was left out of the ArrayWrapper
? If so, how do you recommend dealing with sort?
The readme didn't say if it was possible to call .set() for the root object so I just tested this with console:
var Cortex = require('cortexjs');
var cortex = new Cortex({});
cortex.on('update', function() {
console.log('update')
// Now the data is {a:1}
})
cortex.set({a:1})
Maybe this could be in the readme too?
First off, thanks so much for making cortex. I've been playing with it, and it's improving my React code dramatically.
A minor point: when I call .map on a list in cortex, I keep getting the standard React error for a missing key prop:
Each child in an array should have a unique "key" prop. Check the render method of <class name>. See http://fb.me/react-warning-keys for more information.
I'm passing key props to each item in the list, but I think that the ProxyConstructor object that cortex returns is making React confused.
Hi there,
I use cortex in React Native, it works and there is a callback, however, I can't setState in the callback function as I use createClass which only grants me a descriptor. So where can I get an instance able to call setState because it is react native, the elements are very different, I don't think I could use the way in your example code (can't use renderComponent to gain instance..).
Thanks.
First of all let me tell you that cortex is great!
Is there a way to achieve server side rendering? I read the docs and the examples but I just can´t get it working properly without erros.
I can pass the state with JSON.stringify(new Cortex(data)), but i can´t figure out how to use cortex with React.renderToString(...) server side.
I think it would be very useful to have this functionality.
The only way I get this running is having different react components for server and client, which gives the warning in browser:
"
React attempted to use reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server.
"
but works.
Thanks
Hey.
I have my cortex and my react app instantiated in two different modules.
Currently, here's what I have to do:
cortex.js
module.exports = cortex = new Cortex({}, function() {
app.setProps({cortex: cortex});
});
var app = require('./app');
app.js
var cortex = require('./cortex');
module.exports = React.renderComponent(App({cortex: cortex}), document.body);
But I'd much rather my cortex did not know about my app: in the current scenario, any require('./cortex')
will instantiate my app, and that is not wanted at all. I'd much rather the cortex simply exposed a .on('update', callback)
so that I could do instead:
cortex.js
module.exports = new Cortex({});
app.js
var cortex = require('./cortex');
app = React.renderComponent(App({cortex: cortex}), document.body);
cortex.on('update', function() {
app.setProps({cortex: cortex});
});
What do you think?
Here's a test you can run:
Cortex.on('update', function(data) {
console.log('there was an update');
});
console.log('initial set');
Cortex.currentFolder.set({
folder: {},
children: ['c', 'b', 'a']
});
setTimeout(function () {
// This shows 'c','b','a', as expected
console.log('initial children', Cortex.currentFolder.children.getValue());
var o = Cortex.currentFolder.getValue();
console.log(o); // children are sorted, 'a','b','c' at this point
o.children.sort(); // But the sort doesn't happen until here
// Both arrays are sorted 'a','b','c' here
console.log('sorted', o.children, Cortex.currentFolder.children.getValue());
// Therefore, this does not generate a diff, and there's no update
Cortex.currentFolder.set(o);
}, 0);
I have a project that uses browserify and cortexjs.
I currently solved the problem by adding to my node_modules/cortexjs/package.json
string "browserify":{"transform": ["babelify"]}
. Which is obviously bad, when done on my side. Can you please do it on yours?
Hi! Nice lib.
I have array of objects, and I need to move one object up or down, how I can do it?
React not available in either of them.
Hello,
It would be nice to understand at first sight how Cortex compares to libraries like Om/Mori or functional lenses
Does Cortex use immutable data structures under the hood? Or does Cortex mutate the data in place and fire callbacks afterward
Since Cortex is managing state there's probably a best way to integrate with React's shouldComponentUpdate
method: http://facebook.github.io/react/docs/component-specs.html#updating-shouldcomponentupdate
Any ideas where to start?
Could I ask you to make cortex available for Component(1)?
Stop using coffeescript
I'm not sure if this is an issue or not, but when I try to run set()
on an array, I get a cryptic error in DataWrapper.__subValue()
(line 70) saying "Can't set property '2' of undefined".
My data structure:
{ a: {}, b: [] }
I'm trying to run myCortex.b.set(newArray)
If I log out this.__updates[i].path
, right before the error, I get something that doesn't look quite right:
["b", 1, 2]
.
The fix is to run remove()
on the array before running set()
. Is this by design? If so, should we document it?
(I am attempting to debug further)
> require("./src/cortex")({})
Module._load REQUEST ./src/cortex parent: repl
RELATIVE: requested:./src/cortex set ID to: /Users/glind/gits/cortex/src/cortex from repl
looking for "/Users/glind/gits/cortex/src/cortex" in ["/Users/glind/gits/cortex"]
TypeError: Object #<Object> has no method '__subscribe'
at Cortex (/Users/glind/gits/cortex/src/cortex.js:26:10)
at repl:1:25
Does cortex support batch updates?
this.props.filters.forEach(function(filter) {
filter.active.set(true);
});
This calls the update callback one time for every object in this.props.filters
.
Thanks.
Hi,
I'm using cortex in my website for admin panel, nothing really huge, but I've got a REALLY annoying bug fixed recently.
So I'm using cortex for managing one big global data bundle and I have tabs in the app. When user clicks a tab, I make it active by putting some data into that tabs local state, and making updates throw cortex set method to the data in the tab. At the beginning it worked good. But at some point I've messed up with updates and rerendering somehow. What I've got is that if I call this.props.item.val().is_active
it says true
, and when I call this.props.is_active.val()
it says false
after 2 changes made, i.e. it works for the first time, and doesn't for the second time. And it rerenders component at the first time, and not renders at the second time.
So my point is, if you see some kind of weird things like this, my advice is to check your code for places where you put some cortex wrapped data into local state. It seems to me in my app local state updates somehow interfered with cortex updates.
Could I ask you to make cortex available for Component(1)?
Maybe this is a bit heavy or premature, but I would find a cdnified cortex useful.
I am trying to implement Emberjs's Todo app as a practice exercise for Cortex. I am currently implementing the "All", "Active", "Completed" filter where clicking an anchor will result in the anchor being highlighted (class added). My plan is to create cortex wrapped objects to represent each of these anchor links and have each anchor link's class being rendered by the selected
flag.
I created the following:
var filtercortex = new cortex([
{title:'all', selected:true, key:1},
{title:'completed', selected:false, key:2},
{title:'active', selected:false, key:3}
]);
With the following render function (in the parent):
render: function() {
var filters = filterCortex.map(function(filter) {
return (
<li>
<FilterAnchor cortex={filterCortex} filter={filter} />
</li>
)
});
...
return ...
<ul id='filters'>
{filters}
</ul>
And FilterAnchor's definition:
var FilterAnchor = React.createClass({
handleClick: function() {
var that = this;
this.props.cortex.forEach(function(filter) {
if (filter.key.getValue() == that.props.filter.key.getValue()) {
console.log(filter.title.getValue(), true);
filter.selected.set(true);
} else {
console.log(filter.title.getValue(), false);
filter.selected.set(false);
}
});
return false;
},
render: function() {
var className = (this.props.filter.selected.getValue()) ? 'selected' : '';
return (
<a className={className} href="#" onClick={this.handleClick}>
{this.props.filter.title.getValue()}
</a>
)
}
});
right now, I do not see the class 'selected' being applied to the anchor links when I am clicking.
However, upon investigation I notice this in my developer console:
Clicking "All":
All true
Completed false
Active false
Clicking "Completed":
All true
Completed false
Active false
So I am certain that the objects inside filtercortex has been updated properly (you can open up firebug to check). However, FilterAnchor.render is not being triggered.
Is this a bug?
Source code: https://github.com/vicngtor/ReactTodo/blob/cortex/script.jsx
When including Cortex as an NPM module, this warning is emitted:
npm WARN package.json [email protected] No repository field.
This is printed to the console on any NPM command, so it'd be good to resolve the warning, even if otherwise harmless.
The README stated performs old and new data comparison out of the box so you don't have to implement shouldComponentUpdate
. Unfortunately it seems to atleast not work as expected.
The initial data looks something like this:
var data = new Cortex({
user: {...},
server: {...},
error: null,
url: {
path: "/",
params: {},
},
});
The app is rendered as demonstrated by the README:
var app = React.renderComponent(
App({ history: false, data: data }),
document.body
);
// Run update if data changes
data.on("update", function(updatedData) {
app.setProps({ data: updatedData });
});
The render function of App
looks something like this:
render: function() {
var data = this.props.data;
return (
<div>
<Header user={data.user} server={data.server} />
<div className="wrapper">
...
</div>
</div>
);
},
Now whenever the url bit is changed, i.e. data.url.path.set("/something")
. The Header-Component is still being re-rendered I expected, that no render will be triggered?
Am I mistaken?
One issue we've run up against using Cortex is data validation. Since our views mutate their properties with .set()
calls, validation needs to happen in the view itself. We would prefer to decouple that logic and move it down to the data layer, but it's not clear how to best accomplish that. We could stick something in between Cortex and our views, but then we'd lose the simplicity of passing cortex-wrapped properties down our component chain. Any suggestions?
This issue defeats the purpose of this library. my entire react application re-renders every time any data changes. For example take the skyline example(https://mquan.github.io/cortex/examples/skyline/) and for every components render function(in application.js), add a console.log('rendering ..'). Then when you run the example and just toggle the state of any of the light by clicking on it, you will note that all the components render function is called. To take advantage of immutability only the render functions of parts which have changed should have been called. Else there is no difference of using plain data vs immutable data. The same can be achieved using normal json data and re rendering the entire app on any data change.
var data = new Cortex({a:1,b:2});
var oa = data.a;
var ob = data.b;
data.b.set(10);
oa == data.a
// as a has not changed this should not change, but this is returning false
Hello and thanks for the 'cortex'!
Would it be possible to expose the changes/updates that the state has undergone. For instance in the simple example, the 'on update' let's you update the props.
orderCortex.on("update", function(updatedOrder) {
orderComponent.setProps({order: updatedOrder});
});
I think having a function to get the difference between formerOrder and the updatedOrder could be useful. For instance when some 'root component' needs to communicate the changes it has undergone to another 'root component'.
Very nice library but I would love to see it published on bower.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.