tink: New search UI


(Kat Marchán) #1

If you’re familiar with React, this is a fantastic contribution to make!

I’m making this thread separately from tink: Implement ancillary subcommands because it’s more involved and I want more back-and-forth about the implementation.

I’d like a shiny new search command that allows interactive search + installation of packages from those results. The command should display things significantly better than the current CLI search and act as a damn good alternative to searching on the website. Additionally, it should use the new search endpoint off the configured registry instead of a third-party one.

tl;dr I’d like something like emma cooked directly into tink, but using tink for installations, and npm’s new search endpoint instead of Algolia. This command, depending on how it works out, is very likely to get slurped into the npm CLI proper eventually. Also, although npm-suggestions is really cool, please don’t use that endpoint – it’s going to fall over as soon as npm’s userbase starts hitting it, and npm, Inc will need to build (and scale) its own version of this before we can do it.

I’d also like the UI to be prototyped using ink, which is like React, but for the CLI (and what emma uses). The API should use libnpm.search().

My sketch for the UI is something like this:

$ tink search (no arguments = interactive mode. arguments = api mode)
Find a package: foo
> foo @zkat p 95 q 41 m 69
  bar @iarna p 100 q 84 m 35
  baz @isaacs p 80 q 80 m 80
  ...(53 more)
Full Description:
Does a foo thing and also this is a very long description,
with the text wrapping on the bottom like this.

tink: State of the Unwinder [2018/11/05]
(Chris Forrette) #2

Hi there, I would love to help with this! I’ve been doing lots of React and searchy things (Elasticsearch) lately and I’ve been particularly interested in working more with developer-facing interfaces/DX and would be stoked to learn from and collaborate with you on this.

tink: Implement ancillary subcommands
(Kat Marchán) #3

All yours, then! Let me know if you have any other questions. :tada:

Thought I see @larsgw is typing… :eyes:

(Lars Willighagen) #4

This sounds incredibly fun, and the tink view one too! I assume some communication would need to be done with people working on that if those components are going to be used here? Perhaps some components like <Field path="dist.tarball" /> or <View style="oneline" />. If this one’s claimed already, I’m happy to work on tink view too.

(Lars Willighagen) #5

Yeah, a bit too hesitant in the end :slightly_smiling_face:. Didn’t want to hog such cool projects…

(Kat Marchán) #6

Why don’t you grab the view one, and you two can work together to integrate them? My evil plan was to make it so the “Full description” desction is actually replaced by a <PackageView /> once this was done, so you basically get to see all the general info about a package right in the search screen.

tink: Implement tink view
(Kat Marchán) #7

A note about this: Please just put a placeholder that says “Adding packages…” and finishes on a ~1s timeout. I’ll have an API for you eventually to call but I’m working on rewriting the installer and resolver right now so you won’t be able to test any of this until that’s done.

(Chris Forrette) #8

This all sounds great!

So—caveat—I haven’t contributed a whole lot to open source, so I will probably ask lots of dumb questions.

If I have any questions for you, I assume this is the place to do it? Do you have a timeline you’re aiming for for a PR?

Thanks, excited to dig in!

(Kat Marchán) #9

