libsql-client-ts icon indicating copy to clipboard operation
libsql-client-ts copied to clipboard

Deno example in README.md doesn't work with files

Open penberg opened this issue 1 year ago • 16 comments

The following fails with Deno:

import { createClient } from "https://esm.sh/@libsql/[email protected]/node";

const config = {
  url: "file:local.db"
};
const db = createClient(config);
const rs = await db.execute("SELECT * FROM users");
console.log(rs);
error: Uncaught Error: module "@libsql/darwin-arm64" not found
    at require (https://esm.sh/v135/[email protected]/denonext/libsql.mjs:4:178)
    at https://esm.sh/v135/[email protected]/denonext/libsql.mjs:5:1969
    at https://esm.sh/v135/[email protected]/denonext/libsql.mjs:5:452
    at https://esm.sh/v135/[email protected]/denonext/libsql.mjs:5:4899

this works, however:

import { createClient } from "npm:@libsql/client/node";

const config = {
  url: "file:local.db"
};
const db = createClient(config);
const rs = await db.execute("SELECT * FROM users");
console.log(rs);
penberg@vonneumann deno-example % vi example.ts
penberg@vonneumann deno-example % cat example.ts
//import { createClient } from "https://esm.sh/@libsql/[email protected]/node";
import { createClient } from "npm:@libsql/client/node";

const config = {
  url: "file:local.db"
};
const db = createClient(config);
const rs = await db.execute("SELECT * FROM users");
console.log(rs);

penberg avatar Nov 28 '23 20:11 penberg

I Can confirm this. For me I get the this error:

error: Uncaught (in promise) LibsqlError: URL_SCHEME_NOT_SUPPORTED: The client that uses Web standard APIs supports only "libsql:", "wss:", "ws:", "https:" and "http:" URLs, got "file:". For more information, please read https://github.com/libsql/libsql-client-ts#supported-urls

Using import { createClient } from "npm:@libsql/client/node"; works very well

patrickalima98 avatar Feb 01 '24 18:02 patrickalima98

Same thing happened to me using the Remix vite cloudflare framework and running it with node locally. libsql/client seems to think it's in the cloudflare environment.

candidia avatar Mar 16 '24 16:03 candidia

Same here any update on how you solved with Remix?

blanklob avatar Mar 23 '24 23:03 blanklob

Facing the same issue. The workaround to use npm:@libsql/client/node needs to allow ffi.

igorbrasileiro avatar May 22 '24 15:05 igorbrasileiro

Same issue and i can not use npm:@libsql/client/node due to i'm using supabase edge-runtime don't know a way to pass ffi argument

Necmttn avatar Jul 22 '24 12:07 Necmttn

The problem remains if you try to compile the app with deno --compile or deploy it to deno deploy.

alexdatsyuk avatar Sep 25 '24 12:09 alexdatsyuk

in the meantime the following is a workaround if you want to deploy to Deno Deploy

import type { Client } from 'libsql-core';

interface SqliteConfig {
  url: string;
  authToken?: string;
}

export class Sqlite {
  private client!: Client;

  constructor(private readonly config: SqliteConfig) {}

  async getClient(): Client {
    if (!this.client) {
      await this.createClient();
    }

    return this.client;
  }

  private async createClient() {
    // local db file
    if (this.isFileUrl(this.config.url)) {
      const libsqlNode = await import('libsql-node');

      this.client = libsqlNode.createClient({ url: this.config.url });
      await this.setPragma();

      return this;
    }

    // remote db
    // due to deno limitations we need to use libsql-web
    const libsqlWeb = await import('libsql-web');

    this.client = libsqlWeb.createClient({
      url: this.config.url,
      authToken: this.config.authToken,
    });

    return this;
  }

  private isFileUrl(url: string): boolean {
    return url.startsWith('file:');
  }

  private async setPragma() {
    await this.client.execute('PRAGMA journal_mode = WAL;');
    await this.client.execute('PRAGMA busy_timeout = 5000;');
    await this.client.execute('PRAGMA synchronous = NORMAL;');
    await this.client.execute('PRAGMA cache_size = 2000;');
    await this.client.execute('PRAGMA temp_store = MEMORY;');
    await this.client.execute('PRAGMA foreign_keys = true;');
  }
}

fightbulc avatar Sep 25 '24 13:09 fightbulc

This works, but only in http mode with no support for embedded replicas. The whole point of using Turso is to have embedded replicas for reads in such a simple way.

alexdatsyuk avatar Sep 25 '24 14:09 alexdatsyuk

I'm not using deno, but I'm getting the same error together with next:

 ⨯ Error [LibsqlError]: URL_SCHEME_NOT_SUPPORTED: The client that uses Web standard APIs supports only "libsql:", "wss:", "ws:", "https:" and "http:" URLs, got "file:". For more information, please read https://github.com/libsql/libsql-client-ts#supported-urls
    at <unknown> (webpack-internal:///(middleware)/./node_modules/@libsql/client/lib-esm/web.js:30)
    at _createClient (webpack-internal:///(middleware)/./node_modules/@libsql/client/lib-esm/web.js:30:15)
    at createClient (webpack-internal:///(middleware)/./node_modules/@libsql/client/lib-esm/web.js:19:12)
    at eval (webpack-internal:///(middleware)/./src/db.ts:16:76)
    at (middleware)/./src/db.ts (file://C:\dev\tmp\spaced\.next\server\src\middleware.js:1401:1)
    at __webpack_require__ (file://C:\dev\tmp\spaced\.next\server\edge-runtime-webpack.js:37:33)
    at fn (file://C:\dev\tmp\spaced\.next\server\edge-runtime-webpack.js:285:21)
    at eval (webpack-internal:///(middleware)/./src/auth.ts:8:61)
    at (middleware)/./src/auth.ts (file://C:\dev\tmp\spaced\.next\server\src\middleware.js:1390:1)
    at __webpack_require__ (file://C:\dev\tmp\spaced\.next\server\edge-runtime-webpack.js:37:33)
    at fn (file://C:\dev\tmp\spaced\.next\server\edge-runtime-webpack.js:285:21)

marpe avatar Sep 26 '24 08:09 marpe

Removing the following line: "deno": "./lib-esm/web.js" from the exports property in node_modules/@libsql/client/package.json has been my most successful workaround so far.

EDIT: When using Deno + libsql locally

JTRNS avatar Oct 19 '24 20:10 JTRNS

The following script demonstrates that the import statement import { createClient } from "@libsql/client/node"; is compatible with Deno 2.0.2.

#!/bin/bash
docker run --rm -i denoland/deno:2.0.2 sh <<\EOF
date
env
mkdir myapp
cd myapp
deno init .
deno add npm:@libsql/[email protected]
cat <<EOOF > main.ts
import { createClient } from "@libsql/client/node";
const client = createClient({
    url: "file:local.db",
});
await client.batch(
    [
        "CREATE TABLE IF NOT EXISTS users (email TEXT)",
        "INSERT INTO users VALUES ('[email protected]')",
    ],
    "write",
);
const result = await client.execute("SELECT * FROM users");
console.log("Users:", result.rows);
EOOF
echo
echo "==> test 1"
echo
deno run -A main.ts
EOF

y12studio avatar Oct 23 '24 02:10 y12studio

Working with cloudflare workers and I experience the same issue;

  • bun 1.1.31
  • @libsql/client 0.14.0
LibsqlError: URL_SCHEME_NOT_SUPPORTED: The client that uses Web standard APIs supports only "libsql:", "wss:", "ws:", "https:" and "http:" URLs, got "file:". For more information, please read https://github.com/libsql/libsql-client-ts#supported-urls

jorgechato avatar Dec 02 '24 01:12 jorgechato

It doesn't work for me T.T. These kinds of things are what make you think a lot about switching to Deno.

edard3v avatar Feb 08 '25 06:02 edard3v

opened PR #297 to facilitate our discussion.

Here's a summary of the changes:

  • Added a test for Deno to run the example script in CI.
  • Simply utilizing lib-esm/node.js instead of lib-esm/web.js to use a local file or :memory: database from Deno.

But this requires additional --allow-ffi flag since lib-esm/node.js imports createClient function from sqlite3. (which should be treated as a breaking change, I suppose)

At this point, I'm uncertain about the next steps. I considered dynamically importing createClient from sqlite3, but this approach would necessitate making the function asynchronous.

kj-9 avatar Feb 08 '25 15:02 kj-9

It doesn't work for me T.T. These kinds of things are what make you think a lot about switching to Deno.

I agree. But Deno is becoming more solid with every release. And kinks like these, will be ironed out

williamukoh avatar Feb 27 '25 10:02 williamukoh

@williamukoh I now understand that the problem is not with Deno but with Turso. I am using Neon-postgres in the meantime and it works perfectly. It is a shame because I really like Turso-sqlite.

edard3v avatar Feb 27 '25 13:02 edard3v