goscript 0.2.3 → 0.2.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.
Files changed (160) hide show
  1. package/README.md +8 -8
  2. package/cmd/go_js_wasm_exec/main.go +1 -1
  3. package/cmd/go_js_wasm_exec/main_test.go +1 -1
  4. package/cmd/goscript/cmd-compile.go +9 -1
  5. package/cmd/goscript/cmd-test.go +1 -1
  6. package/cmd/goscript/cmd_compile_test.go +44 -0
  7. package/cmd/goscript/deps.go +1 -1
  8. package/cmd/goscript-wasm/main.go +2 -2
  9. package/compiler/compile-request.go +19 -0
  10. package/compiler/compile_bench_test.go +121 -0
  11. package/compiler/compliance_test.go +17 -1
  12. package/compiler/config.go +2 -0
  13. package/compiler/gotest/result.go +1 -1
  14. package/compiler/gotest/runner.go +2 -2
  15. package/compiler/gotest/runner_test.go +4 -7
  16. package/compiler/index.test.ts +28 -0
  17. package/compiler/index.ts +32 -16
  18. package/compiler/lowering.go +1236 -143
  19. package/compiler/lowering_bench_test.go +4 -0
  20. package/compiler/override-facts.go +1 -1
  21. package/compiler/override-registry_test.go +125 -0
  22. package/compiler/package-graph.go +92 -0
  23. package/compiler/package-graph_test.go +113 -0
  24. package/compiler/runtime-contract.go +1 -1
  25. package/compiler/semantic-model.go +32 -0
  26. package/compiler/skeleton_test.go +284 -11
  27. package/compiler/wasm/compile.go +1 -1
  28. package/compiler/wasm/compile_test.go +1 -1
  29. package/dist/compiler/index.d.ts +4 -0
  30. package/dist/compiler/index.js +26 -15
  31. package/dist/compiler/index.js.map +1 -1
  32. package/dist/gs/compress/gzip/index.d.ts +41 -0
  33. package/dist/gs/compress/gzip/index.js +235 -0
  34. package/dist/gs/compress/gzip/index.js.map +1 -0
  35. package/dist/gs/database/sql/driver/index.d.ts +165 -0
  36. package/dist/gs/database/sql/driver/index.js +432 -0
  37. package/dist/gs/database/sql/driver/index.js.map +1 -0
  38. package/dist/gs/encoding/binary/index.d.ts +71 -0
  39. package/dist/gs/encoding/binary/index.js +778 -0
  40. package/dist/gs/encoding/binary/index.js.map +1 -0
  41. package/dist/gs/fmt/fmt.js +156 -57
  42. package/dist/gs/fmt/fmt.js.map +1 -1
  43. package/dist/gs/github.com/klauspost/cpuid/v2/index.d.ts +11 -0
  44. package/dist/gs/github.com/klauspost/cpuid/v2/index.js +28 -0
  45. package/dist/gs/github.com/klauspost/cpuid/v2/index.js.map +1 -0
  46. package/dist/gs/github.com/pkg/errors/errors.d.ts +0 -2
  47. package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
  48. package/dist/gs/github.com/pkg/errors/index.d.ts +2 -1
  49. package/dist/gs/github.com/pkg/errors/index.js +1 -1
  50. package/dist/gs/github.com/pkg/errors/index.js.map +1 -1
  51. package/dist/gs/github.com/pkg/errors/stack.d.ts +8 -19
  52. package/dist/gs/github.com/pkg/errors/stack.js +26 -61
  53. package/dist/gs/github.com/pkg/errors/stack.js.map +1 -1
  54. package/dist/gs/golang.org/x/crypto/cryptobyte/asn1/index.d.ts +19 -0
  55. package/dist/gs/golang.org/x/crypto/cryptobyte/asn1/index.js +25 -0
  56. package/dist/gs/golang.org/x/crypto/cryptobyte/asn1/index.js.map +1 -0
  57. package/dist/gs/golang.org/x/crypto/cryptobyte/index.d.ts +104 -0
  58. package/dist/gs/golang.org/x/crypto/cryptobyte/index.js +1107 -0
  59. package/dist/gs/golang.org/x/crypto/cryptobyte/index.js.map +1 -0
  60. package/dist/gs/golang.org/x/crypto/internal/alias/index.d.ts +3 -0
  61. package/dist/gs/golang.org/x/crypto/internal/alias/index.js +39 -0
  62. package/dist/gs/golang.org/x/crypto/internal/alias/index.js.map +1 -0
  63. package/dist/gs/io/fs/glob.js +1 -1
  64. package/dist/gs/io/fs/glob.js.map +1 -1
  65. package/dist/gs/io/fs/readlink.d.ts +1 -1
  66. package/dist/gs/io/fs/readlink.js +2 -2
  67. package/dist/gs/io/fs/readlink.js.map +1 -1
  68. package/dist/gs/io/fs/stat.d.ts +4 -2
  69. package/dist/gs/io/fs/stat.js +12 -73
  70. package/dist/gs/io/fs/stat.js.map +1 -1
  71. package/dist/gs/io/fs/sub.d.ts +2 -2
  72. package/dist/gs/io/fs/sub.js +7 -7
  73. package/dist/gs/io/fs/sub.js.map +1 -1
  74. package/dist/gs/io/fs/walk.js +1 -1
  75. package/dist/gs/io/fs/walk.js.map +1 -1
  76. package/dist/gs/net/http/index.d.ts +18 -14
  77. package/dist/gs/net/http/index.js +44 -23
  78. package/dist/gs/net/http/index.js.map +1 -1
  79. package/dist/gs/net/http/pprof/index.d.ts +5 -5
  80. package/dist/gs/net/http/pprof/index.js +21 -21
  81. package/dist/gs/net/http/pprof/index.js.map +1 -1
  82. package/dist/gs/runtime/runtime.d.ts +6 -1
  83. package/dist/gs/runtime/runtime.js +15 -8
  84. package/dist/gs/runtime/runtime.js.map +1 -1
  85. package/dist/gs/runtime/trace/index.d.ts +8 -5
  86. package/dist/gs/runtime/trace/index.js +324 -23
  87. package/dist/gs/runtime/trace/index.js.map +1 -1
  88. package/dist/gs/slices/slices.d.ts +2 -1
  89. package/dist/gs/slices/slices.js +9 -3
  90. package/dist/gs/slices/slices.js.map +1 -1
  91. package/dist/gs/sort/search.gs.d.ts +3 -1
  92. package/dist/gs/sort/search.gs.js +18 -53
  93. package/dist/gs/sort/search.gs.js.map +1 -1
  94. package/dist/gs/sync/sync.d.ts +1 -1
  95. package/dist/gs/sync/sync.js +3 -0
  96. package/dist/gs/sync/sync.js.map +1 -1
  97. package/dist/gs/time/time.d.ts +22 -29
  98. package/dist/gs/time/time.js +111 -32
  99. package/dist/gs/time/time.js.map +1 -1
  100. package/dist/gs/unsafe/unsafe.d.ts +3 -2
  101. package/dist/gs/unsafe/unsafe.js.map +1 -1
  102. package/go.mod +7 -5
  103. package/go.sum +12 -26
  104. package/gs/builtin/runtime-contract.test.ts +25 -0
  105. package/gs/compress/gzip/index.test.ts +86 -0
  106. package/gs/compress/gzip/index.ts +297 -0
  107. package/gs/compress/gzip/meta.json +6 -0
  108. package/gs/compress/gzip/parity.json +45 -0
  109. package/gs/database/sql/driver/index.test.ts +88 -0
  110. package/gs/database/sql/driver/index.ts +675 -0
  111. package/gs/database/sql/driver/meta.json +3 -0
  112. package/gs/database/sql/driver/parity.json +144 -0
  113. package/gs/embed/index.test.ts +1 -1
  114. package/gs/encoding/binary/index.test.ts +239 -0
  115. package/gs/encoding/binary/index.ts +999 -0
  116. package/gs/encoding/binary/meta.json +9 -0
  117. package/gs/encoding/binary/parity.json +72 -0
  118. package/gs/fmt/fmt.test.ts +28 -0
  119. package/gs/fmt/fmt.ts +198 -61
  120. package/gs/fmt/meta.json +2 -1
  121. package/gs/github.com/klauspost/cpuid/v2/index.ts +38 -0
  122. package/gs/github.com/klauspost/cpuid/v2/meta.json +3 -0
  123. package/gs/github.com/pkg/errors/errors.ts +1 -2
  124. package/gs/github.com/pkg/errors/index.ts +2 -1
  125. package/gs/github.com/pkg/errors/stack.ts +34 -62
  126. package/gs/golang.org/x/crypto/cryptobyte/asn1/index.test.ts +19 -0
  127. package/gs/golang.org/x/crypto/cryptobyte/asn1/index.ts +29 -0
  128. package/gs/golang.org/x/crypto/cryptobyte/index.test.ts +255 -0
  129. package/gs/golang.org/x/crypto/cryptobyte/index.ts +1441 -0
  130. package/gs/golang.org/x/crypto/cryptobyte/meta.json +3 -0
  131. package/gs/golang.org/x/crypto/internal/alias/index.test.ts +40 -0
  132. package/gs/golang.org/x/crypto/internal/alias/index.ts +40 -0
  133. package/gs/io/fs/glob.ts +1 -1
  134. package/gs/io/fs/meta.json +3 -0
  135. package/gs/io/fs/readlink.test.ts +2 -2
  136. package/gs/io/fs/readlink.ts +5 -2
  137. package/gs/io/fs/stat.test.ts +79 -0
  138. package/gs/io/fs/stat.ts +24 -10
  139. package/gs/io/fs/sub.test.ts +93 -0
  140. package/gs/io/fs/sub.ts +9 -9
  141. package/gs/io/fs/walk.ts +1 -1
  142. package/gs/net/http/index.test.ts +207 -2
  143. package/gs/net/http/index.ts +68 -37
  144. package/gs/net/http/meta.json +3 -1
  145. package/gs/net/http/pprof/index.test.ts +4 -4
  146. package/gs/net/http/pprof/index.ts +30 -27
  147. package/gs/runtime/runtime.test.ts +16 -0
  148. package/gs/runtime/runtime.ts +17 -9
  149. package/gs/runtime/trace/index.test.ts +113 -14
  150. package/gs/runtime/trace/index.ts +384 -34
  151. package/gs/runtime/trace/meta.json +1 -0
  152. package/gs/slices/slices.test.ts +24 -1
  153. package/gs/slices/slices.ts +14 -4
  154. package/gs/sort/meta.json +1 -0
  155. package/gs/sort/search.gs.ts +20 -5
  156. package/gs/sync/sync.ts +4 -1
  157. package/gs/time/time.test.ts +79 -2
  158. package/gs/time/time.ts +133 -33
  159. package/gs/unsafe/unsafe.ts +4 -2
  160. package/package.json +2 -2
