JavaScript SDK

JavaScript SDK

CrowdHandlerの待合室およびキュー管理用の公式JavaScript SDKです。Node.js環境とブラウザ環境の両方で動作します。

特長

  • 簡単な統合- 1回の関数呼び出しで、あらゆるJavaScriptアプリケーションにキュー管理機能を追加できます
  • 柔軟な導入- Node.js サーバー、ブラウザ、Lambda@Edge、Cloudflare Workers、その他のエッジランタイムで動作します
  • パフォーマンスオプション- ニーズに応じて、リアルタイムAPI検証またはローカル署名検証のいずれかを選択してください
  • キューの継続性- ページの再読み込みやセッションをまたいでも、ユーザーの位置情報を維持します
  • TypeScript サポート- 開発体験を向上させる完全な型定義
  • API アクセス- 待合室の管理、待ち行列の監視、および分析データの取得をプログラムで実行

インストール

NPM

npm install crowdhandler-sdk

CDN

<!-- Load from unpkg -->
<script src="https://unpkg.com/crowdhandler-sdk/dist/crowdhandler.umd.min.js"></script>

<!-- Or specify a version -->
<script src="https://unpkg.com/crowdhandler-sdk@2.4.0/dist/crowdhandler.umd.min.js"></script>

モジュールの形式

このSDKは、以下の形式で提供されています:

  • ESモジュール - import { init } from 'crowdhandler-sdk'
  • CommonJS - const crowdhandler = require('crowdhandler-sdk')
  • UMD - 以下の形式で提供されています window.crowdhandler scriptタグを介して読み込まれた場合
  • 動的インポート - await import('crowdhandler-sdk')

クイックスタート

Node.js / サーバーサイド

const crowdhandler = require('crowdhandler-sdk');
// or ES modules: import { init } from 'crowdhandler-sdk';

// Initialize SDK
const { client, gatekeeper } = crowdhandler.init({
  publicKey: 'YOUR_PUBLIC_KEY',
  // Optional: add privateKey for private API access
  privateKey: 'YOUR_PRIVATE_KEY',
  request: req,  // Express request object
  response: res  // Express response object
});

// Validate the request
const result = await gatekeeper.validateRequest();

// Check for errors first
if (result.error) {
  console.error(`Validation error: ${result.error.message}`);
  // 4xx errors: promoted = false (always block access)
  // 5xx errors: promoted depends on trustOnFail setting
}

// Handle the validation result
if (result.setCookie) {
  gatekeeper.setCookie(result.cookieValue, result.domain);
}

if (result.stripParams) {
  return gatekeeper.redirectToCleanUrl(result.targetURL);
}

if (!result.promoted) {
  return gatekeeper.redirectIfNotPromoted();
}

// User is promoted - continue with your application
// ... your protected content here ...

// Record performance (optional but recommended)
await gatekeeper.recordPerformance();

ブラウザ/クライアントサイド

// Using script tag
const { client, gatekeeper } = window.crowdhandler.init({
  publicKey: 'YOUR_PUBLIC_KEY',
  options: {
    mode: 'clientside'
  }
});

// Or using ES Modules
import { init } from 'crowdhandler-sdk';
const { client, gatekeeper } = init({
  publicKey: 'YOUR_PUBLIC_KEY',
  options: {
    mode: 'clientside'
  }
});

// Validate the request
const result = await gatekeeper.validateRequest();

// Handle the validation result
if (result.setCookie) {
  gatekeeper.setCookie(result.cookieValue, result.domain);
}

if (result.stripParams) {
  // Redirect to clean URL
  window.location.href = result.targetURL;
  return;
}

if (!result.promoted) {
  // Redirect to waiting room
  gatekeeper.redirectIfNotPromoted();
  return;
}

// User is promoted - your application continues
console.log('User granted access');

// Record performance (optional but recommended)
await gatekeeper.recordPerformance();

Cloudflare Workers

import { init } from 'crowdhandler-sdk';

