typesense / typesense/typesense-js

Axios is not supported on Edge Runtime

Open
#161 13 comments 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
569
Forks
99
Avg merge
5h 6m
Merged PRs (30d)
2

Description

Description

As described in this ticket, Axios is not supported (and I don't think it will in any time near future) and you cannot use this library on an Serverless edge functions for example like Vercel, AWS etc. (or any service worker like Cloudflare)

https://github.com/axios/axios/issues/5523

https://vercel.com/guides/library-sdk-compatible-with-vercel-edge-runtime-and-functions#library-recommendations

Steps to reproduce

  • Spin up a new NextJS app, create a new api endpoint using edge runtime. It will fail.
import typeSenseService from "@/services/typesense/typesense";
import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";

export const config = {
  runtime: "edge",
};

export default async function handler(req: NextRequest) {
  if (req.method !== "POST") {
    return NextResponse.json({ error: "no" }, { status: 500 });
  }

  try {
    const { searchParams } = new URL(req?.url ?? "");
    const term = searchParams.get("term") as string;

    console.log(term);

   // Just a simple typesense search here
    const data = typeSenseService.search("index_name", term);

    return NextResponse.json({ result: data });
  } catch (e: any) {
    console.log(e);
    return NextResponse.json({ error: "no" }, { status: 500 });
  }

Expected Behavior

  • It should work if you move to fetch, or create more agnostic way to pass the httpClient. Example below:


export interface Fetch {
  (url: string, init?: RequestInit): Promise<Response>
}

export interface RequestInit {
  headers?: any
  method?: string
  body?: string
  redirect?: string
}

export interface Response {
  headers: Headers
  ok: boolean
  status: number
  statusText: string
  text: () => Promise<string>
  json: () => Promise<any>
}

export interface CallInfo extends RequestInit {
  name: string
  type: string
  url: string
  status: number
  statusText: string
  error?: Error
}

export interface FetcherOptions {
  record?: (info: CallInfo, data: string | Blob | ArrayBuffer | any) => Promise<void>
}

export interface Fetcher {
  (name: string, url: string, init?: RequestInit, childId?: string): Promise<Response>
}

export interface Recorder {
  (info: CallInfo, data: string | Blob | ArrayBuffer | any): Promise<void>
}

const record = async (
  name: string,
  url: string,
  init: RequestInit | undefined,
  type: string,
  options: FetcherOptions,
  response: Response,
  data: string | ArrayBuffer | Blob | any
): Promise<void> => {
  if (!options.record) {
    return
  }
  const info: CallInfo = {
    ...(init || {}),
    name,
    url,
    type,
    status: response.status,
    statusText: response.statusText
  }
  await options.record(info, data)
}

export default function wrap(fetch: Fetch, options: FetcherOptions = {}): Fetcher {
  return async (name: string, url: string, config: RequestInit = { headers: {} }): Promise<Response> => {
    const response = await fetch(url, config)

    const wrapMethod = (res: Response, methodName: string): void => {
      // @ts-ignore
      const original = res[methodName].bind(res)
      // @ts-ignore
      res[methodName] = async (...args) => {
        const result = await original(...args)
        await record(name, url, config, methodName, options, response, result)
        return result
      }
    }
    wrapMethod(response, 'json')
    wrapMethod(response, 'text')

    return response
  }
}


// Usage

const httpClient = wrap(axios, options)
const httpClient = wrap(fetch, options)

const ticketResponse = httpClient('unique-endpoint', '/api/tickets', {
  method: 'POST'
})

Actual Behavior

it... should work :D

Metadata

Typesense Version: 1.5.4

OS: Mac OS X

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the failure in a Next.js API endpoint configured for the Edge Runtime, then inspect how the Typesense client performs HTTP requests through the typeSenseService example. Compare the client’s current request path with the proposed fetch-based interface; done means the same search works in an edge function without relying on unsupported Axios behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
nextjs, typescript
Domain
api, backend, cloud
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.