goscript 0.2.4 → 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 (117) 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 +1238 -194
  19. package/compiler/lowering_bench_test.go +4 -0
  20. package/compiler/override-facts.go +1 -1
  21. package/compiler/package-graph.go +92 -0
  22. package/compiler/package-graph_test.go +113 -0
  23. package/compiler/runtime-contract.go +1 -1
  24. package/compiler/semantic-model.go +32 -0
  25. package/compiler/skeleton_test.go +241 -15
  26. package/compiler/wasm/compile.go +1 -1
  27. package/compiler/wasm/compile_test.go +1 -1
  28. package/dist/compiler/index.d.ts +4 -0
  29. package/dist/compiler/index.js +26 -15
  30. package/dist/compiler/index.js.map +1 -1
  31. package/dist/gs/database/sql/driver/index.d.ts +165 -0
  32. package/dist/gs/database/sql/driver/index.js +432 -0
  33. package/dist/gs/database/sql/driver/index.js.map +1 -0
  34. package/dist/gs/encoding/binary/index.d.ts +71 -0
  35. package/dist/gs/encoding/binary/index.js +778 -0
  36. package/dist/gs/encoding/binary/index.js.map +1 -0
  37. package/dist/gs/fmt/fmt.js +156 -57
  38. package/dist/gs/fmt/fmt.js.map +1 -1
  39. package/dist/gs/github.com/klauspost/cpuid/v2/index.d.ts +11 -0
  40. package/dist/gs/github.com/klauspost/cpuid/v2/index.js +28 -0
  41. package/dist/gs/github.com/klauspost/cpuid/v2/index.js.map +1 -0
  42. package/dist/gs/github.com/pkg/errors/errors.d.ts +0 -2
  43. package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
  44. package/dist/gs/github.com/pkg/errors/index.d.ts +2 -1
  45. package/dist/gs/github.com/pkg/errors/index.js +1 -1
  46. package/dist/gs/github.com/pkg/errors/index.js.map +1 -1
  47. package/dist/gs/github.com/pkg/errors/stack.d.ts +8 -19
  48. package/dist/gs/github.com/pkg/errors/stack.js +26 -61
  49. package/dist/gs/github.com/pkg/errors/stack.js.map +1 -1
  50. package/dist/gs/golang.org/x/crypto/cryptobyte/asn1/index.d.ts +19 -0
  51. package/dist/gs/golang.org/x/crypto/cryptobyte/asn1/index.js +25 -0
  52. package/dist/gs/golang.org/x/crypto/cryptobyte/asn1/index.js.map +1 -0
  53. package/dist/gs/golang.org/x/crypto/cryptobyte/index.d.ts +104 -0
  54. package/dist/gs/golang.org/x/crypto/cryptobyte/index.js +1107 -0
  55. package/dist/gs/golang.org/x/crypto/cryptobyte/index.js.map +1 -0
  56. package/dist/gs/golang.org/x/crypto/internal/alias/index.d.ts +3 -0
  57. package/dist/gs/golang.org/x/crypto/internal/alias/index.js +39 -0
  58. package/dist/gs/golang.org/x/crypto/internal/alias/index.js.map +1 -0
  59. package/dist/gs/runtime/runtime.d.ts +6 -1
  60. package/dist/gs/runtime/runtime.js +15 -8
  61. package/dist/gs/runtime/runtime.js.map +1 -1
  62. package/dist/gs/runtime/trace/index.d.ts +8 -5
  63. package/dist/gs/runtime/trace/index.js +324 -23
  64. package/dist/gs/runtime/trace/index.js.map +1 -1
  65. package/dist/gs/slices/slices.d.ts +2 -1
  66. package/dist/gs/slices/slices.js +9 -3
  67. package/dist/gs/slices/slices.js.map +1 -1
  68. package/dist/gs/sort/search.gs.d.ts +3 -1
  69. package/dist/gs/sort/search.gs.js +18 -53
  70. package/dist/gs/sort/search.gs.js.map +1 -1
  71. package/dist/gs/sync/sync.d.ts +1 -1
  72. package/dist/gs/sync/sync.js +3 -0
  73. package/dist/gs/sync/sync.js.map +1 -1
  74. package/dist/gs/time/time.d.ts +22 -29
  75. package/dist/gs/time/time.js +111 -32
  76. package/dist/gs/time/time.js.map +1 -1
  77. package/dist/gs/unsafe/unsafe.d.ts +3 -2
  78. package/dist/gs/unsafe/unsafe.js.map +1 -1
  79. package/go.mod +7 -5
  80. package/go.sum +12 -26
  81. package/gs/database/sql/driver/index.test.ts +88 -0
  82. package/gs/database/sql/driver/index.ts +675 -0
  83. package/gs/database/sql/driver/meta.json +3 -0
  84. package/gs/database/sql/driver/parity.json +144 -0
  85. package/gs/encoding/binary/index.test.ts +239 -0
  86. package/gs/encoding/binary/index.ts +999 -0
  87. package/gs/encoding/binary/meta.json +9 -0
  88. package/gs/encoding/binary/parity.json +72 -0
  89. package/gs/fmt/fmt.test.ts +28 -0
  90. package/gs/fmt/fmt.ts +198 -61
  91. package/gs/fmt/meta.json +2 -1
  92. package/gs/github.com/klauspost/cpuid/v2/index.ts +38 -0
  93. package/gs/github.com/klauspost/cpuid/v2/meta.json +3 -0
  94. package/gs/github.com/pkg/errors/errors.ts +1 -2
  95. package/gs/github.com/pkg/errors/index.ts +2 -1
  96. package/gs/github.com/pkg/errors/stack.ts +34 -62
  97. package/gs/golang.org/x/crypto/cryptobyte/asn1/index.test.ts +19 -0
  98. package/gs/golang.org/x/crypto/cryptobyte/asn1/index.ts +29 -0
  99. package/gs/golang.org/x/crypto/cryptobyte/index.test.ts +255 -0
  100. package/gs/golang.org/x/crypto/cryptobyte/index.ts +1441 -0
  101. package/gs/golang.org/x/crypto/cryptobyte/meta.json +3 -0
  102. package/gs/golang.org/x/crypto/internal/alias/index.test.ts +40 -0
  103. package/gs/golang.org/x/crypto/internal/alias/index.ts +40 -0
  104. package/gs/runtime/runtime.test.ts +16 -0
  105. package/gs/runtime/runtime.ts +17 -9
  106. package/gs/runtime/trace/index.test.ts +113 -14
  107. package/gs/runtime/trace/index.ts +384 -34
  108. package/gs/runtime/trace/meta.json +1 -0
  109. package/gs/slices/slices.test.ts +24 -1
  110. package/gs/slices/slices.ts +14 -4
  111. package/gs/sort/meta.json +1 -0
  112. package/gs/sort/search.gs.ts +20 -5
  113. package/gs/sync/sync.ts +4 -1
  114. package/gs/time/time.test.ts +79 -2
  115. package/gs/time/time.ts +133 -33
  116. package/gs/unsafe/unsafe.ts +4 -2
  117. package/package.json +2 -2
