Comprehensive WebSim API and Client-Side Documentation

This documentation provides a thorough overview of the WebSim API and client-side TypeScript implementation. It is based on the following resources:

Table of Contents

  1. API Overview
  2. Key Endpoints
  3. Pagination
  4. Client-Side Implementation
  5. Key Concepts
  6. WebSim Socket
  7. Simulated APIs
  8. Error Handling
  9. Fetch Patching
  10. Best Practices
  11. Best Practices for API Usage

1. API Overview

The WebSim API provides a comprehensive set of endpoints for interacting with various aspects of the WebSim platform. It is designed to support the creation, management, and discovery of web-based content and projects.

1.1 Base URL

All API requests should be prefixed with the following base URL:

/api/v1/

1.2 Authentication

Most endpoints require authentication. While the specific authentication method is not detailed in the provided schema, it's likely to use one of the following:

Note: Ensure that you include the necessary authentication headers or cookies with your requests to authenticated endpoints.

1.3 Response Format

API responses are returned in JSON format. Successful responses typically include the requested data, while error responses include an error object with a message and potentially additional details.

1.4 Rate Limiting

While not explicitly mentioned in the schema, it's common for APIs to implement rate limiting. Be prepared to handle 429 (Too Many Requests) responses and implement appropriate backoff strategies.

2. Key Endpoints

2.1 Feed Management

Endpoint Description Parameters
GET /feed/trending Retrieve trending content range, feed, class, unseen_by
GET /users/{usernameOrId}/feed Get user-specific feed range, feed, class, unseen_by
GET /feed/search/{searchQuery} Search for content range, feed, class, unseen_by

2.2 User Management

Endpoint Description Parameters
GET /users/{usernameOrId}/following Get users followed by the specified user first, last, before, after, count
GET /users/{usernameOrId}/followers Get followers of the specified user first, last, before, after, count
GET /users/{usernameOrId} Get user details N/A

2.3 Project Management

Endpoint Description Parameters
GET /projects/{project_id} Get details of a specific project N/A
GET /users/{usernameOrId}/projects Get projects of a specific user first, last, before, after, has_site, posted, sort_by, query, liked_by_owner
GET /projects Get all projects first, last, before, after, has_site, posted, sort_by, query, liked_by_owner
GET /projects/{project_id}/descendants Get descendants of a project first, last, before, after, has_site, posted, sort_by, query, liked_by_owner

2.4 Site Management

Endpoint Description Parameters
GET /sites/{site_id} Get details of a specific site N/A
GET /users/{usernameOrId}/sites Get sites of a specific user first, last, before, after, state

2.5 Like Functionality

Endpoint Description Parameters
GET /users/{usernameOrId}/likes Get likes of a specific user first, last, before, after

3. Pagination

Many endpoints in the WebSim API support cursor-based pagination. Use the following query parameters for pagination:

Paginated responses include a meta object with the following properties:

{
  "has_next_page": boolean,
  "has_previous_page": boolean,
  "start_cursor": string,
  "end_cursor": string
}

4. Client-Side Implementation

The client-side TypeScript implementation provides a set of utilities and interfaces for interacting with the WebSim platform. This section details the key components and their functionality.

4.1 WebSim API

The window.websim object provides methods for interacting with the WebSim platform:

interface WebSimAPI {
  getUser(): Promise;
  getColorScheme(): Promise<"light" | "dark">;
  experimental: {
    v0: {
      siteId: string;
      save(htmlContent: string): Promise<{ id: string }>;
      getHTML(siteId?: string): Promise;
      generate(prompt: string, options?: GenerateOptions): Promise<{ id: string }>;
    }
  };
  internal_only_experimental: {
    getIsLiked(args: { siteId: string }): Promise;
    setIsLiked(args: { siteId: string; isLiked: boolean }): Promise;
    sendViewStartEvent(args: { siteId: string }): Promise;
    sendViewEndEvent(args: { viewUuid: string }): Promise;
  }
}

4.1.1 getUser()

Retrieves the current user's information.

4.1.2 getColorScheme()

Retrieves the current color scheme preference (light or dark).

4.1.3 experimental.v0

Provides experimental methods for site manipulation:

4.1.4 internal_only_experimental

Provides internal experimental methods:

5. Key Concepts

5.1 Sites

Sites represent individual web pages or applications created within the WebSim platform. They have the following key properties:

5.2 Projects

Projects are collections of related sites or revisions. They have the following key properties:

5.3 Feeds

Feeds provide streams of content, which can be trending items, user-specific content, or search results. The feed data typically includes:

6. WebSim Socket

The WebsimSocket class provides real-time communication capabilities, enabling collaborative features and live updates. It extends the standard WebSocket interface with additional WebSim-specific functionality.

6.1 Key Features

6.2 Usage Example

const room = new WebsimSocket();

room.onmessage = (event) => {
  const data = event.data;
  // Handle incoming messages
};

room.onPeersChanged = (peers) => {
  // Update UI with connected peers
};

room.onRecordChanged = (id) => {
  // Handle changes to shared store records
};

// Send a message
room.send({
  type: "chatMessage",
  message: "Hello, world!",
});

// Update shared store
room.store.update({
  id: "gameState",
  dependencies: { score: 100 },
  updateFunction: (currentState) => ({
    ...currentState,
    score: score
  })
});