export default {
  async fetch(request, env, ctx) {
    const { gatekeeper } = init({
      publicKey: env.CROWDHANDLER_PUBLIC_KEY,
      cloudflareWorkersRequest: request
    });

    const result = await gatekeeper.validateRequest();

    // Workers have no mutable response object — build the outgoing
    // Response yourself using values from the result.
    if (!result.promoted) {
      return new Response(null, {
        status: 302,
        headers: { Location: result.targetURL }
      });
    }

    const originResponse = await fetch(request);
    const response = new Response(originResponse.body, originResponse);

    if (result.setCookie) {
      response.headers.append(
        'set-cookie',
        `crowdhandler=${result.cookieValue}; path=/; Secure`
      );
    }

    ctx.waitUntil(gatekeeper.recordPerformance());
    return response;
  }
};

主要な手法

gatekeeper.validateRequest(params?)

CrowdHandlerのキューシステムに対してリクエストを検証するための主要なメソッドです。このメソッドは、ユーザーに対して保護されたリソースへのアクセスを許可するか、待機室に送るかを決定します。

// Basic usage
const result = await gatekeeper.validateRequest();

// With custom parameters
const result = await gatekeeper.validateRequest({
  custom: {
    code: 'ABC123',
    captcha: 'xK9mN2pQ5vL8wR3tY6uZ1aS4dF7gH0j'
  }
});

パラメータ:

  • パラメータ (任意) - カスタムパラメータを含むオブジェクト
    • カスタム - CrowdHandler API に送信する任意のキーと値のペアを含むオブジェクト

仕組み:

  1. トークンの確認:まず、Cookie内に既存のCrowdHandlerセッショントークンが存在するかを確認します
  2. APIの検証:トークンを(または新しいトークンを生成して)CrowdHandlerのAPIに送信します。この際、カスタムパラメータも含まれます。
  3. キューの位置:現在の収容能力に基づいて、ユーザーが優先されるかどうかを決定します
  4. 応答:リクエストの処理方法に関する指示を返します

戻り値:

{
  promoted: boolean,      // true = grant access, false = send to waiting room
  setCookie: boolean,     // true = update the user's session cookie
  cookieValue: string,    // The session token to store in the cookie
  stripParams: boolean,   // true = remove CrowdHandler URL parameters
  targetURL: string,      // Where to redirect (clean URL or waiting room)
  slug: string,           // The waiting room slug (when not promoted)
  responseID: string,     // Response ID for performance tracking (when promoted)
  deployment: string,     // Deployment identifier from the API
  token: string,          // The session token
  hash: string | null,    // Signature hash for validation (when available)
  requested: string,      // Timestamp when the request was made
  liteValidatorRedirect: boolean,  // true = redirect to lite validator
  liteValidatorUrl: string         // URL for lite validator redirect
}

モードごとの挙動:

  • フルモード(デフォルト):すべてのリクエストに対してAPI呼び出しを行い、リアルタイムで検証を行います
  • ハイブリッドモード:昇格されたユーザーに対してローカルで署名を検証し、API呼び出し回数を削減します
  • クライアントサイドモード:クッキーを使用して、ブラウザ内で完全に検証を行います

エラー処理:

try {
  const result = await gatekeeper.validateRequest();
  // ... handle result ...
} catch (error) {
  console.error('Validation failed:', error.message);
  console.error('Status code:', error.statusCode);
  // Handle based on trustOnFail setting
}

gatekeeper.setCookie(value, domain?)

CrowdHandlerのセッションクッキーを設定します。以下の場合は必ずこれを呼び出してください。 result.setCookie これは、ユーザーのキュー内の順位を維持するために有効です。オプションの ドメイン パラメータ(以下に指定された) result.domain) これにより、ワイルドカードドメインに対して適切なクッキーのスコープ設定が可能になります。

if (result.setCookie) {
  gatekeeper.setCookie(result.cookieValue, result.domain);
}

gatekeeper.redirectToCleanUrl(url)

URLからCrowdHandlerのトラッキングパラメータを削除します。以下の場合に使用してください。 result.stripParams URLをすっきりさせるには、これが有効です。

if (result.stripParams) {
  return gatekeeper.redirectToCleanUrl(result.targetURL);
}

gatekeeper.redirectIfNotPromoted()

プロモーション対象外のユーザーに対するリダイレクトの流れをすべて処理する便利な方法です。クッキーの管理とリダイレクトを自動的に行います。

if (!result.promoted) {
  return gatekeeper.redirectIfNotPromoted();
}

gatekeeper.redirectIfPromoted()

待機室の実装において、昇格されたユーザーを、新しいCrowdHandlerパラメータを使用してターゲットサイトへリダイレクトします。この方法は、待機室の実装でのみ使用することを想定しています。

