Fork me on GitHub
#hoplon
<
2017-10-19
>
thedavidmeister00:10:03

ok i'm reading about flapjax 🙂

alandipert04:10:49

it was pretty sweet for its day

thedavidmeister04:10:38

@alandipert i'm only a few pages in, keep getting distracted, but it reminds me of https://cycle.js.org/

alandipert04:10:41

thedavidmeister https://www.youtube.com/watch?v=xaxF5RDdVRE#t=22m21s is a lightning talk i gave on flapjax in cljs in 2012

alandipert05:10:28

oh i hadn't seen that one

thedavidmeister06:10:14

@alandipert so would i be right in saying that in flapjax terminology javelin cells are like behaviours and there isn't really an event system?

alandipert06:10:04

that's right

alandipert06:10:31

one thing we saw is several systems like flapjax implemented events/streams after they had behaviors. by putting random values or counters in behaviors, causing them to fire each time

alandipert06:10:20

or, a timer, causing propagation every tick

alandipert06:10:13

the thing you need though to achieve max behavior is pervasive useful equality

alandipert06:10:49

which is what made flapjax fail in cljs in the end, it had weak equality baked in. so javelin started as a close port of flapjax w/ cljs = as the test

thedavidmeister06:10:52

yeah, so i've been taking the random value approach and it mostly works, but finding edge cases where i don't know how to make it work nicely or at all 😕

thedavidmeister06:10:09

the way i'm thinking about it atm is that if you implement events using behaviours, then you're modelling behaviours as "events + a cache" and then you manually bust the cache with that counter/random value

thedavidmeister06:10:46

but it doesn't 100% work if you want to trigger side effects/callbacks with meaningful event values that aren't counters/uuids

thedavidmeister06:10:03

(defmethod do! :focus
  [elem _ v]
  (with-timeout 0
    (if v (.focus (js/jQuery elem)) (.focusout (js/jQuery elem)))))

thedavidmeister06:10:37

if i want to trigger focusout twice then i have to artificially cycle between nil and false

alandipert06:10:17

ha, that's a cool trick though

thedavidmeister06:10:23

but this relies on an implementation detail of :focus that actually doesn't meet the spec atm

thedavidmeister06:10:27

(defmethod spec/do! :focus
  [_]
  (spec/attr :hoplon.spec/boolean))

thedavidmeister06:10:38

yes it's definitely a cool trick 😛

thedavidmeister06:10:01

if i strictly had to pass a boolean to :focus then i cannot trigger focus or focusout twice without artificially cycling through the other event, which could easily generate FOUCs or jank, etc.

alandipert06:10:02

altho, why would you want trigger focusout twice?

thedavidmeister06:10:11

:focus (j/cell= x)

thedavidmeister06:10:21

so whenever x changes, trigger an event

thedavidmeister06:10:37

but x changing and the current state of the element aren't related in any way

thedavidmeister06:10:44

it seems the flawed assumption is that :focus is singularly responsible for or at least accurately tracking the focus state of the element

alandipert06:10:06

yeah, i'm not sure focus is a good thing to be an attribute

alandipert06:10:13

since it's a singleton state in a way

thedavidmeister06:10:31

also it interacts with children, e.g. focusin vs. focus in jquery

thedavidmeister06:10:23

there very easily can be something outside the sensible responsibility of x that is adding/removing focus from the element

alandipert06:10:29

i think it might make sense for that to be a subsystem of some kind

thedavidmeister06:10:07

so x needs to explicitly focus in/out as needed, it can't just assume that if it gets 2 false values in a row that everything is fine

alandipert06:10:33

yeah, some separate coordination system seems necessary, to keep things in sync

alandipert06:10:16

i gotta run, my brain will consider this further in the shower tomorrow

dm306:10:23

oops - haven’t noticed the conversation

thedavidmeister06:10:42

just whether the equality check should "cache" the result

thedavidmeister06:10:20

i'm suggesting that rather than implicitly working around the internal cache to simulate events by generating counters and uuids and whatnots

thedavidmeister06:10:36

making it explicit somehow that the cache should not apply in certain situations

thedavidmeister06:10:20

then you'd basically have "real" events

thedavidmeister06:10:08

e.g. an un-cell= for "unconditional" or "unchecked" propagation downstream

dm306:10:46

seems like focus should be a separate cell which contains a currently focused element

dm306:10:00

and does something to it

thedavidmeister06:10:25

i have done things like that, but then you have global state to deal with

dm306:10:35

yeah, but isn’t it a global state?

dm306:10:42

conceptually

thedavidmeister06:10:51

the whole DOM is global state, conceptually 😛

thedavidmeister06:10:17

i sort of see what you mean

dm306:10:32

yeah, but the whole DOM is special 🙂

thedavidmeister06:10:36

