Fork me on GitHub
#fulcro
<
2017-11-17
>
cjmurphy08:11:20

A library that assumes that the library consumer will already be providing his own version of a third party library might for instance have [org.omcljs/om "1.0.0-beta1" :scope "provided"], where the third party library is Om Next.

cjmurphy08:11:14

So what to do if there's a library that assumes that the consumer will be providing either Fulcro 2 or Om Next?

cjmurphy08:11:45

I imagine that if you do "provided" for both, then the one the consumer doesn't supply will be dragged in, even although it is not required.

cjmurphy08:11:07

Ideally there would be a directive in the lein project file to specify that any one of this set of third party libraries is enough.

tony.kay16:11:39

@cjmurphy If it has assumed you’ll be providing one or the other, then you must provide one or the other. Why would the other be “dragged in”? Om Next isn’t any kind of dep for Fulcro 2.

tony.kay16:11:19

not sure I understand your question

tony.kay17:11:40

Version 1.1.0 of fulcro is on clojars. Has a couple of bug fixes, some version bumps of dependencies, custom formatters for i18n (cljs only), shadow dom (for browsers that support it), some form improvements, etc. See CHANGELOG for details.

cjmurphy17:11:00

@tony.kay: if the library is to work with one or the other it would provide both, so have [org.omcljs/om "1.0.0-beta1" :scope "provided"] and [fulcro/fulcro "2.0.0" :scope "provided"]. My assumption with "provided" is that if the consumer doesn't provide the library then the version specified is provided instead. Hence the consumer might be using Fulcro 2.0 only, yet om "1.0.0-beta1" would come in as well. But I might be wrong there.

tony.kay17:11:01

provided means it won’t end up in your build product (e.g. uberjar) unless you actually define a version you want

tony.kay17:11:37

e.g. Lib A says X is provided. App B requires A. If B does not specify that X is a specific dependency, then the generated jar/uberjar will not have X in it, and will not work.

tony.kay17:11:03

So, if I want to make Fulcro SQL for example support 20 databases…I can put in integration tests and provided deps for all 20. You won’t ever get any of those. You’ll have to, say, pull in postgres driver. Now, the library has to be very careful not to accidentally refer to any of those 20 database namespaces, or it will cause the downstream consumer to fail without good reason.

tony.kay17:11:24

Typically you use tricks to avoid referring to things that are “optional” like that

tony.kay17:11:33

(e.g. dynamic resolution of vars)

tony.kay17:11:55

JDBC uses DriverManager as a central registry

cjmurphy17:11:34

I thought the "provided" keyword was so that App B could specify its own version of Lib C, and the version provided by Lib A would then be irrelevant. Only if App B did not specify Lib A at all would the version of Lib C provided by Lib B be used. So the version number (of Lib C) provided by Lib B acts as a default.

tony.kay17:11:46

nope…provided basically means “put it on my classpath while I’m working on the project locally, but when someone uses me as a transitive dependency they will select a version of that that suits them. Of course, if they don’t and you really need it to be there, then it will break.

cjmurphy17:11:50

Right - so there's no defaulting, so all will work well!

tony.kay17:11:00

So, I specify devcards in my dev dependencies….which is a little cleaner. I’m not saying the user of my lib is definitely required to provide that, then I do the actual library loading (via require) iff they really use something that needs the lib (devcard-fulcro). So the semantics of provided are different

tony.kay17:11:18

but the functionality is that the user of the lib has to say they use it, or they don’t get it

cjmurphy17:11:52

I do have a library that will want to work with Fulcro and Om Next, and it can say provided for both, and there won't be any problems.

tony.kay17:11:54

is the official definitions

tony.kay17:11:36

technically you should probably put them both in your dev dependencies, and document how the user is meant to work with your library…because there will be “gotchas”

tony.kay17:11:13

you don’t really want to advertise (via provided) that the lib is always going to be there…`:provided` won’t bring it in, but it does tell the consumer that they are supposed to

tony.kay17:11:11

so, if that is not what you mean, then you make it a dev dependency so you can develop the library against both, but then you have to document that they only need to specify one…and then document how they tell you which one to use.

tony.kay17:11:07

This is also the reason I really was very hesitant to fork off from Om Next…the APIs are going to be so similar that people will want a library that works with both 😕

tony.kay17:11:26

well, my hope is that most ppl just use Fulcro, since it is much easier to target libraries at 🙂

tony.kay17:11:09

In Om Next you don’t know the database format, networking system, how the server is constructed, etc, etc. Makes it kind of hard to make much that is actually reusable IMHO

tony.kay17:11:05

Then again: If all you’re dependent on is the react generation wrappers (e.g. om.dom), it won’t hurt to have both…those are 100% compatible cross lib

cjmurphy17:11:30

The library in question understands the database format.

tony.kay17:11:39

then how can it work with Om Next?

tony.kay17:11:45

oh, if they choose the default one

cjmurphy17:11:14

Only be used by projects that use default database format.

tony.kay17:11:36

that’s a big if. I kind of think the only reason to consider using vanilla Om Next is if you want a custom db format…

tony.kay18:11:05

anyway. Hope that answers your deps quesion 🙂

cjmurphy18:11:10

Yes - breaking unless the consumer requires it is a good thing.

wilkerlucio18:11:53

@tony.kay what is about the shadow dom? what is been supported about that?

tony.kay18:11:12

I just added a component that can wrap DOM in shadow dom

tony.kay18:11:31

doesn’t work with Firefox unless you turn on a special option in the settings of the browser

tony.kay18:11:43

but does work with Chrome and some others

wilkerlucio18:11:05

ah, gotcha, I was wondering if would be something about app isolation, but makes sense know that you said, just about been able to use it, right?

tony.kay18:11:01

More of an experimental feature that shows you how to do it…but not very generally usable yet, since the standard isn’t supported on all browsers

tony.kay18:11:15

isolation of CSS for embedding is mainly the benefit for Fulcro

tony.kay18:11:49

(i.e. not being affected by global resets, etc.) Fulcro-css does a nice job of keeping collisions from happening, but you still inherit

wilkerlucio19:11:37

yeah, I love fulcro css by that

wilkerlucio19:11:53

also, recently I learned that you can use the css: all: initial;

wilkerlucio19:11:31

with that you can easily reset the entire children group, makes me question if the shadow dom will ever be useful enough to be adopted

tony.kay19:11:05

Oh, really? That’s cool…so, you can put that in your root, and you get isolation from parent’s?

wilkerlucio19:11:46

unless there is some crazy rule inside, I just saw someone using it, have to test more

tony.kay19:11:54

sweet…going to have to agree with you…shadow dom is nice in the “guaranteed isolation” sense without an iframe. So, I do hope it catches on for that purpose…but web components look like an OO disaster to me

urbank19:11:54

What I've heard about web components is that they're going to be a -standard-. Therefore everyone will be making these amazing web components, and not integrating with them will be a huge loss. I'm very sceptical about that. I think it happens quite often that you're better off with your own custom components for anything complex. Otherwise it happens very fast that you get requierments that are difficult to integrate with the component.

wilkerlucio19:11:24

React FTW, just works so well, and browser-drama free

tony.kay19:11:54

bummer. docs say Safari doesn’t support initial

tony.kay19:11:01

nor android or iOS

tony.kay19:11:09

perhaps that is out of date

wilkerlucio19:11:00

seems like all is more of a problem, if you care about Edge: https://caniuse.com/#search=all

tony.kay19:11:39

ah, I was looking at an outdate page

tony.kay19:11:02

you mean IE 11?…it says edge is fine

wilkerlucio19:11:36

edge is fine for initial, but not for all

wilkerlucio19:11:52

the all property isn't supported there

tony.kay19:11:47

yeah, I see that now

tony.kay19:11:09

looks like it’s still iframes for most real embedded uses 😞

tony.kay19:11:47

I guess you could do a combo…shadow dom if you detect it, and css all…that might cover the gamut

tony.kay19:11:10

Oh no…edge is out on that too

wilkerlucio19:11:46

Microsoft should just give up on browsers building, seriously....

tony.kay19:11:07

as should Apple

wilkerlucio19:11:35

at least they keep the most important features up to date

tony.kay19:11:45

I’ve been using a mac since 2004 or something…never found Sarafi usable

wilkerlucio19:11:07

I've used it for a while, but in the end Chrome is always my preferred

wilkerlucio19:11:50

I was trying that new Firefox, but it doesn't have all the dev features I use, and I didn't notice that much of a speed difference as they clame (well, one thing that is noticible is that they seem to render the page before the CSS is available, I'm not sure if that is a good thing)

tony.kay19:11:26

I wonder since initial is well-supported, if you just couldn’t generate a verbose reset that names all of the css tags

tony.kay19:11:32

simulate all

urbank19:11:24

I'm wondering if the default graph db should be extended with set #{} and map {}. By that I mean that the idents could be stored and resolved in them. Like this for sets: #{ [:entity/id 1] [:entity/id 2] } and something like this for maps { 1 [:entity/id 1], 2 [:entity/id 2] } Im wondering if there's an issue with this, or if you think it's unnecessary.

wilkerlucio19:11:25

@tony.kay you probably can do something with the * selector

wilkerlucio19:11:43

but I guess all works better, because it was made for it

tony.kay19:11:53

@urbank So, not desirable, I don’t think: 1. UI’s have order. Sets don’t preserve it. So, your to-many would jumble itself 2. Not sure how you’d interpret the map version Perhaps you have more thoughts…can’t read your mind about the why so, it adds complexity to the query engine, but I’m not sure of a clear benefit. Care to enlighten me with a use-case?

urbank19:11:56

@tony.kay Well, I'm thinking of components that care about whether some entity with an ident is inside the collection of identsthat it receives. If it always gets a vector of idents it has to convert them to sets or maps every time, should it need them in that form.

urbank19:11:36

a Multiselect component would be an example

tony.kay19:11:13

I see. So, your logic would benefit from being able to test for inclusion.

tony.kay19:11:53

but then aren’t you just moving the overhead to a sort operation when you display them?

urbank19:11:37

Hm... I supose that is true 🙂

urbank19:11:03

Also true for maps

urbank20:11:53

But the db could hold both a vector which tells you the order and a set which tells you if its there, thereby moving the overhead to the mutation... I think

tony.kay20:11:53

So, the mutation is where the overhead belongs. And yes, you can hold onto them as a set there if you wish..or a map. But denormalization only happens if things match a query…and multiple things won’t

urbank20:11:45

The denormalization is the reason why I thought including sets and maps might be a good idea. Because some of the things in the db might be redundant, and there only for the logic. Like a seta nad a vector corresponding to the same idents, but only the vector being used directly for the rendering. Might be a naive idea though, of course. 🙂

tony.kay21:11:46

So, it would not be that hard to do sets…not sure how maps would work

tony.kay21:11:27

I think for your purposes: write some easy helpers that can denormalize sets and maps, and use those

tony.kay21:11:52

or do you need them at the UI layer?

tony.kay21:11:19

In your example of a multiselect: What you care about is that the items themselves have state that says “selected”. It shouldn’t be separate outside logic on them. They can each just have :ui.multiselect/selected? as a transient UI-only property

tony.kay21:11:51

so instead of testing against set inclusion, they would just render “am I selected?” and the mutation should just mess with the UI property.

tony.kay21:11:06

wondering if you have another use-case that might be more difficult to solve

tony.kay21:11:19

that one seems like you’re just approaching it in a way that is more difficult

urbank21:11:52

@tony.kay Thanks for the response! All good points, I'll think more about this tomorrow!

tony.kay21:11:49

Version 1.1.1 released to clojars. Has a bugfix that allows :elide-asserts true to work properly. Thanks to @gardnervickers, @wilkerlucio, and the friendly folks on the #core-async channel.