// In waiting room implementation
if (result.promoted) {
  return gatekeeper.redirectIfPromoted();
}

ユースケース:自社のインフラ上で動作するカスタム待合室を構築する場合、このメソッドは、適切なCrowdHandlerパラメータを指定して、保護されたリソースへのリダイレクトを処理します。

gatekeeper.recordPerformance(options?)

パフォーマンス指標を記録し、CrowdHandlerがキューの処理フローと処理能力を最適化できるよう支援します。

// Simple usage (recommended)
await gatekeeper.recordPerformance();

// With custom options
await gatekeeper.recordPerformance({
  sample: 1,             // Record 100% of requests (default 0.2)
  statusCode: 200,       // HTTP status code (default 200)
  overrideElapsed: 1234, // Custom timing in ms
  timeout: 1500          // Per-call API timeout in ms (default 1500)
});

gatekeeper.overrideWaitingRoomUrl(url)

デフォルトのCrowdHandler待機室を、ユーザー指定のURLに上書きします。

// Redirect to your custom queue page
gatekeeper.overrideWaitingRoomUrl('https://mysite.com/custom-queue');

設定

初期化オプション

const instance = crowdhandler.init({
  // Required
  publicKey: 'YOUR_PUBLIC_KEY',
  
  // Optional
  privateKey: 'YOUR_PRIVATE_KEY',  // Required for private API methods
  
  // Request context (choose one based on your environment)
  request: req,                       // Express/Node.js request
  response: res,                      // Express/Node.js response
  lambdaEdgeEvent: event,             // Lambda@Edge event
  cloudflareWorkersRequest: request,  // Cloudflare Workers Request
  // (none)                           // Browser environment (auto-detected)
  
  // Options
  options: {
    mode: 'full',         // 'full' (default), 'hybrid', 'clientside'
    apiUrl: 'https://api.crowdhandler.com',  // Custom API endpoint
    debug: false,         // Enable debug logging
    timeout: 5000,        // API timeout in milliseconds
    trustOnFail: true,    // Allow access if API fails
    fallbackSlug: '',     // Fallback room slug when trustOnFail is false
    cookieName: 'crowdhandler',  // Custom cookie name (default: 'crowdhandler')
    cookieMaxAgeSeconds: 86400,  // Optional. Persist the cookie via Max-Age (seconds).
                                 // Omit for a session cookie (default).
    forceCloudflareWorkers: true,  // Optional. Bypass navigator-based runtime inference
                                   // and treat the runtime as Cloudflare Workers. Only `true`
                                   // is accepted; omit for auto-detection.
    waitingRoom: false,   // Set to true if SDK is running in a waiting room context
    liteValidator: false, // Enable lite validator mode (default: false)
    roomsConfig: [{       // Array of room configurations for lite validator
      domain: string,     // e.g. 'https://example.com'
      slug: string,       // Room identifier
      urlPattern?: string,  // URL pattern to match
      patternType?: 'regex' | 'contains' | 'all',
      queueActivatesOn?: number,  // Unix timestamp
      timeout?: number    // Timeout in seconds
    }]
  }
});

検証モード

フルモード(デフォルト)

ほとんどのサーバーサイド統合に最適です。

  • メリット:セットアップが簡単、秘密鍵が不要、機能が充実している
  • デメリット:リクエストごとにAPI呼び出しが発生する(20~100msの遅延)

ハイブリッドモード

パフォーマンスが重要なアプリケーション向け。

  • メリット:レイテンシが最小限(2~10ms)、API呼び出し回数が少ない
  • デメリット:秘密鍵が必要、補助機能にはクライアントサイドのJavaScriptが必要
const instance = crowdhandler.init({
  publicKey: 'YOUR_PUBLIC_KEY',
  privateKey: 'YOUR_PRIVATE_KEY',  // Required for hybrid mode
  options: { mode: 'hybrid' }
});

クライアントサイドモード

シングルページアプリケーションおよび静的サイト向け。

  • メリット:サーバー不要で動作する、統合が容易
  • デメリット:クライアントサイドのみ、JavaScriptが必要

カスタムクッキー名

デフォルトでは、CrowdHandler は 群衆誘導員 をクッキー名として設定します。これをカスタム名で上書きすることも可能です:

