gofront 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -100,8 +100,9 @@ operation on it is silently permitted, preventing cascading errors.
100
100
  Walks the typed AST and emits clean, readable JavaScript. No intermediate representation
101
101
  — the codegen writes directly to an output buffer with indentation tracking.
102
102
 
103
- Runtime helpers (`__len`, `__append`, `__s`, `__sprintf`) are tree-shaken: only emitted
104
- when actually used. Optional inline source maps are supported via VLQ-encoded mappings.
103
+ Runtime helpers (`__len`, `__append`, `__s`, `__sprintf`, `__cmul`, `__cdiv`, `__error`,
104
+ `__errorIs`) are tree-shaken: only emitted when actually used. Optional inline source
105
+ maps are supported via VLQ-encoded mappings.
105
106
 
106
107
  ---
107
108
 
@@ -120,7 +121,7 @@ readable and debuggable — no name mangling, no opaque wrappers.
120
121
  | `[]T` (slice) | `Array` | `append` → spread, `len` → `.length` |
121
122
  | `map[K]V` | Plain object `{}` | Key access via `[]`, iteration via `Object.entries()` |
122
123
  | `nil` | `null` | |
123
- | `error` | `string` | `error("msg")` → `"msg"`, `.Error()` → the string itself |
124
+ | `error` | `__error` object | `error("msg")` → `__error("msg")`, `.Error()` → real method call. `toString()` for string context compat |
124
125
  | Pointers (`*T`) | `{ value: T }` | `new(T)` allocates a boxed zero value |
125
126
 
126
127
  ### Functions
@@ -145,7 +146,7 @@ readable and debuggable — no name mangling, no opaque wrappers.
145
146
  | `for {}` | `while (true) {}` |
146
147
  | `for i, v := range slice` | `for (const [i, v] of arr.entries())` |
147
148
  | `for k, v := range map` | `for (const [k, v] of Object.entries(m))` |
148
- | `for i, ch := range str` | `for (const [i, ch] of Array.from(s).entries())` |
149
+ | `for i, r := range str` | `for (const [i, r] of Array.from(s, (c, i) => [i, c.codePointAt(0)]))` — `r` is a rune integer |
149
150
  | `for i := range n` | `for (let i = 0; i < n; i++)` |
150
151
  | `switch` / `fallthrough` | `switch` / case fall-through |
151
152
  | `switch v := x.(type)` | `if/else if` with `typeof` / `instanceof` checks |
@@ -164,24 +165,20 @@ readable and debuggable — no name mangling, no opaque wrappers.
164
165
  | `make(map[K]V)` | `{}` |
165
166
  | `delete(m, k)` | `delete m[k]` |
166
167
  | `new(T)` | `{ value: zeroOf(T) }` |
167
- | `min(a, b, ...)` | `Math.min(a, b, ...)` |
168
- | `max(a, b, ...)` | `Math.max(a, b, ...)` |
168
+ | `min` / `max` | `Math.min` / `Math.max` |
169
169
  | `clear(x)` | `.length = 0` (slice) or delete-loop (map) |
170
170
  | `print` / `println` | `console.log` |
171
+ | `complex(r, i)` | `{ re: r, im: i }` |
172
+ | `real(z)` / `imag(z)` | `z.re` / `z.im` |
171
173
  | `fmt.Sprintf` | `__sprintf` tree-shaken helper |
172
- | `strings.*` | JS string methods (`.includes`, `.startsWith`, `.split`, etc.) |
173
- | `strconv.*` | `String()`, `parseInt()`, `Number()` |
174
- | `sort.Slice` | `Array.prototype.sort()` with comparator wrapping |
175
- | `math.*` | `Math.*` methods and constants |
176
- | `errors.New` | Identity (returns string) |
177
- | `time.Now()` | `Date.now()` |
178
174
 
179
175
  ### Type system at runtime
180
176
 
181
177
  All type checking happens at compile time. At runtime, types are erased — there are no
182
178
  type tags, no reflection, no runtime overhead. Sized integers (`int8`–`int64`,
183
- `uint8`–`uint64`) are all `number` at runtime. `float32` is `number`. The type checker
184
- enforces correctness; JavaScript doesn't need to know.
179
+ `uint8`–`uint64`) are all `number` at runtime. `float32` is `number`. Generic type
180
+ parameters are erased completely — `func Map[T, U any](...)` compiles to `function Map(...)`.
181
+ The type checker enforces correctness; JavaScript doesn't need to know.
185
182
 
