maadhattah / brookjs Goto Github PK
View Code? Open in Web Editor NEWreactive programming tools for well-structured, testable applications
Home Page: https://mAAdhaTTah.github.io/brookjs/
License: MIT License
reactive programming tools for well-structured, testable applications
Home Page: https://mAAdhaTTah.github.io/brookjs/
License: MIT License
Since it automatically returns the state if it doesn't match any action, the requirement of combineReducers
to return the initial state if the state is undefined
cannot be satisfied.
The tl;dr is this: Use webpack for apps, and Rollup for libraries
https://medium.com/webpack/webpack-and-rollup-the-same-but-different-a41ad427058c
https://github.com/semantic-release/semantic-release
https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-automating-releases-with-semantic-release
We should set this up post-1.0.0, once we've got ourselves a stable framework.
Should create components with React rather than brookjs#component
.
When testing deltas, you have to push to the state first before the action, in order to match the behavior of observeDelta
. This isn't something userland should have to know, so we should provide a set of helpers to setup and test deltas.
Emitting an event synchronously from a delta (which an Observable does by default) can cause some odd behavior, mostly in other deltas not receiving the expected action. We should add a note to the delta docs to prefer immediate actions use Kefir.later(0, myAction())
, rather than Kefir.constant(myAction())
.
For pages that aren't particularly dynamic, or which are primarily static pages with a few dynamic components on them, being able to mount the DOM as-is and use brookjs' data attributes to wire up events and onMount
to do some minor DOM updates in response to props changes. Similar to how Vue.js can use the DOM as a template when mounting, but only allowing event wiring and subcomponent mounting, this should be supported as an expected use case, tested explicitly with defined semantics.
I don't want to make additional breaking API changes at this point, but I'm not convinced the current animation API is effective. The problem is that the callback currently doesn't have any way of interacting with other renders, so you can't cancel a render based another render starting.
What I'd like to do is change the callback to take a stream of renders:
export default render(
template,
effects$$ => effects$$.map(effect$ => /* do things with it */)
);
The effect$
can hang meta off it, and now you're able to cancel your animations based on other effects:
export default render(template, effects$$ => effects$$.map(effect$ => {
if (effect$.$meta.type === 'ATTACH') {
return Kefir.concat([
// Hide the element first.
hideElement$(effect$.$meta.element),
// Attach the element to the DOM.
effect$,
// Fade in the element over time.
fadeInElement(effect$.$meta.element)
])
// Cancel animation if incoming element is about to be detached
.takeUntilBy(effect$$.filter(other$ =>
other$.$meta.type === 'DETACH' &&
other$.$meta.element === effect$.$meta.element
));
}
return effect$;
});
This should be more flexible than the current implementation, which only gives you access to the current effect but doesn't allow coordination between effects.
The evolution of this framework has been to replace API's that pass individual values to pass streams of values, so this keeps in line with that evolution, but it would cause a breaking change, as the stream being passed is no longer the effect itself but a stream of effects.
I don't have any committed work taking advantage of the animation API, so if someone is, please let me know. Otherwise, we are going to go ahead with this change in 0.9.0
.
I'm not sure whether this should be 1.0.0-required or not, but this is a major, required step for making sure this remains performant as it scales. Right now, small-scale apps have no problem with performance, but larger apps might.
See https://github.com/rpominov/kefir/issues/177
After we've done that, we can convert the actions$
pool to a usual stream with https://github.com/rpominov/kefir/issues/239
I've made a couple abortive attempts to build a set of testing helpers, which I had dubbed desalinate
, but I haven't pulled together a definitive "how to test brookjs
components" yet. Testing deltas is pretty easy/straightforward, although it requires some modification to how your deltas are structured–curry the function, pass in the delta services as the first parameter, and mock them during unit testing. This is kind of how redux-observable
suggests doing tests, although they provide an explicit mechanism for passing in dependencies. Adding a similar feature to observeDelta
would likely require breaking changes, so the currying method works well enough and we can break that in 2.0 if it feels cumbersome.
Should be downloadable by consumers as well.
Now that this PR has been merged, Karma's Chrome runner supports headless Chrome. That plus the lead developer of PhantomJS stepping down means we'll want to switch from PhantomJS -> headless Chrome at some point in the near-ish future.
I think meta
might be appropriate to put the source information. We could also take this as an opportunity to make the source
an array, to keep track of all the sources the action has passed through.
Or we could drop the sources
key completely and just do what it says on tin: map one action type
to another.
This is a catch-all issue for additional features that should be added to the API in order to take advantage of Observables in React.
Scaffolding out a new component should include the tests and development environment associated with it.
We've currently got some circular dependencies because projects are dependent upon brookjs
just for Kefir. In this case, we should probably move Kefir to a peerDependency and let projects depend on Kefir directly.
Because the framework grabs the props by key for an iterated child automatically, it can be difficult to reason about how the props flow down through a component. A better way may be to call modifyChildProps
with a second parameter key
, which the developer would use to write their own props-mapping function. This would make the data flow more explicit.
While this is a nice construct, needing to babel it down to another dependency isn't worth it. Remove it and its dependency.
Related to #120.
We should probably create and export an iteration helper so we cache and reuse the stream.
Currently doesn't export it. Check to make sure all documented modules are exported through the entry file.
See angular-cli & ember-cli as possible examples of features. Makes it easy to spin up a new project, add new components/deltas/etc. This is probably something we should avoid locking in until we have a better sense of how applications should be structured. There's a bit of movement in the Redux community away from grouping by "type" (reducer, component, etc.) and towards grouping by feature, or domain, as adding a new feature when things are grouped by type requires some bouncing between folders. I'm not sure I prefer that, but I haven't built a project that way yet.
Since we're relying on React handles cross-browser inconsistencies, so neither we nor userland need to, so we can remove it from all the packages as well as skip developing for it. This should make testing faster and more reliable, and we could explore integrating with alternative testing frameworks.
This will be a breaking change, but we should land thru
in Kefir, and recommend people use that + a new function (filterByType
or something similar).
If we're trying to comply with the Flux Standard Action, we should not append key
to the action emitted by the children
.
Using Flowtype or TypeScript, I want to include support for some kind of static typing. At a minimum, we should add a .d.ts
file and a .js.flow
file, but I would seriously consider (re)writing the library into either of those directly. Statlz makes a good argument that all libraries should be written in TypeScript, but it's really an argument for types of any kind.
Up to this point, I've favored Flowtype's philosophy, designed to allow adding types incrementally. TypeScript has bigger community uptake, and the development on Flowtype seems slower, so all of these seem like decent arguments for writing it in TypeScript, and then possibly figuring out how to compile it to Flowtype definitions.
Either way, we should eventually pick one and use it.
This breaks the webpack-dashboard
output.
Having access to the DOM node that emits the event could be helpful to fetch attributes to pass into the payload. Maybe wrap the Event in a custom ProxyEvent
/ SyntheticEvent
of some kind.
Counterpoint: If an application is structured correctly, you should never need more than the key
attribute.
As noted in #61.
Ink would be a really nice method for writing the UI; alternatively, react-blessed looks quite cool. Both provide a JSX-component-based means of writing a terminal UI. I think it would be really cool to eventually write a renderer for brookjs that works for terminals, and it would probably be easier to do that by borrowing from Ink, but both are options.
Build a small PHP application using the Slim framework, using server side rendering with LightNCandy. Todo apps are so boring but it would provide a good example of how to structure both the FE and BE and how to handle the "seams" between them (types? json-schema?).
I think good stories with Storybook are going to be fair more useful than snapshot tests. Screenshot tests may be useful here though. Should we integrate those into brookjs-cli
?
We have a Handlebars implementation for Java + PHP that are both solid, so we should add helpers for both of those languages that can be pulled into any project and allow things like {{container "myContainer}}
to be rendered by these BE languages without requiring them to reimplement brookjs
logic.
We should probably go ahead and just remove the old component implementation in 0.12.0
, and introduce the React-based version over the course of the 0.11.*
line. Once that version is stable enough, we'll deprecate brookjs#component
and start the new Docusaurus documentation with info on the new API, including how to migrate from the old one to the new one.
ofType
-> thru
w/ function to be named laterTesting tools will also be released when they're ready. We're still trying to decide on which testing framework to recommend and use.
Enhance render module to manage DOM node transitions. diffhtml
ships with this by default, so this may be more effectively implemented by switching our rendering implementation.
This is long-future stuff, but any-observable provides a way for a library author to depend on a generic Observable and allow the consumer to choose which Observable implementation they want to use. Right now, we have a hard dependency on Kefir, and are returning Kefir.Observable
s for all the library methods. Allowing the library consumers to choose which Observable implementation will allow brookjs
to be more flexible. Especially given the popularity of RxJS, I suspect consumers are going to want to use that, although I've found the complexity of dealing with the various builds hard to deal with and much prefer the smaller surface area and semantics of Kefir.
Major Blockers:
es-observable
spec ratification
map
, flatMap
, etc.)See 74d221f for details.
All of the raf$
-related functions are intended to be consumed by users, so we should export those through the main entry point and document them.
Check if any of the other modules have publicly-usable functions/streams.
We need to distribute to npm with ES5 compatible code.
This function should work like map
but also prevent new values from being emitted if previous values match.
The docs currently explain each individual modules' API, but don't provide an overall "here's how to build a component" walkthrough.
Hexo has always been a bit of a hack, since it was intended for static site blogs. A tool designed for docs, written in JS, would be perfect.
This should add --inspect-brk
to whatever / wherever we need to start the node debugger.
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.