I have Noticed two things when comparing webmx to hoplon and electric: 1. Web-mx does not have a text function. This means that static text is easier to write, but dynamic text needs to be in :content which is less understandable. 2. There is are small discrepancies such as onclick on-click.
Question on the "me" concept: If I understand this correctly then this allows me to query the dom-tree that is managed by web-mx. That is pretty unique concept. Is this idea coming from smalltalk? What usecases did you find for this that are useful when writing Apps? I guess it allows me to do cell calculations that depend on cells of Parents or siblings. It is unique and I feel it allows to do crazy stuff. But I have no IDE what it could be. And then I have a questio nto the second map argument. So there basically the me cells are being defined. What I find curios is that a map is not guaranteed to have keys in any order. There exist SortedMaps for that requirement. I would have thought that one Has to do a topological sort to be Sure before building a model. But your code does not do that. So I guess clojurescript map when put to the reader is parsed always from top down.
"Is this idea coming from smalltalk?"
Yes, me is like self in ST, ot this in JS. It is a lexical variable supplied by many macros, bound to the object that owns the Cell.
Yes, it is very handy, especially because 'me' objects know their parents and their children. This means any Cell can see the entire universe, benefitting from the natural scoping of the app structure itself. eg, duplicates by name resolve naturally to the one nearest me, the one we want 99% of the time. A bit of code lets us find a different duplicate we might have in mind.
"What I find curios is that a map is not guaranteed to have keys in any order."
Well, when I write a formula or watch function that needs the disabled? property of a widget, I just say (mget widget :disabled?). Why would we need the properties to be sorted?
Oh, I see the concern: "I would have thought that one Has to do a topological sort to be Sure before building a model." This was a message from god that Cells is correct: when a new instance is created, the very first thing we do is "awaken" it (by calling md-awaken). That just runs down every property evaluating any cells it finds (and btw calling any watch functions on a propert, cell-mediated or not). When a formula runs, it finds and evaluates needed other cells and even other models JIT, on the fly. Note that this often requires widgets to instantiate their children, just to get the desired widget! As I said, when this worked out of the box I knew Cells was Deeply Correct. Good question!
btw, the first time I implemented this I assumed that, as cool as Cells was, that this is where the wheels would come off. No way a dev could deal with getting things instantiated in the right order. In a sense, if you check out https://tilton.medium.com/the-making-of-cells-5ab873d1e6c7, that challenge is what led to the creation of Cells. The functional paradigm naturally ordered calculations, as long as we could have properties compute JIT if they had already been compuetd and cached.
Thanks Kenny!
Can you explain me how to do two thingsL
1. how can I get what reagent would ref to a dom element. So Inside a web-mx component, I need to be able to get the reference of a dom element, and then I can basically do watch the required properites and then run a function that updates the dom outside of webmx context.
I need this because I am using webgl renderers (so no dom impact other than the container), and I also use npm render libraries like highcharts that I need to say when they have to render where.
2. What I need to do is watch the dom elment, mainly to get its size.
I'll have to check, but I hope you just call mx-dom on the widget. 🙂
Because I am showing timeseries, and so I want to show each point in time in a 5 pixel spacing,
then if I have 500 pixel width, I know I have to request 500 rows.
And the onther thing I need to now is how I should manage multiple web-mx views inside a react view.
Getting the size of a dom element can be tricky if you are using a library that alters the size dynamically. MathJax made me work quite hard to get the dimensions of a math expression after it had rendered--but their API did support that!
I use flexlayout-react, which basically allows the user to dynamically add components to a layout.
What flexlayout-react does, it handles resizing of components, and does show them in a layout
similar to how modern desktop operating systems work.
Oh, wow, MX inside a React component? That could be tough.
I will post some of my sub projects here.
Okay.
So:
I am exposing clojure functions via clj-service,
this allows to do a request-reply communication.
What clj-service does it exposes such functions via a http endpoint and via a websocket endpoint.
The trick is, that I allow also stateful functions,
whcih basically get their config.
With re-flow I can expose flows,
so basically an event stream to the browser.
This allows to do publish-subscribe,
I am working on a technical analysis framework called quanta-studio,
so the calculations mainly are done using techml dataset,
which allows me to do fast calculations huge vectors and matrizes.
I made a browser-extension for this,
The clj side reactive mordel is in quanta-dag-algo.
There I can do specifications using edn files,
and this allows me to do calculations either historically as of a specific date,
or going forward dynamically as "real" time passes.
https://github.com/clojure-quant/quanta/blob/master/lib/calendar/src/quanta/calendar/core.clj
I have my own calendar module,
so basically I can work on different time streams.
The time streams power calculations.
Ah, it is called tag-dom. Better actually than mx-dom. mx- is pretty general. tag is historical, refers to HTML tags.
Hey, I have to break out for the afternoon. More later, but the concern is that MX will need to extend the DOM created for the surrounding React component, and I think React likes to regenerate that on its own when it likes, Could get crazy re-potting the MX DOM.
Ever since I went to over 100.000 data-points per chart,
I had to basically keep all this data out of the dom,
and even out of the websocket,
because it would block the main communication for a little bit.
I want to extend this layout system,
so that I can also dynamically add new calculations.
I have an options-ui,
where simple options for an algo can be changed, that will then rerun algos that depend on that options.
What my goal is that I have a data-model, and a visual-model.
with data-model I mean data that is not going to be shown in the dom.
Like a huge table for example.
And the visual-model is what gets shown.
So from each cell in the data-model I will be able to generate new visual-model cells that then get shown in the dom.
So depending on the datatype and a module that will determine which vizualisations could possibly make sense for that type of data, it will then give me a dialog to show what I could want to show.
I think I am using reagent to the maximum possible right now.
And at some point I need to start replacing it with something else.
My goal is to have reproduceable notebooks.
But basically not focused on clojure forms, but multiple computations.\
So to me the nodes are sort of cells.
I have seen a system like what I am building in smalltalk at some point.
But I forgot how it was called.
I had a look at flutter yesterday, and yes its an amazing platform. But for what I want to do I fear it is too early.
I want to be able to arbitrarily let users define how to visualize the data.
So I am bringing sci interpreter as well,
so basically new ui can be defined with sci.
In its simplest form I use that to highlight a cell in a table in red if the value is negative.
To give an example.
And I do have one question:
missionary has included in there rendering system something, that detects is a dom node is moved somewhere else.
In which case it does not need to remove/add again.
They also sample the state 60 times a second, so they will do dom updates at that speed.
Have you ever found a need for something like that?
Since web-mx api is just a few hundred lines of code, I am thinking of doing something similar, but for server-side rendering.
Many thanks for helping me along!
I am not sure if I will start using Matrix or not.
I just know that my current design needs something new.
"Since web-mx api is just a few hundred lines of code,..." There ya go. You do not need MX you need missionary to work on the DOM. mx-web shows it is not that hard. The DOM is insanely well-documented at this point. Extending Missionary to handle DOM will be an order of magnitude (or two) easier thang getting MX to work inside Missionary and React.
I am trying to understand how matrix does its rendering. So what I figure is when you first Mount it run once and creates whatever is visible. When there is a change in a cell then this change leads to a recalc of the element that observes the cell. And then the refresh needs to have a link to the dom element and then update first the element itself and then perhaps it's children.
"And then the refresh needs to have a link to the dom element and then update first the element itself and then perhaps it's children." Correct. The MX proxy decides some property has changed. When this proxy property corresponds to a DOM property, a side-effect handler actually uses the DOM API to alter the DOM property.
"but dynamic text needs to be in :content which is less understandabl" Can't say I disagree with that, but that is how the DOM works once you get under the hood. And MX libraries, wherever they wrap another library, follow the principle "when in Rome do as Romans do". In my experience, things work better if we work with a library instead of subsituting what we might think is a better approach. Deviating can trip up on undocumented details of a library.
"There is are small discrepancies such as onclick on-click." Not sure on that one. As I said in another reply, I try to ape a library precisely. I wonder if sth scared me off that. Possibly I wanted to support authoring a widget either with a direct handler or one that lived at the MX abstraction? Sorry, I have been awayy doing Flutter for a couple of years, some things are fuzzy.
If you want help with using mxWeb I'll fire it up and get my cobwebs cleaned up.
"you could run the entire mx server side and client side you just need a websocket and an eventhandler." Well-spotted. The Algebra app is a Common Lisp app that ships JS over in XHR responses to events generated by straightforward JS event handlers. Works well, but for CLJS I thought it might be better to avoid the round trips. I guess a socket would be a bit more efficient, and avoid a problem I had where client events arrived in different order than generated. Not sure, I have not done much with WebSockets.
Which qould mean that you could run the entire mx server side and client side you just need a websocket and an eventhandler. Then the websocket protocol would basically have two operations: 1. Initial dom 2. Dom update. Andngoing back to the server 1. Dom event.