loam

package module
v0.5.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 8, 2025 License: AGPL-3.0 Imports: 4 Imported by: 2

README

Loam 🌱

A Transactional Storage Engine for Content & Metadata.

Go Report Card Go Doc

Loam é uma engine de armazenamento transacional de notas (Headless CMS), focada em conteúdo textual e metadados. Embora a implementação padrão utilize Markdown + Frontmatter sobre Git (FS Adapter), a arquitetura é agnóstica e permite outros backends (S3, SQL, etc).

Ele oferece operações de CRUD atômicas e seguras, garantindo que suas automações não corrompam seu cofre pessoal. É ideal para toolmakers que querem criar bots ou scripts sobre suas bases de conhecimento (Obsidian, Logseq, etc).

🚀 Instalação

go install github.com/aretw0/loam/cmd/loam@latest

🛠️ CLI: Uso Básico

O Loam CLI funciona como um "Gerenciador de Conteúdo", abstraindo a persistência.

Inicializar

Inicia um cofre Loam. Por padrão usa o adapter de sistema de arquivos (FS + Git).

loam init
# Ou explicitamente:
loam init --adapter fs
Criar/Editar Nota

Salva conteúdo e registra a razão da mudança (Commits no caso do Git).

# Modo Simples (apenas mensagem)
loam write -id daily/2025-12-06 -content "Hoje foi um dia produtivo." -m "log diário"

# Modo Semântico (Type, Scope, Body)
loam write -id feature/nova-ideia -content "..." --type feat --scope ideias -m "adiciona rascunho"
Sincronizar (Sync)

Sincroniza o cofre com o remoto configurado (se o adapter suportar).

loam sync
Outros Comandos
  • Ler: loam read -id daily/2025-12-06
  • Listar: loam list
  • Deletar: loam delete -id daily/2025-12-06

📦 Library: Uso em Go

Você pode embutir o Loam em seus próprios projetos Go para gerenciar persistência de dados.

go get github.com/aretw0/loam
Exemplo
package main

import (
 "context"
 "fmt"
 "log/slog"
 "os"

 "github.com/aretw0/loam/pkg/core"
 "github.com/aretw0/loam"
)

func main() {
 // 1. Inicializar Serviço (Factory) com Functional Options.
 // O primeiro argumento é a URI ou Path do cofre. Para o adapter FS, use o caminho do diretório.
 service, err := loam.New("./minhas-notas",
  loam.WithAdapter("fs"), // Padrão
  loam.WithAutoInit(true), // Cria diretório e git init se necessário
  loam.WithLogger(slog.New(slog.NewTextHandler(os.Stdout, nil))),
 )
 if err != nil {
  panic(err)
 }

 ctx := context.Background()

 // 2. Escrever (Save)
 // Salvamos o conteúdo com uma "razão de mudança" (Commit Message)
 // Isso garante que toda mudança tenha um porquê.
 ctxMsg := context.WithValue(ctx, core.ChangeReasonKey, "nota inicial")
 err = service.SaveNote(ctxMsg, "daily/hoje", "# Dia Incrível\nComeçamos o projeto.", nil)
 if err != nil {
  panic(err)
 }
 fmt.Println("Nota salva com sucesso!")

 // 3. Ler (Read)
 note, err := service.GetNote(ctx, "daily/hoje")
 if err != nil { // Tratamento simplificado
  panic(err)
 }
 fmt.Printf("Conteúdo recuperado:\n%s\n", note.Content)

 // ... (veja exemplos completos em examples/basic/crud)
}

📚 Documentação Técnica

Status

🚧 Alpha. A API interna pkg/loam está se estabilizando, mas mudanças podem ocorrer. A CLI é estável para uso diário.

Documentation

Overview

Package loam is the Composition Root for the Loam application.

It connects the core business logic (Domain Layer) with the infrastructure adapters (Persistence Layer) using the Hexagonal Architecture pattern.

Philosophy:

Loam is a "Headless CMS" for toolmakers. It treats a collection of notes as a transactional database, abstracting the underlying storage mechanism. While the default implementation uses the File System and Git, Loam's core is agnostic, allowing for future adapters (e.g., S3, SQLite).

Features:

  • **Hexagonal Architecture**: Core domain is isolated from persistence details.
  • **Transactional Safe**: Atomic operations regardless of the underlying storage.
  • **Metadata First**: Native support for Frontmatter parsing and indexing.
  • **Default Adapter (FS + Git)**: Out-of-the-box support for local Markdown files with Git versioning.
  • **Extensible**: Designed to support other backends (SQL, S3, NoSQL) via `core.Repository`.

Usage:

// Initialize service with functional options
svc, err := loam.New("./vault",
	loam.WithAutoInit(true),
	loam.WithLogger(logger),
)

// Save a note
err := svc.SaveNote(ctx, "my-note", "content", nil)
Example (Advanced)

Example_advanced demonstrates how to use Loam in "Gitless" mode (no version history) and strict configuration.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/aretw0/loam"
)

