factory_wasm.go raw
1 //go:build js && wasm
2
3 package database
4
5 import (
6 "context"
7 "fmt"
8 "strings"
9 "time"
10 )
11
12 // DatabaseConfig holds all database configuration options that can be passed
13 // to any database backend. Each backend uses the relevant fields for its type.
14 // This centralizes configuration instead of having each backend read env vars directly.
15 type DatabaseConfig struct {
16 // Common settings for all backends
17 DataDir string
18 LogLevel string
19
20 // Badger-specific settings (not available in WASM)
21 BlockCacheMB int // ORLY_DB_BLOCK_CACHE_MB
22 IndexCacheMB int // ORLY_DB_INDEX_CACHE_MB
23 QueryCacheSizeMB int // ORLY_QUERY_CACHE_SIZE_MB
24 QueryCacheMaxAge time.Duration // ORLY_QUERY_CACHE_MAX_AGE
25
26 // Serial cache settings for compact event storage (Badger-specific)
27 SerialCachePubkeys int // ORLY_SERIAL_CACHE_PUBKEYS - max pubkeys to cache (default: 100000)
28 SerialCacheEventIds int // ORLY_SERIAL_CACHE_EVENT_IDS - max event IDs to cache (default: 500000)
29
30 // Neo4j-specific settings
31 Neo4jURI string // ORLY_NEO4J_URI
32 Neo4jUser string // ORLY_NEO4J_USER
33 Neo4jPassword string // ORLY_NEO4J_PASSWORD
34
35 // Neo4j driver tuning (memory and connection management)
36 Neo4jMaxConnPoolSize int // ORLY_NEO4J_MAX_CONN_POOL - max connection pool size (default: 25)
37 Neo4jFetchSize int // ORLY_NEO4J_FETCH_SIZE - max records per fetch batch (default: 1000)
38 Neo4jMaxTxRetrySeconds int // ORLY_NEO4J_MAX_TX_RETRY_SEC - max transaction retry time (default: 30)
39 Neo4jQueryResultLimit int // ORLY_NEO4J_QUERY_RESULT_LIMIT - max results per query (default: 10000, 0=unlimited)
40 }
41
42 // NewDatabase creates a database instance based on the specified type.
43 // Supported types in WASM: "wasmdb", "neo4j"
44 // Note: "badger" is not available in WASM builds due to filesystem dependencies
45 func NewDatabase(
46 ctx context.Context,
47 cancel context.CancelFunc,
48 dbType string,
49 dataDir string,
50 logLevel string,
51 ) (Database, error) {
52 // Create a default config for backward compatibility with existing callers
53 cfg := &DatabaseConfig{
54 DataDir: dataDir,
55 LogLevel: logLevel,
56 }
57 return NewDatabaseWithConfig(ctx, cancel, dbType, cfg)
58 }
59
60 // NewDatabaseWithConfig creates a database instance with full configuration.
61 // This is the preferred method when you have access to the app config.
62 func NewDatabaseWithConfig(
63 ctx context.Context,
64 cancel context.CancelFunc,
65 dbType string,
66 cfg *DatabaseConfig,
67 ) (Database, error) {
68 switch strings.ToLower(dbType) {
69 case "wasmdb", "indexeddb", "wasm", "badger", "":
70 // In WASM builds, default to wasmdb (IndexedDB backend)
71 // "badger" is mapped to wasmdb since Badger is not available
72 if newWasmDBDatabase == nil {
73 return nil, fmt.Errorf("wasmdb database backend not available (import _ \"next.orly.dev/pkg/wasmdb\")")
74 }
75 return newWasmDBDatabase(ctx, cancel, cfg)
76 case "neo4j":
77 // Use the neo4j implementation (HTTP-based, works in WASM)
78 if newNeo4jDatabase == nil {
79 return nil, fmt.Errorf("neo4j database backend not available (import _ \"next.orly.dev/pkg/neo4j\")")
80 }
81 return newNeo4jDatabase(ctx, cancel, cfg)
82 default:
83 return nil, fmt.Errorf("unsupported database type: %s (supported in WASM: wasmdb, neo4j)", dbType)
84 }
85 }
86
87 // newNeo4jDatabase creates a neo4j database instance
88 // This is defined here to avoid import cycles
89 var newNeo4jDatabase func(context.Context, context.CancelFunc, *DatabaseConfig) (Database, error)
90
91 // RegisterNeo4jFactory registers the neo4j database factory
92 // This is called from the neo4j package's init() function
93 func RegisterNeo4jFactory(factory func(context.Context, context.CancelFunc, *DatabaseConfig) (Database, error)) {
94 newNeo4jDatabase = factory
95 }
96
97 // newWasmDBDatabase creates a wasmdb database instance (IndexedDB backend for WebAssembly)
98 // This is defined here to avoid import cycles
99 var newWasmDBDatabase func(context.Context, context.CancelFunc, *DatabaseConfig) (Database, error)
100
101 // RegisterWasmDBFactory registers the wasmdb database factory
102 // This is called from the wasmdb package's init() function
103 func RegisterWasmDBFactory(factory func(context.Context, context.CancelFunc, *DatabaseConfig) (Database, error)) {
104 newWasmDBDatabase = factory
105 }
106