Client Libraries

Overview

Cloudillo provides a comprehensive set of TypeScript/JavaScript client libraries for building applications. These libraries handle authentication, API communication, real-time synchronization, and React integration.

Available Libraries

@cloudillo/core

Core SDK for initialization and API access. This is the foundation for all Cloudillo applications.

Key Features:

  • App initialization via message bus (getAppBus())
  • Type-safe REST API client
  • CRDT document opening
  • URL helper functions
  • Storage API for apps

Install:

pnpm add @cloudillo/core

@cloudillo/react

React hooks for Cloudillo integration.

Key Features:

  • useAuth() hook for authentication state (returns tuple)
  • useApi() hook for API client access (returns object)
  • useCloudillo() hook for microfrontend initialization
  • useCloudilloEditor() hook for CRDT editors
  • useInfiniteScroll() hook for pagination

Install:

pnpm add @cloudillo/react

@cloudillo/types

Shared TypeScript types with runtime validation using @symbion/runtype.

Key Features:

  • All data types (Profile, Action, File, etc.)
  • Runtime type validation
  • Compile-time type safety
  • Action type enums
  • Type guards and validators

Install:

pnpm add @cloudillo/types

@cloudillo/rtdb

Real-time database client with Firebase-like API.

Key Features:

  • Firebase-like API (familiar to developers)
  • Real-time subscriptions
  • Type-safe queries
  • Batch operations

Install:

pnpm add @cloudillo/rtdb

@cloudillo/canvas-tools

React components and hooks for interactive object manipulation in SVG canvas applications.

Key Features:

  • Transform gizmo with rotation, scaling, and positioning
  • Rotation and pivot handle components
  • Gradient picker with presets
  • Coordinate and geometry utilities

Install:

pnpm add @cloudillo/canvas-tools

@cloudillo/fonts

Font metadata and pairing suggestions for typography systems.

Key Features:

  • Curated metadata for 22 Google Fonts
  • Pre-defined font pairings (heading + body combinations)
  • Helper functions for filtering by category and role
  • Full TypeScript support

Install:

pnpm add @cloudillo/fonts

Quick Comparison

Library Purpose Use When
@cloudillo/core Core functionality Every app
@cloudillo/react React integration Building React apps
@cloudillo/types Type definitions TypeScript projects
@cloudillo/rtdb Real-time database Need structured real-time data
@cloudillo/canvas-tools SVG canvas manipulation Building drawing/design apps
@cloudillo/fonts Font metadata and pairings Typography selection UI

Installation

Minimal Setup (vanilla JS)

pnpm add @cloudillo/core

React Setup

pnpm add @cloudillo/core @cloudillo/react

Full Setup (with real-time features)

pnpm add @cloudillo/core @cloudillo/react @cloudillo/rtdb yjs y-websocket

Basic Usage

With @cloudillo/core

import { getAppBus, createApiClient } from '@cloudillo/core'

// Get the singleton message bus
const bus = getAppBus()

// Initialize (communicates with shell)
await bus.init('my-app')

// Access state
console.log(bus.idTag)       // User's identity
console.log(bus.accessToken) // JWT token

// Create API client
const api = createApiClient({
  idTag: bus.idTag!,
  authToken: bus.accessToken
})

// Make requests
const profile = await api.profiles.getOwn()

With @cloudillo/react

import { useCloudillo, useAuth, useApi } from '@cloudillo/react'

function App() {
  // useCloudillo handles initialization
  const { token, idTag, ownerTag, fileId } = useCloudillo('my-app')

  if (!token) return <div>Loading...</div>

  return <MyComponent />
}

function MyComponent() {
  const [auth] = useAuth()  // Returns tuple [auth, setAuth]
  const { api } = useApi()  // Returns { api, authenticated, setIdTag }

  if (!api) return <div>Loading...</div>

  // Use auth and api...
}

With @cloudillo/rtdb

import { RtdbClient } from '@cloudillo/rtdb'
import { getRtdbUrl } from '@cloudillo/core'

const rtdb = new RtdbClient({
  dbId: 'my-db-file-id',
  auth: { getToken: () => bus.accessToken },
  serverUrl: getRtdbUrl(bus.idTag!, 'my-db-file-id', bus.accessToken!)
})

await rtdb.connect()

const todos = rtdb.collection('todos')
todos.onSnapshot(snapshot => {
  console.log(snapshot.docs.map(doc => doc.data()))
})

Common Patterns

Pattern 1: Authentication Flow

import { getAppBus } from '@cloudillo/core'

// Get message bus singleton
const bus = getAppBus()

// Initialize (gets token from shell)
const state = await bus.init('my-app')

// Access auth state via bus properties
console.log(bus.idTag)       // User's identity
console.log(bus.tnId)        // Tenant ID
console.log(bus.roles)       // User roles
console.log(bus.accessToken) // JWT token
console.log(bus.access)      // 'read' or 'write'

Pattern 2: API Requests

import { getAppBus, createApiClient } from '@cloudillo/core'

const bus = getAppBus()
await bus.init('my-app')

const api = createApiClient({
  idTag: bus.idTag!,
  authToken: bus.accessToken
})

// GET requests
const profile = await api.profiles.getOwn()

// POST requests
const action = await api.actions.create({
  type: 'POST',
  content: { text: 'Hello!' }
})

// Query with parameters
const actions = await api.actions.list({
  type: 'POST',
  limit: 20
})

Pattern 3: Real-Time CRDT

import { getAppBus, openYDoc } from '@cloudillo/core'
import * as Y from 'yjs'

const bus = getAppBus()
await bus.init('my-app')

// Open CRDT document
const yDoc = new Y.Doc()
const { provider } = await openYDoc(yDoc, 'alice.cloudillo.net:doc-id')

// Use shared types
const yText = yDoc.getText('content')
yText.insert(0, 'Hello!')

// Listen for changes
yText.observe(() => {
  console.log('Text updated:', yText.toString())
})

Pattern 4: React Integration

import { useCloudillo, useApi, useAuth } from '@cloudillo/react'
import { useEffect, useState } from 'react'

function App() {
  const { token } = useCloudillo('my-app')

  if (!token) return <div>Initializing...</div>

  return <PostsList />
}

function PostsList() {
  const { api } = useApi()
  const [posts, setPosts] = useState([])

  useEffect(() => {
    if (!api) return

    api.actions.list({ type: 'POST', limit: 20 })
      .then(setPosts)
  }, [api])

  if (!api) return <div>Loading...</div>

  return (
    <div>
      {posts.map(post => (
        <div key={post.actionId}>{post.content?.text}</div>
      ))}
    </div>
  )
}

TypeScript Support

All libraries are written in TypeScript and provide full type definitions.

import type { Profile, Action, NewAction } from '@cloudillo/types'
import { createApiClient } from '@cloudillo/core'

// Types are automatically inferred
const api = createApiClient({ idTag: 'alice.cloudillo.net' })
const profile: Profile = await api.profiles.getOwn()

// Type-safe action creation
const newAction: NewAction = {
  type: 'POST',
  content: { text: 'Hello!' }
}

const created: Action = await api.actions.create(newAction)

Error Handling

API errors are thrown as standard errors with status codes:

import { createApiClient } from '@cloudillo/core'

try {
  const api = createApiClient({ idTag: 'alice.cloudillo.net' })
  const data = await api.profiles.getOwn()
} catch (error) {
  if (error instanceof Error) {
    console.error('Error:', error.message)
  }
}

Library Details

Explore each library in detail:

Next Steps