186
183
  ---
187
184
 
@@ -205,7 +202,7 @@ example/simple/
205
202
  styles.go ← injectStyles() creates <style> element with all CSS
206
203
  main.go ← createApp() builds DOM shell · setupEvents() · event delegation
207
204
  utils/
208
- utils.go ← Plural() — cross-package import demo
205
+ utils.go ← Plural() · generic Filter/Map — cross-package import demo
209
206
  browser.d.ts ← minimal external type declarations (sleep)
210
207
  index.html ← bare HTML shell, loads app.js as ES module
211
208
  app.js ← generated output
@@ -228,7 +225,7 @@ example/reactive/
228
225
  styles.go ← injectStyles()
229
226
  main.go ← wires everything together
230
227
  utils/
231
- utils.go ← Plural()
228
+ utils.go ← Plural() · generic Filter/Map
232
229
  browser.d.ts ← Signal interface · Signals/Reactive/ComponentContext namespaces
233
230
  reactive.js ← signals framework (from microtastic)
234
231
  index.html ← loads reactive.js + app.js
@@ -239,7 +236,8 @@ example/reactive/
239
236
 
240
237
  Both apps cover: structs & methods, iota constants, named return values, closures,
241
238
  slices, `for range`, `switch`, cross-package imports, multi-file same-package compilation,
242
- `async`/`await`, `defer`/`recover`, localStorage persistence, and DOM APIs.
239
+ `async`/`await`, `defer`/`recover`, localStorage persistence, DOM APIs, and generic
240
+ utility functions (`Filter[T]`, `Map[T, U]`).
243
241
 
244
242
  The reactive example additionally demonstrates: external `.d.ts` type imports,
245
243
  `declare namespace` patterns for typing JS libraries, and reactive UI updates via signals.
