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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@conduit-client/service-bindings-imperative

v3.5.0

Published

Conduit services for imperative bindings

Readme

@conduit-client/service-bindings-imperative

Conduit services for imperative bindings, providing flexible data invocation strategies and patterns.

Overview

This package provides imperative data fetching and mutation services for the Conduit ecosystem. It offers multiple invoker strategies to handle different data fetching patterns including GraphQL, legacy systems, and subscribable data streams. It then wraps these in services to be used as needed within an environment.

Key Features

  • Multiple Invoker Strategies: Support for various data fetching patterns
  • GraphQL Support: Full GraphQL query and mutation support
  • Legacy System Integration: Backward compatibility with legacy APIs
  • Subscribable Data: Real-time data subscriptions and updates
  • Flexible Architecture: Pluggable invoker system for custom implementations

Service Types

Available Services

DefaultImperativeBindingsService

Standard invoker for general-purpose data fetching.

  • Handles standard REST API calls
  • Provides error handling and retry logic
  • Can be used for subscribable and non-subscribable results

QueryImperativeBindingsService

Specialized invoker for query operations.

  • Supports all properties of the default invoker

GraphQLImperativeBindingsService

GraphQL-specific invoker for modern GraphQL APIs.

  • Executes GraphQL queries
  • Handles GraphQL errors
  • Supports variables and fragments

GraphQLMutationBindingsService

Dedicated invoker for GraphQL mutations.

  • Executes GraphQL mutations
  • Handles optimistic updates
  • Manages mutation side effects

GraphQLLegacyImperativeBindingsService

Bridge invoker for legacy GraphQL implementations.

  • Backward compatibility with older GraphQL systems
  • Handles legacy response formats

LegacyImperativeBindingsService

Compatibility invoker for legacy systems.

  • Supports older REST APIs

SubscribableImperativeBindingsService

Real-time data subscription invoker.

  • Specific to subscribable results

Usage Examples

Basic Data Fetching

import { buildDefaultImperativeBindingsServiceDescriptor } from '@conduit-client/services/bindings-imperative/v1';

// Build the service
const { service: defaultImperativeBindingsService } =
  buildDefaultImperativeBindingsServiceDescriptor();

// Create a command that returns data
const getCommand = () => ({
  execute: () =>
    Promise.resolve({
      isOk: () => true,
      value: {
        data: { foo: 'bar' },
        subscribe: (callback) => {
          // Optional subscription logic
          return () => {}; // Return unsubscribe function
        },
      },
    }),
});

// Bind the command to the service
const invoker = defaultImperativeBindingsService.bind(getCommand);

// Execute and get the result
const result = await invoker({ required: 'param' });
console.log(result); // { foo: 'bar' }

GraphQL Query

import { buildGraphQLImperativeBindingsServiceDescriptor } from '@conduit-client/services/bindings-imperative/v1';

// Build the service
const { service: graphQLImperativeBindingsService } =
  buildGraphQLImperativeBindingsServiceDescriptor();

// Create a GraphQL command
const getGraphQLCommand = () => ({
  execute: () =>
    Promise.resolve({
      isOk: () => true,
      value: {
        data: {
          data: { user: { id: '1', name: 'John' } },
          errors: [],
        },
        subscribe: (callback) => {
          // Handle GraphQL subscriptions
          return () => {};
        },
        refresh: async () => {
          // Optional refresh logic
        },
      },
    }),
});

// Bind with refresh support
const invoker = graphQLImperativeBindingsService.bind(getGraphQLCommand, true);

// Execute GraphQL query
const result = await invoker('query { user { id name } }', { id: '123' });
console.log(result.data); // { user: { id: '1', name: 'John' } }
console.log(result.errors); // undefined or array of errors
console.log(result.subscribe); // Subscription function
console.log(result.refresh); // Refresh function (if enabled)

GraphQL Mutation

import { buildGraphQLMutationBindingsServiceDescriptor } from '@conduit-client/services/bindings-imperative/v1';

// Build the service
const { service: graphQLMutationBindingsService } = buildGraphQLMutationBindingsServiceDescriptor();

// Create a mutation command
const getMutationCommand = () => ({
  execute: (overrides) => {
    // Note: Mutations automatically use no-cache
    console.log(overrides.cacheControlConfig); // { type: 'no-cache' }
    return Promise.resolve({
      isOk: () => true,
      value: {
        data: {
          data: { doThing: { id: '123' } },
          errors: [],
        },
      },
    });
  },
});

// Bind the command
const invoker = graphQLMutationBindingsService.bind(getMutationCommand);

// Execute mutation
const result = await invoker({
  query: 'mutation DoThing { doThing { id } }',
  variables: {
    /* variables */
  },
});
console.log(result); // { data: { doThing: { id: '123' } }, errors: [] }