You can discuss it in this thread (it’s what #development is for!), or if you don’t want it to be so public, you’re totally fine DMing me (assuming you can do that by now?).

(Chris Forrette) #10

Hey there, just wanted to check in! I’m still getting my mind around ink (seems pretty rad, and so weird using React for a CLI…), borrowing heavily from the emma CLI, and I’m hoping to have something rough to share in the next couple days.

I was going to ask if I should configure Babel so we can use JSX (it looks pretty simple), but I know that would involve a dist/ directory of some sort and pointing the bin/ stuff at dist/ (and probably other things I’m not aware of…). I caught up over here and you had mentioned not using JSX for the view. Would you like to avoid JSX altogether? Or should I get it configured for search view?


(Kat Marchán) #11

No need to configure Babel! tink already supports jsx out of the box:

Though if that doesn’t work (it should), I’d rather just write out the entire thing using raw h() calls and we can revisit this later when I can fix jsx support (or if you want to fix it, go for it). I don’t expect that to be any more painful than plain jsx.

(Chris Forrette) #12

Oh nice! I get an Unexpected token < error when I try to use JSX-ish stuff. I’m testing this way: ./bin/tink.js search "florp"—I’m wondering if I might need to use it some other way to pick up that JSX snazziness…? I see some magic happening in lib/node/module.js

(Kat Marchán) #13

Can you try rebasing onto the latest tink? I’ve been thrashing around the past few days. I think a recent patch will probably fix that for you. Beware this may involve changes to how your command is set up.

(Kat Marchán) #14

Oh and of course, remember your command has have a . jsx extension :warning:

(Chris Forrette) #15

Totally missed the .jsx extension! I changed it but still no dice, and I think I see why…

I registered my command in CMDS in bin/tink.js similarly to the others, by adding this to it:

['search', require('../lib/commands/search.jsx')]

So because the require is happening there and the JSX overrides aren’t required until runCommandWithYargs is run, the commands are showing up too early to catch the JSX boat.

I tried switching those requires in CMDS to strings and requiring them in the for loop in runCommandWithYargs and hit another error: Class constructor Color cannot be invoked without 'new'. Apparently it’s something to do with ES6 class transpilation (or lack of…? I found an issue about it here).

Anyway, I wanted to capture all of that for reference, but I’ll just stick with h() for now :smile:. Seems like you’re still sizing up ink, so it’s probably not worth sinking too much effort into tooling for it just yet.

(Kat Marchán) #16

Pretty sure it’s fully fixed now. Can you rebase one more time onto latest and try again? If this one doesn’t work, we can definitely go ahead and fall back to h() :slight_smile:

tink: Implement tink view
(Chris Forrette) #17

Yay it works! :tada: Thank you so much!

(Kat Marchán) #18

that is so exciting. I never thought I’d be so thrilled at having JSX available somewhere other than web code lol

(Chris Forrette) #19

It is really rad, and kind of blowing my mind… :exploding_head:

(Chris Forrette) #20

Alright so I’ve got a WIP branch (feature/search-command) up here if you wanna check out my progress so far:

To use it: ./bin/tink.js search or ./bin/tink.js search "some term". I set it up so that if you don’t enter a term at command execution, it’s interactive, and if you do, it’s still interactive, it just fills your term in the input and auto-executes a search for you.

The main thing I’m still working out is input focus. It’s kind of weird in context of a CLI, but I installed ink-text-input to handle the search terms input, and ink-select-input to handle results listing/selecting and there’s a sense of “focus” I need to nail down. Currently if you search, then select a package (hitting Enter on a highlighted package), it will select the package and submit the search again. Shouldn’t be too tough to iron out.

And I didn’t address CLI arguments really, aside from the one optional positional argument for search terms. I included the options in lib/common-opts.js, but maybe those are mostly irrelevant here? registry and json jump out, but I’m guessing there’s no standardized registry search API, and for json we could just dump JSON of the matches if that’s desirable. Now that I’m thinking about it, it probably makes more sense to just expose arguments that get passed in for options to libnpm.search. Would be pretty sweet in particular to be able to sort results by popularity, quality, maintenance, etc.

The flow so far is pretty rough, but working. It’ll be nice to polish it up, show a nicer “Installed” message, handle errors nicely, etc. It’ll definitely be good to look into accessibility too. I assume since this is an all-text interface it’s probably mostly good but I wonder, for example, if the little arrow selector for package matches is accessible…

I assume it might be good to get either this or @larsgw’s work over here merged, and then integrate the PackageView here. I assume the intended functionality is: as you are perusing up and down through search results, as you highlight one you see a <PackageView /> with a bunch of details below the search results list, is that accurate?

Let me know if I should open a WIP PR to the tink repo—would probably be easier to talk about the code and exchange feedback there.