const { gatekeeper } = crowdhandler.init({
  publicKey: 'YOUR_PUBLIC_KEY',
  options: {
    cookieName: 'my-custom-queue'  // Use custom cookie name
  }
});

次のような場合に便利です:

  • 同じドメイン上で複数のCrowdHandlerインスタンスを実行する
  • 既存のクッキーとの競合を避ける
  • 特定の命名規則に従う

クッキーの有効期間

デフォルトでは、CrowdHandlerのクッキーは セッションクッキー — ユーザーがブラウザを完全に終了すると、ブラウザはこれを破棄します(注:「前回の続きから再開」機能が有効になっている場合、多くのブラウザではセッション Cookie が復元されます)。待機室のようなユースケースで、ブラウザの再起動後も待ち行列に並んでいるユーザーの順位を維持したい場合は、以下の設定で永続化を有効にしてください。 cookieMaxAgeSeconds:

const { gatekeeper } = crowdhandler.init({
  publicKey: 'YOUR_PUBLIC_KEY',
  options: {
    cookieMaxAgeSeconds: 86400  // Persist for 24 hours via Max-Age
  }
});

注記:

  • その値は、クッキーの Max-Age 属性(以下よりも推奨される) 有効期限 (クライアントのクロックスキューの影響を受けないため)。
  • このオプションは、ユーザーが待機中である場合とプロモーション後の両方で、SDKが発行するすべてのSet-Cookieに適用されます。
  • そのオプションを省略する(またはそのままにしておく) 未定義) これにより、セッション Cookie の本来の動作を維持します。

Cloudflare Workers のランタイムを強制する

SDKは、以下の情報からCloudflare Workersのランタイムを推測します。 navigator.userAgent. もしお使いの環境(カスタムWorkerのビルド、グローバル変数を削除するバンドラー、テストハネスなど)においてそのシグナルが信頼できない場合は、その判断を明示的に行うことができます:

const { gatekeeper } = crowdhandler.init({
  publicKey: env.CROWDHANDLER_PUBLIC_KEY,
  cloudflareWorkersRequest: request,
  options: {
    forceCloudflareWorkers: true
  }
});

ただ true が指定されている場合、このオプションを省略すると自動検出に切り替わります。 debug: true, SDKは、その決定の要因となったシグナルをログに記録します。例えば、 [CH] Cloudflare Workers ランタイム: true(オーバーライドによる) vs (ナビゲーター推論による). オーバーライドは、毎回リセットされます。 init() 再初期化の際にも値が漏れないように呼び出します。

APIクライアント

このSDKは、パブリックAPIとプライベートAPIの両方に対応した統一されたクライアントを提供します:

// List all waiting rooms
const rooms = await client.rooms().get();

// Get specific room
const room = await client.rooms().get('room_id');

// Create a new room (requires privateKey)
const newRoom = await client.rooms().post({
  name: 'Product Launch',
  domain: 'example.com'
});

// Update room settings
await client.rooms().put('room_id', {
  capacity: 1000
});

// Delete a room
await client.rooms().delete('room_id');

利用可能なリソース

公開API(公開鍵のみ):

  • client.requests() - 検証をリクエストする
  • client.responses() - 応答の追跡
  • client.rooms() - 待合室に関する情報

プライベートAPI(privateKeyが必要):

  • client.account() - アカウント情報
  • client.accountPlan() - アカウントプランの詳細
  • client.codes() - アクセスコードの管理
  • client.domains() - ドメインの設定
  • client.domainIPs() - ドメインのIPアドレス
  • client.domainReports() - ドメイン分析
  • client.domainRequests() - ドメインリクエストログ
  • client.domainRooms() - ドメインごとのルーム
  • client.domainURLs() - 保護されたURL
  • client.groups() - アクセスコードグループ
  • client.groupBatch() - ロットコードの処理
  • client.groupCodes() - グループ内のコード
  • client.ips() - IPアドレスの管理
  • client.reports() - 分析レポート
  • client.rooms() - 待合室の管理
  • client.roomReports() - 部屋の分析
  • client.roomSessions() - 現在開催中のルームセッション
  • client.sessions() - セッション管理
  • client.templates() - 待合室のテンプレート