Subscribable Data

import { buildSubscribableImperativeBindingsServiceDescriptor } from '@conduit-client/services/bindings-imperative/v1';

// Build the service
const { service: subscribableImperativeBindingsService } =
  buildSubscribableImperativeBindingsServiceDescriptor();

// Create a subscribable command
const getSubscribableCommand = () => ({
  execute: () =>
    Promise.resolve({
      isOk: () => true,
      value: {
        data: { foo: 'bar' },
        subscribe: (callback) => {
          // Set up subscription
          const interval = setInterval(() => {
            callback({
              isOk: () => true,
              value: { data: { foo: 'updated' } },
            });
          }, 1000);

          // Return unsubscribe function
          return () => clearInterval(interval);
        },
        refresh: async () => {
          // Optional refresh logic
          return { isOk: () => true, value: undefined };
        },
      },
    }),
});

// Bind with refresh support
const invoker = subscribableImperativeBindingsService.bind(getSubscribableCommand, true);

// Get subscribable result
const result = await invoker({ required: 'param' });
console.log(result.data); // { foo: 'bar' }

// Subscribe to updates
const unsubscribe = result.subscribe((update) => {
  console.log('Updated:', update);
});

// Refresh data
if (result.refresh) {
  await result.refresh();
}

// Later: unsubscribe
unsubscribe();

Legacy System Integration

import { buildLegacyImperativeBindingsServiceDescriptor } from '@conduit-client/services/bindings-imperative/v1';

// Build the service
const { service: legacyImperativeBindingsService } =
  buildLegacyImperativeBindingsServiceDescriptor();

// Create a legacy command
const getLegacyCommand = () => ({
  execute: (overrides) => {
    // Handle cache policy if provided
    const cachePolicy = overrides?.cacheControlConfig;

    return Promise.resolve({
      isOk: () => true,
      value: {
        data: { foo: 'legacy data' },
        subscribe: (callback) => {
          // Legacy subscription pattern
          return () => {};
        },
      },
    });
  },
});

// Bind the command
const legacyAdapter = legacyImperativeBindingsService.bind(getLegacyCommand);

// Use legacy invoke pattern
legacyAdapter.invoke(
  { test: 'param' },
  { cachePolicy: { type: 'no-cache' } }, // Optional request context
  (result) => {
    console.log(result); // { data: { foo: 'legacy data' }, error: undefined }
  }
);

// Use legacy subscribe pattern
const unsubscribe = legacyAdapter.subscribe({ test: 'param' }, {}, (result) => {
  console.log('Updated:', result);
});

// Later: unsubscribe
unsubscribe();

Query Service

import { buildQueryImperativeBindingsServiceDescriptor } from '@conduit-client/services/bindings-imperative/v1';

// Build the service
const { service: queryImperativeBindingsService } = buildQueryImperativeBindingsServiceDescriptor();

// Create a query command
const getQueryCommand = () => ({
  execute: () =>
    Promise.resolve({
      isOk: () => true,
      value: { message: 'query result' },
    }),
});

// Bind the command
const invoker = queryImperativeBindingsService.bind(getQueryCommand);

// Execute query
const result = await invoker('queryParam', 42);
console.log(result); // { data: { message: 'query result' } }

API Reference

Service Descriptors

Each service type is exported as a service descriptor builder function:

  • buildDefaultImperativeBindingsServiceDescriptor() - Returns default service descriptor
  • buildQueryImperativeBindingsServiceDescriptor() - Returns query service descriptor
  • buildSubscribableImperativeBindingsServiceDescriptor() - Returns subscribable service descriptor
  • buildLegacyImperativeBindingsServiceDescriptor() - Returns legacy service descriptor
  • buildGraphQLImperativeBindingsServiceDescriptor() - Returns GraphQL service descriptor
  • buildGraphQLLegacyImperativeBindingsServiceDescriptor() - Returns GraphQL legacy service descriptor
  • buildGraphQLMutationBindingsServiceDescriptor() - Returns GraphQL mutation service descriptor

Service Methods

Each service provides a bind method:

bind<TParams extends unknown[]>(getCommand: CommandFactory, exposeRefresh?: boolean): Invoker

Binds a command factory to the service and returns an invoker function.

  • getCommand: A function that returns a command object with an execute method
  • exposeRefresh: Optional boolean to enable refresh functionality (for subscribable services)
  • Returns: An invoker function that accepts parameters and returns a promise

Command Interface

Commands must implement the interface from @conduit-client/command-base

Dependencies

  • @conduit-client/utils: Core utility functions
  • @conduit-client/bindings-utils: Shared binding utilities
  • @conduit-client/jsonschema-validate: JSON schema validation
  • @conduit-client/command-base: Base command interfaces
  • @conduit-client/onestore-graphql-parser: GraphQL parsing utilities