invertase / dart_edge

Run Dart on the Edge - supporting Vercel & Cloudflare Workers (more coming soon).
https://docs.dartedge.dev
Apache License 2.0
318 stars 22 forks source link

Error: Dart library 'dart:html' is not available on this platform. #32

Closed MichealReed closed 1 year ago

MichealReed commented 1 year ago

Error:

Error: Dart library 'dart:html' is not available on this platform.
import 'dart:html' show Blob, FormData, UrlSearchParams;
       ^
Info: The unavailable library 'dart:html' is imported through these packages:

    package:supabase_edge_functions_example => package:dart_openai => package:fetch_client => package:fetch_api => dart:html

Any edge function that references packages that nest dart:html should trigger this.

https://github.com/anasfik/openai uses https://github.com/Zekfad/fetch_client uses https://github.com/Zekfad/fetch_api

Example:

create new edge function

dart pub add fetch_api

import 'package:supabase_functions/supabase_functions.dart';
import 'package:fetch_api/fetch_api.dart' as api;

void main() {
  SupabaseFunctions(fetch: (request) {
    void main() async {
      // Simple cors request
      final response = await fetch(
        Resource('https://api.restful-api.dev/objects/1'),
      );

      print(await response.text());
    }

    return Response("Hello from Supabase Edge Functions!");
  });
}

This all makes sense in that dart_edge has created a custom fetch client, but some packages use custom fetch clients as well. I am attempted to get the dart_openai package to work, which uses conditional importing of the referenced fetch package here:

https://github.com/anasfik/openai/blob/aa42ccee89c0fef5b4102eceee11d28890d0bcdb/lib/src/core/networking/client.dart

if I remove the conditional import so that it only sees the http_client_io, the package will compile as an edge function. If the conditional import is present based on dart.library.io, or even refactoring the imports to look like this

import 'package:dart_openai/src/core/utils/http_client_io.dart'
    if (dart.library.js) 'package:dart_openai/src/core/utils/http_client_web.dart'
    if (dart.library.io) 'package:dart_openai/src/core/utils/http_client_io.dart';

I run into the error referenced above as the import takes the web path. I am not sure if this is directly a dart_edge issue, but thought I would start here as it is likely similar imports / nesting of dart:html will be found across the package ecosystem.

Ehesp commented 1 year ago

Unfortunately the Zekfad/fetch_api package is assuming the user is running on the web environment, not a JS one. I'll take a look at the openai package but I'm not sure there's much we can do.

Ehesp commented 1 year ago

Hmm, replacing this:

fetch.FetchClient createClient() =>
    fetch.FetchClient(mode: fetch.RequestMode.cors);

with

import 'package:edge_http_client/edge_http_client.dart';

http.Client createClient() => EdgeHttpClient();

Could do the trick.

MichealReed commented 1 year ago

The problem is that the code execution follows the JS path for building edge functions, if it followed the normal io path it seems your override would work. If I remove the web dependency from the lib the edge function compiles fine.

MichealReed commented 1 year ago

After forcing the import path, or modifying the package to use

import 'package:edge_http_client/edge_http_client.dart';

http.Client createClient() => EdgeHttpClient();

as suggested, I now see the same issue as in https://github.com/invertase/dart_edge/issues/34. Will close this to resolve there.