### Interval Installation Steps Source: https://interval.com/docs/installation The core steps to get started with Interval involve deploying the Interval Server and then integrating the Interval SDK into your application. The Interval Server manages the rendering of interfaces, while your application contains the business logic and secrets. ```markdown 1. Deploy an instance of Interval Server 2. Create a new TypeScript app or add the Interval SDK to your existing app ``` -------------------------------- ### Interval Server Local Setup Source: https://interval.com/docs/interval-server Steps to install and run the Interval Server locally for development. This includes global npm installation, setting up a `.env` file with required environment variables, initializing the database, and starting the server. ```shell npm i -g @interval/server ``` ```shell DATABASE_URL= SECRET= APP_URL= AUTH_COOKIE_SECRET= WSS_API_SECRET= ``` ```shell interval-server db-init ``` ```shell interval-server start ``` -------------------------------- ### Interval Server Setup Source: https://interval.com/docs/installation To begin building tools with Interval, you must first deploy an instance of the Interval Server. Refer to the specific documentation for the Interval Server for detailed setup instructions. ```markdown Follow the instructions in the Interval Server documentation to get started. ``` -------------------------------- ### Interval SDK Integration Source: https://interval.com/docs/installation After successfully deploying the Interval Server, you can install the Interval SDK to start building applications. The SDK enables the integration of your app with the Interval platform. ```markdown Once you have an instance of Interval Server running, you can install the SDK and begin building apps with Interval. Follow the instructions in the Interval SDK documentation to get started. ``` -------------------------------- ### Interval Server Setup (JavaScript) Source: https://interval.com/docs/index Sets up the Interval SDK in a JavaScript project, configuring the server endpoint, API key, and the directory for action routes. It then starts the Interval server listener. ```JavaScript const path =require("path"); const{ Interval }=require("@interval/sdk"); const interval =newInterval({ endpoint:"wss:///websocket", apiKey:"", routesDirectory: path.resolve(__dirname,"routes"), }); interval.listen(); ``` -------------------------------- ### Interval Server Setup (TypeScript) Source: https://interval.com/docs/index Sets up the Interval SDK in a TypeScript project, configuring the server endpoint, API key, and the directory for action routes. It then starts the Interval server listener. ```TypeScript import path from"path"; import{ Interval }from"@interval/sdk"; const interval =newInterval({ endpoint:"wss:///websocket",// Don't forget the /websocket path! apiKey:"", routesDirectory: path.resolve(__dirname,"routes"), }); interval.listen(); ``` -------------------------------- ### Install Interval SDK Source: https://interval.com/docs/interval-sdk Installs the Interval SDK package using npm. ```bash npm install @interval/sdk ``` -------------------------------- ### ctx.loading.start Examples Source: https://interval.com/docs/action-context/loading-start Demonstrates how to use ctx.loading.start with a label and as a shorthand with just a label. ```JavaScript await ctx.loading.start({ label:"Reticulating splines...", }); await ctx.loading.start("Label only shorthand"); ``` -------------------------------- ### ctx.loading.start Examples Source: https://interval.com/docs/action-context/loading-start Demonstrates how to use ctx.loading.start with a label and as a shorthand with just a label. ```TypeScript await ctx.loading.start({ label:"Reticulating splines...", }); await ctx.loading.start("Label only shorthand"); ``` -------------------------------- ### Interval Server Commands Source: https://interval.com/docs/interval-server Reference for essential `interval-server` commands. Includes starting the server, initializing the database with options to skip database creation, and the required `DATABASE_URL` format. ```shell interval-server start ``` ```shell interval-server db-init ``` ```shell interval-server db-init --skip-create ``` ```shell postgresql://username:password@host:port/dbname ``` -------------------------------- ### Initialize Interval SDK (JavaScript) Source: https://interval.com/docs/writing-actions Initializes the Interval SDK with endpoint, API key, and routes directory. It then starts listening for actions. ```JavaScript const { Interval } = require("@interval/sdk"); const path = require("path"); const interval = new Interval({ endpoint: "wss:///websocket", apiKey: "", // get an API key from the Keys page in your Interval dashboard routesDirectory: path.resolve(__dirname, "routes"), }); interval.listen(); ``` -------------------------------- ### Create requirements.txt for Interval SDK Source: https://interval.com/docs/getting-started/deploy Creates a `requirements.txt` file to specify the Interval SDK as a dependency. Railway uses this file to install necessary packages during deployment. ```Text interval-sdk ``` -------------------------------- ### Initialize Interval SDK (TypeScript) Source: https://interval.com/docs/writing-actions Initializes the Interval SDK with endpoint, API key, and routes directory. It then starts listening for actions. ```TypeScript import { Interval } from "@interval/sdk"; import path from "path"; const interval = new Interval({ endpoint: "wss:///websocket", apiKey: "", // get an API key from the Keys page in your Interval dashboard routesDirectory: path.resolve(__dirname, "routes"), }); interval.listen(); ``` -------------------------------- ### Install Railway CLI Source: https://interval.com/docs/getting-started/deploy Installs the Railway command-line interface (CLI) globally using either npm or yarn. This tool is essential for interacting with the Railway platform for deployment. ```npm npm i -g @railway/cli ``` ```yarn yarn global add @railway/cli ``` -------------------------------- ### Initialize Railway Project Source: https://interval.com/docs/getting-started/deploy Initializes a new project within Railway. This command guides the user through creating a project and configuring environment variables for the deployment. ```Shell railway init ``` -------------------------------- ### Run Interval App (npm/yarn) Source: https://interval.com/docs/getting-started Provides the commands to run the Interval application locally using either npm or yarn. This starts the development server and connects the app to the Interval platform. ```Shell npm run dev ``` ```Shell yarn dev ``` -------------------------------- ### io.select.table Usage Example Source: https://interval.com/docs/io-methods/select-table Demonstrates how to use the `io.select.table` function to prompt the user to select albums from a list. It shows the data structure required for the table. ```typescript const albums =await io.select.table("Select your favorites",{ data:[ { album:"Exile on Main Street", artist:"The Rolling Stones", year:1972, }, { artist:"Michael Jackson", album:"Thriller", year:1982, }, { album:"Enter the Wu-Tang (36 Chambers)", artist:"Wu-Tang Clan", year:1993, }, ], }); ``` ```javascript const albums =await io.select.table("Select your favorites",{ data:[ { album:"Exile on Main Street", artist:"The Rolling Stones", year:1972, }, { artist:"Michael Jackson", album:"Thriller", year:1982, }, { album:"Enter the Wu-Tang (36 Chambers)", artist:"Wu-Tang Clan", year:1993, }, ], }); ``` -------------------------------- ### io.select.multiple Usage Example Source: https://interval.com/docs/io-methods/select-multiple Demonstrates how to use the io.select.multiple method to prompt a user for multiple selections, including setting default values and help text. ```TypeScript const condiments =await io.select.multiple("Condiments",{ options:[ { label:"Ketchup", value:0, }, { label:"Mustard", value:1, }, { label:"Mayo", value:2, }, ], defaultValue:[ { label:"Ketchup", value:0, }, { label:"Mustard", value:1, }, ], helpText:"What goes on it?", }); const condimentIds = condiments.map(condiment => condiment.value); ``` ```JavaScript const condiments =await io.select.multiple("Condiments",{ options:[ { label:"Ketchup", value:0, }, { label:"Mustard", value:1, }, { label:"Mayo", value:2, }, ], defaultValue:[ { label:"Ketchup", value:0, }, { label:"Mustard", value:1, }, ], helpText:"What goes on it?", }); const condimentIds = condiments.map(condiment => condiment.value); ``` -------------------------------- ### io.input.date API Documentation Source: https://interval.com/docs/io-methods/input-date Provides detailed information about the io.input.date method, including its parameters, return values, and usage examples. ```APIDOC io.input.date(label: string, options?: { defaultValue?: Date | { year: number; month: number; day: number }; disabled?: boolean; helpText?: string; max?: Date | { year: number; month: number; day: number }; min?: Date | { year: number; month: number; day: number } }): Promise<{ day: number; jsDate: Date; month: number; year: number; defaultValue?: Date | { year: number; month: number; day: number }; disabled?: boolean; helpText?: string; max?: Date | { year: number; month: number; day: number }; min?: Date | { year: number; month: number; day: number }> Requests a date input from the user. Parameters: label: The label for the date input. options: Optional configuration for the date input. defaultValue: Optional. The default date value for the input. Can be a Date object or an object with year, month (1-12), and day. disabled: Optional. If true, the input is disabled and cannot be changed from the defaultValue. helpText: Optional. Additional context for the input, supporting markdown. max: Optional. The latest possible date value. Can be a Date object or an object with year, month (1-12), and day. min: Optional. The earliest possible date value. Can be a Date object or an object with year, month (1-12), and day. Returns: A promise that resolves to an object containing the date components: day, jsDate (JavaScript Date object), month (1-12), and year. ``` -------------------------------- ### Interval App Deployment on Render Source: https://interval.com/docs/deployments/render Instructions for deploying an Interval application on Render. This involves setting up a Background Worker service, configuring the Node.js environment, and specifying build and start commands. ```APIDOC Deploy on Render: 1. Create a new Background Worker service in the Render Dashboard. 2. Select your repository (GitHub/GitLab). 3. Set Environment to Node. 4. Configure Build Command (e.g., `yarn build`) and Start Command (e.g., `yarn start`). 5. Choose a paid plan (Starter is recommended). 6. Under Advanced settings, add an Environment Variable: - Key: `INTERVAL_KEY` - Value: Your Interval Live mode key 7. Click 'Create Background Worker'. ``` -------------------------------- ### Deploy Interval App on Railway Source: https://interval.com/docs/deployments/railway Steps to deploy an Interval application on Railway. This involves installing the Railway CLI, initializing a new project, setting the INTERVAL_KEY environment variable, and deploying the application. ```APIDOC Installation Steps: 1. Install the Railway CLI and log in to Railway. 2. Navigate to your project's directory and run `railway init`. 3. Choose 'Empty Project' and name your app. 4. When prompted about environment variables, enter 'N'. 5. Obtain your Live mode key from the Interval dashboard. 6. Set the environment variable: `railway variables set INTERVAL_KEY=`. 7. Deploy the app: `railway up`. Verification: Check the Railway dashboard logs for a message indicating Interval is connected. ``` -------------------------------- ### Define Interval Action with Name and Description Source: https://interval.com/docs/best-practices This example demonstrates how to define an Interval action with a human-readable name and a descriptive explanation, improving discoverability and understanding for team members. ```typescript import { Action, io } from "@interval/sdk"; export default new Action({ name: "👥 Transfer membership", description: "Removes a membership from one account and applies it to another.", handler: async () => { /* ... */ }, }); ``` -------------------------------- ### Interval Server Docker Deployment Source: https://interval.com/docs/interval-server Information on deploying the Interval Server using its official Docker image. It highlights the image name and the necessity of providing environment variables during deployment, similar to local setup. ```shell docker.io/alexarena/interval-server:latest ``` -------------------------------- ### Display Table with Data Source: https://interval.com/docs/io-methods/display-table Demonstrates how to use the io.display.table function to render a table with predefined data, including column headers and data rows. This example shows basic table creation with album information. ```TypeScript await io.display.table("Albums",{ helpText:"Includes the artist and its year of release.", data:[ { album:"Exile on Main Street", artist:"The Rolling Stones", year:1972, }, { album:"Thriller", artist:"Michael Jackson", year:1982, }, { album:"Enter the Wu-Tang (36 Chambers)", artist:"Wu-Tang Clan", year:1993, }, ], }); ``` ```JavaScript await io.display.table("Albums",{ helpText:"Includes the artist and its year of release.", data:[ { album:"Exile on Main Street", artist:"The Rolling Stones", year:1972, }, { album:"Thriller", artist:"Michael Jackson", year:1982, }, { album:"Enter the Wu-Tang (36 Chambers)", artist:"Wu-Tang Clan", year:1993, }, ], }); ``` -------------------------------- ### Safely Shutting Down Deployment (Blue-Green) Source: https://interval.com/docs/concepts/interval Demonstrates using `safelyClose` to ensure no service interruptions during deployment shutdowns, illustrated with TypeScript and JavaScript examples. ```typescript import path from"path"; import{ Interval }from"@interval/sdk"; const interval =new Interval({ endpoint:"wss:///websocket", apiKey:"",// get an API key from the Keys page in your Interval dashboard routesDirectory: path.resolve(__dirname,"routes"), }); interval.listen(); process.on("SIGINT",()=>{ interval .safelyClose() .then(()=>{ console.log("Safely shut down successfully."); process.exit(0); }) .catch(err =>{ console.error( "Failed shutting down safely, forcibly closing connection." ); interval.immediatelyClose(); process.exit(0); }); }); ``` ```javascript const path =require("path"); const{ Interval }=require("@interval/sdk"); const interval =new Interval({ endpoint:"wss:///websocket", apiKey:"",// get an API key from the Keys page in your Interval dashboard routesDirectory: path.resolve(__dirname,"routes"), }); interval.listen(); process.on("SIGINT",()=>{ interval .safelyClose() .then(()=>{ console.log("Safely shut down successfully."); process.exit(0); }) .catch(err =>{ console.error( "Failed shutting down safely, forcibly closing connection." ); interval.immediatelyClose(); process.exit(0); }); }); ``` -------------------------------- ### CursorPagination Usage Example (TypeScript) Source: https://interval.com/docs/io-methods/display-table A TypeScript example demonstrating how to integrate the CursorPagination class within an Interval SDK application to display paginated data from a database using Prisma. ```TypeScript import{ io, Layout, Page }from"@interval/sdk"; import prisma from"~/prisma.server"; import CursorPagination from"./cursor-pagination"; exportdefaultnewPage({ name:"Tags", handler:async()=>{ // 1️⃣ Initialize the CursorPagination class const cursor =newCursorPagination(); returnnewLayout({ title:"Tags", children:[ io.display.table("",{ defaultPageSize:30, columns:["name","slug"], getData:async newState =>{ const{ sortColumn, sortDirection, pageSize, queryTerm }= newState; // 2️⃣ Update with the new state cursor.update(newState); const where = queryTerm ?{ name:{ contains: queryTerm }, }:undefined; let orderBy; if(sortColumn && sortDirection){ orderBy ={ [sortColumn]: sortDirection, }; } // 3️⃣ Use the previous cursor in your query const lastResultId = cursor.lastCursor; const data =await prisma.tag.findMany({ where, cursor: lastResultId ?{ id: lastResultId }:undefined, skip: lastResultId ?1:0,// skip the cursor take: pageSize, orderBy, }); const totalRecords =await prisma.tag.count({ where, }); // 4️⃣ Store the cursor for the data you're returning cursor.add(data[data.length -1]?.id); return{ data, totalRecords, }; }, }), ], }); }, }); ``` -------------------------------- ### Scheduled Action Example with Input Handling Source: https://interval.com/docs/writing-actions/scheduled-actions This example demonstrates how to create a scheduled action that syncs data from an external service. It includes logic to handle missing email addresses by prompting the user for input using Interval's I/O methods. ```TypeScript import { Action, io } from "@interval/sdk"; export default asyncAction(async () => { const data = await fetch("").then(resp => resp.json()); for (let row of data) { if (!row.email) { const [, email] = await io.group([ io.display.markdown(` ## An issue was encountered syncing data. No email was present in the row, provide an email before continuing. `), io.input.email("Enter an email:"), ]); row.email = email; } // Now every row is guaranteed to have an email // We can insert the row into our app's database } }); ``` ```JavaScript const { Action, io } = require("@interval/sdk"); module.exports = asyncAction(async () => { const data = await fetch("").then(resp => resp.json()); for (let row of data) { if (!row.email) { const [, email] = await io.group([ io.display.markdown(` ## An issue was encountered syncing data. No email was present in the row, provide an email before continuing. `), io.input.email("Enter an email:"), ]); row.email = email; } // Now every row is guaranteed to have an email // We can insert the row into our app's database } }); ``` -------------------------------- ### Initialize Interval App (JavaScript) Source: https://interval.com/docs/getting-started Imports necessary modules (path, Interval, dotenv) and initializes the Interval SDK with server endpoint, API key, and routes directory. It then establishes a persistent connection to the Interval server. ```JavaScript const path =require("path"); const{ Interval }=require("@interval/sdk"); require("dotenv").config(); const interval =new Interval({ endpoint:"wss:///websocket", apiKey: process.env.INTERVAL_KEY, routesDirectory: path.resolve(__dirname,"routes"), }); // Establishes a persistent connection between Interval and your app. interval.listen(); ``` -------------------------------- ### ctx.loading.start API Documentation Source: https://interval.com/docs/action-context/loading-start Details the parameters and return value for the ctx.loading.start function, used to display loading indicators. ```APIDOC ctx.loading.start(options?: { label?: string; description?: string; itemsInQueue?: number; }): Promise // Parameters: // label: Primary label for the loading indicator. // description: Secondary label providing additional context for the loading indicator. // itemsInQueue: Number of "items" your action needs to work through to complete loading. Subsequently calling `ctx.loading.completeOne` (e.g. within a loop) updates the indicator’s progress. // // Returns: // null ``` -------------------------------- ### io.input.boolean Usage Source: https://interval.com/docs/io-methods/input-boolean Requests a boolean value from the user. This method is used to get a true/false answer to a question. ```TypeScript const shouldSubscribe = await io.input.boolean("Subscribe to our newsletter?"); ``` ```JavaScript const shouldSubscribe = await io.input.boolean("Subscribe to our newsletter?"); ``` -------------------------------- ### Initialize Interval App (JavaScript) Source: https://interval.com/docs/interval-sdk Initializes the Interval client with server endpoint, API key, and routes directory. The `.listen()` method establishes a connection to the Interval server. ```JavaScript const path =require("path"); const{ Interval }=require("@interval/sdk"); const interval =new Interval({ endpoint:"wss:///websocket",// Don't forget the /websocket path! apiKey:"",// get an API key from the Keys page in your Interval dashboard routesDirectory: path.resolve(__dirname,"routes"), }); // This is important! If you don't call listen(), your app won't connect to Interval. interval.listen(); ``` -------------------------------- ### Hello World Action (JavaScript) Source: https://interval.com/docs/index Defines a simple 'Hello, world' action using the Interval SDK in JavaScript. It prompts the user for their name using `io.input.text` and returns a personalized greeting. ```JavaScript const{ Action, io }=require("@interval/sdk"); module.exports =newAction(async( )=>{ const name =await io.input.text("Your name"); return`Hello, ${name}`; }); ``` -------------------------------- ### Initialize Interval App (TypeScript) Source: https://interval.com/docs/getting-started Imports necessary modules (path, Interval, dotenv) and initializes the Interval SDK with server endpoint, API key, and routes directory. It then establishes a persistent connection to the Interval server. ```TypeScript import path from"path"; import{ Interval }from"@interval/sdk"; import"dotenv/config"; const interval =new Interval({ endpoint:"wss:///websocket", apiKey: process.env.INTERVAL_KEY, routesDirectory: path.resolve(__dirname,"routes"), }); // Establishes a persistent connection between Interval and your app. interval.listen(); ``` -------------------------------- ### Display Asynchronous Metadata Source: https://interval.com/docs/io-methods/display-metadata An example of using the `io.display.metadata` function to display data asynchronously. The `value` property is an async function that counts users from the database. ```javascript await io.display.metadata({ data: [ { label: "Total users", value: async () => await db.users.count(), }, ], }); ``` -------------------------------- ### Interval Class Initialization with API Key Source: https://interval.com/docs/concepts/environments Demonstrates how to initialize the Interval class using an API key to determine the environment the actions will run in. This is crucial for differentiating between development and production deployments. ```javascript import Interval from '@interval/sdk'; // For Development environment, use your Personal Development Key const intervalDev = new Interval({ apiKey: 'YOUR_PERSONAL_DEVELOPMENT_KEY' }); // For Production environment, use a Live mode Interval API key const intervalProd = new Interval({ apiKey: 'YOUR_LIVE_MODE_API_KEY' }); ``` -------------------------------- ### Connecting Interval App to Server Source: https://interval.com/docs/interval-server Example of how to connect your Interval application to an Interval Server instance using the Interval SDK. It shows how to configure the `endpoint` property, noting the difference between local (`ws://`) and production (`wss://`) URLs. ```javascript const interval =new Interval({ apiKey: process.env.INTERVAL_KEY, endpoint:"wss:///websocket",// Don't forget the /websocket path! }); ``` -------------------------------- ### Issue Refunds with Loading Indicator (JavaScript) Source: https://interval.com/docs/getting-started This JavaScript code snippet demonstrates how to initiate a refund process using the Interval SDK. It includes starting a loading state with a progress indicator, iterating through selected charges, refunding each charge using a helper function, and completing the loading state. ```JavaScript const{ Action, io, ctx }=require("@interval/sdk"); const{ getCharges, refundCharge }=require("./payments"); module.exports =newAction(async()=>{ const customerEmail =await io.input.email( "Email of the customer to refund:" ); console.log("Email:", customerEmail); const charges =awaitgetCharges(customerEmail); const chargesToRefund =await io.select.table( "Select one or more charges to refund", { data: charges, } ); await ctx.loading.start({ title:"Refunding charges", // Because we specified `itemsInQueue`, Interval will render a progress bar versus an indeterminate loading indicator. itemsInQueue: chargesToRefund.length, }); for(const charge of chargesToRefund){ awaitrefundCharge(charge.id); await ctx.loading.completeOne(); } // Values returned from actions are automatically stored with Interval transaction logs return{ chargesRefunded: chargesToRefund.length }; }); ``` -------------------------------- ### Display Specific Columns in Table Source: https://interval.com/docs/io-methods/display-table This example demonstrates how to display only specific columns ('first_name', 'last_name', 'email') in a table by providing an array of column names to the 'columns' property. ```JavaScript await io.display.table("Users",{ data:[ { email:"carsta.rocha@example.com", phone_number:"(60) 1416-4953", birthdate:"1993-08-04", first_name:"Carsta", last_name:"Rocha", image:"https://example.com/photos/21351234.jpg", website_url:"https://example.com", }, { email:"irene.morales@example.org", phone_number:"625-790-958", birthdate:"1982-04-28", first_name:"Irene", last_name:"Morales", image:"https://example.com/photos/8321527.jpg", website_url:"https://example.org", }, ], columns:["first_name","last_name","email"], }); ``` -------------------------------- ### Initialize Interval SDK Source: https://interval.com/docs/concepts/interval Demonstrates how to initialize the Interval SDK with essential configuration like endpoint, API key, and routes directory. This is the primary method for connecting to the Interval server and enabling functionality. ```TypeScript import path from"path"; import{ Interval }from"@interval/sdk"; const interval =new Interval({ endpoint:"wss:///websocket", apiKey:"",// get an API key from the Keys page in your Interval dashboard routesDirectory: path.resolve(__dirname,"routes"), }); interval.listen(); ``` ```JavaScript const path =require("path"); const{ Interval }=require("@interval/sdk"); const interval =new Interval({ endpoint:"wss:///websocket", apiKey:"",// get an API key from the Keys page in your Interval dashboard routesDirectory: path.resolve(__dirname,"routes"), }); interval.listen(); ``` -------------------------------- ### Initialize Interval App (TypeScript) Source: https://interval.com/docs/interval-sdk Initializes the Interval client with server endpoint, API key, and routes directory. The `.listen()` method establishes a connection to the Interval server. ```TypeScript import path from"path"; import{ Interval }from"@interval/sdk"; const interval =new Interval({ endpoint:"wss:///websocket",// Don't forget the /websocket path! apiKey:"",// get an API key from the Keys page in your Interval dashboard routesDirectory: path.resolve(__dirname,"routes"), }); // This is important! If you don't call listen(), your app won't connect to Interval. interval.listen(); ``` -------------------------------- ### Shorthand Loading State Source: https://interval.com/docs/writing-actions/loading Uses a shorthand syntax to start a loading state by providing only a string for the label, simplifying the process for basic loading indicators. ```TypeScript import{ Action, ctx }from"@interval/sdk"; exportdefaultnewAction(async()=>{ await ctx.loading.start("This may take a while"); // ... arduous logic here }); ``` -------------------------------- ### Hello World Action (TypeScript) Source: https://interval.com/docs/index Defines a simple 'Hello, world' action using the Interval SDK in TypeScript. It prompts the user for their name using `io.input.text` and returns a personalized greeting. ```TypeScript import{ Action, io }from"@interval/sdk"; exportdefaultnewAction(async( )=>{ const name =await io.input.text("Your name"); return`Hello, ${name}`; }); ``` -------------------------------- ### Display Specific Columns in Table Source: https://interval.com/docs/io-methods/select-table This example demonstrates how to display only specific columns ('first_name', 'last_name', 'email') in a table by providing an array of column names to the 'columns' property. ```JavaScript await io.select.table("Users",{ data:[ { email:"carsta.rocha@example.com", phone_number:"(60) 1416-4953", birthdate:"1993-08-04", first_name:"Carsta", last_name:"Rocha", image:"https://example.com/photos/21351234.jpg", website_url:"https://example.com", }, { email:"irene.morales@example.org", phone_number:"625-790-958", birthdate:"1982-04-28", first_name:"Irene", last_name:"Morales", image:"https://example.com/photos/8321527.jpg", website_url:"https://example.org", }, ], columns:["first_name","last_name","email"], }); ``` -------------------------------- ### TypeScript Example for io.search Type Inference Source: https://interval.com/docs/io-methods/search Demonstrates how to use TypeScript with the io.search function to ensure proper type inference for the return type and the renderResult argument. ```TypeScript const selectedUser =await io.search("Search for a user",{ renderResult: user =>({ label: user.name, description: user.email, image:{ url: user.avatar, size:"small", }, }), onSearch:async query =>{ return users.filter(user => user.name.includes(query)); }, }); ``` -------------------------------- ### Display Object - TypeScript/JavaScript Example Source: https://interval.com/docs/io-methods/display-object Demonstrates how to use the io.display.object method to show nested data, such as an array of objects, to the action user. This method is useful for presenting structured information. ```TypeScript await io.display.object("Example object",{ data:[ { album:"Exile on Main Street", artist:"The Rolling Stones", year:1972, }, ], }); ``` ```JavaScript await io.display.object("Example object",{ data:[ { album:"Exile on Main Street", artist:"The Rolling Stones", year:1972, }, ], }); ``` -------------------------------- ### Configure Interval API Key Source: https://interval.com/docs/getting-started Set your Interval API key in the .env file to link your local project to your Interval dashboard. This key is essential for running your Interval application. ```dotenv INTERVAL_KEY= ``` -------------------------------- ### Initialize Interval SDK Source: https://interval.com/docs/security Initializes the Interval SDK with your server endpoint and API key, establishing a connection for message passing. ```javascript const path =require("path"); const{ Interval }=require("@interval/sdk"); const databaseClient =require("./db"); const interval =newInterval({ endpoint:"wss:///websocket", apiKey:"",// get an API key from the Keys page in your Interval dashboard }); interval.listen(); ``` -------------------------------- ### Shorthand Loading State (JavaScript) Source: https://interval.com/docs/writing-actions/loading Uses a shorthand syntax to start a loading state by providing only a string for the label, simplifying the process for basic loading indicators. ```JavaScript const{ Action, ctx }=require("@interval/sdk"); module.exports =newAction(async()=>{ await ctx.loading.start("This may take a while"); // ... arduous logic here }); ``` -------------------------------- ### Refund User Action with Interval SDK Source: https://interval.com/docs/getting-started This code snippet demonstrates how to create an Interval action that prompts the user for a customer's email, fetches their charges using a `getCharges` function, and then displays these charges in a table for selection. It utilizes the Interval SDK's `io.input.email` and `io.select.table` methods. ```TypeScript import{ Action, io }from"@interval/sdk"; import{ getCharges }from"./payments"; exportdefaultnewAction(async()=>{ const customerEmail =await io.input.email( "Email of the customer to refund:" ); console.log("Email:", customerEmail); const charges =awaitgetCharges(customerEmail); const chargesToRefund =await io.select.table( "Select one or more charges to refund", { data: charges, } ); }); ``` -------------------------------- ### Custom Table Column Rendering Source: https://interval.com/docs/io-methods/display-table This example shows how to define custom columns with labels, accessor keys, and renderCell callbacks for advanced formatting, including images, dates, and navigation links. ```JavaScript await io.display.table("Users",{ data:[ { email:"carsta.rocha@example.com", phone_number:"(60) 1416-4953", birthdate:"1993-08-04", first_name:"Carsta", last_name:"Rocha", image:"https://example.com/photos/21351234.jpg", website_url:"https://example.com", }, { email:"irene.morales@example.org", phone_number:"625-790-958", birthdate:"1982-04-28", first_name:"Irene", last_name:"Morales", image:"https://example.com/photos/8321527.jpg", website_url:"https://example.org", }, ], columns:[ { label:"Name", renderCell: row =>`${row.first_name}${row.last_name}`, }, { label:"Phone number", accessorKey:"phone_number", }, { label:"Photo", renderCell: row =>({ image:{ url: row.image, alt:`${row.first_name}${row.last_name} profile photo`, size:"small", }, }), }, { label:"Birth date", renderCell: row =>{ const[y, m, d]= row.birthdate.split("-").map(s =>Number(s)); const birthDate =newDate(y, m -1, d); return{ label: birthDate.toLocaleDateString(), value: birthDate, }; }, }, { label:"Website", renderCell: row =>({ label: row.website_url, url: row.website_url, }), }, { label:"Edit action", renderCell: row =>({ label:"Edit user", route:"edit_user", params:{ email: row.email, }, }), }, ], }); ``` -------------------------------- ### Custom Table Column Rendering Source: https://interval.com/docs/io-methods/select-table This example shows how to define custom columns with labels, accessor keys, and renderCell callbacks for advanced formatting, including images and formatted dates. ```JavaScript await io.select.table("Users",{ data:[ { email:"carsta.rocha@example.com", phone_number:"(60) 1416-4953", birthdate:"1993-08-04", first_name:"Carsta", last_name:"Rocha", image:"https://example.com/photos/21351234.jpg", website_url:"https://example.com", }, { email:"irene.morales@example.org", phone_number:"625-790-958", birthdate:"1982-04-28", first_name:"Irene", last_name:"Morales", image:"https://example.com/photos/8321527.jpg", website_url:"https://example.org", }, ], columns:[ { label:"Name", renderCell: row =>`${row.first_name}${row.last_name}`, }, { label:"Phone number", accessorKey:"phone_number", }, { label:"Photo", renderCell: row =>({ image:{ url: row.image, alt:`${row.first_name}${row.last_name} profile photo`, size:"small", }, }), }, { label:"Birth date", renderCell: row =>{ const[y, m, d]= row.birthdate.split("-").map(s =>Number(s)); const birthDate =newDate(y, m -1, d); return{ label: birthDate.toLocaleDateString(), value: birthDate, }; }, }, { label:"Website", renderCell: row =>({ label: row.website_url, url: row.website_url, }), }, ], }); ```