tql icon indicating copy to clipboard operation
tql copied to clipboard

Is it possible to drop the `()` from the end of every property access?

Open geelen opened this issue 3 years ago • 4 comments

Maybe this is changed with the new RC, but I was wondering if it's possible to make fields getters instead of function calls? Atm I have this:

query('', (t) => [
  t.getPostById({ id: post1 }, (t) => [
    t.slug(),
    t.author((t) => [
      t.username(), 
      t.avatar()
    ]),
  ]),
])

Any way it could be changed to this?

query('', (t) => [
  t.getPostById({ id: post1 }, (t) => [
    t.slug,
    t.author((t) => [
      t.username, 
      t.avatar
    ]),
  ]),
])

And while I'm dreamcoding, how about this?

query('', t => {
  t.getPostById({id: post1}, [
    t.slug,
    t.author([
      t.username,
      t.avatar
    ])
  ])
})

I mean I have literally no idea how the typescript reflection stuff works but I thought I'd ask!

geelen avatar Jan 19 '22 16:01 geelen

Getters are not in the RC but are definitely an API improvement I’ve been thinking about. Good reinforcement to see that someone else thought of it too :)

I don’t know of a way of accomplishing the second example exactly (at least with what JS/TS support today). We could support static arrays in place of selector callbacks. Not sure if that would be better though..part of the beauty of the callbacks is that they give you the appropriate selector object t from which to select from (w/o having to import a specific selector object separately).

Good feedback though, keep it coming!

timkendall avatar Jan 20 '22 05:01 timkendall

Yeah once I'd sent that last one I realised my mistake with the t var.

FWIW on a second look, the getters-based one looks great to my eyes, makes the nested t.author(t => line stand out.

The only other improvement I thought of was using query.getPostById instead of query('', (t) => [ t.getPostById. That feels like a nice shorthand if you've only got one operation and you don't need to name it?

query.getPostById({ id: post1 }, (t) => [
  t.slug,
  t.author((t) => [
    t.username, 
    t.avatar
  ]),
])

This really looks great to me, I could see myself writing that instead of string-based GQL tags pretty muche every time...

Oh and just because I'm a monster, would this ever be possible?

query
  .getPostById({ id: post1 }, (p) => p
    .slug
    .author((a) => a
      .username
      .avatar
    )
  )

I'm not suggesting it, more just curious. Prettier kinda obliterates anyway:

query.getPostById({ id: post1 }, (p) => p.slug.author((a) => a.username.avatar))

Now I wanna trawl TC39 proposals for any new syntax to make fancy new DSLs with :) I had a glance at the pipeline operator but I don't think that helps. Anyway, fun to explore :)

geelen avatar Jan 20 '22 09:01 geelen

The only other improvement I thought of was using query.getPostById instead of query('', (t) => [ t.getPostById. That feels like a nice shorthand if you've only got one operation and you don't need to name it?

Totally agree. The 1.x RC removes the requirement for an operation name as the first argument. There's also an undocumented option in the pre-1.x version (e.g 0.8.0) to get a similar API if you want to try that (geared towards use-cases where you have a single operation you need to run as you mention).

  1. Pass a --client <name> flag to the codegen CLI
  2. Import the new client class and provide it an Executor (this API ties together query building and execution...hence the "client" name
import { Executor } from '@timkendall/tql'
import { MyClient } from './generated'

const client = new MyClient(new Executor({ uri: 'http://localhost:8080' }))

await client.query.getPostById({ id: post1 }, (t) => [
  t.slug(),
  t.author((t) => [
    t.username(), 
    t.avatar(),
  ]),
])

Oh and just because I'm a monster, would this ever be possible?

Hmm so a combination between the callback and a more traditional builder API...I'll have to think about that. Not sure if it's cleaner IMO though.

Now I wanna trawl TC39 proposals for any new syntax to make fancy new DSLs with :)

Ha same! If JS/TypeScript offered an implicit this functionality we could make this DSL pretty ideal (take a look at what you can do in Kotlin and Ruby).

timkendall avatar Jan 23 '22 17:01 timkendall

The getter syntax is such a great idea! It would totally become my number 1 preferred syntax over all the alternatives. 🤩

jgoux avatar Feb 02 '22 10:02 jgoux