like, triggering focus on something implies that something else somewhere loses focus

thedavidmeister06:10:07

but that doesn't sit well with bubbling and whether parents are in focus

thedavidmeister06:10:19

you don't just have a single "focussed element"

thedavidmeister06:10:37

there's a whole chain of elements in focus, at least in the jquery model with focusin

dm306:10:58

can you find out the chain from the one that got the event initially?

thedavidmeister06:10:13

yes, i have done exactly this, built up a set of elements that are "in focus"

thedavidmeister06:10:35

but then you have a lot to co-ordinate and you're just re-implementing what already exists

dm306:10:36

the focus-set

thedavidmeister06:10:43

sort of like a virtual dom...

dm306:10:23

it seems like :focus is an event, and a :focused property should be specifically supported by hoplon

thedavidmeister06:10:25

and this is just focus, what about mousedown, is that not also an event with all the same characteristics?

thedavidmeister06:10:43

or the majority of events, really

dm306:10:50

you mean w.r.t. bubbling?

thedavidmeister06:10:15

w.r.t. wanting to trigger them on an element more than once without juggling counters/uuids

thedavidmeister06:10:36

bubbling was a reason why co-ordinating this is more difficult than simply having a "currently focussed" element

thedavidmeister06:10:58

but the goal is to trigger DOM events reliably, and still leverage all the javelin goodness

dm306:10:44

you mean have a (elem :mousedown cell)?

thedavidmeister06:10:59

yeah, or any other event

thedavidmeister06:10:16

forget the specific event, they broadly all function the same for the purpose of this discussion

dm306:10:17

not sure I understand how that works

dm306:10:33

haven’t worked with hoplon for a long time now 🙂

thedavidmeister06:10:45

(elem :eventname cell) triggers eventname whenever cell is truthy

thedavidmeister06:10:40

so to trigger it more than once, you have to make sure it's a different truthy value (according to =) for each trigger

thedavidmeister06:10:43

hence, counters and uuids

thedavidmeister06:10:40

but that's just a workaround/trick really

dm306:10:59

well, I don’t think vanilla cells are suitable here

dm306:10:12

you are triggering events

dm306:10:19

not propagating state changes

thedavidmeister06:10:42

well i agree, yes, that's why i'm thinking an extension or new type of cell atm

thedavidmeister06:10:01

that's the flapjax reference ^^

dm306:10:04

so it has to be some sort of (elem :eventname (event-cell cell :every-update))

thedavidmeister06:10:06

they distinguish between behaviour and events

dm306:10:47

trying to push that into Javelin 🙂

dm307:10:06

one way to override equality

dm307:10:20

the other to add a stream concept

dm307:10:26

which is actually an event stream

thedavidmeister07:10:02

well whatever the final outcome is, i hope it has nice hoplon support 🙂

dm307:10:05

kinda, but it’s a different aspect

dm307:10:28

I’m working with Javelin on the JVM now

thedavidmeister07:10:43

"Custom error propagation strategy per graph. E.g. you can set the graph to behave like Excel and propagate #ERR on formula errors instead of the default throwing behaviour." - seems pretty close to custom value propagation 😉

dm307:10:09

yeah, but this only determines where you customize it

dm307:10:24

you can do it per graph or per cell

dm307:10:32

think this one is better per cell

dm307:10:57

although the same can be said about errors probably…

dm307:10:59

not sure

dm307:10:32

I had to get the graphs working because I’ve got many graphs in one application

dm307:10:58

you don’t really need that in Hoplon

thedavidmeister07:10:23

oh ok, what were you working on?

dm307:10:42

monitoring logic

dm307:10:24

I have a CEP part based on an event query language which then signals state transitions to the cell graph

dm307:10:15

sort of select * from ThisHappened where average(window(5 minutes)) > 5 -> (defc happened? false) -> more cells

thedavidmeister07:10:06

so each query was a different graph of cells?

dm307:10:19

no, each instance of the “engine”

dm307:10:38

has many queries/cells

dm307:10:44

but different partition of events

dm307:10:57

needs to run concurrently

dm307:10:16

you’d have multiple processes on e.g. NodeJs

dm307:10:41

but JVM has threads

thedavidmeister07:10:31

not really a use case for hoplon >.<

thedavidmeister07:10:27

the added benefit of custom propagation vs. event streams

thedavidmeister07:10:42

is that custom propagation could also address https://github.com/hoplon/hoplon/pull/193 at the javelin layer

thedavidmeister07:10:45

which is the situation where direct user input modifies the DOM "underneath" hoplon, so setting the same value twice is necessary even for a behaviour

alandipert14:10:27

dm3 sounds really cool, what kinds of actions to you have hung off your cell graph? is it for UI or something different?

dm318:10:59

@alandipert no, it’s for alerts. Like sending messages to Slack, etc