すべてのメソッドは、該当する場合、標準的なREST操作に対応しています:

  • .get() - すべての一覧を表示するか、ID 指定で特定のリソースを取得する
  • .post(data) - 新しいリソースを作成する
  • .put(id, data) - 既存のリソースを更新する
  • .patch(id, data) - 部分的な更新
  • .delete(id) - リソースを削除する

リクエスト/レスポンスの例を含むAPIの完全なドキュメントは、CrowdHandlerダッシュボードの「アカウント」→「API」からご覧いただけます。

エラー処理

すべてのSDKエラーは、以下のいずれかに該当します。 CrowdHandlerError 一貫した構成で:

try {
  const rooms = await client.rooms().get();
} catch (error) {
  console.error(error.message);    // The actual API error message
  console.error(error.statusCode); // HTTP status code (e.g., 401, 404)
  console.error(error.suggestion); // Helpful guidance for resolution
  console.error(error.code);       // Error code for programmatic handling
}

APIエラーの透明性

このSDKは、CrowdHandler APIのエラーメッセージをそのまま保持しているため、特定のエラーシナリオに対処することができます:

try {
  const result = await gatekeeper.validateRequest({
    custom: { code: 'user-code' }
  });
} catch (error) {
  // Check the specific error message from the API
  if (error.message.includes('Invalid priority code')) {
    // Handle invalid access code
  }
  
  // For advanced debugging, access the full API response
  const apiResponse = error.context?.apiResponse;
}

よくあるエラーコード

  • INVALID_CONFIG - SDKの設定が不正です
  • MISSING_PRIVATE_KEY - この操作には秘密鍵が必要です
  • API_CONNECTION_FAILED - CrowdHandler API に接続できません
  • API_INVALID_RESPONSE - APIからエラーが返されました
  • RATE_LIMITED - リクエストが多すぎます(retry-after を含む)

統合事例

「examples」ディレクトリには、以下のような完全な動作例が含まれています。

  • Express.js の実装(完全保護、API のみ、プライベート API)
  • Lambda@Edge ハンドラー
  • Reactとの連携
  • エラー処理のパターン
  • TypeScript の使用方法

Express.js

const express = require('express');
const crowdhandler = require('crowdhandler-sdk');

const app = express();

// Middleware to protect routes
async function protectRoute(req, res, next) {
  try {
    const { gatekeeper } = crowdhandler.init({
      publicKey: process.env.CROWDHANDLER_PUBLIC_KEY,
      request: req,
      response: res
    });

    const result = await gatekeeper.validateRequest();
    
    // Check if there was an error during validation
    if (result.error) {
      console.error(`API Error ${result.error.statusCode}: ${result.error.message}`);
      // 4xx errors (e.g., invalid key, bad request): promoted = false (user blocked)
      // 5xx errors (e.g., server error): promoted based on trustOnFail setting
    }
    
    if (result.setCookie) {
      gatekeeper.setCookie(result.cookieValue, result.domain);
    }
    
    if (result.stripParams) {
      return gatekeeper.redirectToCleanUrl(result.targetURL);
    }
    
    if (!result.promoted) {
      return gatekeeper.redirectIfNotPromoted();
    }
    
    // User is promoted, continue
    res.locals.gatekeeper = gatekeeper;
    next();
  } catch (error) {
    // This catches unexpected errors (e.g., network issues, config errors)
    console.error('CrowdHandler SDK error:', error.message);
    // trustOnFail: true (default) = allow access on error
    // trustOnFail: false = block access on error
    next();
  }
}

// Protect specific routes
app.get('/limited-product', protectRoute, (req, res) => {
  res.send('This is a limited product page!');
  
  // Record performance after response
  if (res.locals.gatekeeper) {
    res.locals.gatekeeper.recordPerformance();
  }
});

Lambda@Edge

const crowdhandler = require('crowdhandler-sdk');

exports.handler = async (event) => {
  const { gatekeeper } = crowdhandler.init({
    publicKey: process.env.CROWDHANDLER_PUBLIC_KEY,
    lambdaEdgeEvent: event
  });

  const result = await gatekeeper.validateRequest();
  
  if (!result.promoted) {
    // Redirect to waiting room
    return {
      status: '302',
      statusDescription: 'Found',
      headers: {
        location: [{
          key: 'Location',
          value: result.targetURL
        }]
      }
    };
  }
  
  // Continue with normal request processing
  return event.Records[0].cf.request;
};

