Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Sep 16 08:21
    Starzu opened #401
  • Sep 16 07:58
    Starzu opened #400
  • Sep 14 07:25
  • Sep 13 07:42
    scala-steward opened #399
  • Sep 11 18:55

    ddworak on validation-less

    (compare)

  • Sep 11 18:55

    ddworak on master

    Remove property validations Cleanup property validation usa… Fix UdashForm validation and 11 more (compare)

  • Sep 11 18:55
    ddworak closed #291
  • Sep 11 18:55
    ddworak closed #273
  • Sep 11 18:39
    ddworak synchronize #291
  • Sep 11 18:39

    ddworak on validation-less

    Restore validationProperties si… (compare)

  • Sep 11 18:04

    ddworak on master

    Update circe-core, circe-parser… Merge pull request #397 from sc… (compare)

  • Sep 11 18:04
    ddworak closed #397
  • Sep 11 18:04

    ddworak on master

    Update flexmark-all to 0.50.40 Merge branch 'master' into upda… Merge pull request #395 from sc… (compare)

  • Sep 11 18:04
    ddworak closed #395
  • Sep 11 17:17

    ddworak on master

    Update monix to 3.0.0 Merge pull request #398 from sc… (compare)

  • Sep 11 17:17
    ddworak closed #398
  • Sep 11 17:16
    ddworak synchronize #395
  • Sep 11 13:56
    scala-steward opened #398
  • Sep 10 19:29
    scala-steward opened #397
  • Sep 10 12:02
    ddworak review_requested #291
Dawid Dworak
@ddworak
Then why do you want to run it in node?
You'd probably have to manage dependencies in other way then, e.g. using https://github.com/scalacenter/scalajs-bundler
Miklos Szots
@smiklos
I don't want to , but sbt run supposed to serve the code via some http server mechanism and it choose to do that via node :) I was purely wondering why it doesn't work
Dawid Dworak
@ddworak
From the error message it looks as if it runs the code, not serves it
That obviously cannot work :D
I can't seem to find an environment setup for the SJS plugin which would run a web server, see: http://www.scala-js.org/doc/project/building.html "Running in the console". Usually with Udash you'd just run the backend module which serves the statics along the RPCs using e.g. Jetty.
sidnt
@sidnt
While defining the RPC interfaces, is it possible to use any concurrency mechanism other than scala futures?
Dawid Dworak
@ddworak
@sidnt basically whatever you like, I'll try to add a basic example in tests. In general, it will be similar to adding such support to our REST RPCs https://github.com/UdashFramework/udash-core/blob/master/rest/src/test/scala/io/udash/rest/monix/MonixRestImplicits.scala
Dawid Dworak
@ddworak
There's a lot of duplication involved now (unfortunately) compared to the REST one, but we have an ongoing work on atmosphere removal - we'll update the RPC layer to be more unified. For now, you can try using REST RPC instead which is much easier to customize. See ddworak/udash-with-rest@9b93800 for example
Peter Aaser
@PeterAaser
How do I generate a codec for a case class with FiniteDuration?
Roman Janusz
@ghik

@PeterAaser first you need to have a codec for FiniteDuration itself. The easiest way to write this custom codec is by defining a "fake" companion object for FiniteDuration with appropriate apply and unapply and then materializing the codec with GenCodec.fromApplyUnapplyProvider macro:

object CustomCodecs {
  private object FiniteDurationAU {
    def apply(length: Long, unit: TimeUnit): FiniteDuration = FiniteDuration(length, unit)
    def unapply(duration: FiniteDuration): Option[(Long, TimeUnit)] = Some((duration.length, duration.unit))
  }
  implicit val finiteDurationCodec: GenCodec[FiniteDuration] = 
    GenCodec.fromApplyUnapplyProvider[FiniteDuration](FiniteDurationAU)
}

This codec will yield JSON objects that reflect the signature of apply, e.g. {"length":30,"unit":"MINUTES"}.
Then you can inject it into macro materialization of GenCodec for your case class using HasGenCodecWithDeps:

case class ContainsDuration(duration: FiniteDuration)
object ContainsDuration extends HasGenCodecWithDeps[CustomCodecs.type, ContainsDuration]
Peter Aaser
@PeterAaser
Thanks :D
I ended up making an object extending GenCodec[MyCaseClass] which seems to work too
Peter Aaser
@PeterAaser
Or no, it didn't, think I'll go with your suggested approach then
Peter Aaser
@PeterAaser
Oh wait, turns out it did work, I just had some syntax errors
Roman Janusz
@ghik
@PeterAaser sure, but now you'll have to write such custom codec for every single case class which uses FiniteDuration. This kind of defeats the purpose of GenCodec's auto-materialization.
Peter Aaser
@PeterAaser
Good point
decapo01
@decapo01
I'm trying to get a project started and I'm getting the error module not found: io.udash#udash-core-frontend_sjs0.6_2.12;0.8.0
Dawid Dworak
@ddworak
@decapo01 the best way to setup the project would be the g8 generator bt new UdashFramework/udash.g8. Anyway, the issue you're getting is related to the fact, that the docs are updated for 0.8.0 release, but there's no final JAR available yet - only 0.8.0-RC10, which will probably go final as long as we don't find more issues in it
Roman Janusz
@ghik
@decapo01 right now we only have a cross-compiled udash-core artifact, no -frontend or -backend
ChengChe
@chengchelo
Just noitced 0.8.0 released. Really excited about this. Awesome!!
Dawid Dworak
@ddworak
@chengchelo happy to hear that!
The release notes for 0.8.0 can be found here: https://github.com/UdashFramework/udash-core/releases/tag/v0.8.0
ChengChe
@chengchelo
@ddworak Got it. Can't wait to check out the goodies, especially the enhancements. Starting to upgrade my project to 0.8.0 release now!
Ondřej Španěl
@OndrejSpanel
Hi. Are there some guidelines or tutorials how can one provide custom rendering for some data? I would like to provide some map rendered using Mapbox GL, with custom Mapbox route. I have experience how to integrate this into normal HTML, but no experience so far with Udash.
And a separate question: how is Udash supposed to be pronounced? U - dash, or micro dash? I miss this critical info in the readme. :)
Dawid Dworak
@ddworak

@OndrejSpanel I don't now Mapbox, but I guess the simplest way to start would be to use a wrapper (e.g. https://github.com/bbarker/scalajs-mapbox or https://github.com/oyvindberg/ScalablyTyped/tree/master/m/mapbox-gl) and work with the types. They probably have some API which either returns or works on Elements from JS DOM and you can render such within your views with ease.

The name question is simpler - we usually pronounce it U-dash (IPA: [ˈjudaʃ], AS: [i ̯udaš]). The origins of the name are actually quite funny so I guess we'll add the info at some point :D

Ondřej Španěl
@OndrejSpanel
Another question, I am struggling to grasp basic concepts: I want to run my application on Google App Engine (Standard Environment). GAE uses Jetty internally, but I do not have any access to low level functionality, I am only able to respond to ordinary http requests (there is certainly no websockets support). How can I proceed when not using Atmosphere / Jetty? Do I provide my own implementation for RpcClientsService?
Dawid Dworak
@ddworak
@OndrejSpanel no worries, you can just use udash-rest instead. You can see a minimal integration commit here: ddworak/udash-with-rest@9b93800 - shouldn't be too outdated
Ondřej Španěl
@OndrejSpanel
Looks nice, thanks. I will experiment with that next week.
Ondřej Španěl
@OndrejSpanel
Progress report: I have tried running udash-with-rest. At first sight it seems to be it is still using both Atmosphere and Websockets. I think perhaps another project is a better starting point for me: https://github.com/UdashFramework/udash-demos/tree/master/rest-akka-http
Ondřej Španěl
@OndrejSpanel
More progress: I have more or less converted akka http to Spark Java Framework, which should allow me to use it on Goggle App Engine easily. I might be missing something, because there seems to be a lot of manual effort in defining the REST API this way. It seems your commit handles this with some magic, but I am afraid I do not understand that yet. My progress can be see in https://github.com/OndrejSpanel/udash-demos in the spark branch: https://github.com/OndrejSpanel/udash-demos/tree/spark
Dawid Dworak
@ddworak
@OndrejSpanel I didn't disable the websocket RPC in my demo, I've just added another (rest-based) one. The demo you're using is based on the old (0.7) rest module which is completely different in 0.8. The 0.8 one generates both backend and frontend code automatically, see: https://guide.udash.io/rest#overview for reference. We didn't get to rewriting the 0.7 demos just yet.
Ondřej Španěl
@OndrejSpanel
I am trying to convert the rest of the udash-with-rest to REST as well. I have replaced DefaultServerRpcCompanion with DefaultRestApiCompanion in several places, I am not sure how to proceed with UserContext, though. The trouble is UserContext uses PermissionId, which already has a companion object I am unable to modify. I have find a documentation how to add serialization for 3rd party classes, but I did not find anything similar how to create REST API for them. The error I get is:
RestSchema for Set[io.udash.auth.PermissionId] not found
Ondřej Španěl
@OndrejSpanel
Another question: the REST docs show how to define the API and say:
Then, implement your trait on server side
and show how to do that. In your commit I see the ping API defined, but I do not see any implementation for it anywhere.
Ondřej Španěl
@OndrejSpanel
I have found the ping implementation. It is implemented using Scala 2.12 / Java 8 SAM as s => Future.successful(s"pong $s")
Bartłomiej Grochal
@bgrochal