@@ -789,6 +789,61 @@ func TestCompilePackagesReadsShadowedVarRefStructFieldsOnce(t *testing.T) {
789
789
  }
790
790
  }
791
791
 
792
+ func TestCompilePackagesUnwrapsAnonymousStructPointerFieldReceivers(t *testing.T) {
793
+ moduleDir := writePackageGraphFixture(t, map[string]string{
794
+ "go.mod": "module example.test/anonstructptr\n\ngo 1.25.3\n",
795
+ "main.go": strings.Join([]string{
796
+ "package anonstructptr",
797
+ "func mergeCore(dst, src *struct {",
798
+ " IsBare bool",
799
+ " Worktree string",
800
+ "}) {",
801
+ " if src.IsBare {",
802
+ " dst.IsBare = true",
803
+ " }",
804
+ " if src.Worktree != \"\" {",
805
+ " dst.Worktree = src.Worktree",
806
+ " }",
807
+ "}",
808
+ "",
809
+ }, "\n"),
810
+ })
811
+ outputDir := filepath.Join(t.TempDir(), "output")
812
+ comp, err := NewCompiler(&Config{Dir: moduleDir, OutputPath: outputDir}, nil, nil)
813
+ if err != nil {
814
+ t.Fatal(err.Error())
815
+ }
816
+
817
+ if _, err := comp.CompilePackages(context.Background(), "."); err != nil {
818
+ t.Fatal(err.Error())
819
+ }
820
+ outputFile := filepath.Join(outputDir, "@goscript", "example.test", "anonstructptr", "main.gs.ts")
821
+ content, err := os.ReadFile(outputFile)
822
+ if err != nil {
823
+ t.Fatal(err.Error())
824
+ }
825
+ text := string(content)
826
+ for _, want := range []string{
827
+ `$.pointerValue<{"IsBare": boolean, "Worktree": string}>(src).IsBare`,
828
+ `$.pointerValue<{"IsBare": boolean, "Worktree": string}>(dst).IsBare = true`,
829
+ `$.pointerValue<{"IsBare": boolean, "Worktree": string}>(dst).Worktree = $.pointerValue<{"IsBare": boolean, "Worktree": string}>(src).Worktree`,
830
+ } {
831
+ if !strings.Contains(text, want) {
832
+ t.Fatalf("missing %q in generated output:\n%s", want, text)
833
+ }
834
+ }
835
+ for _, bad := range []string{
836
+ "src.IsBare",
837
+ "dst.IsBare",
838
+ "src.Worktree",
839
+ "dst.Worktree",
840
+ } {
841
+ if strings.Contains(text, bad) {
842
+ t.Fatalf("anonymous struct pointer field receiver stayed wrapped at %q:\n%s", bad, text)
843
+ }
844
+ }
845
+ }
846
+
792
847
  func TestCompilePackagesWrapsChannelSendInterfaceValues(t *testing.T) {
793
848
  moduleDir := writePackageGraphFixture(t, map[string]string{
794
849
  "go.mod": "module example.test/chansendiface\n\ngo 1.25.3\n",
@@ -1436,7 +1491,7 @@ func TestCompilePackagesEmitsSideEffectImportsForInterfaceRegistry(t *testing.T)
1436
1491
  "import * as dep from \"@goscript/example.test/interface-registry/dep/index.js\"",
1437
1492
  "import \"@goscript/example.test/interface-registry/dep/index.js\"",
1438
1493
  "import type * as __goscript_local from \"./local.gs.ts\"",
1439
- "case $.typeAssert<Exclude<__goscript_local.Local, null>>(__goscriptTypeSwitchValue, \"main.Local\").ok",
1494
+ "case $.typeAssert<__goscript_local.Local | null>(__goscriptTypeSwitchValue, \"main.Local\").ok",
1440
1495
  "$.typeAssertTuple<dep.Remote | null>(v, \"dep.Remote\")",
1441
1496
  } {
1442
1497
  if !strings.Contains(mainText, want) {
@@ -1546,6 +1601,56 @@ func TestCompilePackagesLowersUnsafeBytePointerArithmetic(t *testing.T) {
1546
1601
  }
1547
1602
  }
1548
1603
 
1604
+ func TestCompilePackagesLowersGMSUnsafeArrayPointerConversions(t *testing.T) {
1605
+ moduleDir := writePackageGraphFixture(t, map[string]string{
1606
+ "go.mod": "module example.test/gmsunsafe\n\ngo 1.25.3\n",
1607
+ "main.go": strings.Join([]string{
1608
+ "package main",
1609
+ "import (",
1610
+ " \"reflect\"",
1611
+ " \"unsafe\"",
1612
+ ")",
1613
+ "func IntBytes(n int64) byte {",
1614
+ " mem := (*[8]byte)(unsafe.Pointer(&n))",
1615
+ " bytes := *mem",
1616
+ " return bytes[0]",
1617
+ "}",
1618
+ "func StringToBytes(str string) []byte {",
1619
+ " if len(str) == 0 {",
1620
+ " return []byte{}",
1621
+ " }",
1622
+ " return (*[0x7fff0000]byte)(unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&str)).Data))[:len(str):len(str)]",
1623
+ "}",
1624
+ "",
1625
+ }, "\n"),
1626
+ })
1627
+ outputDir := filepath.Join(t.TempDir(), "output")
1628
+ comp, err := NewCompiler(&Config{Dir: moduleDir, OutputPath: outputDir}, nil, nil)
1629
+ if err != nil {
1630
+ t.Fatal(err.Error())
1631
+ }
1632
+
1633
+ _, err = comp.CompilePackages(context.Background(), ".")
1634
+ if err != nil {
1635
+ t.Fatal(err.Error())
1636
+ }
1637
+ outputFile := filepath.Join(outputDir, "@goscript", "example.test", "gmsunsafe", "main.gs.ts")
1638
+ content, err := os.ReadFile(outputFile)
1639
+ if err != nil {
1640
+ t.Fatal(err.Error())
1641
+ }
1642
+ text := string(content)
1643
+ if !strings.Contains(text, "$.arrayPointerFromIndexRef<number>($.indexRef([n.value], 0), 8, 8, 1)") {
1644
+ t.Fatalf("missing scalar unsafe array pointer conversion:\n%s", text)
1645
+ }
1646
+ if !strings.Contains(text, "$.arrayPointerFromIndexRef<number>($.indexRef($.stringToBytes(str.value), 0), 2147418112, 1, 1)") {
1647
+ t.Fatalf("missing string data unsafe array pointer conversion:\n%s", text)
1648
+ }
1649
+ if strings.Contains(text, "unsafe.Pointer(&n) as any") || strings.Contains(text, "StringHeader)(unsafe.Pointer(&str)).Data) as any") {
1650
+ t.Fatalf("unsafe array pointer conversion fell back to any cast:\n%s", text)
1651
+ }
1652
+ }
1653
+
1549
1654
  func TestCompilePackagesEmitsStructMethodsAndPointerAssertions(t *testing.T) {
1550
1655
  moduleDir := writePackageGraphFixture(t, map[string]string{
1551
1656
  "go.mod": "module example.test/structs\n\ngo 1.25.3\n",
@@ -1669,6 +1774,124 @@ func TestCompilePackagesEscapesReservedTypeNames(t *testing.T) {
1669
1774
  }
1670
1775
  }
1671
1776
 
1777
+ func TestCompilePackagesEscapesStrictModeRestrictedIdentifiers(t *testing.T) {
1778
+ moduleDir := writePackageGraphFixture(t, map[string]string{
1779
+ "go.mod": "module example.test/strictidents\n\ngo 1.25.3\n",
1780
+ "main.go": strings.Join([]string{
1781
+ "package main",
1782
+ "func choose(arguments int) (eval int) {",
1783
+ " eval = arguments + 1",
1784
+ " arguments = eval + arguments",
1785
+ " return",
1786
+ "}",
1787
+ "func main() {",
1788
+ " eval := choose(1)",
1789
+ " arguments := eval + 1",
1790
+ " println(eval, arguments)",
1791
+ "}",
1792
+ "",
1793
+ }, "\n"),
1794
+ })
1795
+ outputDir := filepath.Join(t.TempDir(), "output")
1796
+ comp, err := NewCompiler(&Config{Dir: moduleDir, OutputPath: outputDir}, nil, nil)
1797
+ if err != nil {
1798
+ t.Fatal(err.Error())
1799
+ }
1800
+
1801
+ if _, err := comp.CompilePackages(context.Background(), "."); err != nil {
1802
+ t.Fatal(err.Error())
1803
+ }
1804
+ outputFile := filepath.Join(outputDir, "@goscript", "example.test", "strictidents", "main.gs.ts")
1805
+ content, err := os.ReadFile(outputFile)
1806
+ if err != nil {
1807
+ t.Fatal(err.Error())
1808
+ }
1809
+ text := string(content)
1810
+ for _, want := range []string{
1811
+ "function choose(_arguments: number): number",
1812
+ "let _eval: number = 0",
1813
+ "_eval = _arguments + 1",
1814
+ "_arguments = _eval + _arguments",
1815
+ "let _eval = choose(1)",
1816
+ "let _arguments = _eval + 1",
1817
+ } {
1818
+ if !strings.Contains(text, want) {
1819
+ t.Fatalf("missing %q in generated output:\n%s", want, text)
1820
+ }
1821
+ }
1822
+ for _, bad := range []string{
1823
+ "let eval",
1824
+ " eval =",
1825
+ "function choose(arguments",
1826
+ "let arguments",
1827
+ " arguments =",
1828
+ } {
1829
+ if strings.Contains(text, bad) {
1830
+ t.Fatalf("strict-mode restricted identifier was not escaped, found %q:\n%s", bad, text)
1831
+ }
1832
+ }
1833
+ }
1834
+
1835
+ func TestCompilePackagesDoesNotEmitHiddenEmbeddedMethodOverField(t *testing.T) {
1836
+ moduleDir := writePackageGraphFixture(t, map[string]string{
1837
+ "go.mod": "module example.test/hiddenembeddedmethod\n\ngo 1.25.3\n",
1838
+ "main.go": strings.Join([]string{
1839
+ "package main",
1840
+ "type embedded struct{}",
1841
+ "func (embedded) Database() string {",
1842
+ " return \"method\"",
1843
+ "}",
1844
+ "type holder struct {",
1845
+ " Database string",
1846
+ " embedded",
1847
+ "}",
1848
+ "func value(h holder) string {",
1849
+ " return h.Database",
1850
+ "}",
1851
+ "",
1852
+ }, "\n"),
1853
+ })
1854
+ outputDir := filepath.Join(t.TempDir(), "output")
1855
+ comp, err := NewCompiler(&Config{Dir: moduleDir, OutputPath: outputDir}, nil, nil)
1856
+ if err != nil {
1857
+ t.Fatal(err.Error())
1858
+ }
1859
+
1860
+ if _, err := comp.CompilePackages(context.Background(), "."); err != nil {
1861
+ t.Fatal(err.Error())
1862
+ }
1863
+ outputFile := filepath.Join(outputDir, "@goscript", "example.test", "hiddenembeddedmethod", "main.gs.ts")
1864
+ content, err := os.ReadFile(outputFile)
1865
+ if err != nil {
1866
+ t.Fatal(err.Error())
1867
+ }
1868
+ text := string(content)
1869
+ for _, want := range []string{
1870
+ "public get Database(): string",
1871
+ "public set Database(value: string)",
1872
+ "return h.Database",
1873
+ } {
1874
+ if !strings.Contains(text, want) {
1875
+ t.Fatalf("missing %q in generated output:\n%s", want, text)
1876
+ }
1877
+ }
1878
+ if got := strings.Count(text, "public Database("); got != 1 {
1879
+ t.Fatalf("expected only embedded.Database method, got %d declarations:\n%s", got, text)
1880
+ }
1881
+ holderStart := strings.Index(text, "export class holder")
1882
+ embeddedStart := strings.Index(text, "export class embedded")
1883
+ if holderStart < 0 || embeddedStart < 0 {
1884
+ t.Fatalf("missing holder or embedded class:\n%s", text)
1885
+ }
1886
+ holderText := text[holderStart:]
1887
+ if embeddedStart > holderStart {
1888
+ holderText = text[holderStart:embeddedStart]
1889
+ }
1890
+ if strings.Contains(holderText, "public Database(") {
1891
+ t.Fatalf("hidden embedded method was emitted on holder:\n%s", holderText)
1892
+ }
1893
+ }
1894
+
1672
1895
  func TestCompilePackagesAvoidsPointerMethodTypeNameShadow(t *testing.T) {
1673
1896
  moduleDir := writePackageGraphFixture(t, map[string]string{
1674
1897
  "go.mod": "module example.test/methodshadow\n\ngo 1.25.3\n",
@@ -1907,9 +2130,9 @@ func TestCompilePackagesEmitsArraySliceMapStringAndNamedMethods(t *testing.T) {
1907
2130
  "let literal: $.Slice<number> = $.arrayToSlice<number>([1, 2])",
1908
2131
  "literal = $.append(literal, 3)",
1909
2132
  "slice![0] = arr[1]",
1910
- "let m: Map<string, number> | null = $.makeMap<string, number>()",
2133
+ "let m: globalThis.Map<string, number> | null = $.makeMap<string, number>()",
1911
2134
  "$.mapSet(m, \"one\", 1)",
1912
- "let [value, ok] = $.mapGet(m, \"missing\", 0)",
2135
+ "let [value, ok] = $.mapGet<string, number, number>(m, \"missing\", 0)",
1913
2136
  "slice![0]",
1914
2137
  "literal![2]",
1915
2138
  "let list: $.VarRef<MySlice> = $.varRef(null as MySlice)",
@@ -2447,8 +2670,8 @@ func TestCompilePackagesEmitsInterfacesMethodValuesTypeSwitchesAndFunctionAssert
2447
2670
  "elemType: { kind: $.TypeKind.Struct, methods: [], fields: [{ name: \"Name\", key: \"Name\", type: { kind: $.TypeKind.Basic, name: \"string\" }",
2448
2671
  "let fn = __goscriptTuple",
2449
2672
  "switch (true)",
2450
- "case $.typeAssert<Exclude<ReadCloser, null>>(__goscriptTypeSwitchValue, \"main.ReadCloser\").ok",
2451
- "let v: Exclude<ReadCloser, null> = $.typeAssert<Exclude<ReadCloser, null>>(__goscriptTypeSwitchValue, \"main.ReadCloser\").value",
2673
+ "case $.typeAssert<ReadCloser | null>(__goscriptTypeSwitchValue, \"main.ReadCloser\").ok",
2674
+ "let v: ReadCloser | null = $.typeAssert<ReadCloser | null>(__goscriptTypeSwitchValue, \"main.ReadCloser\").value",
2452
2675
  } {
2453
2676
  if !strings.Contains(text, want) {
2454
2677
  t.Fatalf("missing %q in generated output:\n%s", want, text)
@@ -2541,8 +2764,8 @@ func TestCompilePackagesUsesNonNilInterfaceTypeSwitchCaseVarRefs(t *testing.T) {
2541
2764
  text := string(content)
2542
2765
  for _, want := range []string{
2543
2766
  "export type tcpConn = {",
2544
- "case $.typeAssert<Exclude<tcpConn, null>>(__goscriptTypeSwitchValue, \"main.tcpConn\").ok",
2545
- "let c: $.VarRef<Exclude<tcpConn, null>> = $.varRef($.typeAssert<Exclude<tcpConn, null>>(__goscriptTypeSwitchValue, \"main.tcpConn\").value)",
2767
+ "case $.typeAssert<tcpConn | null>(__goscriptTypeSwitchValue, \"main.tcpConn\").ok",
2768
+ "let c: $.VarRef<tcpConn | null> = $.varRef($.typeAssert<tcpConn | null>(__goscriptTypeSwitchValue, \"main.tcpConn\").value)",
2546
2769
  "$.pointerValue<Exclude<tcpConn, null>>(c.value).SyscallConn()",
2547
2770
  } {
2548
2771
  if !strings.Contains(text, want) {
@@ -3454,7 +3677,7 @@ func TestCompilePackagesEmitsAsyncChannelsSelectAndDefer(t *testing.T) {
3454
3677
  "await $.chanSend($.pointerValue<Worker>(w).ch, v)",
3455
3678
  "return await $.chanRecv($.pointerValue<Worker>(w).ch)",
3456
3679
  "await using __defer = new $.AsyncDisposableStack()",
3457
- "queueMicrotask(async () => { await ($.functionValue(async (): globalThis.Promise<void> => {",
3680
+ "queueMicrotask(async () => { await (async (): globalThis.Promise<void> => {",
3458
3681
  "$.selectStatement<any, void>([",
3459
3682
  "let v = __goscriptSelect1Result.value",
3460
3683
  "return $.selectVoidReturn()",
@@ -4743,8 +4966,8 @@ func TestCompilePackagesLowersMethodValuesWithFixedParameters(t *testing.T) {
4743
4966
  }
4744
4967
  text := string(content)
4745
4968
  for _, want := range []string{
4746
- "((__receiver) => (n: number) => Counter_Add(__receiver, n))(c)",
4747
- "((__receiver) => () => __receiver.Run())(",
4969
+ "$.functionValue(((__receiver) => (n: number) => Counter_Add(__receiver, n))(c), ({ kind: $.TypeKind.Function",
4970
+ "$.functionValue(((__receiver) => () => __receiver.Run())(",
4748
4971
  } {
4749
4972
  if !strings.Contains(text, want) {
4750
4973
  t.Fatalf("missing %q in generated output:\n%s", want, text)
@@ -4755,6 +4978,56 @@ func TestCompilePackagesLowersMethodValuesWithFixedParameters(t *testing.T) {
4755
4978
  }
4756
4979
  }
4757
4980
 
4981
+ func TestCompilePackagesLowersSortSearchCallbackAsAsyncCompatible(t *testing.T) {
4982
+ moduleDir := writePackageGraphFixture(t, map[string]string{
4983
+ "go.mod": "module example.test/sync-callback\n\ngo 1.25.3\n",
4984
+ "main.go": strings.Join([]string{
4985
+ "package main",
4986
+ "import \"sort\"",
4987
+ "type Item interface {",
4988
+ " Name() string",
4989
+ "}",
4990
+ "type Items interface {",
4991
+ " Len() int",
4992
+ " Get(i int) Item",
4993
+ "}",
4994
+ "func Lookup(items Items, name string) int {",
4995
+ " return sort.Search(items.Len(), func(i int) bool {",
4996
+ " item := items.Get(i)",
4997
+ " if item == nil {",
4998
+ " return true",
4999
+ " }",
5000
+ " return item.Name() >= name",
5001
+ " })",
5002
+ "}",
5003
+ "",
5004
+ }, "\n"),
5005
+ })
5006
+ outputDir := filepath.Join(t.TempDir(), "output")
5007
+ comp, err := NewCompiler(&Config{Dir: moduleDir, OutputPath: outputDir}, nil, nil)
5008
+ if err != nil {
5009
+ t.Fatal(err.Error())
5010
+ }
5011
+
5012
+ if _, err := comp.CompilePackages(context.Background(), "."); err != nil {
5013
+ t.Fatal(err.Error())
5014
+ }
5015
+ content, err := os.ReadFile(filepath.Join(outputDir, "@goscript", "example.test", "sync-callback", "main.gs.ts"))
5016
+ if err != nil {
5017
+ t.Fatal(err.Error())
5018
+ }
5019
+ text := string(content)
5020
+ for _, want := range []string{
5021
+ "return await sort.Search(",
5022
+ "$.functionValue(async (i: number): globalThis.Promise<boolean> => {",
5023
+ "let item = await $.pointerValue<Exclude<Items, null>>(items).Get(i)",
5024
+ } {
5025
+ if !strings.Contains(text, want) {
5026
+ t.Fatalf("missing %q in generated output:\n%s", want, text)
5027
+ }
5028
+ }
5029
+ }
5030
+
4758
5031
  func TestCompilePackagesQualifiesImportedTypesInSignaturesAndZeroValues(t *testing.T) {
4759
5032
  moduleDir := writePackageGraphFixture(t, map[string]string{
4760
5033
  "go.mod": "module example.test/qualified\n\ngo 1.25.3\n",
@@ -5332,7 +5605,7 @@ func TestCompilePackagesLowersNamedStructConversionWithTypedAsyncFact(t *testing
5332
5605
  if !strings.Contains(text, "$.markAsStructValue(new Target({Value: __goscriptConvert") {
5333
5606
  t.Fatalf("missing typed named struct conversion target:\n%s", text)
5334
5607
  }
5335
- if !strings.Contains(text, "const __goscriptConvert1 = await ($.functionValue(async ") {
5608
+ if !strings.Contains(text, "const __goscriptConvert1 = await (async ") {
5336
5609
  t.Fatalf("missing async fact from function literal conversion source:\n%s", text)
5337
5610
  }
5338
5611
  }
@@ -2,7 +2,7 @@
2
2
  package wasm
3
3
 
4
4
  import (
5
- "github.com/aperturerobotics/goscript/compiler"
5
+ "github.com/s4wave/goscript/compiler"
6
6
  )
7
7
 
8
8
  // CompileSource compiles import-free browser source strings to TypeScript.
@@ -5,7 +5,7 @@ import (
5
5
  "strings"
6
6
  "testing"
7
7
 
8
- "github.com/aperturerobotics/goscript/compiler"
8
+ "github.com/s4wave/goscript/compiler"
9
9
  )
10
10
 
11
11
  func TestCompileSourceCompilesSingleFile(t *testing.T) {
@@ -8,6 +8,10 @@ export interface CompileConfig {
8
8
  output?: string;
9
9
  /** The working directory for the compiler. Defaults to the current working directory. */
10
10
  dir?: string;
11
+ /** Compile all transitive dependencies of the requested package. */
12
+ allDependencies?: boolean;
13
+ /** Go import paths to reject from the compiled package graph. */
14
+ packageBlocklist?: string[] | string;
11
15
  /** The path to the goscript executable. Defaults to `go run ./cmd/goscript`. */
12
16
  goscriptPath?: string;
13
17
  }
@@ -16,21 +16,7 @@ export async function compile(config) {
16
16
  }
17
17
  const cwd = config.dir ? path.resolve(config.dir) : process.cwd();
18
18
  const output = config.output ? path.resolve(config.output) : './output';
19
- if (config.goscriptPath) {
20
- await execFileAsync(config.goscriptPath, [
21
- 'compile',
22
- '--package',
23
- config.pkg,
24
- '--output',
25
- output,
26
- '--dir',
27
- cwd,
28
- ]);
29
- return;
30
- }
31
- await execFileAsync('go', [
32
- 'run',
33
- path.join(projectRoot, 'cmd/goscript'),
19
+ const args = [
34
20
  'compile',
35
21
  '--package',
36
22
  config.pkg,
@@ -38,8 +24,33 @@ export async function compile(config) {
38
24
  output,
39
25
  '--dir',
40
26
  cwd,
27
+ ];
28
+ if (config.allDependencies) {
29
+ args.push('--all-dependencies');
30
+ }
31
+ const packageBlocklist = normalizePackageBlocklist(config.packageBlocklist);
32
+ if (packageBlocklist) {
33
+ args.push('--package-blocklist', packageBlocklist);
34
+ }
35
+ if (config.goscriptPath) {
36
+ await execFileAsync(config.goscriptPath, args);
37
+ return;
38
+ }
39
+ await execFileAsync('go', [
40
+ 'run',
41
+ path.join(projectRoot, 'cmd/goscript'),
42
+ ...args,
41
43
  ]);
42
44
  }
45
+ function normalizePackageBlocklist(value) {
46
+ if (!value) {
47
+ return '';
48
+ }
49
+ if (Array.isArray(value)) {
50
+ return value.map((item) => item.trim()).filter(Boolean).join(',');
51
+ }
52
+ return value.trim();
53
+ }
43
54
  /**
44
55
  * Default export for convenience.
45
56
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../compiler/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAErC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;AACzC,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAA;AACjD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;AACrC,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;AAgBtC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,MAAqB;IACjD,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAA;IAC1D,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAA;IACjE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAA;IAEvE,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACxB,MAAM,aAAa,CAAC,MAAM,CAAC,YAAY,EAAE;YACvC,SAAS;YACT,WAAW;YACX,MAAM,CAAC,GAAG;YACV,UAAU;YACV,MAAM;YACN,OAAO;YACP,GAAG;SACJ,CAAC,CAAA;QACF,OAAM;IACR,CAAC;IAED,MAAM,aAAa,CAAC,IAAI,EAAE;QACxB,KAAK;QACL,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC;QACtC,SAAS;QACT,WAAW;QACX,MAAM,CAAC,GAAG;QACV,UAAU;QACV,MAAM;QACN,OAAO;QACP,GAAG;KACJ,CAAC,CAAA;AACJ,CAAC;AAED;;GAEG;AACH,eAAe;IACb,OAAO;CACR,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../compiler/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAErC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;AACzC,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAA;AACjD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;AACrC,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;AAoBtC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,MAAqB;IACjD,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAA;IAC1D,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAA;IACjE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAA;IACvE,MAAM,IAAI,GAAG;QACX,SAAS;QACT,WAAW;QACX,MAAM,CAAC,GAAG;QACV,UAAU;QACV,MAAM;QACN,OAAO;QACP,GAAG;KACJ,CAAA;IACD,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAA;IACjC,CAAC;IACD,MAAM,gBAAgB,GAAG,yBAAyB,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAA;IAC3E,IAAI,gBAAgB,EAAE,CAAC;QACrB,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,gBAAgB,CAAC,CAAA;IACpD,CAAC;IAED,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACxB,MAAM,aAAa,CAAC,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,CAAA;QAC9C,OAAM;IACR,CAAC;IAED,MAAM,aAAa,CAAC,IAAI,EAAE;QACxB,KAAK;QACL,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC;QACtC,GAAG,IAAI;KACR,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,yBAAyB,CAAC,KAAoC;IACrE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,CAAA;IACX,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACnE,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,EAAE,CAAA;AACrB,CAAC;AAED;;GAEG;AACH,eAAe;IACb,OAAO;CACR,CAAA"}
@@ -0,0 +1,41 @@
1
+ import * as $ from '@goscript/builtin/index.js';
2
+ import * as io from '@goscript/io/index.js';
3
+ export declare const NoCompression = 0;
4
+ export declare const BestSpeed = 1;
5
+ export declare const BestCompression = 9;
6
+ export declare const DefaultCompression = -1;
7
+ export declare const HuffmanOnly = -2;
8
+ export declare let ErrChecksum: $.GoError;
9
+ export declare let ErrHeader: $.GoError;
10
+ export declare function __goscript_set_ErrChecksum(value: $.GoError): void;
11
+ export declare function __goscript_set_ErrHeader(value: $.GoError): void;
12
+ export declare class Header {
13
+ Comment: string;
14
+ Extra: $.Bytes;
15
+ ModTime: any;
16
+ Name: string;
17
+ OS: number;
18
+ }
19
+ export declare class Reader {
20
+ private data;
21
+ private offset;
22
+ private pending;
23
+ constructor(r?: io.Reader | null);
24
+ Read(p: $.Bytes): Promise<[number, $.GoError]>;
25
+ Close(): $.GoError;
26
+ Reset(r: io.Reader | null): $.GoError;
27
+ }
28
+ export declare class Writer {
29
+ private w;
30
+ private level;
31
+ private chunks;
32
+ private closed;
33
+ constructor(w: io.Writer | null, level?: number);
34
+ Write(p: $.Bytes): [number, $.GoError];
35
+ Close(): Promise<$.GoError>;
36
+ Flush(): $.GoError;
37
+ Reset(w: io.Writer | null): void;
38
+ }
39
+ export declare function NewReader(r: io.Reader | null): [io.ReadCloser | null, $.GoError];
40
+ export declare function NewWriter(w: io.Writer | null): Writer;
41
+ export declare function NewWriterLevel(w: io.Writer | null, level: number): [Writer | null, $.GoError];