Cloudflare Workers

このSDKには、Cloudflare Workers(workerd)ランタイムのネイティブサポートが組み込まれており、Nodeのポリフィルは必要ありません。Workersを渡す リクエスト オブジェクトを介して cloudflareWorkersRequest また、このSDKではネイティブを使用しています フェッチ すべてのAPI呼び出しについて、内部的に。

import { init } from 'crowdhandler-sdk';

export default {
  async fetch(request, env, ctx) {
    const { gatekeeper } = init({
      publicKey: env.CROWDHANDLER_PUBLIC_KEY,
      cloudflareWorkersRequest: request
    });

    const result = await gatekeeper.validateRequest();

    if (result.error) {
      console.error(`API Error ${result.error.statusCode}: ${result.error.message}`);
    }

    // Strip CrowdHandler params from a freshly promoted URL
    if (result.stripParams) {
      return new Response(null, {
        status: 302,
        headers: {
          Location: decodeURIComponent(result.targetURL),
          'Set-Cookie': `crowdhandler=${result.cookieValue}; path=/; Secure`
        }
      });
    }

    // Send unpromoted users to the waiting room
    if (!result.promoted) {
      return new Response(null, {
        status: 302,
        headers: { Location: result.targetURL }
      });
    }

    // Promoted: fetch the origin and attach the session cookie if needed
    const originResponse = await fetch(request);
    const response = new Response(originResponse.body, originResponse);

    if (result.setCookie) {
      response.headers.append(
        'set-cookie',
        `crowdhandler=${result.cookieValue}; path=/; Secure`
      );
    }

    // Performance recording continues after the response is returned
    ctx.waitUntil(gatekeeper.recordPerformance());
    return response;
  }
};

Workers 対 Express/Lambda — 違いは何か:

  • Workers には変更可能なレスポンスオブジェクトがありません。送信用を構築してください。 回答 以下の値を使用して、ご自身で 結果 (cookieValue, targetURL, setCookie) レスポンスそのものを変更してしまうヘルパーメソッドに頼るのではなく。
  • 使用方法 ctx.waitUntil() ~のために recordPerformance() これにより、メトリクスへの呼び出しによってユーザーの応答が遅延することはありません。Workers上では、SDKは内部で基盤となるAPI呼び出しを待機します(つまり、実際には内部でフラッシュが行われます)。 ctx.waitUntil); デフォルトでは、putの最大値は1500msに制限されています — 合格 { timeout: <ms> } 調整する。
  • デフォルト mode: 'full' (上記で使用されている)方式では、公開鍵のみが必要です。ハイブリッドモードもサポートされていますが、この場合は秘密鍵をWorkerシークレットとして送信する必要があります。この方法を選択するのは、そのメリットとデメリットを十分に検討した上でにしてください。

React / Next.js

import { useEffect, useState } from 'react';
import { init } from 'crowdhandler-sdk';

function ProtectedComponent() {
  const [isPromoted, setIsPromoted] = useState(null);
  
  useEffect(() => {
    const checkAccess = async () => {
      const { gatekeeper } = init({
        publicKey: 'YOUR_PUBLIC_KEY',
        options: { mode: 'clientside' }
      });
      
      const result = await gatekeeper.validateRequest();
      
      if (!result.promoted) {
        window.location.href = result.targetURL;
      } else {
        setIsPromoted(true);
      }
    };
    
    checkAccess();
  }, []);
  
  if (isPromoted === null) return <div>Checking access...</div>;
  if (!isPromoted) return <div>Redirecting to waiting room...</div>;
  
  return <div>Protected content here!</div>;
}

高度な機能

待合室のURLを上書きする

gatekeeper.overrideWaitingRoomUrl('https://custom-wait.example.com');

カスタム無視パターン

// Don't check these paths
gatekeeper.setIgnoreUrls(/\.(css|js|png|jpg)$/);

上書きリクエストの詳細

gatekeeper.overrideHost('example.com');
gatekeeper.overridePath('/special-path');
gatekeeper.overrideIP('203.0.113.0');
gatekeeper.overrideLang('en-US');
gatekeeper.overrideUserAgent('Custom Bot 1.0');

パフォーマンスの記録

// Basic usage (records automatically)
await gatekeeper.recordPerformance();