6.3 WebSim Socket Events

WebsimSocket broadcasts 2 built-in events to all clients:

  1. connected: Triggered when a client connects to the room.
    Signature: { type: "connected", clientId: string, avatarUrl: string, username: string }
  2. disconnected: Triggered when a client disconnects from the room.
    Signature: { type: "disconnected", clientId: string, avatarUrl: string, username: string }

6.4 WebSim Socket Store

The WebsimSocket provides a shared store for managing state across all connected clients:

// Get a value from the store
const value = await room.store.get('key');

// Update a value in the store
room.store.update({
  id: 'key',
  dependencies: { newValue: 42 },
  updateFunction: (currentValue) => newValue
});

// Reset the entire store
room.store.reset();

// Get all values from the store
const allValues = await room.store.getAll();

7. Simulated APIs

WebSim provides simulated APIs that can be used within the WebSim environment. These APIs allow you to interact with the platform and create dynamic content.

7.1 SQL API

The SQL API allows you to create and interact with a simulated database within your WebSim project.

async function createMessageTable() {
  let query = `CREATE TABLE if not exists message (id INTEGER PRIMARY KEY, msg TEXT)`;
  let results = await fetch('/api/v1/sql/?' + new URLSearchParams({sql: query}));
  let data = await results.json();
  console.log(data);
}

async function insertMessage(msg) {
  let query = `INSERT INTO message (msg) VALUES ('${msg}')`;
  let results = await fetch('/api/v1/sql/?' + new URLSearchParams({sql: query}));
  let data = await results.json();
  console.log(data);
}

async function fetchMessages() {
  let query = `SELECT * FROM message ORDER BY id ASC`;
  let results = await fetch('/api/v1/sql/?' + new URLSearchParams({sql: query}));
  let data = await results.json();
  return data;
}

7.2 WebSim Global Object

The WebSim global object provides access to various platform features and user information. Here are some key functions:

// Get the current user
const user = await window.websim.getUser();

// Navigate to a different page
window.websim.navigate('/some-page');

// Show a toast notification
window.websim.toast('Hello, World!');

// Get the current project ID
const projectId = window.websim.getProjectId();

// Check if the current user is the owner of the current project
const isOwner = window.websim.isOwner();

// Get the current project's visibility
const visibility = window.websim.getVisibility();

// Get the current user's role (if applicable)
const role = window.websim.getRole();

// Check if the current user has a specific permission
const hasPermission = window.websim.hasPermission('edit_project');

// Get the current project's slug
const slug = window.websim.getSlug();

// Get the current project's version
const version = window.websim.getVersion();

8. Error Handling

The client-side implementation includes error catching for unhandled rejections and general errors. This helps in identifying and debugging issues in the application.

window.addEventListener('unhandledrejection', (event) => {
  const error = {
    type: 'unhandledRejection',
    message: event.reason?.message || 'Unknown promise rejection',
    stack: event.reason?.stack,
  };
  parentApi.reportError(error);
});

window.addEventListener('error', (event) => {
  const error = {
    type: 'error',
    message: event.message,
    stack: event.error?.stack,
  };
  parentApi.reportError(error);
});

These error handlers report errors to the parent application, allowing for centralized error tracking and analysis.

9. Fetch Patching

The implementation patches the global fetch function to handle WebSim-specific API calls and add custom headers. This patching allows for:

window.fetch = async function (a, options = {}) {
  const url = new URL(
    (a as Request)?.url ? String((a as Request).url) : String(a),
    window.location.origin
  );

  // Custom logic for WebSim API calls
  if (isWebSimApiCall(url)) {
    // Add custom headers
    options.headers = {
      ...options.headers,
      'Websim-Update': `${websimUpdateVersion}`,
    };

    // Handle request body
    if (options.body) {
      // Process body based on content type
    }

    // Make the API call using parentApi
    const response = await parentApi.fetchApi({
      url: url.toString(),
      options,
      originalOptions,
    });

    return new Response(response.body, response);
  }

  // For non-WebSim API calls, use the original fetch
  return originalFetch(url, options);
};

10. Best Practices

10.1 Error Handling

10.2 Performance

10.3 Security

10.4 Real-time Communication

10.5 API Usage

11. Best Practices for API Usage

  1. Caching: Implement caching for frequently accessed data to reduce API calls and improve performance.
  2. Rate Limiting: Be mindful of API rate limits and implement request throttling to avoid exceeding limits.
  3. Error Handling: Implement robust error handling for both API requests and simulated APIs.
  4. Pagination: Use pagination features efficiently to handle large datasets and improve load times.
  5. Security: Always use HTTPS for API requests and never expose sensitive information in client-side code.
  6. Performance: Optimize API usage by requesting only the data you need and using appropriate filters and queries.
  7. Testing: Thoroughly test your integrations, including error scenarios and edge cases.
  8. Documentation: Keep your API usage well-documented for easier maintenance and collaboration.
  9. Versioning: Be aware of API versions and update your integrations accordingly when new versions are released.
  10. Feedback: Provide feedback to the WebSim team about API functionality, bugs, or feature requests to help improve the platform.
Note: This documentation provides a comprehensive overview of the WebSim API and client-side implementation. However, as the platform evolves, new features may be added or existing ones modified. Always refer to the most up-to-date documentation and schema for the latest information.