@farcaster/snap-turso 0.0.0-canary-20260404123848

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,8 @@
1
+ import { type SnapFunction } from "@farcaster/snap";
2
+ /** Reserved for future options (e.g. custom table name). */
3
+ export type WithTursoServerlessOptions = Record<string, never>;
4
+ /**
5
+ * Wraps a SnapFunction and injects a Turso serverless-backed data store into the
6
+ * context.
7
+ */
8
+ export declare function withTursoServerless(snapFn: SnapFunction, _options?: WithTursoServerlessOptions): SnapFunction;
package/dist/index.js ADDED
@@ -0,0 +1,45 @@
1
+ import { connect } from "@tursodatabase/serverless";
2
+ const TABLE_SQL = `CREATE TABLE IF NOT EXISTS snap_kv (key TEXT PRIMARY KEY, value TEXT NOT NULL)`;
3
+ /**
4
+ * Wraps a SnapFunction and injects a Turso serverless-backed data store into the
5
+ * context.
6
+ */
7
+ export function withTursoServerless(snapFn, _options) {
8
+ const url = process.env.TURSO_DATABASE_URL;
9
+ const authToken = process.env.TURSO_AUTH_TOKEN;
10
+ if (!url || !authToken) {
11
+ console.warn("missing env vars -- skipping Turso data store setup");
12
+ return snapFn;
13
+ }
14
+ const conn = connect({ url, authToken });
15
+ let ensureTablePromise;
16
+ const ensureTable = async () => {
17
+ if (!ensureTablePromise) {
18
+ ensureTablePromise = conn.execute(TABLE_SQL).then(() => undefined);
19
+ }
20
+ await ensureTablePromise;
21
+ };
22
+ const store = {
23
+ async get(key) {
24
+ await ensureTable();
25
+ const stmt = await conn.prepare("SELECT value FROM snap_kv WHERE key = ?");
26
+ const row = await stmt.get([key]);
27
+ if (row == null) {
28
+ return null;
29
+ }
30
+ const text = typeof row === "object" &&
31
+ row !== null &&
32
+ "value" in row &&
33
+ typeof row.value === "string"
34
+ ? row.value
35
+ : String(row);
36
+ return JSON.parse(text);
37
+ },
38
+ async set(key, value) {
39
+ await ensureTable();
40
+ const stmt = await conn.prepare("INSERT OR REPLACE INTO snap_kv (key, value) VALUES (?, ?)");
41
+ await stmt.run([key, JSON.stringify(value)]);
42
+ },
43
+ };
44
+ return (ctx) => snapFn({ ...ctx, data: store });
45
+ }
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@farcaster/snap-turso",
3
+ "version": "0.0.0-canary-20260404123848",
4
+ "description": "Turso data store adapter for Farcaster Snaps",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/farcasterxyz/snap.git",
8
+ "directory": "pkgs/turso"
9
+ },
10
+ "type": "module",
11
+ "main": "dist/index.js",
12
+ "types": "dist/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js",
17
+ "default": "./dist/index.js"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "src"
23
+ ],
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "license": "MIT",
28
+ "dependencies": {
29
+ "@tursodatabase/serverless": "^0.2.0",
30
+ "@farcaster/snap": "0.0.0-canary-20260404123848"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^25.5.0",
34
+ "tsc-alias": "^1.8.16",
35
+ "typescript": "^5.4.0",
36
+ "vitest": "^1.6.0"
37
+ },
38
+ "scripts": {
39
+ "build": "tsc && tsc-alias --resolve-full-paths --resolve-full-extension .js",
40
+ "clean": "rm -rf dist",
41
+ "test": "vitest run",
42
+ "typecheck": "tsc --noEmit"
43
+ }
44
+ }
package/src/index.ts ADDED
@@ -0,0 +1,69 @@
1
+ import { connect } from "@tursodatabase/serverless";
2
+ import {
3
+ type DataStoreValue,
4
+ type SnapDataStore,
5
+ type SnapFunction,
6
+ } from "@farcaster/snap";
7
+
8
+ /** Reserved for future options (e.g. custom table name). */
9
+ export type WithTursoServerlessOptions = Record<string, never>;
10
+
11
+ const TABLE_SQL = `CREATE TABLE IF NOT EXISTS snap_kv (key TEXT PRIMARY KEY, value TEXT NOT NULL)`;
12
+
13
+ /**
14
+ * Wraps a SnapFunction and injects a Turso serverless-backed data store into the
15
+ * context.
16
+ */
17
+ export function withTursoServerless(
18
+ snapFn: SnapFunction,
19
+ _options?: WithTursoServerlessOptions,
20
+ ): SnapFunction {
21
+ const url = process.env.TURSO_DATABASE_URL;
22
+ const authToken = process.env.TURSO_AUTH_TOKEN;
23
+
24
+ if (!url || !authToken) {
25
+ console.warn("missing env vars -- skipping Turso data store setup");
26
+ return snapFn;
27
+ }
28
+
29
+ const conn = connect({ url, authToken });
30
+
31
+ let ensureTablePromise: Promise<void> | undefined;
32
+
33
+ const ensureTable = async (): Promise<void> => {
34
+ if (!ensureTablePromise) {
35
+ ensureTablePromise = conn.execute(TABLE_SQL).then(() => undefined);
36
+ }
37
+ await ensureTablePromise;
38
+ };
39
+
40
+ const store: SnapDataStore = {
41
+ async get(key: string): Promise<DataStoreValue | null> {
42
+ await ensureTable();
43
+ const stmt = await conn.prepare(
44
+ "SELECT value FROM snap_kv WHERE key = ?",
45
+ );
46
+ const row = await stmt.get([key]);
47
+ if (row == null) {
48
+ return null;
49
+ }
50
+ const text =
51
+ typeof row === "object" &&
52
+ row !== null &&
53
+ "value" in row &&
54
+ typeof (row as { value: unknown }).value === "string"
55
+ ? (row as { value: string }).value
56
+ : String(row);
57
+ return JSON.parse(text) as DataStoreValue;
58
+ },
59
+ async set(key: string, value: DataStoreValue): Promise<void> {
60
+ await ensureTable();
61
+ const stmt = await conn.prepare(
62
+ "INSERT OR REPLACE INTO snap_kv (key, value) VALUES (?, ?)",
63
+ );
64
+ await stmt.run([key, JSON.stringify(value)]);
65
+ },
66
+ };
67
+
68
+ return (ctx) => snapFn({ ...ctx, data: store });
69
+ }