gofront 1.5.1 → 1.6.1

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 (91) hide show
  1. package/README.md +174 -466
  2. package/package.json +16 -20
  3. package/src/backend/js/expressions.js +288 -128
  4. package/src/backend/js/index.js +138 -56
  5. package/src/backend/js/runtime.js +1055 -53
  6. package/src/backend/js/source-map.js +32 -0
  7. package/src/backend/js/statements.js +151 -83
  8. package/src/backend/js/stdlib/base64.js +12 -0
  9. package/src/backend/js/stdlib/binary.js +102 -0
  10. package/src/backend/js/stdlib/bits.js +15 -1
  11. package/src/backend/js/stdlib/builder.js +28 -9
  12. package/src/backend/js/stdlib/bytes.js +75 -18
  13. package/src/backend/js/stdlib/errors.js +22 -3
  14. package/src/backend/js/stdlib/fmt.js +95 -20
  15. package/src/backend/js/stdlib/hex.js +17 -0
  16. package/src/backend/js/stdlib/html.js +1 -1
  17. package/src/backend/js/stdlib/index.js +19 -0
  18. package/src/backend/js/stdlib/io.js +105 -3
  19. package/src/backend/js/stdlib/maps.js +1 -1
  20. package/src/backend/js/stdlib/math.js +13 -1
  21. package/src/backend/js/stdlib/path.js +20 -6
  22. package/src/backend/js/stdlib/rand.js +10 -5
  23. package/src/backend/js/stdlib/sha256.js +12 -0
  24. package/src/backend/js/stdlib/shared.js +17 -0
  25. package/src/backend/js/stdlib/slices.js +53 -27
  26. package/src/backend/js/stdlib/sort.js +1 -1
  27. package/src/backend/js/stdlib/strconv.js +52 -11
  28. package/src/backend/js/stdlib/strings.js +152 -16
  29. package/src/backend/js/stdlib/sync.js +13 -0
  30. package/src/backend/js/stdlib/testing.js +2 -2
  31. package/src/backend/js/stdlib/time.js +93 -22
  32. package/src/backend/js/stdlib/unicode.js +2 -2
  33. package/src/backend/js/templ.js +1 -1
  34. package/src/backend/wasm/boundary.js +1677 -58
  35. package/src/backend/wasm/const-fold.js +205 -0
  36. package/src/backend/wasm/emit-builtins.js +1230 -0
  37. package/src/backend/wasm/emit-exprs.js +2096 -0
  38. package/src/backend/wasm/emit-maps.js +1999 -0
  39. package/src/backend/wasm/emit-shared.js +519 -0
  40. package/src/backend/wasm/emit-stdlib.js +13 -0
  41. package/src/backend/wasm/emit-stmts.js +2466 -0
  42. package/src/backend/wasm/emit.js +656 -5031
  43. package/src/backend/wasm/encode.js +259 -85
  44. package/src/backend/wasm/glue.js +19 -5
  45. package/src/backend/wasm/index.js +2432 -86
  46. package/src/backend/wasm/monomorph.js +711 -0
  47. package/src/backend/wasm/optimize.js +236 -0
  48. package/src/backend/wasm/stdlib/bytes.js +5039 -0
  49. package/src/backend/wasm/stdlib/core.js +8903 -0
  50. package/src/backend/wasm/stdlib/index.js +40 -0
  51. package/src/backend/wasm/stdlib/io.js +2161 -0
  52. package/src/backend/wasm/stdlib/packages.js +2400 -0
  53. package/src/backend/wasm/stdlib/pure.js +720 -0
  54. package/src/backend/wasm/stdlib/time.js +1200 -0
  55. package/src/backend/wasm/types.js +312 -36
  56. package/src/backend/wasm/wat.js +49 -2
  57. package/src/cli-core.js +276 -73
  58. package/src/compiler.js +162 -25
  59. package/src/dts-parser.js +79 -126
  60. package/src/index.js +88 -121
  61. package/src/lexer.js +80 -29
  62. package/src/lower/boxing.js +4 -6
  63. package/src/lower/captures.js +12 -23
  64. package/src/lower/escape.js +4 -9
  65. package/src/lower/functions.js +277 -5
  66. package/src/lower/globals.js +7 -15
  67. package/src/lower/index.js +5 -2
  68. package/src/lower/ownership.js +35 -19
  69. package/src/lower/range.js +2 -5
  70. package/src/lower/walk.js +25 -0
  71. package/src/minifier.js +20 -68
  72. package/src/parser/declarations.js +3 -6
  73. package/src/parser/expressions.js +3 -8
  74. package/src/parser/index.js +18 -3
  75. package/src/parser/statements.js +25 -38
  76. package/src/parser/types.js +1 -2
  77. package/src/resolver.js +3 -27
  78. package/src/templ-lexer.js +29 -63
  79. package/src/templ-parser.js +22 -45
  80. package/src/test-runner.js +20 -0
  81. package/src/typechecker/assignability.js +123 -14
  82. package/src/typechecker/expressions.js +244 -4
  83. package/src/typechecker/index.js +27 -1
  84. package/src/typechecker/resolve.js +71 -12
  85. package/src/typechecker/statements.js +0 -7
  86. package/src/typechecker/stdlib/core.js +292 -103
  87. package/src/typechecker/stdlib/extended.js +471 -4
  88. package/src/typechecker/stdlib/shared.js +53 -0
  89. package/src/typechecker/stdlib.js +2 -0
  90. package/src/typechecker/types.js +545 -8
  91. package/src/vendor.js +2 -2