func main() {
	tmpDir, err := os.MkdirTemp("", "loam-gitless-*")
	if err != nil {
		log.Fatal(err)
	}
	defer os.RemoveAll(tmpDir)

	// Initialize with explicit options:
	// - WithVersioning(false): Disables Git integration (behaves like a normal file store).
	// - WithAutoInit(true): Creates directories if they don't exist.
	vault, err := loam.New(tmpDir,
		loam.WithVersioning(false),
		loam.WithAutoInit(true),
	)
	if err != nil {
		log.Fatal(err)
	}

	ctx := context.TODO()

	// Save a config file
	err = vault.SaveNote(ctx, "config", "debug_mode: true", nil)
	if err != nil {
		log.Fatal(err)
	}

	// List notes
	notes, err := vault.ListNotes(ctx)
	if err != nil {
		log.Fatal(err)
	}

	for _, n := range notes {
		fmt.Printf("Found note: %s\n", n.ID)
	}

}
Output:
Found note: config
Example (Basic)

Example_basic demonstrates how to initialize a Vault, save a note, and read it back.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/aretw0/loam"
	"github.com/aretw0/loam/pkg/core"
)

func main() {
	// Create a temporary directory for the example
	tmpDir, err := os.MkdirTemp("", "loam-example-*")
	if err != nil {
		log.Fatal(err)
	}
	defer os.RemoveAll(tmpDir)

	// Initialize the Loam service (Vault) targeting the temporary directory.
	// WithAutoInit(true) ensures the underlying storage (git repo) is initialized.
	vault, err := loam.New(tmpDir, loam.WithAutoInit(true))
	if err != nil {
		log.Fatal(err)
	}

	ctx := context.TODO()

	// 1. Save a Note
	// ID: "hello-world"
	// Content: "This is my first note in Loam."
	// Metadata: Tags=["example"], Author="Gopher"
	err = vault.SaveNote(ctx, "hello-world", "This is my first note in Loam.", core.Metadata{
		"tags":   []string{"example"},
		"author": "Gopher",
	})
	if err != nil {
		log.Fatal(err)
	}

	// 2. Read the Note
	note, err := vault.GetNote(ctx, "hello-world")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("ID: %s\n", note.ID)
	fmt.Printf("Content: %s\n", note.Content)
	fmt.Printf("Author: %s\n", note.Metadata["author"])

}
Output:
ID: hello-world
Content: This is my first note in Loam.
Author: Gopher

Index

Examples

Constants

View Source
const (
	CommitTypeFeat     = platform.CommitTypeFeat
	CommitTypeFix      = platform.CommitTypeFix
	CommitTypeDocs     = platform.CommitTypeDocs
	CommitTypeStyle    = platform.CommitTypeStyle
	CommitTypeRefactor = platform.CommitTypeRefactor
	CommitTypePerf     = platform.CommitTypePerf
	CommitTypeTest     = platform.CommitTypeTest
	CommitTypeChore    = platform.CommitTypeChore
)

Variables

View Source
var Version string

Functions

func AppendFooter added in v0.5.1

func AppendFooter(msg string) string

AppendFooter appends the Loam footer to an arbitrary message.

func FormatChangeReason added in v0.5.1

func FormatChangeReason(ctype, scope, subject, body string) string

FormatChangeReason builds a Conventional Commit message.

func Init added in v0.5.1

func Init(path string, opts ...Option) (core.Repository, error)

Init initializes a repository explicitly.

func IsDevRun added in v0.5.1

func IsDevRun() bool

IsDevRun checks if the current process is running via `go run` or `go test`.

func New added in v0.5.1

func New(path string, opts ...Option) (*core.Service, error)

New creates a new Loam Service.

func ResolveVaultPath added in v0.5.1

func ResolveVaultPath(userPath string, forceTemp bool) string

ResolveVaultPath determines the actual path for the vault based on safety rules.

func Sync added in v0.5.1

func Sync(path string, opts ...Option) error

Sync performs a synchronization (pull/push) of the vault.

Types

type Option added in v0.5.1

type Option = platform.Option

Option defines a functional option for configuring Loam.

func WithAdapter added in v0.5.1

func WithAdapter(name string) Option

WithAdapter allows specifying the storage adapter to use by name.

func WithAutoInit added in v0.5.1

func WithAutoInit(auto bool) Option

WithAutoInit enables automatic initialization of the vault (git init).

func WithForceTemp added in v0.5.1

func WithForceTemp(force bool) Option

WithForceTemp forces the use of a temporary directory (useful for testing).

func WithLogger added in v0.5.1

func WithLogger(logger *slog.Logger) Option

WithLogger sets the logger for the service.

func WithMustExist added in v0.5.1

func WithMustExist(must bool) Option

WithMustExist ensures the vault directory must already exist.

func WithRepository added in v0.5.1

func WithRepository(repo core.Repository) Option

WithRepository allows injecting a custom storage adapter.

func WithVersioning added in v0.5.1

func WithVersioning(enabled bool) Option

WithVersioning enables or disables version control (e.g. Git).

Directories

Path Synopsis
cmd
loam command
examples
basic/crud command
internal
pkg
git

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL