implement wasm/js specific database engine
Some checks failed
Go / build-and-release (push) Has been cancelled
Some checks failed
Go / build-and-release (push) Has been cancelled
This commit is contained in:
115
pkg/database/factory_wasm.go
Normal file
115
pkg/database/factory_wasm.go
Normal file
@@ -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
|
||||||
|
}
|
||||||
26
pkg/database/types.go
Normal file
26
pkg/database/types.go
Normal file
@@ -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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user