With the exception of Collection folds, rework everything in the framework that still felt half-baked, iffy, or dangerous. Many small renamings and major refactors of core components.
- New features:
View#attach()
now works; given a data tree and DOM tree previously rendered by (eg server-side) Janus, instantiates a new View tree and binds it against all the existing DOM points.- The viewtree navigator was introduced, allowing direct navigation around the View tree hierarchy by data key, or subject or View classtype.
- Breaking changes:
- Reworked API surface so that instead of eg
length
/watchLength
, we uselength_
/length
respectively now throughout. Less memorization, and emphasizes Varying-based computation.
- Reworked API surface so that instead of eg
- Refactors:
- Redid entire
application
package:Library
no longer auto-instantiates things it hands back. Also simplified call format to remove the explicitattributes
object.acceptor
andrejector
are no longer supported.Endpoint
,Handler
, andManifest
got all simplified and collapsed down to justManifest
. Actually gained some features in this process.App
got simplified as well, primarily because it no longer shadow-copies with each returned artifact and no longer worries about Stores so much. Almost all the "automagic" in the framework is now contained withinApp
.- All three are now top-level exports in the Janus package.
- Reworked implementation behind all three core components:
Varying
,from
, andcase
.Varying
did not change externally, but the internal propagation mechanism was completely redone andComposedVarying
was merged substantially into the primary codepath.from
didn't really change externally except that the semantics around transforming afrom
to aVarying
is now concretely whenever.point()
is called. Removed all the complicated internal casing.case
no longer typechecks full case set onmatch
which makes it a simple tight loop. It also once again relies oninstanceof
and class instances. Generally much more pleasant to look at.
- Request/Resolve got reworked one last time:
- Resolvers are now just simple functions (req) -> Varying[types.result[x]] rather than class instances.
Model
now knows nothing about request resolution.App
deals with it directly.- All the magic around setting request results into the Model now live on the
ReferenceAttribute
itself, which feels cleaner.
Set
was completely reimplemented and now provides much-closer-to true Set semantics.Model
issues/validate moved around a little bit; their names make more sense now.Map
andList
no longer rely on events to manage their Varying change propagation.- The
KeySet
andIndexList
enumerations have been rewritten. Most of the options forKeySet
(formerlyKeyList
) have been eliminated. Traversal
has been recoded to properly allow the intended full semantics. The default diff functions have been rewritten to not rely on unintended bugs.Base
no longer derives fromEventEmitter2
; it lazily instantiates one when it needs it.DomView
no longer uses.withOptions()
; the only option is the viewmodel class, which is an optional leading parameter inDomView.build
.
- Redid entire
- Quality of life improvements:
- We now support
Varying.all([ vx, vy, vz ]).react((x, y, z) -> …)
to directly react on multiple Varyings. - In ES6, we now allow
for (const x of list)
where list is a JanusList
. - Named templates allow references into template trees for reuse elsewhere.
- We now support
- Fixes:
- General audit for memory leaks and accidental returns.
- No longer rely on a global singleton (commit to peerDependencies on NPM).
- ES6 classtree detection now works for subtle corner cases.
Once again focused on two things. First, a huge number of small-scale quality of life improvements were implemented to provide better answers for awkward syntactical constructions and codify some common-in-practice patterns into simpler forms. Secondly, as part of an important effort to ensure broad language compatibility, the Model and DomView declaration systems were entirely refactored to move away from class-based definition, which were tightly bound with Coffeescript's classdef particulars. The new system also improves behavioural composition.
- Quality of life improvements:
- Make
.react()
do what.reactNow()
used to do, as it is the more common call.reactLater
replaces the oldreact
. from(…).asVarying()
will now get you an unflatVarying
mapping argument, in case it is better for performance, eg when creating things like filtered lists.- Add
varying.pipe()
which makes stdlib Varying helpers easier to use; eg:varying.map(…).pipe(throttle(30)).react(…)
. - Allow
from.app('key')
to watch the given key. Previously, no arguments were taken. - Add a curried form of
map.set('key')
which returns a function which sets that k/v data. map.with({ attrs })
shortcut to shadow a Map with the given data override.default()
andtransient()
Model attribute declaration shortcuts.
- Make
- Big refactors:
- Rather than declaring a class with
@_dom
and@_template
to create a DomView, the newDomView.build(dom, template)
facility takes a DOM fragment and atemplate()
and constructs a DomView.- Template mutator definitions can now chain, eg
find('.title').text(from('name')).classed('active', from('enabled'))
. This works even with interally-chaining mutators like.render()
- The new
.on()
declaration isn't technically an idempotent mutator like the others but enables much quicker event wiring definition without having to write a full_wireEvents
method.
- Template mutator definitions can now chain, eg
Model
no longer has classdef methods@attribute
and@bind
. Now these are declared viaModel.build(…)
.attribute
,bind
,issue
,default
, andtransient
are top-level package exports that can be used inModel.build(…)
to define the Model.- Class-based inheritance still works if so desired.
- But preferred is the new Trait system, which is essentially
template()
but forModel
s, enabling egModel.build(TraitA, TraitB, bind(…), attribute(…))
. Traits may contain other Traits. Last write wins.
- Rather than declaring a class with
Focused on two major areas: unbundling and formalizing models as data structures and enumeration/traversal of data structures; and resource lifecycle management. Also improved request/store handling, updated dependencies, and improved test coverage overall.
- Unbundled
Model
intoMap
andModel
, and movedMap
into thecollections
package.Map
gets all core functionality around key/value storage, basic (de)serialization, and shadowing.Model
derives fromMap
; it retains attribute definition, issue tracking, attribute binding, request resolution, and more-advanced (de)serialization features.
Map
, now more of a data structure, derives from the newEnumerable
trait along withList
. Enumerability covers the following basic features:- Static enumeration via
enumerate
and live enumeration viaenumeration
, which provide all keys (string keys in the case ofMap
and integer indices in the case ofList
) as either anArray
orList
, respectively. Live enumerations then providemapPairs
andflatMapPairs
, which provide(k, v)
arguments to a mapping function. - Serialization via traversal (see below) on a static enumeration.
- Diff tracking via traversal (ditto), which tracks differences between arbitrary data structures and provides a
Varying[Boolean]
signalling as such. Modification tracking is now just diff tracking against an object's shadow parent.
- Static enumeration via
Traversal
provides a principled way to recursively walk a data structure tree and map the result onto a like-structured result or into a reducibleList
. Default serialization and default diff tracking are implemented in terms ofTraversal
, such that their behaviour can easily be overridden piecemeal deep into a structure.- Resource management becomes much more automatic and memory-safe:
Varying
getsrefCount
, enabling resources or processing to be spun up and down as necessary.Varying
also getsmanaged
, in the case that aVarying
return value depends on intermediate calculatedBase
objects. Withmanaged
, the intermediate resources are automatically generated when theVarying
is actually active, and destroyed when it is not.Base
gets a similarmanaged
, but instead of managing intermediate resources is concerned with being able to share read-only computed resources likeEnumeration
s. Methods like.enumerate()
can depend onBase.managed
to vend one shared resource that is spun up or down as needed and destroyed.- The request handling code is upgraded to use these new features.
Varying
got a huge internal refactor to cut down significantly on memory and processing usage, and eliminate classes of race condition bugs that became a big problem with the addition ofrefCount
.Request
andStore
get upgraded with better handling, new and more consistent APIs, and full test coverage.- The casing system was upgraded with global attributes, case arity, and case subclassing.
Completely overhauled and rewrote the Varying
abstraction, as well as much of the templating, view, model, and collections systems that were too tightly-bound to Varying
to escape rewrite. Introduced case
and from
as vital core abstractions. Also dramatically increased test coverage, streamlined and removed a bunch of fluff components, and other miscellenia.
Varying
became a true monad: it no longer automatically flattens its contents. It also no longer uses an event-based system for change propagation, as this resulted in intractable race condition problems as well as performance issues. Many improvements and changes aren't listed here.- The
case
system is new, and an attempt to formalize and abstract the internal behaviour-handling models of Janus such that they can be easily augmented or replaced in userland where needed. It is a response to the problems withinstanceof
-based casing. - The
from
system is a reconsideration of how databinding can be declared and executed. Its point-free programming model enables it to be freely leveraged to solve any number of problems unrelated to databinding. Mutator
andTemplate
are ground-up reconsiderations of how to bundle template-like behaviour.View
andModel
are impacted insofar as their interfaces to the above are concerned.- Alongside this release is the new
janus-stdlib
, which contains a slew of very useful default View implementations for the objects in the library.
Initial release. All the basics are here, but given that the philosophy codified alongside the development, the exposed API is less than precise and often in conflict with the underlying machinations.