// With options
await gatekeeper.recordPerformance({
  sample: 1.0,           // Record 100% of requests (default 0.2)
  statusCode: 200,       // HTTP status code
  overrideElapsed: 1234, // Custom timing in ms
  timeout: 1500          // Per-call API timeout in ms (default 1500, overrides global SDK timeout)
});

テストエラーのシミュレーション

実際のAPI呼び出しを行わずにエラー処理をテストするには、エラーをシミュレートすることができます:

const { gatekeeper } = init({
  publicKey: 'YOUR_PUBLIC_KEY',
  request: req,
  response: res,
  options: {
    testError: {
      statusCode: 500,  // Simulate a 500 error
      message: 'Simulated server error for testing'
    }
  }
});

// This will return immediately with a simulated error
const result = await gatekeeper.validateRequest();
// result.error will contain the test error
// result.promoted will be true (with default trustOnFail: true)

これは次のような場合に役立ちます:

  • 開発段階におけるエラー処理ロジックのテスト
  • さまざまなエラータイプに対するフォールバック動作の確認
  • 本番環境のメトリクスに影響を与えない統合テスト

注:4xxのテストエラーは常に設定されます promoted: false, 一方、5xxのテストエラーはあなたの trustOnFail 設定。

ライトバリデータモード

Lite バリデータモードでは、API を呼び出すことなく、ローカルでルームの設定を確認することでトークンの更新を行います。これを有効にするには:

  1. セット liteValidator: true [オプション] 内で
  2. CrowdHandler API からルームの設定情報を取得して提供します
// First, fetch your rooms configuration
const { client } = init({ publicKey: 'YOUR_PUBLIC_KEY' });
const roomsResponse = await client.rooms().get();

// Then initialize with lite validator enabled
const { gatekeeper } = init({
  publicKey: 'YOUR_PUBLIC_KEY',
  request: req,
  response: res,
  options: {
    liteValidator: true,              // Enable lite validator
    roomsConfig: roomsResponse.result // Pass the rooms array from API
  }
});

// Handle the lite validator redirect
const result = await gatekeeper.validateRequest();

if (result.liteValidatorRedirect) {
  // Redirect to refresh token/session
  return gatekeeper.redirect(result.liteValidatorUrl);
}

Lite Validator が起動したとき:

  • URLが設定ファイル内のルームと一致しています
  • トークンが見つからないか、12時間以上経過しています
  • セッションを更新するためにCrowdHandlerへリダイレクトします

テスト

このSDKには、包括的なテストツールが含まれています:

ローカルテストサーバー

# 自分の鍵を使用してテストサーバーを起動する
npm run test:server -- --publicKey=YOUR_KEY --privateKey=YOUR_PRIVATE_KEY

# カスタムオプションを指定して実行
npm run test:server -- --apiUrl=https://staging-api.crowdhandler.com --mode=hybrid

# 開発モード(SDKを自動再構築)
npm run test:server:dev

ブラウザのテストページ

  1. テストサーバーを起動する
  2. http://localhost:3000/test/browser-test.htmlを開く
  3. 実際のAPI連携を用いた対話型テスト

テストクライアント

# テストサーバーに対して自動テストを実行する
npm run test:client

TypeScript のサポート

型定義を含む、TypeScriptの完全なサポート:

import { init, CrowdHandlerError, ErrorCodes } from 'crowdhandler-sdk';
import type { Mode, Room, Domain, ValidationResult } from 'crowdhandler-sdk';

// All types are properly inferred
const { client, gatekeeper } = init({
  publicKey: 'YOUR_KEY'
});

// TypeScript knows this returns Room[]
const rooms = await client.rooms().get();

// Error handling with types
try {
  await client.domains().get();
} catch (error) {
  if (error instanceof CrowdHandlerError) {
    if (error.code === ErrorCodes.MISSING_PRIVATE_KEY) {
      // Handle missing key
    }
  }
}

ビルド情報

このSDKは、以下の複数の形式で提供されています:

  • CommonJS (dist/crowdhandler.cjs.js) - Node.js用 require()
  • ESモジュール (dist/crowdhandler.esm.js) - 現代の インポート
  • UMD (dist/crowdhandler.umd.js) - ブラウザ経由の場合は <script>
  • UMD ミニファイド (dist/crowdhandler.umd.min.js) - 開発用ブラウザビルド