2 changed files with 141 additions and 0 deletions
@ -0,0 +1,115 @@ |
|||||||
|
//go:build js && wasm
|
||||||
|
|
||||||
|
package database |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
"fmt" |
||||||
|
"strings" |
||||||
|
"time" |
||||||
|
) |
||||||
|
|
||||||
|
// DatabaseConfig holds all database configuration options that can be passed
|
||||||
|
// to any database backend. Each backend uses the relevant fields for its type.
|
||||||
|
// This centralizes configuration instead of having each backend read env vars directly.
|
||||||
|
type DatabaseConfig struct { |
||||||
|
// Common settings for all backends
|
||||||
|
DataDir string |
||||||
|
LogLevel string |
||||||
|
|
||||||
|
// Badger-specific settings (not available in WASM)
|
||||||
|
BlockCacheMB int // ORLY_DB_BLOCK_CACHE_MB
|
||||||
|
IndexCacheMB int // ORLY_DB_INDEX_CACHE_MB
|
||||||
|
QueryCacheSizeMB int // ORLY_QUERY_CACHE_SIZE_MB
|
||||||
|
QueryCacheMaxAge time.Duration // ORLY_QUERY_CACHE_MAX_AGE
|
||||||
|
InlineEventThreshold int // ORLY_INLINE_EVENT_THRESHOLD
|
||||||
|
|
||||||
|
// DGraph-specific settings
|
||||||
|
DgraphURL string // ORLY_DGRAPH_URL
|
||||||
|
|
||||||
|
// Neo4j-specific settings
|
||||||
|
Neo4jURI string // ORLY_NEO4J_URI
|
||||||
|
Neo4jUser string // ORLY_NEO4J_USER
|
||||||
|
Neo4jPassword string // ORLY_NEO4J_PASSWORD
|
||||||
|
} |
||||||
|
|
||||||
|
// NewDatabase creates a database instance based on the specified type.
|
||||||
|
// Supported types in WASM: "wasmdb", "dgraph", "neo4j"
|
||||||
|
// Note: "badger" is not available in WASM builds due to filesystem dependencies
|
||||||
|
func NewDatabase( |
||||||
|
ctx context.Context, |
||||||
|
cancel context.CancelFunc, |
||||||
|
dbType string, |
||||||
|
dataDir string, |
||||||
|
logLevel string, |
||||||
|
) (Database, error) { |
||||||
|
// Create a default config for backward compatibility with existing callers
|
||||||
|
cfg := &DatabaseConfig{ |
||||||
|
DataDir: dataDir, |
||||||
|
LogLevel: logLevel, |
||||||
|
} |
||||||
|
return NewDatabaseWithConfig(ctx, cancel, dbType, cfg) |
||||||
|
} |
||||||
|
|
||||||
|
// NewDatabaseWithConfig creates a database instance with full configuration.
|
||||||
|
// This is the preferred method when you have access to the app config.
|
||||||
|
func NewDatabaseWithConfig( |
||||||
|
ctx context.Context, |
||||||
|
cancel context.CancelFunc, |
||||||
|
dbType string, |
||||||
|
cfg *DatabaseConfig, |
||||||
|
) (Database, error) { |
||||||
|
switch strings.ToLower(dbType) { |
||||||
|
case "wasmdb", "indexeddb", "wasm", "badger", "": |
||||||
|
// In WASM builds, default to wasmdb (IndexedDB backend)
|
||||||
|
// "badger" is mapped to wasmdb since Badger is not available
|
||||||
|
if newWasmDBDatabase == nil { |
||||||
|
return nil, fmt.Errorf("wasmdb database backend not available (import _ \"next.orly.dev/pkg/wasmdb\")") |
||||||
|
} |
||||||
|
return newWasmDBDatabase(ctx, cancel, cfg) |
||||||
|
case "dgraph": |
||||||
|
// Use the dgraph implementation (HTTP-based, works in WASM)
|
||||||
|
if newDgraphDatabase == nil { |
||||||
|
return nil, fmt.Errorf("dgraph database backend not available (import _ \"next.orly.dev/pkg/dgraph\")") |
||||||
|
} |
||||||
|
return newDgraphDatabase(ctx, cancel, cfg) |
||||||
|
case "neo4j": |
||||||
|
// Use the neo4j implementation (HTTP-based, works in WASM)
|
||||||
|
if newNeo4jDatabase == nil { |
||||||
|
return nil, fmt.Errorf("neo4j database backend not available (import _ \"next.orly.dev/pkg/neo4j\")") |
||||||
|
} |
||||||
|
return newNeo4jDatabase(ctx, cancel, cfg) |
||||||
|
default: |
||||||
|
return nil, fmt.Errorf("unsupported database type: %s (supported in WASM: wasmdb, dgraph, neo4j)", dbType) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// newDgraphDatabase creates a dgraph database instance
|
||||||
|
// This is defined here to avoid import cycles
|
||||||
|
var newDgraphDatabase func(context.Context, context.CancelFunc, *DatabaseConfig) (Database, error) |
||||||
|
|
||||||
|
// RegisterDgraphFactory registers the dgraph database factory
|
||||||
|
// This is called from the dgraph package's init() function
|
||||||
|
func RegisterDgraphFactory(factory func(context.Context, context.CancelFunc, *DatabaseConfig) (Database, error)) { |
||||||
|
newDgraphDatabase = factory |
||||||
|
} |
||||||
|
|
||||||
|
// newNeo4jDatabase creates a neo4j database instance
|
||||||
|
// This is defined here to avoid import cycles
|
||||||
|
var newNeo4jDatabase func(context.Context, context.CancelFunc, *DatabaseConfig) (Database, error) |
||||||
|
|
||||||
|
// RegisterNeo4jFactory registers the neo4j database factory
|
||||||
|
// This is called from the neo4j package's init() function
|
||||||
|
func RegisterNeo4jFactory(factory func(context.Context, context.CancelFunc, *DatabaseConfig) (Database, error)) { |
||||||
|
newNeo4jDatabase = factory |
||||||
|
} |
||||||
|
|
||||||
|
// newWasmDBDatabase creates a wasmdb database instance (IndexedDB backend for WebAssembly)
|
||||||
|
// This is defined here to avoid import cycles
|
||||||
|
var newWasmDBDatabase func(context.Context, context.CancelFunc, *DatabaseConfig) (Database, error) |
||||||
|
|
||||||
|
// RegisterWasmDBFactory registers the wasmdb database factory
|
||||||
|
// This is called from the wasmdb package's init() function
|
||||||
|
func RegisterWasmDBFactory(factory func(context.Context, context.CancelFunc, *DatabaseConfig) (Database, error)) { |
||||||
|
newWasmDBDatabase = factory |
||||||
|
} |
||||||
@ -0,0 +1,26 @@ |
|||||||
|
package database |
||||||
|
|
||||||
|
import "time" |
||||||
|
|
||||||
|
// Subscription represents a user's subscription status
|
||||||
|
type Subscription struct { |
||||||
|
TrialEnd time.Time `json:"trial_end"` |
||||||
|
PaidUntil time.Time `json:"paid_until"` |
||||||
|
BlossomLevel string `json:"blossom_level,omitempty"` // Service level name (e.g., "basic", "premium")
|
||||||
|
BlossomStorage int64 `json:"blossom_storage,omitempty"` // Storage quota in MB
|
||||||
|
} |
||||||
|
|
||||||
|
// Payment represents a recorded payment
|
||||||
|
type Payment struct { |
||||||
|
Amount int64 `json:"amount"` |
||||||
|
Timestamp time.Time `json:"timestamp"` |
||||||
|
Invoice string `json:"invoice"` |
||||||
|
Preimage string `json:"preimage"` |
||||||
|
} |
||||||
|
|
||||||
|
// NIP43Membership represents membership metadata for NIP-43
|
||||||
|
type NIP43Membership struct { |
||||||
|
Pubkey []byte |
||||||
|
AddedAt time.Time |
||||||
|
InviteCode string |
||||||
|
} |
||||||
Loading…
Reference in new issue