@@ -3,29 +3,77 @@
3
3
  /** @typedef {import('../index.js').CodeGen} CodeGen */
4
4
 
5
5
  const TIME_METHOD_DISPATCH = {
6
- Year: (r) => `${r}._d.getFullYear()`,
7
- Month: (r) => `${r}._d.getMonth() + 1`,
8
- Day: (r) => `${r}._d.getDate()`,
9
- Hour: (r) => `${r}._d.getHours()`,
10
- Minute: (r) => `${r}._d.getMinutes()`,
11
- Second: (r) => `${r}._d.getSeconds()`,
12
- Weekday: (r) => `${r}._d.getDay()`,
6
+ Year: (r) =>
7
+ `(${r}._offset === 0 ? ${r}._d.getUTCFullYear() : ${r}._d.getFullYear())`,
8
+ Month: (r) =>
9
+ `(${r}._offset === 0 ? ${r}._d.getUTCMonth() + 1 : ${r}._d.getMonth() + 1)`,
10
+ Day: (r) => `(${r}._offset === 0 ? ${r}._d.getUTCDate() : ${r}._d.getDate())`,
11
+ Hour: (r) =>
12
+ `(${r}._offset === 0 ? ${r}._d.getUTCHours() : ${r}._d.getHours())`,
13
+ Minute: (r) =>
14
+ `(${r}._offset === 0 ? ${r}._d.getUTCMinutes() : ${r}._d.getMinutes())`,
15
+ Second: (r) =>
16
+ `(${r}._offset === 0 ? ${r}._d.getUTCSeconds() : ${r}._d.getSeconds())`,
17
+ Weekday: (r) =>
18
+ `(${r}._offset === 0 ? ${r}._d.getUTCDay() : ${r}._d.getDay())`,
13
19
  Unix: (r) => `Math.floor(${r}._d.getTime() / 1000)`,
14
20
  UnixMilli: (r) => `${r}._d.getTime()`,
15
- Add: (r, a) => `{_d: new Date(${r}._d.getTime() + (${a[0]}))}`,
16
- Sub: (r, a) => `${r}._d.getTime() - (${a[0]})._d.getTime()`,
17
- Before: (r, a) => `${r}._d < (${a[0]})._d`,
18
- After: (r, a) => `${r}._d > (${a[0]})._d`,
19
- Equal: (r, a) => `${r}._d.getTime() === (${a[0]})._d.getTime()`,
21
+ Add: (r, a) =>
22
+ `{_d: new Date(${r}._d.getTime() + Math.round(Number(${a[0]}) / 1000000))}`,
23
+ Sub: (r, a) =>
24
+ `Math.round((${r}._d.getTime() - (${a[0]})._d.getTime()) * 1000000)`,
25
+ Before: (r, a) => `(${r}._d < (${a[0]})._d)`,
26
+ After: (r, a) => `(${r}._d > (${a[0]})._d)`,
27
+ Equal: (r, a) => `(${r}._d.getTime() === (${a[0]})._d.getTime())`,
28
+ IsZero: (r) =>
29
+ `(!${r} || !${r}._d || ${r}._isZero === true || ${r}._d.getTime() === -62135596800000 || (${r}._d.getUTCFullYear() <= 1 && ${r}._d.getUTCMonth() === 0 && ${r}._d.getUTCDate() === 1 && ${r}._d.getUTCHours() === 0 && ${r}._d.getUTCMinutes() === 0 && ${r}._d.getUTCSeconds() === 0 && ${r}._d.getUTCMilliseconds() === 0))`,
30
+ UnixNano: (r) => `(${r}?._d ? Math.round(${r}._d.getTime() * 1000000) : 0)`,
31
+ Nanosecond: (r) =>
32
+ `(${r}?._d ? (${r}._offset === 0 ? ${r}._d.getUTCMilliseconds() : ${r}._d.getMilliseconds()) * 1000000 : 0)`,
33
+ UTC: (r) => `({_d: ${r}?._d ?? new Date(0), _offset: 0})`,
34
+ Local: (r) => `({_d: ${r}?._d ?? new Date(0)})`,
35
+ AddDate: (r, a) =>
36
+ `({_d: new Date(${r}._d.getFullYear() + Number(${a[0]}), ${r}._d.getMonth() + Number(${a[1]}), ${r}._d.getDate() + Number(${a[2]}))})`,
37
+ Truncate: (r, a) =>
38
+ `({_d: new Date(Math.floor(${r}._d.getTime() / (Number(${a[0]}) / 1000000)) * (Number(${a[0]}) / 1000000))})`,
39
+ Round: (r, a) =>
40
+ `({_d: new Date(Math.round(${r}._d.getTime() / (Number(${a[0]}) / 1000000)) * (Number(${a[0]}) / 1000000))})`,
41
+ Date: (r) =>
42
+ `[${r}._offset === 0 ? ${r}._d.getUTCFullYear() : ${r}._d.getFullYear(), ${r}._offset === 0 ? ${r}._d.getUTCMonth() + 1 : ${r}._d.getMonth() + 1, ${r}._offset === 0 ? ${r}._d.getUTCDate() : ${r}._d.getDate()]`,
43
+ Clock: (r) =>
44
+ `[${r}._offset === 0 ? ${r}._d.getUTCHours() : ${r}._d.getHours(), ${r}._offset === 0 ? ${r}._d.getUTCMinutes() : ${r}._d.getMinutes(), ${r}._offset === 0 ? ${r}._d.getUTCSeconds() : ${r}._d.getSeconds()]`,
45
+ YearDay: (r) =>
46
+ `Math.floor((${r}._d - new Date(${r}._d.getFullYear(), 0, 0)) / 86400000)`,
47
+ Compare: (r, a) =>
48
+ `(${r}._d.getTime() < (${a[0]})._d.getTime() ? -1 : (${r}._d.getTime() > (${a[0]})._d.getTime() ? 1 : 0))`,
49
+ In: (r) => `${r}`,
50
+ Location: () => `null`,
51
+ Zone: (r) =>
52
+ `[${r}._offset === 0 ? "UTC" : "LOCAL", ${r}._offset === 0 ? 0 : -${r}._d.getTimezoneOffset() * 60]`,
53
+ };
54
+
55
+ const DURATION_METHOD_DISPATCH = {
56
+ Nanoseconds: (r) => `${r}`,
57
+ Microseconds: (r) => `Math.trunc(Number(${r}) / 1000)`,
58
+ Milliseconds: (r) => `Math.trunc(Number(${r}) / 1000000)`,
59
+ Seconds: (r) => `(Number(${r}) / 1000000000)`,
60
+ Minutes: (r) => `(Number(${r}) / 60000000000)`,
61
+ Hours: (r) => `(Number(${r}) / 3600000000000)`,
62
+ String: (r) => `__durationString(${r})`,
20
63
  };
