feat: funciones Wails — scaffold, CRUD bindings, build, eventos y streaming
Funciones Go para crear apps Wails: scaffold estructura, bind CRUD genérico, build multiplataforma, emit eventos y stream de datos al frontend. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
//go:build ignore
|
||||
// NOTE: requires wails dependency in target project — use this file by copying into a Wails project
|
||||
|
||||
package infra
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
)
|
||||
|
||||
// WailsStreamConfig configura un stream de datos hacia el frontend.
|
||||
type WailsStreamConfig struct {
|
||||
StreamName string // Nombre del stream (evento base)
|
||||
ChunkDelay time.Duration // Delay entre chunks (default 0)
|
||||
}
|
||||
|
||||
// WailsStreamData envía un slice de datos como stream al frontend.
|
||||
// Emite cada elemento como chunk en {streamName}, y {streamName}:complete al terminar.
|
||||
func WailsStreamData[T any](ctx context.Context, cfg WailsStreamConfig, data []T) error {
|
||||
if cfg.StreamName == "" {
|
||||
return fmt.Errorf("stream name is required")
|
||||
}
|
||||
|
||||
for _, chunk := range data {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
runtime.EventsEmit(ctx, cfg.StreamName+":error", map[string]string{
|
||||
"message": "stream cancelled",
|
||||
})
|
||||
return ctx.Err()
|
||||
default:
|
||||
runtime.EventsEmit(ctx, cfg.StreamName, chunk)
|
||||
if cfg.ChunkDelay > 0 {
|
||||
time.Sleep(cfg.ChunkDelay)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
runtime.EventsEmit(ctx, cfg.StreamName+":complete", nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
// WailsStreamFunc ejecuta una función generadora y envía resultados como stream.
|
||||
// La función generadora envía datos por el canal, y esta función los retransmite al frontend.
|
||||
func WailsStreamFunc[T any](ctx context.Context, streamName string, generator func(ctx context.Context, ch chan<- T) error) error {
|
||||
ch := make(chan T, 100)
|
||||
errCh := make(chan error, 1)
|
||||
|
||||
go func() {
|
||||
defer close(ch)
|
||||
errCh <- generator(ctx, ch)
|
||||
}()
|
||||
|
||||
for chunk := range ch {
|
||||
runtime.EventsEmit(ctx, streamName, chunk)
|
||||
}
|
||||
|
||||
if err := <-errCh; err != nil {
|
||||
runtime.EventsEmit(ctx, streamName+":error", map[string]string{
|
||||
"message": err.Error(),
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
runtime.EventsEmit(ctx, streamName+":complete", nil)
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user