tursodatabase / libsql-client-ts

TypeScript/JavaScript client API for libSQL
https://docs.turso.tech/sdk/ts/quickstart
MIT License
287 stars 37 forks source link

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

Open penberg opened 11 months ago

penberg commented 11 months ago

The following fails with Deno:

import { createClient } from "https://esm.sh/@libsql/client@0.4.0-pre.2/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/libsql@0.2.0-pre.2/denonext/libsql.mjs:4:178)
    at https://esm.sh/v135/libsql@0.2.0-pre.2/denonext/libsql.mjs:5:1969
    at https://esm.sh/v135/libsql@0.2.0-pre.2/denonext/libsql.mjs:5:452
    at https://esm.sh/v135/libsql@0.2.0-pre.2/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/client@0.4.0-pre.2/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);
patrickalima98 commented 9 months ago

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

bitofbreeze commented 8 months ago

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.

blanklob commented 8 months ago

Same here any update on how you solved with Remix?

igorbrasileiro commented 6 months ago

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

Necmttn commented 3 months ago

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

alexdatsyuk commented 1 month ago

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

fightbulc commented 1 month ago

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;');
  }
}
alexdatsyuk commented 1 month ago

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.

marpe commented 1 month ago

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)
JTRNS commented 1 month ago

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

y12studio commented 3 weeks ago

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/client@0.14.0
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 ('first@example.com')",
    ],
    "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