@@ -263,7 +261,8 @@ gofront <input> -o out.js write output to file (prints elapsed compile ti
263
261
  gofront <input> --check type-check only
264
262
  gofront <input> --watch watch for changes and recompile
265
263
  gofront <input> --source-map append inline source map to output
266
- gofront <input> --minify minify output with terser
264
+ gofront <input> --minify minify output (built-in minifier)
265
+ gofront <input> --minify --mangle minify and rename local identifiers
267
266
  gofront <file.go> --ast dump AST (debug)
268
267
  gofront <file.go> --tokens dump tokens (debug)
269
268
  gofront init [dir] scaffold a new project
@@ -337,77 +336,96 @@ signatures into GoFront's internal type representation.
337
336
 
338
337
  ## Language features
339
338
 
339
+ ### Core language
340
+
340
341
  | Feature | Status |
341
342
  |---|---|
342
343
  | Variables (`var`, `:=` short re-declaration) | ✓ |
343
- | Constants (`const`, `iota`) | ✓ |
344
- | `if` / `else if` / `else` | ✓ |
345
- | `if` with init statement (`if err := f(); err != nil`) | ✓ |
346
- | Type definitions (`type MyType ...`) | ✓ |
347
- | Functions, multiple returns | ✓ |
348
- | Named return values | ✓ |
349
- | Variadic parameters | ✓ |
344
+ | Constants (`const`, `iota`, untyped constants) | ✓ |
345
+ | Functions, multiple returns, named returns, variadic | ✓ |
350
346
  | `init()` functions | ✓ |
351
- | Structs + methods | ✓ |
352
- | Anonymous struct types (`struct { Name string }`) | ✓ — compile to plain JS objects (no class emitted) |
353
- | Embedded structs | ✓ |
354
- | Pointer receivers | ✓ |
355
- | Interfaces | ✓ |
356
- | Interface embedding | ✓ |
357
- | Closures | ✓ |
347
+ | Closures / function literals | ✓ |
348
+ | `async func` / `await` expressions | ✓ |
349
+ | `defer`, `panic()` / `recover()` | ✓ |
350
+ | `print` / `println` builtins | ✓ — compile to `console.log` |
351
+
352
+ ### Types & data structures
353
+
354
+ | Feature | Status |
355
+ |---|---|
356
+ | Structs + methods (value & pointer receivers) | ✓ |
357
+ | Embedded structs (flattened fields + promoted methods) | ✓ |
358
+ | Anonymous struct types | ✓ — compile to plain JS objects |
359
+ | Interfaces (with embedding) | ✓ |
358
360
  | Slices (`append`, `len`, `make`) | ✓ |
359
- | Maps (`make`, `delete`, comma-ok) | ✓ — note: iteration order is insertion-order (JS), not randomised (Go) |
360
- | `for`, `for range`, `for {}` | ✓ |
361
- | `range` over string | ✓ |
362
- | `switch` / `fallthrough` | ✓ |
363
- | `switch` with init statement (`switch x := f(); x {}`) | ✓ |
364
- | `new(T)` | ✓ |
365
- | Type conversions | ✓ |
366
- | Type assertions (`x.(T)`) | ✓ |
367
- | Type switch (`switch x.(type)`, `switch v := x.(type)`) | ✓ — compiles to `if/else if` with `typeof` / `instanceof` checks |
368
- | Slice expressions (`s[lo:hi]`, `s[lo:hi:max]`) | ✓ — three-index form is parsed; `max` is ignored at runtime (JS has no capacity) |
369
- | `break` / `continue` / labeled `break` / labeled `continue` | ✓ |
370
- | `cap()`, `copy()`, `panic()` | ✓ |
361
+ | Maps (`make`, `delete`, comma-ok) | ✓ |
362
+ | Arrays with compile-time enforcement | ✓ — reject `append`, bounds checking, size matching, `[...]T` inference, compile-time `len()` |
363
+ | Slice → array conversion (`[N]T(slice)`) | ✓ — Go 1.20 |
364
+ | Pointers (`&x`, `*p`, `new(T)`) | ✓ — scalar locals boxed as `{ value: T }` for shared mutation |
365
+ | `error` type | ✓ — interface `{ Error() string }`; custom error types, `errors.Is`/`Unwrap`, `%w` wrapping |
366
+ | Complex numbers (`complex64`, `complex128`, `3i`) | ✓ — `complex()`, `real()`, `imag()` builtins; `__cmul`/`__cdiv` helpers |
367
+ | Type definitions, type aliases (`type A = B`) | ✓ |
368
+ | Type conversions, type assertions (plain & comma-ok) | ✓ |
369
+ | Type switch (`switch v := x.(type)`) | ✓ — compiles to `if/else if` with `typeof` / `instanceof` |
370
+ | Sized integers (`int8`–`int64`, `uint8`–`uint64`, `float32`) | ✓ — mapped to `number` at runtime |
371
+ | Generics (`func F[T any]`, `type S[T any] struct`) | ✓ — type erasure to JS; generic functions, structs, constraints (`any`, `comparable`, interfaces, unions), type inference |
372
+ | Struct field tags | ✓ — parsed and ignored (no reflection) |
373
+ | Struct and array equality (`a == b`) | ✓ — deep comparison via `__equal` helper |
374
+
375
+ ### Control flow
376
+
377
+ | Feature | Status |
378
+ |---|---|
379
+ | `if` / `else if` / `else` (with init statement) | ✓ |
380
+ | `for` (C-style, condition-only, infinite, `range`) | ✓ |
381
+ | `range` over slice, map, string, integer | ✓ |
382
+ | Range over iterator functions (Go 1.23) | ✓ — `func(yield func(K, V) bool)` protocol; break/continue/return propagation |
383
+ | `switch` / `fallthrough` (with init statement) | ✓ |
384
+ | `break` / `continue` / labeled variants | ✓ |
385
+ | Terminating statement analysis | ✓ — missing `return` in non-void functions is a type error |
386
+
387
+ ### Expressions & literals
388
+
389
+ | Feature | Status |
390
+ |---|---|
391
+ | Arithmetic, comparison, logical, bitwise operators | ✓ — includes `&^` (bit clear) |
392
+ | Compound assignment, increment / decrement | ✓ |
393
+ | Slice expressions (`s[lo:hi]`, `s[lo:hi:max]`) | ✓ |
371
394
  | Variadic spread (`f(slice...)`, `append(a, b...)`) | ✓ |
372
- | Bitwise operators (`&`, `\|`, `^`, `&^`, `<<`, `>>`) | ✓ — `&^` (bit clear) compiles to `& ~` |
373
- | Compound assignment (`+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `\|=`, `^=`, `<<=`, `>>=`) | ✓ |
374
- | Increment / decrement (`i++`, `i--`) | ✓ |
375
- | Raw string literals (backticks) | ✓ |
376
- | Rune / char literals (`'a'`, `'\n'`) | ✓ — compiled to integer char codes |
377
- | `defer` | ✓ |
378
- | `panic()` / `recover()` | ✓ |
379
- | `print` / `println` builtins | ✓ — compile to `console.log` |
380
- | Pointer operators (`&`, `*`) | ✓ |
381
- | `error` type / `error("msg")` / `.Error()` | ✓ |
382
- | `async func` / `await` expressions | ✓ |
383
- | `fmt.Sprintf` / `fmt.Printf` / `fmt.Println` / `fmt.Print` / `fmt.Errorf` | ✓ — expanded: `%t`, `%x`, `%X`, `%o`, `%b`, `%q`, `%e`, `%g`, width/precision |
384
- | `strings` package | ✓ — 20 functions: `Contains`, `HasPrefix`, `Split`, `Join`, `ToUpper`, `ToLower`, `TrimSpace`, etc. |
385
- | `strconv` package | ✓ — `Itoa`, `Atoi`, `FormatBool`, `FormatInt`, `ParseFloat`, `ParseInt`, `ParseBool` |
386
- | `sort` package | ✓ — `Ints`, `Float64s`, `Strings`, `Slice`, `SliceStable`, `SliceIsSorted` |
387
- | `math` package | ✓ — `Sqrt`, `Pow`, `Abs`, `Floor`, `Ceil`, `Round`, `Log`, trig functions + `Pi`, `E`, `MaxInt` constants |
388
- | `errors` package | ✓ — `errors.New` (returns plain string) |
389
- | `time` package (partial) | ✓ — `Now`, `Since`, `Sleep` + `Millisecond`, `Second`, `Minute`, `Hour` constants |
390
- | External `.d.ts` types | ✓ |
391
- | npm package types | ✓ |
395
+ | Positional struct literals (`Point{1, 2}`) | ✓ |
396
+ | Method expressions (`T.Method`) / method values (`x.Method`) | ✓ |
397
+ | Multi-value function forwarding (`f(g())`) | ✓ |
398
+ | Raw string literals (backticks), rune literals | ✓ |
399
+ | Numeric separators (`1_000_000`), binary/octal/hex literals | ✓ |
400
+ | `[]byte(s)` / `[]rune(s)` conversions | ✓ |
401
+
402
+ ### Standard library shims
403
+
404
+ | Package | Functions |
405
+ |---|---|
406
+ | `fmt` | `Sprintf`, `Printf`, `Println`, `Print`, `Errorf` — format verbs: `%v`, `%d`, `%s`, `%t`, `%x`, `%o`, `%b`, `%q`, `%e`, `%g`, `%w`, width/precision |
407
+ | `strings` | `Contains`, `HasPrefix`, `HasSuffix`, `Index`, `LastIndex`, `Count`, `Repeat`, `Replace`, `ReplaceAll`, `ToUpper`, `ToLower`, `TrimSpace`, `Trim`, `TrimPrefix`, `TrimSuffix`, `TrimLeft`, `TrimRight`, `Split`, `Join`, `EqualFold` |
408
+ | `bytes` | `Contains`, `HasPrefix`, `HasSuffix`, `Index`, `Join`, `Split`, `Replace`, `ToUpper`, `ToLower`, `TrimSpace`, `Equal`, `Count`, `Repeat` |
409
+ | `strconv` | `Itoa`, `Atoi`, `FormatBool`, `FormatInt`, `FormatFloat`, `ParseFloat`, `ParseInt`, `ParseBool` |
410
+ | `sort` | `Ints`, `Float64s`, `Strings`, `Slice`, `SliceStable`, `SliceIsSorted` |
411
+ | `math` | `Abs`, `Floor`, `Ceil`, `Round`, `Sqrt`, `Cbrt`, `Pow`, `Log`, `Log2`, `Log10`, trig functions + `Pi`, `E`, `MaxFloat64`, `MaxInt`, `MinInt` |
412
+ | `errors` | `New`, `Is`, `Unwrap` — custom error types via interface satisfaction |
413
+ | `time` | `Now`, `Since`, `Sleep` + `Millisecond`, `Second`, `Minute`, `Hour` constants |
414
+ | `unicode` | `IsLetter`, `IsDigit`, `IsSpace`, `IsUpper`, `IsLower`, `IsPunct`, `IsControl`, `IsPrint`, `IsGraphic`, `ToUpper`, `ToLower` |
415
+ | `os` | `Exit`, `Args`, `Getenv` |
416
+
417
+ ### Packages & imports
418
+
419
+ | Feature | Status |
420
+ |---|---|
392
421
  | Multi-file packages | ✓ |
393
422
  | Cross-package imports | ✓ |
394
423
  | Import aliases (`import m "./pkg"`) | ✓ |
395
- | Sized integer types (`uint`, `int8`–`int64`, `uint8`–`uint64`, `float32`) | ✓ — mapped to `int` / `float64` at runtime |
396
- | Struct field tags (`` `json:"name"` ``) | ✓ — parsed and ignored (no reflection) |
397
- | `[]byte(s)` conversion | ✓ — produces UTF-8 byte values via `TextEncoder` |
398
- | `[]rune(s)` conversion | ✓ — produces Unicode code points via `Array.from` |
399
- | `[...]T{...}` array length inference | ✓ |
400
- | Side-effect imports (`import _ "pkg"`) | ✓ — dependency code is bundled; package namespace is not exposed |
401
- | Dot imports (`import . "pkg"`) | ✓ — merges package exports into the current scope (no qualifier needed) |
402
- | Unused local import detection | ✓ — unused cross-package imports are type errors (matching Go); `import _` exempt |
403
- | `min()` / `max()` builtins | ✓ — compiles to `Math.min` / `Math.max` |
404
- | `clear()` builtin | ✓ — zeroes slice length or deletes all map keys |
405
- | `range` over integer (`for i := range n`) | ✓ — Go 1.22; also supports `for range n` |
406
- | Type aliases (`type A = B`) | ✓ — transparent alias; no conversion needed between alias and original |
407
- | Numeric literal separators (`1_000_000`) | ✓ — underscores stripped at lex time |
408
- | Binary / octal literals (`0b1010`, `0o777`) | ✓ — passed through to JS which supports them natively |
409
- | Hex float literals (`0x1.8p1`) | ✓ — evaluated at lex time to a decimal value |
410
- | Untyped constants | ✓ — `const x = 5` produces an untyped int that coerces to `int` or `float64` on use (Go spec §Constants) |
424
+ | Side-effect imports (`import _ "pkg"`) | ✓ |
425
+ | Dot imports (`import . "pkg"`) | ✓ |
426
+ | Unused import detection | ✓ |
427
+ | External `.d.ts` types | ✓ |
428
+ | npm package type resolution | ✓ |
411
429
 
412
430
  ---
413
431
 
@@ -415,35 +433,7 @@ signatures into GoFront's internal type representation.
415
433
 
416
434
  GoFront implements a practical subset of the
417
435
  [Go Language Specification](https://go.dev/ref/spec) (go1.26). It is not aiming for
418
- byte-level parity — it is a Go-inspired language for the JavaScript platform. This
419
- section explains exactly where GoFront matches Go, where it intentionally diverges, and
420
- where JS fundamentally prevents matching Go semantics.
421
-
422
- ### What matches Go
423
-
424
- The core language surface is well covered. All of these compile and behave as a Go
425
- developer would expect:
426
-
427
- - **Declarations**: `var`, `:=` (with re-declaration), `const` (with `iota`), `type`,
428
- `func`, methods, `init()`.
429
- - **Control flow**: `if`/`else` (with init statement), `for` (classic, condition-only,
430
- infinite, `range`), `switch`/`case`/`default`/`fallthrough`, type switches, labeled
431
- `break`/`continue`, `defer`, `panic`/`recover`.
432
- - **Types**: `int`, `float64`, `string`, `bool`, sized integers (`int8`–`int64`,
433
- `uint8`–`uint64`), `float32`, `byte`, `rune`, `error`, slices, maps, arrays, structs,
434
- interfaces (with embedding), pointers (`*T`, `&x`), type aliases, function types.
435
- - **Expressions**: all arithmetic, comparison, logical, and bitwise operators (including
436
- `&^`), compound assignment, increment/decrement, type conversions, type assertions
437
- (plain and comma-ok), slice expressions (`a[lo:hi]`, `a[lo:hi:max]`), composite
438
- literals, `[...]T{...}` inference, rune literals, raw string literals, variadic
439
- spread, blank identifier `_`.
440
- - **Builtins**: `len`, `cap`, `append`, `copy`, `make`, `delete`, `new`, `clear`, `min`,
441
- `max`, `print`, `println`, `panic`, `recover`, `fmt.Sprintf`/`Printf`/`Println`/`Errorf`.
442
- - **Standard library shims**: `strings` (20 functions), `strconv` (8 functions),
443
- `sort` (6 functions), `math` (20 functions + 6 constants), `errors.New`,
444
- `time.Now`/`Since`/`Sleep` + duration constants.
445
- - **Packages**: multi-file packages, cross-package imports, import aliases,
446
- dot imports, blank imports, unused import detection.
436
+ byte-level parity — it is a Go-inspired language for the JavaScript platform.
447
437
 
448
438
  ### GoFront extensions (not in Go)
449
439
 
@@ -460,11 +450,7 @@ These features are intentional additions for the JavaScript platform:
460
450
 
461
451
  | Feature | Reason | Prospect |
462
452
  |---|---|---|
463
- | Generics (`[T any]`) | Touches every compiler stage. Large effort, limited runtime payoff on a JS target. | Feasible — highest-priority future feature. |
464
- | Range over iterator functions (Go 1.23) | `func(yield func(K, V) bool)` protocol. | Feasible. |
465
- | Complex numbers (`complex64`, `complex128`, `3i`) | Would need a runtime complex type. Rarely used in frontend. | Feasible but low priority. |
466
453
  | `goto` | No clean JS translation. Rare in idiomatic Go. | Not planned. |
467
- | Method expressions (`T.Method`) | Requires function-wrapping with explicit receiver. | Feasible. |
468
454
  | Goroutines / channels / `select` | Go's concurrency model has no JS equivalent. A userland scheduler defeats the "no runtime" goal. | Out of scope. |
469
455
  | `unsafe`, `reflect`, `cgo` | Require memory model or runtime type metadata that JS cannot provide. | Out of scope. |
470
456
 
@@ -480,37 +466,25 @@ you know exactly what to expect.
480
466
  | Integer overflow | IEEE 754 float64 semantics | Wraps at type boundary (e.g. `int32`) | All JS numbers are float64. |
481
467
  | Integer precision | Safe up to 2⁵³ | Full width per type (`int64` = 64 bits) | JS `number` limitation. |
482
468
  | `cap()` | Always equals `len()` | May exceed `len()` | JS arrays have no separate capacity. |
483
- | Fixed-size arrays (`[n]T`) | Plain JS arrays (no length enforcement) | Fixed at compile time | Runtime enforcement adds overhead for no JS benefit. |
469
+ | Fixed-size arrays (`[n]T`) | Compile-time enforcement (bounds, append rejected, size matching); plain JS arrays at runtime | Fixed at compile time, value-type copy semantics | Runtime enforcement adds overhead; compile-time checks catch most errors. |
484
470
  | `nil` | Maps to `null` | Typed nil (distinct per type) | JS has no typed nil concept. |
485
471
  | `rune` / `byte` | Treated as `int` | Distinct types with UTF-8 encoding | JS strings are UTF-16. |
486
- | `range` over string | JS characters (UTF-16 via `Array.from`) | Runes (UTF-8 code points) | UTF-16 vs UTF-8 mismatch. |
472
+ | `range` over string | Rune integers via `.codePointAt()` | Runes (UTF-8 code points) | Close match — indices are byte-sequential, values are code points. |
487
473
  | `len()` on strings | JS `.length` (UTF-16 code units) | Byte count (UTF-8) | Matching Go would require `TextEncoder` on every call. |
488
- | `error` type | Plain string | Interface `{ Error() string }` | Practical simplification for JS. |
474
+ | `error` type | Interface `{ Error() string }` with `__error` runtime objects | Interface `{ Error() string }` | Close match. Custom error types, `errors.Is`/`Unwrap`, `%w` wrapping all work. `toString()` added for JS string context compat. |
489
475
  | `defer` | `try`/`finally` with a defer stack | Runtime stack unwinding | Covers most cases but not identical to Go internals. |
490
476
  | Struct field tags | Parsed, silently discarded | Available via `reflect` | No reflection = no use for tag values. |
491
- | Pointers (`&x`, `*p`) | Syntax accepted, semantically transparent | True memory indirection | JS has no pointer model. |
477
+ | Pointers (`&x`, `*p`) | Address-taken scalars boxed as `{ value: T }`; structs/slices/maps are reference types (no boxing) | True memory indirection | Shared mutation works for scalars; struct fields and slice elements not yet addressable. |
492
478
  | Three-index slice (`a[lo:hi:max]`) | `max` is parsed but ignored | Sets result capacity | JS arrays have no capacity. |
493
- | Exported / unexported | Uppercase names exported across packages | Access enforced per-identifier | Cross-package access to lowercase names is not yet an error. |
479
+ | Exported / unexported | Enforced for GoFront packages; external `.d.ts`/npm namespaces are exempt | Access enforced uniformly | External JS APIs use lowercase names by convention. |
494
480
 
495
481
  ---
496
482
 
497
483
  ## Roadmap
498
484
 
499
- These are the open items roughly in priority order. GoFront's guiding principle is
500
- **no runtime** — features that need a scheduler, runtime type descriptors, or raw memory
501
- access are out of scope.
502
-
503
- | Feature | Difficulty | Notes |
504
- |---|---|---|
505
- | Generics (`[T any]`) | High | Biggest modern Go feature gap. Touches every compiler stage but has low runtime pressure. |
506
- | Range over iterator functions | Medium | Go 1.23 `func(yield func(K, V) bool)` protocol. Low runtime pressure. |
507
- | Complex number types | Medium | New type kind + builtins (`complex`, `real`, `imag`). Shimmed with a two-field object. |
508
- | Richer error values | Medium | Move `error` from plain string to an interface-like value. |
509
- | Better array semantics | Medium | Arrays are currently indistinguishable from slices at runtime. |
510
- | Better pointer model | High | Current `{ value: T }` boxing is useful but shallow. |
511
-
512
- Explicitly **out of scope**: goroutines, channels, `select`, `unsafe`, full `reflect`,
513
- `cgo`, exact integer overflow, Go-equivalent map semantics.
485
+ See [`docs/ROADMAP.md`](docs/ROADMAP.md) for the full roadmap and release history.
486
+ Design documents for planned features are organised by release under `docs/v*/`
487
+ (e.g. [`docs/v0.0.5/`](docs/v0.0.5/)).
514
488
 
515
489
  ---
516
490
 
@@ -520,7 +494,8 @@ Explicitly **out of scope**: goroutines, channels, `select`, `unsafe`, full `ref
520
494
  npm test
521
495
  ```
522
496
 
523
- 611 tests covering language features, type errors, edge cases, DOM (jsdom), external
497
+ 869 tests covering language features, type errors, edge cases, DOM (jsdom), external
524
498
  `.d.ts`, npm resolver, multi-file compilation, embedded structs, string formatting, map
525
499
  iteration order, integer overflow semantics, unused variable detection, unused import
526
- detection, semantic difference verification, stdlib shim packages, and both example apps.
500
+ detection, semantic difference verification, stdlib shim packages, generics (type params,
501
+ inference, constraints), and both example apps.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gofront",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "author": "Luuk van Venrooij",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -39,7 +39,6 @@
39
39
  },
40
40
  "devDependencies": {
41
41
  "@biomejs/biome": "^2.4.11",
42
- "jsdom": "^29.0.2",
43
- "terser": "^5.46.1"
42
+ "jsdom": "^29.0.2"
44
43
  }
45
44
  }