21
64
 
22
65
  const TIME_DISPATCH = {
23
- Now: () => "{_d: new Date()}",
24
- Since: (a) => `(Date.now() - (${a[0]})._d.getTime())`,
66
+ Now: () =>
67
+ '(typeof globalThis.__GOFRONT_CLOCK === "function" ? {_d: new Date(globalThis.__GOFRONT_CLOCK())} : {_d: new Date()})',
68
+ Since: (a) =>
69
+ `(Math.round(((typeof globalThis.__GOFRONT_CLOCK === "function" ? globalThis.__GOFRONT_CLOCK() : Date.now()) - (${a[0]})._d.getTime()) * 1000000))`,
25
70
  Sleep: (a) => `await new Promise(r => setTimeout(r, ${a[0]} / 1000000))`,
26
- Unix: (a) => `{_d: new Date((${a[0]}) * 1000)}`,
71
+ Unix: (a) =>
72
+ `{_d: new Date(Number(${a[0]}) * 1000 + Math.round(Number(${a[1] || 0}) / 1000000))}`,
73
+ UnixMicro: (a) => `{_d: new Date(Math.round(Number(${a[0]}) / 1000))}`,
74
+ UnixMilli: (a) => `{_d: new Date(Number(${a[0]}))}`,
27
75
  Date: (a) =>
28
- `{_d: new Date(${a[0]}, ${a[1]} - 1, ${a[2]}, ${a[3]}, ${a[4]}, ${a[5]})}`,
76
+ `{_d: new Date(${a[0]}, ${a[1]} - 1, ${a[2]}, ${a[3]}, ${a[4]}, ${a[5]}, Math.round(Number(${a[6] || 0}) / 1000000))}`,
29
77
  };
