103 lines
3.2 KiB
Markdown
103 lines
3.2 KiB
Markdown
# Poiesis
|
|
|
|
## Module Name
|
|
|
|
`reichard.io/poiesis`
|
|
|
|
## Overview
|
|
|
|
Go tool that transpiles TypeScript to JavaScript using esbuild API and executes it with goja. Features a flexible builtin system for exposing Go functions to TypeScript with support for both synchronous and asynchronous (Promise-based) operations.
|
|
|
|
## Build & Test
|
|
|
|
```bash
|
|
go build ./cmd/poiesis
|
|
go test ./...
|
|
golangci-lint run
|
|
```
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
reichard.io/poiesis/
|
|
├── cmd/poiesis/ # CLI entry point
|
|
│ └── main.go
|
|
├── internal/
|
|
│ ├── runtime/ # Runtime management, transpilation, execution
|
|
│ │ ├── runtime.go
|
|
│ │ └── runtime_test.go
|
|
│ ├── builtin/ # Builtin registration framework
|
|
│ │ ├── types.go
|
|
│ │ ├── registry.go
|
|
│ │ ├── wrapper.go
|
|
│ │ ├── convert.go
|
|
│ │ ├── typescript.go
|
|
│ │ └── builtin_test.go
|
|
│ └── standard/ # Standard builtin implementations
|
|
│ ├── fetch.go
|
|
│ ├── fetch_test.go
|
|
│ └── fetch_promise_test.go
|
|
└── test_data/ # Test TypeScript files
|
|
```
|
|
|
|
## Key Packages
|
|
|
|
- `reichard.io/poiesis/internal/runtime` - Runtime management, TypeScript transpilation, JavaScript execution
|
|
- `reichard.io/poiesis/internal/builtin` - Generic builtin registration framework (sync/async wrappers, JS/Go conversion, type definition generation)
|
|
- `reichard.io/poiesis/internal/standard` - Standard builtin implementations (fetch, add, greet, etc.)
|
|
|
|
## Builtin System
|
|
|
|
### Registration
|
|
|
|
Two types of builtins:
|
|
- **Sync**: `RegisterBuiltin[T, R](name, fn)` - executes synchronously, returns value
|
|
- **Async**: `RegisterAsyncBuiltin[T, R](name, fn)` - runs in goroutine, returns Promise
|
|
|
|
### Requirements
|
|
|
|
- Args must be a struct implementing `Args` interface with `Validate() error` method
|
|
- Use JSON tags for TypeScript type definitions
|
|
- Async builtins automatically generate `Promise<R>` return types
|
|
|
|
### Example
|
|
|
|
```go
|
|
type AddArgs struct {
|
|
A int `json:"a"`
|
|
B int `json:"b"`
|
|
}
|
|
|
|
func (a AddArgs) Validate() error { return nil }
|
|
|
|
func Add(_ context.Context, args AddArgs) (int, error) {
|
|
return args.A + args.B, nil
|
|
}
|
|
|
|
// Register sync builtin
|
|
builtin.RegisterBuiltin[AddArgs, int]("add", Add)
|
|
|
|
// Register async builtin
|
|
builtin.RegisterAsyncBuiltin[FetchArgs, *FetchResult]("fetch", Fetch)
|
|
```
|
|
|
|
## Testing Patterns
|
|
|
|
- **Test framework**: Go's built-in `testing` package
|
|
- **Assertions**: `github.com/stretchr/testify/assert` and `require`
|
|
- **Linting**: `golangci-lint run` - must pass before committing
|
|
- **Test organization**: Test files use `_test.go` suffix, test functions prefixed with `Test`
|
|
|
|
## Dependencies
|
|
|
|
- `github.com/evanw/esbuild/pkg/api` - TypeScript transpilation
|
|
- `github.com/dop251/goja` - JavaScript execution
|
|
- `github.com/stretchr/testify/assert` - Test assertions
|
|
|
|
## Code Conventions
|
|
|
|
- Handle all return values from external functions (enforced by golangci-lint)
|
|
- Use `os` package instead of deprecated `io/ioutil`
|
|
- Error logging uses `_, _ = fmt.Fprintf(stderr, ...)` pattern
|
|
- Package structure follows standard Go project layout with internal packages
|