Hello, @OndrejSpanel. If I understand correctly, you have just equipped UserContext and UserToken with RestDataCompanion by, respectively:

object UserContext extends RestDataCompanion[UserContext]

and

object UserToken extends RestDataCompanion[UserToken]

According to the provided exception message, RestSchema for UserContext cannot be generated since there is no such for Set[PermissionId]. To provide RestSchema for PermissionId instances, please refer to the last example presented under the Macro materialized ADT schemas section of REST guide (macro materialization without RestDataCompanion). The following should do the trick:

object UserContext extends HasGenCodec[UserContext] {
  implicit val permissionIdSchema: RestSchema[PermissionId] = RestStructure.materialize[PermissionId].standaloneSchema
  implicit val userContextSchema: RestSchema[UserContext] = RestStructure.materialize[UserContext].standaloneSchema
}

Please note a few nuances in this snippet:

  • you cannot mix RestDataCompanion[UserContext] with macro-materialized schema for PermissionId inside UserContext companion; hence, UserContext does not extend RestDataCompanion anymore (appropriate schema is macro-materialized as well),
  • to provide a (JSON) serializer for UserContext, a GenCodec[UserContext] has to be defined (either by extending HasGenCodec[UserContext] or explicitly: implicit val userContextCodec: GenCodec[UserContext] = GenCodec.materialize).

Hope that helps :)

As mentioned above, implementation of io.company.app.shared.rpc.server.AdditionalRpc can be found under io.company.app.backend.serverApplicationServer#createRestServletHolder.

Ondřej Španěl
@OndrejSpanel
Thanks a lot. I think it starts to make sense to me now.
Ondřej Španěl
@OndrejSpanel
I already have a simple REST API working on Google App Engine. There is one more issue I had to overcome: GAE supports only Servlet 3 specs, not 3.1, therefore there is no async support (request.startAsync() fails). I had to create an alternative to io.udash.rest.RestServlet, and as the methods like readParameters are private, it involved more copy and paste than I like.
Roman Janusz
@ghik
Ugh, that's bad. I guess for now you'll have to live with that custom servlet implementation.
Ondřej Španěl
@OndrejSpanel

@ddworak

no worries, you can just use udash-rest instead

I think I am able to provide rest services now, but compared to RPC there are substantial limitations. Most of all I am missing client-aware services, which force me to pass Client ID in the REST API (and reimplement client management). Do you think there is some possibility how to use RPC, but not with Atmosphere / Jetty? Providing an alternative to DefaultAtmosphereServiceConfig does not seem difficult, but I fail to see what else would I have to provide to implement the RPC communication protocol without Atmosphere.

Roman Janusz
@ghik
Do you know about prefix methods? https://guide.udash.io/rest#prefix-methods you could use that to send client ID once for entire API and leave your RPC traits unchanged
It's a similar pattern to that for authentication, e.g.
trait UserApi { ... }
object UserApi extends DefaultRestApiCompanion[UserApi]

trait RootApi {
  @Prefix("") def auth(@Header("Authorization") token: String): UserApi
}
object RootApi extends DefaultRestApiCompanion[RootApi]
You could also use regular RPC with alternative network implementation but it's going to require more work
Essentially, you'll have to implement io.udash.rpc.ServerRawRpc on the client side so that it uses e.g. some opaque, plain HTTP to send invocations to the server. Then on the server side you'll have to implement a servlet or another network endpoint which will receive invocations and translate them back into calls on io.udash.rpc.ServerRawRpc
Giulio Mecocci
@gm2211

Still on the theme of REST serialization, how do I get generic types to conform to AsRawReal and RestSchema? I'm basically trying to expose an api that allows one to define policy templates that contain a set of statements of the shape: case class Statement(verb: Verb, operations: VariableOrLiteral[Set[Operation]], condition: Condition) and I'm having a little trouble getting the following to serialize properly:

sealed trait VariableOrLiteral[T]
case class Variable[T](name: String, typeInfo: TypeTag[T]) extends VariableOrLiteral[T]
case class Literal[T](value: T) extends VariableOrLiteral[T]

I'm sure I'm missing something obvious, but the only thing that half-worked was completely custom serialization, but then I didn't get any RestSchema

mowczare
@mowczare

I am not sure if I fully understand you, but this may do the trick for the RestSchema materialization:

object VariableOrLiteral {
  implicit def typeTagSchema[T: RestSchema]: RestSchema[TypeTag[T]] = ??? // This should be implemented with method of your choice
  implicit def restSchema[T: RestSchema]: RestSchema[VariableOrLiteral[T]] = RestStructure.materialize[VariableOrLiteral[T]].standaloneSchema
}

The general concept should propagate to AsRawReal.