@@ -4,6 +4,7 @@ import * as $ from '@goscript/builtin/index.js'
4
4
 
5
5
  import {
6
6
  ANSIC,
7
+ Date,
7
8
  Duration_Abs,
8
9
  Duration_Hours,
9
10
  Duration_Microseconds,
@@ -18,6 +19,8 @@ import {
18
19
  Friday,
19
20
  January,
20
21
  Kitchen,
22
+ LoadLocation,
23
+ LoadLocationFromTZData,
21
24
  Local,
22
25
  Microsecond,
23
26
  Millisecond,
@@ -26,17 +29,17 @@ import {
26
29
  NewTicker,
27
30
  NewTimer,
28
31
  RFC1123,
32
+ RFC3339,
29
33
  RFC3339Nano,
30
34
  Saturday,
31
35
  Second,
32
36
  StampMicro,
33
37
  Sunday,
34
- Date,
35
38
  May,
36
- RFC3339,
37
39
  Time,
38
40
  UTC,
39
41
  } from './time.js'
42
+ import type { Month } from './time.js'
40
43
 
41
44
  describe('time.Duration_String', () => {
42
45
  it('formats common durations', () => {
@@ -86,6 +89,9 @@ describe('time constants and timers', () => {
86
89
  })
87
90
 
88
91
  it('exports month and weekday constants directly', () => {
92
+ const zeroMonth: Month = 0
93
+
94
+ expect(zeroMonth).toBe(0)
89
95
  expect(January).toBe(1)
90
96
  expect(Month_String(May)).toBe('May')
91
97
  expect(Sunday).toBe(0)
@@ -126,3 +132,74 @@ describe('time.Time.In', () => {
126
132
  )
127
133
  })
128
134
  })
135
+
136
+ describe('time.Time calendar and binary helpers', () => {
137
+ it('appends formatted text to byte slices', () => {
138
+ const t = Date(2025, May, 15, 1, 10, 42, 0, UTC)
139
+ const out = t.AppendFormat($.stringToBytes('ts='), RFC3339)
140
+
141
+ expect(new TextDecoder().decode(out as Uint8Array)).toBe(
142
+ 'ts=2025-05-15T01:10:42Z',
143
+ )
144
+ })
145
+
146
+ it('computes yearday in the receiver location', () => {
147
+ const utc = Date(2025, January, 1, 1, 0, 0, 0, UTC)
148
+ const pst = FixedZone('PST', -8 * 60 * 60)
149
+
150
+ expect(utc.YearDay()).toBe(1)
151
+ expect(utc.In(pst).YearDay()).toBe(366)
152
+ })
153
+
154
+ it('computes ISO weeks across year boundaries', () => {
155
+ expect(Date(2020, 12, 31, 12, 0, 0, 0, UTC).ISOWeek()).toEqual([2020, 53])
156
+ expect(Date(2021, January, 1, 12, 0, 0, 0, UTC).ISOWeek()).toEqual([
157
+ 2020, 53,
158
+ ])
159
+ expect(Date(2021, January, 4, 12, 0, 0, 0, UTC).ISOWeek()).toEqual([
160
+ 2021, 1,
161
+ ])
162
+ })
163
+
164
+ it('marshals Go binary time encodings', () => {
165
+ const utc = Date(2025, May, 15, 1, 10, 42, 123456789, UTC)
166
+ const pdt = Date(
167
+ 2025,
168
+ May,
169
+ 14,
170
+ 18,
171
+ 10,
172
+ 42,
173
+ 123456789,
174
+ FixedZone('PDT', -7 * 60 * 60),
175
+ )
176
+
177
+ expect(utc.MarshalBinary()).toEqual([
178
+ new Uint8Array([1, 0, 0, 0, 14, 223, 183, 54, 18, 7, 91, 205, 21, 255, 255]),
179
+ null,
180
+ ])
181
+ expect(pdt.MarshalBinary()).toEqual([
182
+ new Uint8Array([1, 0, 0, 0, 14, 223, 183, 54, 18, 7, 91, 205, 21, 254, 92]),
183
+ null,
184
+ ])
185
+ })
186
+ })
187
+
188
+ describe('time location loading', () => {
189
+ it('returns Go-style location tuples', () => {
190
+ expect(LoadLocation('UTC')).toEqual([UTC, null])
191
+ expect(LoadLocation('')).toEqual([UTC, null])
192
+ expect(LoadLocation('Local')).toEqual([Local, null])
193
+
194
+ const [missing, err] = LoadLocation('America/NotReal')
195
+ expect(missing).toBeNull()
196
+ expect(err?.Error()).toBe('time: unknown time zone America/NotReal')
197
+ })
198
+
199
+ it('returns tuple shape for timezone data loaders', () => {
200
+ const [loc, err] = LoadLocationFromTZData('Custom/Zone', new Uint8Array())
201
+
202
+ expect(err).toBeNull()
203
+ expect(loc?.String()).toBe('Custom/Zone')
204
+ })
205
+ })
package/gs/time/time.ts CHANGED
@@ -167,6 +167,10 @@ export class Time {
167
167
  return Time.create(this._date, this._nsec, undefined, $.pointerValue(loc))
168
168
  }
169
169
 
170
+ public AppendFormat(b: $.Bytes | null, layout: string): $.Bytes {
171
+ return $.appendSlice(b, $.stringToBytes(this.Format(layout))) as $.Bytes
172
+ }
173
+
170
174
  // Format returns a textual representation of the time value formatted according to the layout
171
175
  public Format(layout: string): string {
172
176
  // Implementation of Go's time formatting based on reference time:
@@ -510,6 +514,66 @@ export class Time {
510
514
  return result
511
515
  }
512
516
 
517
+ public YearDay(): number {
518
+ const [year, month0, day] = this.wallDateParts()
519
+ const start = globalThis.Date.UTC(year, 0, 1)
520
+ const current = globalThis.Date.UTC(year, month0, day)
521
+ return Math.floor((current - start) / millisecondsPerDay) + 1
522
+ }
523
+
524
+ public ISOWeek(): [number, number] {
525
+ const [year, month0, day] = this.wallDateParts()
526
+ const date = new globalThis.Date(globalThis.Date.UTC(year, month0, day))
527
+ const weekday = date.getUTCDay() || 7
528
+ date.setUTCDate(date.getUTCDate() + 4 - weekday)
529
+
530
+ const isoYear = date.getUTCFullYear()
531
+ const yearStart = new globalThis.Date(globalThis.Date.UTC(isoYear, 0, 1))
532
+ const week = Math.ceil(
533
+ ((date.getTime() - yearStart.getTime()) / millisecondsPerDay + 1) / 7,
534
+ )
535
+ return [isoYear, week]
536
+ }
537
+
538
+ public AppendBinary(b: $.Bytes | null): [$.Bytes, $.GoError] {
539
+ const [zoneName, zoneOffsetSeconds] = this.Zone()
540
+ let offsetMinutes = -1
541
+ let offsetSeconds = 0
542
+ let version = timeBinaryVersionV1
543
+
544
+ if (zoneName !== 'UTC' || zoneOffsetSeconds !== 0) {
545
+ offsetSeconds = zoneOffsetSeconds % 60
546
+ if (offsetSeconds !== 0) {
547
+ version = timeBinaryVersionV2
548
+ }
549
+
550
+ offsetMinutes = Math.trunc(zoneOffsetSeconds / 60)
551
+ if (offsetMinutes < -32768 || offsetMinutes === -1 || offsetMinutes > 32767) {
552
+ return [b, $.newError('Time.MarshalBinary: unexpected zone offset')]
553
+ }
554
+ }
555
+
556
+ const seconds = BigInt(this.Unix()) + unixToInternalSeconds
557
+ const nanos = this.Nanosecond()
558
+ const bytes = new Uint8Array(version === timeBinaryVersionV2 ? 16 : 15)
559
+ bytes[0] = version
560
+ writeInt64BE(bytes, 1, seconds)
561
+ writeInt32BE(bytes, 9, nanos)
562
+ writeInt16BE(bytes, 13, offsetMinutes)
563
+ if (version === timeBinaryVersionV2) {
564
+ bytes[15] = offsetSeconds & 0xff
565
+ }
566
+
567
+ if (b == null) {
568
+ return [bytes, null]
569
+ }
570
+ return [$.appendSlice(b, bytes) as $.Bytes, null]
571
+ }
572
+
573
+ public MarshalBinary(): [$.Bytes, $.GoError] {
574
+ return this.AppendBinary(null)
575
+ }
576
+
513
577
  // Sub returns the duration t-u
514
578
  // If both times have monotonic readings, use them for accurate duration calculation
515
579
  public Sub(u: Time): Duration {
@@ -635,6 +699,24 @@ export class Time {
635
699
 
636
700
  return result
637
701
  }
702
+
703
+ private wallDateParts(): [number, number, number] {
704
+ if (this._location.offsetSeconds !== undefined) {
705
+ const adjustedTime = new globalThis.Date(
706
+ this._date.getTime() + this._location.offsetSeconds * 1000,
707
+ )
708
+ return [
709
+ adjustedTime.getUTCFullYear(),
710
+ adjustedTime.getUTCMonth(),
711
+ adjustedTime.getUTCDate(),
712
+ ]
713
+ }
714
+ return [
715
+ this._date.getFullYear(),
716
+ this._date.getMonth(),
717
+ this._date.getDate(),
718
+ ]
719
+ }
638
720
  }
639
721
 
640
722
  // Duration represents a span of time (nanoseconds)
@@ -643,6 +725,32 @@ export type Duration = number
643
725
  const maxDuration = Number(9223372036854775807n)
644
726
  const minDuration = Number(-9223372036854775808n)
645
727
  const maxTimerDelayMilliseconds = 0x7fffffff
728
+ const millisecondsPerDay = 24 * 60 * 60 * 1000
729
+ const unixToInternalSeconds = 62135596800n
730
+ const timeBinaryVersionV1 = 1
731
+ const timeBinaryVersionV2 = 2
732
+
733
+ function writeInt64BE(bytes: Uint8Array, offset: number, value: bigint): void {
734
+ let encoded = BigInt.asUintN(64, value)
735
+ for (let idx = 7; idx >= 0; idx--) {
736
+ bytes[offset + idx] = Number(encoded & 0xffn)
737
+ encoded >>= 8n
738
+ }
739
+ }
740
+
741
+ function writeInt32BE(bytes: Uint8Array, offset: number, value: number): void {
742
+ const encoded = value >>> 0
743
+ bytes[offset] = (encoded >>> 24) & 0xff
744
+ bytes[offset + 1] = (encoded >>> 16) & 0xff
745
+ bytes[offset + 2] = (encoded >>> 8) & 0xff
746
+ bytes[offset + 3] = encoded & 0xff
747
+ }
748
+
749
+ function writeInt16BE(bytes: Uint8Array, offset: number, value: number): void {
750
+ const encoded = value & 0xffff
751
+ bytes[offset] = (encoded >>> 8) & 0xff
752
+ bytes[offset + 1] = encoded & 0xff
753
+ }
646
754
 
647
755
  function durationNumber(d: Duration): number {
648
756
  return Number(d)
@@ -837,20 +945,7 @@ export class Location {
837
945
  }
838
946
 
839
947
  // Month represents a month of the year
840
- export enum Month {
841
- January = 1,
842
- February = 2,
843
- March = 3,
844
- April = 4,
845
- May = 5,
846
- June = 6,
847
- July = 7,
848
- August = 8,
849
- September = 9,
850
- October = 10,
851
- November = 11,
852
- December = 12,
853
- }
948
+ export type Month = number
854
949
 
855
950
  // Weekday represents a day of the week
856
951
  export enum Weekday {
@@ -1042,8 +1137,12 @@ export function Date(
1042
1137
  min: number,
1043
1138
  sec: number,
1044
1139
  nsec: number,
1045
- loc: Location,
1140
+ loc: Location | $.VarRef<Location> | null,
1046
1141
  ): Time {
1142
+ if (loc === null) {
1143
+ throw new Error('time: missing Location in call to Date')
1144
+ }
1145
+ loc = $.pointerValue(loc)
1047
1146
  let date: globalThis.Date
1048
1147
 
1049
1148
  if (loc.offsetSeconds !== undefined) {
@@ -1111,18 +1210,18 @@ export async function Sleep(d: Duration): Promise<void> {
1111
1210
  }
1112
1211
 
1113
1212
  // Export month constants
1114
- export const January = Month.January
1115
- export const February = Month.February
1116
- export const March = Month.March
1117
- export const April = Month.April
1118
- export const May = Month.May
1119
- export const June = Month.June
1120
- export const July = Month.July
1121
- export const August = Month.August
1122
- export const September = Month.September
1123
- export const October = Month.October
1124
- export const November = Month.November
1125
- export const December = Month.December
1213
+ export const January: Month = 1
1214
+ export const February: Month = 2
1215
+ export const March: Month = 3
1216
+ export const April: Month = 4
1217
+ export const May: Month = 5
1218
+ export const June: Month = 6
1219
+ export const July: Month = 7
1220
+ export const August: Month = 8
1221
+ export const September: Month = 9
1222
+ export const October: Month = 10
1223
+ export const November: Month = 11
1224
+ export const December: Month = 12
1126
1225
 
1127
1226
  // Export weekday constants
1128
1227
  export const Sunday = Weekday.Sunday
@@ -1336,14 +1435,15 @@ export function Tick(d: Duration): ChannelRef<Time> {
1336
1435
 
1337
1436
  // LoadLocation returns the Location with the given name
1338
1437
  // This is a simplified implementation that only supports UTC and Local
1339
- export function LoadLocation(name: string): Location {
1438
+ export function LoadLocation(name: string): [Location | null, $.GoError] {
1340
1439
  switch (name) {
1440
+ case '':
1341
1441
  case 'UTC':
1342
- return UTC
1442
+ return [UTC, null]
1343
1443
  case 'Local':
1344
- return Local
1444
+ return [Local, null]
1345
1445
  default:
1346
- throw new Error(`time: unknown time zone ${name}`)
1446
+ return [null, $.newError(`time: unknown time zone ${name}`)]
1347
1447
  }
1348
1448
  }
1349
1449
 
@@ -1352,7 +1452,7 @@ export function LoadLocation(name: string): Location {
1352
1452
  export function LoadLocationFromTZData(
1353
1453
  name: string,
1354
1454
  _data: Uint8Array,
1355
- ): Location {
1455
+ ): [Location | null, $.GoError] {
1356
1456
  // TODO: parse the timezone data
1357
- return new Location(name)
1457
+ return [new Location(name), null]
1358
1458
  }
@@ -2,6 +2,8 @@
2
2
  // that violate the type system. Most operations are not supported in JavaScript/TypeScript
3
3
  // and will throw errors when used.
4
4
 
5
+ import type * as $ from '../builtin/index.js'
6
+
5
7
  // ArbitraryType is a shorthand for an arbitrary Go type; it is not a real type
6
8
  export type ArbitraryType = any
7
9
 
@@ -46,7 +48,7 @@ export function Add(_ptr: Pointer, _len: IntegerType): Pointer {
46
48
 
47
49
  // Slice returns a slice whose underlying array starts at ptr
48
50
  // This operation is not meaningful in JavaScript/TypeScript
49
- export function Slice(_ptr: Pointer, _len: IntegerType): any[] {
51
+ export function Slice<T = any>(_ptr: Pointer, _len: IntegerType): $.Slice<T> {
50
52
  throw new Error(
51
53
  'unsafe.Slice is not supported in JavaScript/TypeScript: direct memory access is not available in JavaScript',
52
54
  )
@@ -54,7 +56,7 @@ export function Slice(_ptr: Pointer, _len: IntegerType): any[] {
54
56
 
55
57
  // SliceData returns a pointer to the underlying array of the slice
56
58
  // This operation is not meaningful in JavaScript/TypeScript
57
- export function SliceData(_slice: any[]): Pointer {
59
+ export function SliceData(_slice: $.Slice<any> | Uint8Array | any[]): Pointer {
58
60
  throw new Error(
59
61
  'unsafe.SliceData is not supported in JavaScript/TypeScript: direct memory access is not available in JavaScript',
60
62
  )
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "goscript",
3
3
  "description": "Go to TypeScript transpiler",
4
- "version": "0.2.4",
4
+ "version": "0.2.5",
5
5
  "author": {
6
6
  "name": "Aperture Robotics LLC.",
7
7
  "email": "support@aperture.us",
@@ -15,7 +15,7 @@
15
15
  }
16
16
  ],
17
17
  "repository": {
18
- "url": "git+ssh://git@github.com/aperturerobotics/goscript.git"
18
+ "url": "git+ssh://git@github.com/s4wave/goscript.git"
19
19
  },
20
20
  "type": "module",
21
21
  "bin": {