ArchitectureControls

Number Control

Number controls provide a numeric input field for integer and decimal values. They support minimum and maximum bounds, step increments, and placeholder text, making them ideal for timeouts, limits, counts, and any scenario where users need to supply a precise numeric value.

Basic Usage

import * as i from '@xentom/integration-framework';

// Simple number input
i.controls.number({
  label: 'Timeout',
  placeholder: 'Enter timeout in milliseconds...',
});

// With constraints
i.controls.number({
  label: 'Page Size',
  default: 25,
  min: 1,
  max: 100,
  step: 1,
});

Configuration Options

Prop

Type

Common Use Cases

Timeouts and Delays

// Request timeout in milliseconds
requestTimeout: i.pins.data({
  control: i.controls.number({
    label: 'Request Timeout',
    description: 'Maximum time to wait for a response, in milliseconds',
    default: 5000,
    min: 0,
    step: 100,
  }),
});

// Retry delay
retryDelay: i.pins.data({
  control: i.controls.number({
    label: 'Retry Delay',
    description: 'Time to wait between retry attempts, in milliseconds',
    default: 1000,
    min: 0,
    max: 60000,
    step: 500,
  }),
});

Pagination and Limits

// Page size for API pagination
pageSize: i.pins.data({
  control: i.controls.number({
    label: 'Page Size',
    description: 'Number of records to fetch per page',
    default: 25,
    min: 1,
    max: 100,
    step: 1,
  }),
});

// Maximum number of results
limit: i.pins.data({
  control: i.controls.number({
    label: 'Result Limit',
    description: 'Maximum number of results to return',
    default: 50,
    min: 1,
  }),
});

Rate Limiting

// Requests per second
rateLimit: i.pins.data({
  control: i.controls.number({
    label: 'Rate Limit',
    description: 'Maximum number of requests per second',
    default: 10,
    min: 1,
    max: 1000,
    step: 1,
  }),
});

Port Numbers

// Server port for environment variables
PORT: i.env({
  control: i.controls.number({
    label: 'Port',
    description: 'TCP port the service listens on',
    default: 8080,
    min: 1,
    max: 65535,
    step: 1,
  }),
});

Usage in Nodes

Number controls work in both environment variables and node pins:

export default i.integration({
  env: {
    // Global numeric setting for the entire integration
    MAX_CONNECTIONS: i.env({
      control: i.controls.number({
        label: 'Max Connections',
        description: 'Maximum number of concurrent database connections',
        default: 10,
        min: 1,
        max: 100,
        step: 1,
      }),
    }),
  },

  nodes: {
    fetchRecords: i.nodes.action({
      inputs: {
        // Per-node numeric settings
        pageSize: i.pins.data({
          control: i.controls.number({
            label: 'Page Size',
            description: 'Number of records per page',
            default: 25,
            min: 1,
            max: 200,
            step: 1,
          }),
        }),
        offset: i.pins.data({
          control: i.controls.number({
            label: 'Offset',
            description: 'Number of records to skip',
            default: 0,
            min: 0,
            step: 1,
          }),
        }),
      },

      outputs: {
        records: i.pins.data(),
        total: i.pins.data(),
      },

      async run({ inputs, env, next }) {
        const records = await fetchFromApi({
          limit: inputs.pageSize,
          offset: inputs.offset,
          maxConnections: env.MAX_CONNECTIONS,
        });

        next({ records: records.items, total: records.total });
      },
    }),
  },
});

Validation with Constraints

Use min, max, and step to guide users toward valid values:

// Integer-only input (step: 1 prevents decimals in the UI)
retryCount: i.pins.data({
  control: i.controls.number({
    label: 'Retry Count',
    description: 'Number of times to retry on failure',
    default: 3,
    min: 0,
    max: 10,
    step: 1,
  }),
});

// Decimal input for percentages
discountRate: i.pins.data({
  control: i.controls.number({
    label: 'Discount Rate',
    description: 'Percentage discount to apply (0–100)',
    default: 0,
    min: 0,
    max: 100,
    step: 0.5,
  }),
});

// Unbounded input when any positive value is valid
maxFileSize: i.pins.data({
  control: i.controls.number({
    label: 'Max File Size (MB)',
    description: 'Maximum allowed file size in megabytes',
    default: 10,
    min: 0,
  }),
});

Best Practices

Use Meaningful Units in Labels

Make the unit clear directly in the label or description so users never have to guess:

// Good - unit is explicit
cacheTtl: i.pins.data({
  control: i.controls.number({
    label: 'Cache TTL (seconds)',
    description: 'How long to keep cached responses',
    default: 300,
    min: 0,
  }),
});

// Avoid - ambiguous unit
cacheTtl: i.pins.data({
  control: i.controls.number({
    label: 'Cache TTL', // Seconds? Minutes? Hours?
  }),
});

Set Sensible Defaults

Choose defaults that represent the most common or safest option:

// Safe default for a request timeout
timeout: i.pins.data({
  control: i.controls.number({
    label: 'Timeout (ms)',
    default: 10000, // 10 seconds — reasonable for most APIs
    min: 0,
  }),
});

Constrain Where Appropriate

Apply min/max/step whenever the valid range is known, to prevent runtime errors caused by out-of-range values:

workerCount: i.pins.data({
  control: i.controls.number({
    label: 'Worker Count',
    description: 'Number of parallel workers to spawn',
    default: 4,
    min: 1,   // At least one worker is required
    max: 32,  // Cap to avoid resource exhaustion
    step: 1,  // Must be a whole number
  }),
});

On this page