npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@interopio/search-api

v2.4.3

Published

Glue42 Search API

Downloads

1,410

Readme

IO Connect Search API

Apps can perform searches and provide results for others' searches.

For example, let's say an app provides Seinfeld quotes, and wants to make those quotes available to any other app. The Seinfeld app could register itself as a search provider with this:

// Registering as a provider
const provider = await glue.search.registerProvider({
    name: "Seinfeld-Quotes"
});

// Registering how the provider will respond to queries
provider.onQuery(({search, sendResults, done}) => {
    const textOfQuote = doStuffInternally(search);
    
    sendResults({
        type: {
            name: "tv-quote",
            displayName: "Seinfeld Quotes"
        },
        id: "quote-123",
        description: textOfQuote
    });

    done();
})

Now, let's say an app is interested to see if there are any Seinfeld quotes with the word "architect". It would use the following function:

const query = await glue.search.query({search: "architect"});
query.onResults((result) => {
/*
// Example value for result - 
{
    provider: {
        id: "INTERNAL_ID",
        interopId: "INTERNAL_INSTANCE_ID",
        name: "Seinfeld-Quotes"     // The search provider's name
        appName: "seinfeld-app",    // The app that registered the search provider
    },
    result: {
        type: {
            name: "tv-quote",
            displayName: "Seinfeld Quotes"
        },
        id: "quote-123",
        description: "You know I always wanted to pretend I was an architect.
    }
}
*/
})

Checklists

If you're writing a custom search provider, here are things to make sure you implement:

Basics

  • [ ] Registering provider
  • [ ] Generate and send results

Other considerations:

  • [ ] Call done() once you are done (in case queriers are waiting on onCompleted())
  • [ ] Are you checking the types property? You don't want to ignore the restrictions the querier placed on their query.
  • [ ] Are you checking the maxResults property? You don't want to return more that the querier asked for.
  • [ ] Ditto for maxResultsByType
  • [ ] Did you set up error handling, and include the error() callback if necessary?
  • [ ] Do your queries take a long enough time that they might get cancelled? If so, are you handling onQueryCancel?

If you're querying a search providerm here are things to make sure you implement:

  • [ ] Call the query (eg const query = await glue.search.query({search: "My search string"}))
  • [ ] Handle onResults (eg query.onResults(displaySearchResult))
  • [ ] Handle onError

Other considerations:

  • [ ] Is there a situation where you need to cancel() your query?
  • [ ] Do you need to limit the quantity of results you receive (using providerLimits)?
  • [ ] Do you need onCompleted, to see when different search providers have finished? If so, does it also make sense to include a timeout (in case a search provider doesn't indicate when they're done()?)
  • [ ] Are you interested in only certain types of content? Would it make sense to call listTypes() to see if the type you're looking is being provided? Would it makse sense to limit your search results to a certain type?
  • [ ] Are you interested in only certain providers? Would it make sense to call listProviders() to see if the provider you're looking is present? Would it makse sense to limit your search results to certain providers?
  • [ ] Sometimes, search results include actions. If that makes sense for your use cases, are you handling incoming actions?

API

glue.search has the following methods:

  • getDebounceMS
  • listProviders
  • listTypes
  • query
  • registerProvider
  • setDebounceMS
  • version

registerProvider

Config options for .registerProvider() are:

  • name (required)
  • types (optional but recommended). If you register a custom type, it will appear in the .listTypes method.
const provider = await glue.search.registerProvider({name: "test"});
const provider = await glue.search.registerProvider({
    name: "test", 
    types: [
        {name: "application"}
    ]
});

registerProvider returns a promise that resolves to a Provider object. This has the following available methods:

  • onQuery - callback when search queries are executed
  • onQueryCancel - callback when an app cancels its search query
  • unregister - an unregistration method.

:::tip Search providers are automatically unregistered when windows are closed. Unregistration is a good cleanup action, but may not be required. :::

The onQuery callback provides a ProviderQuery object, with the following properties:

  • id - referenced when cancelling the query
  • search - the text being searched for
  • providers - the providers the querier is interested in
  • types - the SearchTypes the querier is interested in
  • providerLimits.maxResults - the maximum number of results the querier wants to receive from each provider
  • providerLimits.maxResultsPerType - the maximum number of results PER TYPE the querier wants to recevie from each provider
  • sendResult - callback for sending an individual result. (The querier receives this with the query.onResults() callback)
  • error - callback if there's an error (The querier receives this with the query.onError() callback)
  • done - callback once all results have been sent (The querier receives this with the query.done() callback)

When sending a result, you supply a QueryResult object. The properties of that object are:

  • type (required) - a SearchType (eg: {name: "application"})
  • id
  • displayName
  • description
  • iconURL
  • metadata
  • action - metadata information about a method you'd want to invoke
  • secondaryActions - more actions

query

You create a query object with the query() method:

const query = await glue.search.query({search: "My search query"});

The query method takes the following properties:

  • search (required) (string) - what you're searching for
  • providers (ProviderData[]) - providers you want to limit your search to
  • types (SearchType[]) - the types of results you want to limit your search to
  • providerLimits.maxResults (number) - the maximum number of results the querier wants to receive from each provider
  • providerLimits.maxResultsPerType (number) - the maximum number of results PER TYPE the querier wants to recevie from each provider

The query object you receive has the following methods:

  • cancel() - Cancels the query. (See provider's onQueryCancel())
  • onResults() - Callback to receive results (See provider's query handling for sendResult())
  • onCompleted() - Callback when provider is done (See provider's query handling for done())
  • onError() - Callback when provider has an error (See provider's query handling for error())

listProviders

await glue.search.listProviders();
/*
Example results: [
    {
        appName: "fsbl-test-butler",
        id: "INTERNAL_ID",
        interopId: "INSTANCE_ID",
        name: "registered-search-provider-custom-name",
    },
    {
        appName: "tester",
        id: "INTERNAL_ID",
        interopId: "INSTANCE_ID",
        name: "my-tester",
        types: [{name: "test-type"}]
    }
]
*/

listTypes

You can see what search types are available. This is especially useful if you are relying on a custom search type from another app, and want to confirm that that app has already been registered.

await glue.search.listTypes();
/*
Example results: [
    {name: "customSearchType"},
    {name: "application"},
    {name: "layout"},
    {name: "workspace"},
    {name: "swimlane"},
    {name: "action"}
]
*/

getDebounceMS, setDebounceMS

Default debounce: 0ms

Queries can be debounced. If you plan on querying based on individual keystrokes or mouse movements, you can potentially generate an unnecessarily large message flurry. Debouncing the queries will reduce search query traffic.

Here are examples of getting/setting the debounce time:

// Get the debounce time:
glue.search.getDebounceMS();    // returns 0 by default

// Set the debounce time to 20ms:
glue.search.setDebounceMS(20);

Actions

TBD

Developer notes

/* eslint-disable @typescript-eslint/no-explicit-any */

// package name: @interopio/search-api -> adds the Search API

// @interopio/browser-platform -> can use the package to register as a provider or use as a client, by default register as a provider for applications, workspaces, layouts and optionally actions // @interopio/browser -> can use the package to register as a provider or use as a client // GD3 -> by default register as a provider for applications, workspaces, layouts and optionally actions

// Foundation: Interop and Shared Context // lib registers: lazily two methods // lib uses: shared context to providers state management // method used when registered as provider to accept queries

// category = display name for type