30
78
 
31
79
  /** @type {ThisType<CodeGen>} */
@@ -35,22 +83,45 @@ export const timeMethods = {
35
83
  const recvJs = this.genExpr(recv);
36
84
  const args = expr.args.map((a) => this.genExpr(a));
37
85
  if (method === "Format") {
38
- this._usesTimeFmt = true;
39
- return `__timeFmt(${recvJs}._d, ${args[0]})`;
86
+ this.useHelper("timeFmt");
87
+ return `__timeFmt(${recvJs}, ${args[0]})`;
40
88
  }
41
89
  if (method === "String") {
42
- this._usesTimeFmt = true;
43
- return `__timeFmt(${recvJs}._d, "2006-01-02T15:04:05Z07:00")`;
90
+ this.useHelper("timeFmt");
91
+ return `__timeFmt(${recvJs}, "2006-01-02 15:04:05.999999999 -0700 MST")`;
44
92
  }
45
93
  const gen = TIME_METHOD_DISPATCH[method];
46
94
  return gen ? gen(recvJs, args) : undefined;
47
95
  },
48
96
 
49
- _genTime(fn, a) {
97
+ _genDurationMethodCall(method, expr) {
98
+ const recv = expr.func.expr;
99
+ const recvJs = this.genExpr(recv);
100
+ if (method === "String") {
101
+ this.useHelper("duration");
102
+ }
103
+ const gen = DURATION_METHOD_DISPATCH[method];
104
+ return gen ? gen(recvJs) : undefined;
105
+ },
106
+
107
+ _genTime(fn, a, expr) {
50
108
  if (fn === "Parse") {
51
- this._usesTimeParse = true;
109
+ this.useHelper("timeParse");
52
110
  return `__timeParse(${a()[0]}, ${a()[1]})`;
53
111
  }
112
+ if (fn === "Date") {
113
+ const args = a();
114
+ const locArg = expr?.args?.[7];
115
+ const isUtc =
116
+ (locArg?.kind === "SelectorExpr" &&
117
+ (locArg.sel?.name === "UTC" || locArg.field === "UTC")) ||
118
+ (locArg?.kind === "Ident" && locArg.name === "UTC") ||
119
+ args[7] === '"UTC"';
120
+ if (isUtc) {
121
+ return `{_d: new Date(Date.UTC(${args[0]}, ${args[1]} - 1, ${args[2]}, ${args[3]}, ${args[4]}, ${args[5]}, Math.round(Number(${args[6] || 0}) / 1000000))), _offset: 0}`;
122
+ }
123
+ return `{_d: new Date(${args[0]}, ${args[1]} - 1, ${args[2]}, ${args[3]}, ${args[4]}, ${args[5]}, Math.round(Number(${args[6] || 0}) / 1000000))}`;
124
+ }
54
125
  const gen = TIME_DISPATCH[fn];
55
126
  return gen ? gen(a()) : undefined;
56
127
  },
@@ -11,8 +11,8 @@ export const unicodeMethods = {
11
11
  IsLetter: `/\\p{L}/u.test(${cp})`,
12
12
  IsDigit: `/\\p{Nd}/u.test(${cp})`,
13
13
  IsSpace: `/\\s/.test(${cp})`,
14
- IsUpper: `((__c) => __c === __c.toUpperCase() && /\\p{L}/u.test(__c))(${cp})`,
15
- IsLower: `((__c) => __c === __c.toLowerCase() && /\\p{L}/u.test(__c))(${cp})`,
14
+ IsUpper: `/\\p{Lu}/u.test(${cp})`,
15
+ IsLower: `/\\p{Ll}/u.test(${cp})`,
16
16
  IsPunct: `/\\p{P}/u.test(${cp})`,
17
17
  IsControl: `/\\p{Cc}/u.test(${cp})`,
18
18
  IsPrint: `!/\\p{Cc}/u.test(${cp})`,
@@ -286,7 +286,7 @@ export const templGenMethods = {
286
286
  if (valName === "_")
287
287
  return `for (const [${keyName}] of Object.entries(${iterJs})) {`;
288
288
  // Default to .entries() for arrays, Object.entries for objects
289
- this._usesSliceGuard = true;
289
+ this.useHelper("sliceGuard");
290
290
  return `for (const [${keyName}, ${valName}] of __s(${iterJs}).entries()) {`;
291
291
  },
292
292