goscript 0.0.26 → 0.0.29

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 (228) hide show
  1. package/README.md +4 -4
  2. package/cmd/goscript/cmd_compile.go +0 -3
  3. package/cmd/goscript/deps.go +11 -0
  4. package/compiler/analysis.go +298 -55
  5. package/compiler/assignment.go +2 -2
  6. package/compiler/builtin_test.go +1 -1
  7. package/compiler/compiler.go +200 -68
  8. package/compiler/compiler_test.go +17 -24
  9. package/compiler/composite-lit.go +32 -8
  10. package/compiler/decl.go +6 -6
  11. package/compiler/expr-call.go +170 -15
  12. package/compiler/expr-selector.go +100 -0
  13. package/compiler/expr.go +1 -1
  14. package/compiler/protobuf.go +557 -0
  15. package/compiler/spec-struct.go +4 -0
  16. package/compiler/spec-value.go +89 -10
  17. package/compiler/spec.go +254 -1
  18. package/compiler/stmt-assign.go +35 -0
  19. package/compiler/type-assert.go +87 -0
  20. package/compiler/type.go +4 -1
  21. package/dist/gs/builtin/builtin.d.ts +20 -1
  22. package/dist/gs/builtin/builtin.js +95 -4
  23. package/dist/gs/builtin/builtin.js.map +1 -1
  24. package/dist/gs/builtin/slice.d.ts +1 -1
  25. package/dist/gs/builtin/slice.js +21 -2
  26. package/dist/gs/builtin/slice.js.map +1 -1
  27. package/dist/gs/errors/errors.d.ts +5 -6
  28. package/dist/gs/errors/errors.js.map +1 -1
  29. package/dist/gs/internal/oserror/errors.d.ts +6 -0
  30. package/dist/gs/internal/oserror/errors.js +7 -0
  31. package/dist/gs/internal/oserror/errors.js.map +1 -0
  32. package/dist/gs/internal/oserror/index.d.ts +1 -0
  33. package/dist/gs/internal/oserror/index.js +2 -0
  34. package/dist/gs/internal/oserror/index.js.map +1 -0
  35. package/dist/gs/io/fs/format.d.ts +3 -0
  36. package/dist/gs/io/fs/format.js +56 -0
  37. package/dist/gs/io/fs/format.js.map +1 -0
  38. package/dist/gs/io/fs/fs.d.ts +79 -0
  39. package/dist/gs/io/fs/fs.js +200 -0
  40. package/dist/gs/io/fs/fs.js.map +1 -0
  41. package/dist/gs/io/fs/glob.d.ts +10 -0
  42. package/dist/gs/io/fs/glob.js +141 -0
  43. package/dist/gs/io/fs/glob.js.map +1 -0
  44. package/dist/gs/io/fs/index.d.ts +8 -0
  45. package/dist/gs/io/fs/index.js +9 -0
  46. package/dist/gs/io/fs/index.js.map +1 -0
  47. package/dist/gs/io/fs/readdir.d.ts +7 -0
  48. package/dist/gs/io/fs/readdir.js +152 -0
  49. package/dist/gs/io/fs/readdir.js.map +1 -0
  50. package/dist/gs/io/fs/readfile.d.ts +6 -0
  51. package/dist/gs/io/fs/readfile.js +118 -0
  52. package/dist/gs/io/fs/readfile.js.map +1 -0
  53. package/dist/gs/io/fs/stat.d.ts +6 -0
  54. package/dist/gs/io/fs/stat.js +87 -0
  55. package/dist/gs/io/fs/stat.js.map +1 -0
  56. package/dist/gs/io/fs/sub.d.ts +6 -0
  57. package/dist/gs/io/fs/sub.js +172 -0
  58. package/dist/gs/io/fs/sub.js.map +1 -0
  59. package/dist/gs/io/fs/walk.d.ts +7 -0
  60. package/dist/gs/io/fs/walk.js +76 -0
  61. package/dist/gs/io/fs/walk.js.map +1 -0
  62. package/dist/gs/io/index.d.ts +1 -0
  63. package/dist/gs/io/index.js +2 -0
  64. package/dist/gs/io/index.js.map +1 -0
  65. package/dist/gs/io/io.d.ts +107 -0
  66. package/dist/gs/io/io.js +385 -0
  67. package/dist/gs/io/io.js.map +1 -0
  68. package/dist/gs/path/index.d.ts +2 -0
  69. package/dist/gs/path/index.js +3 -0
  70. package/dist/gs/path/index.js.map +1 -0
  71. package/dist/gs/path/match.d.ts +6 -0
  72. package/dist/gs/path/match.js +281 -0
  73. package/dist/gs/path/match.js.map +1 -0
  74. package/dist/gs/path/path.d.ts +7 -0
  75. package/dist/gs/path/path.js +256 -0
  76. package/dist/gs/path/path.js.map +1 -0
  77. package/dist/gs/strings/builder.d.ts +18 -0
  78. package/dist/gs/strings/builder.js +205 -0
  79. package/dist/gs/strings/builder.js.map +1 -0
  80. package/dist/gs/strings/clone.d.ts +1 -0
  81. package/dist/gs/strings/clone.js +16 -0
  82. package/dist/gs/strings/clone.js.map +1 -0
  83. package/dist/gs/strings/compare.d.ts +1 -0
  84. package/dist/gs/strings/compare.js +14 -0
  85. package/dist/gs/strings/compare.js.map +1 -0
  86. package/dist/gs/strings/index.d.ts +2 -0
  87. package/dist/gs/strings/index.js +3 -0
  88. package/dist/gs/strings/index.js.map +1 -0
  89. package/dist/gs/strings/iter.d.ts +8 -0
  90. package/dist/gs/strings/iter.js +160 -0
  91. package/dist/gs/strings/iter.js.map +1 -0
  92. package/dist/gs/strings/reader.d.ts +34 -0
  93. package/dist/gs/strings/reader.js +418 -0
  94. package/dist/gs/strings/reader.js.map +1 -0
  95. package/dist/gs/strings/replace.d.ts +106 -0
  96. package/dist/gs/strings/replace.js +1136 -0
  97. package/dist/gs/strings/replace.js.map +1 -0
  98. package/dist/gs/strings/search.d.ts +24 -0
  99. package/dist/gs/strings/search.js +169 -0
  100. package/dist/gs/strings/search.js.map +1 -0
  101. package/dist/gs/strings/strings.d.ts +47 -0
  102. package/dist/gs/strings/strings.js +418 -0
  103. package/dist/gs/strings/strings.js.map +1 -0
  104. package/dist/gs/stringslite/index.d.ts +1 -0
  105. package/dist/gs/stringslite/index.js +2 -0
  106. package/dist/gs/stringslite/index.js.map +1 -0
  107. package/dist/gs/stringslite/strings.d.ts +11 -0
  108. package/dist/gs/stringslite/strings.js +67 -0
  109. package/dist/gs/stringslite/strings.js.map +1 -0
  110. package/dist/gs/sync/index.d.ts +1 -0
  111. package/dist/gs/sync/index.js +2 -0
  112. package/dist/gs/sync/index.js.map +1 -0
  113. package/dist/gs/sync/sync.d.ts +79 -0
  114. package/dist/gs/sync/sync.js +392 -0
  115. package/dist/gs/sync/sync.js.map +1 -0
  116. package/dist/gs/time/time.d.ts +11 -2
  117. package/dist/gs/time/time.js +337 -12
  118. package/dist/gs/time/time.js.map +1 -1
  119. package/dist/gs/unicode/index.d.ts +1 -0
  120. package/dist/gs/unicode/index.js +2 -0
  121. package/dist/gs/unicode/index.js.map +1 -0
  122. package/dist/gs/unicode/unicode.d.ts +105 -0
  123. package/dist/gs/unicode/unicode.js +332 -0
  124. package/dist/gs/unicode/unicode.js.map +1 -0
  125. package/dist/gs/unicode/utf8/index.d.ts +1 -0
  126. package/dist/gs/unicode/utf8/index.js +3 -0
  127. package/dist/gs/unicode/utf8/index.js.map +1 -0
  128. package/dist/gs/unicode/utf8/utf8.d.ts +20 -0
  129. package/dist/gs/unicode/utf8/utf8.js +196 -0
  130. package/dist/gs/unicode/utf8/utf8.js.map +1 -0
  131. package/dist/gs/unsafe/index.d.ts +1 -0
  132. package/dist/gs/unsafe/index.js +2 -0
  133. package/dist/gs/unsafe/index.js.map +1 -0
  134. package/dist/gs/unsafe/unsafe.d.ts +11 -0
  135. package/dist/gs/unsafe/unsafe.js +44 -0
  136. package/dist/gs/unsafe/unsafe.js.map +1 -0
  137. package/go.mod +2 -1
  138. package/go.sum +6 -2
  139. package/gs/README.md +6 -0
  140. package/gs/builtin/builtin.ts +171 -0
  141. package/gs/builtin/channel.ts +683 -0
  142. package/gs/builtin/defer.ts +58 -0
  143. package/gs/builtin/index.ts +1 -0
  144. package/gs/builtin/io.ts +22 -0
  145. package/gs/builtin/map.ts +50 -0
  146. package/gs/builtin/slice.ts +1030 -0
  147. package/gs/builtin/type.ts +1106 -0
  148. package/gs/builtin/varRef.ts +25 -0
  149. package/gs/cmp/godoc.txt +8 -0
  150. package/gs/cmp/index.ts +29 -0
  151. package/gs/context/context.ts +401 -0
  152. package/gs/context/godoc.txt +69 -0
  153. package/gs/context/index.ts +1 -0
  154. package/gs/errors/errors.ts +223 -0
  155. package/gs/errors/godoc.txt +63 -0
  156. package/gs/errors/index.ts +1 -0
  157. package/gs/internal/goarch/godoc.txt +39 -0
  158. package/gs/internal/goarch/index.ts +18 -0
  159. package/gs/internal/oserror/errors.ts +14 -0
  160. package/gs/internal/oserror/index.ts +1 -0
  161. package/gs/io/fs/format.ts +65 -0
  162. package/gs/io/fs/fs.ts +359 -0
  163. package/gs/io/fs/glob.ts +167 -0
  164. package/gs/io/fs/godoc.txt +35 -0
  165. package/gs/io/fs/index.ts +8 -0
  166. package/gs/io/fs/readdir.ts +126 -0
  167. package/gs/io/fs/readfile.ts +77 -0
  168. package/gs/io/fs/stat.ts +38 -0
  169. package/gs/io/fs/sub.ts +208 -0
  170. package/gs/io/fs/walk.ts +89 -0
  171. package/gs/io/godoc.txt +61 -0
  172. package/gs/io/index.ts +1 -0
  173. package/gs/io/io.go +75 -0
  174. package/gs/io/io.ts +546 -0
  175. package/gs/iter/godoc.txt +203 -0
  176. package/gs/iter/index.ts +1 -0
  177. package/gs/iter/iter.ts +117 -0
  178. package/gs/math/bits/index.ts +356 -0
  179. package/gs/math/godoc.txt +76 -0
  180. package/gs/path/index.ts +2 -0
  181. package/gs/path/match.ts +307 -0
  182. package/gs/path/path.ts +301 -0
  183. package/gs/runtime/godoc.txt +331 -0
  184. package/gs/runtime/index.ts +1 -0
  185. package/gs/runtime/runtime.ts +178 -0
  186. package/gs/slices/godoc.txt +44 -0
  187. package/gs/slices/index.ts +1 -0
  188. package/gs/slices/slices.ts +22 -0
  189. package/gs/strings/builder.test.ts +121 -0
  190. package/gs/strings/builder.ts +223 -0
  191. package/gs/strings/clone.test.ts +43 -0
  192. package/gs/strings/clone.ts +17 -0
  193. package/gs/strings/compare.test.ts +84 -0
  194. package/gs/strings/compare.ts +13 -0
  195. package/gs/strings/godoc.txt +66 -0
  196. package/gs/strings/index.ts +2 -0
  197. package/gs/strings/iter.test.ts +343 -0
  198. package/gs/strings/iter.ts +171 -0
  199. package/gs/strings/reader.test.ts +242 -0
  200. package/gs/strings/reader.ts +451 -0
  201. package/gs/strings/replace.test.ts +181 -0
  202. package/gs/strings/replace.ts +1310 -0
  203. package/gs/strings/search.test.ts +214 -0
  204. package/gs/strings/search.ts +213 -0
  205. package/gs/strings/strings.test.ts +477 -0
  206. package/gs/strings/strings.ts +510 -0
  207. package/gs/stringslite/godoc.txt +17 -0
  208. package/gs/stringslite/index.ts +1 -0
  209. package/gs/stringslite/strings.ts +82 -0
  210. package/gs/sync/godoc.txt +21 -0
  211. package/gs/sync/index.ts +1 -0
  212. package/gs/sync/sync.go +64 -0
  213. package/gs/sync/sync.ts +449 -0
  214. package/gs/time/godoc.txt +116 -0
  215. package/gs/time/index.ts +1 -0
  216. package/gs/time/time.ts +585 -0
  217. package/gs/unicode/godoc.txt +52 -0
  218. package/gs/unicode/index.ts +1 -0
  219. package/gs/unicode/unicode.go +38 -0
  220. package/gs/unicode/unicode.ts +418 -0
  221. package/gs/unicode/utf8/godoc.txt +22 -0
  222. package/gs/unicode/utf8/index.ts +2 -0
  223. package/gs/unicode/utf8/utf8.ts +227 -0
  224. package/gs/unsafe/godoc.txt +19 -0
  225. package/gs/unsafe/index.ts +1 -0
  226. package/gs/unsafe/unsafe.test.ts +68 -0
  227. package/gs/unsafe/unsafe.ts +77 -0
  228. package/package.json +4 -3
@@ -0,0 +1,25 @@
1
+ /**
2
+ * VarRef represents a Go variable which can be referred to by other variables.
3
+ *
4
+ * For example:
5
+ * var myVariable int // variable referenced
6
+ * myOtherVar := &myVariable
7
+ */
8
+ export type VarRef<T> = { value: T }
9
+
10
+ /** Wrap a non-null T in a variable reference. */
11
+ export function varRef<T>(v: T): VarRef<T> {
12
+ // We create a new object wrapper for every varRef call to ensure
13
+ // distinct pointer identity, crucial for pointer comparisons (p1 == p2).
14
+ return { value: v }
15
+ }
16
+
17
+ /** Dereference a variable reference, throws on null → simulates Go panic. */
18
+ export function unref<T>(b: VarRef<T>): T {
19
+ if (b === null) {
20
+ throw new Error(
21
+ 'runtime error: invalid memory address or nil pointer dereference',
22
+ )
23
+ }
24
+ return b.value
25
+ }
@@ -0,0 +1,8 @@
1
+ package cmp // import "cmp"
2
+
3
+ Package cmp provides types and functions related to comparing ordered values.
4
+
5
+ func Compare[T Ordered](x, y T) int
6
+ func Less[T Ordered](x, y T) bool
7
+ func Or[T comparable](vals ...T) T
8
+ type Ordered interface{ ... }
@@ -0,0 +1,29 @@
1
+ // Minimal stub for cmp package
2
+ // This provides the Ordered type and comparison functions needed by slices
3
+
4
+ // Ordered represents types that can be ordered (comparable)
5
+ export type Ordered = number | string | boolean | bigint
6
+
7
+ // Compare compares two values and returns:
8
+ // -1 if a < b
9
+ // 0 if a == b
10
+ // 1 if a > b
11
+ export function Compare<T extends Ordered>(a: T, b: T): number {
12
+ if (a < b) return -1
13
+ if (a > b) return 1
14
+ return 0
15
+ }
16
+
17
+ // Less reports whether a < b
18
+ export function Less<T extends Ordered>(a: T, b: T): boolean {
19
+ return a < b
20
+ }
21
+
22
+ // Or returns the first non-zero result from the comparison functions,
23
+ // or zero if all comparisons return zero
24
+ export function Or(...comparisons: number[]): number {
25
+ for (const cmp of comparisons) {
26
+ if (cmp !== 0) return cmp
27
+ }
28
+ return 0
29
+ }
@@ -0,0 +1,401 @@
1
+ import * as $ from '@goscript/builtin/builtin.js'
2
+
3
+ export const Canceled = new Error('context canceled')
4
+ Canceled.name = 'CanceledError'
5
+
6
+ export class DeadlineExceededError extends Error {
7
+ constructor() {
8
+ super('context deadline exceeded')
9
+ this.name = 'DeadlineExceededError'
10
+ }
11
+ }
12
+ export const DeadlineExceeded = new DeadlineExceededError()
13
+
14
+ // Function types
15
+ export type CancelFunc = () => void
16
+ export type CancelCauseFunc = (cause: Error | null) => void
17
+
18
+ // Context interface matching Go's context.Context
19
+ export interface Context {
20
+ // Deadline returns the time when work done on behalf of this context should be canceled
21
+ Deadline(): [Date | null, boolean]
22
+
23
+ // Done returns a channel that's closed when work done on behalf of this context should be canceled
24
+ Done(): $.Channel<{}>
25
+
26
+ // Err returns a non-nil error value after Done is closed
27
+ Err(): Error | null
28
+
29
+ // Value returns the value associated with this context for key, or null
30
+ Value(key: any): any
31
+ }
32
+
33
+ // Base implementation for all contexts
34
+ abstract class baseContext implements Context {
35
+ abstract Deadline(): [Date | null, boolean]
36
+ abstract Done(): $.Channel<{}>
37
+ abstract Err(): Error | null
38
+ abstract Value(key: any): any
39
+ }
40
+
41
+ // Background/TODO context that is never canceled
42
+ class backgroundContext extends baseContext {
43
+ private static readonly neverClosedChannel = $.makeChannel<{}>(0, {}, 'both')
44
+
45
+ static getNeverClosedChannel(): $.Channel<{}> {
46
+ return backgroundContext.neverClosedChannel
47
+ }
48
+
49
+ Deadline(): [Date | null, boolean] {
50
+ return [null, false]
51
+ }
52
+
53
+ Done(): $.Channel<{}> {
54
+ return backgroundContext.neverClosedChannel
55
+ }
56
+
57
+ Err(): Error | null {
58
+ return null
59
+ }
60
+
61
+ Value(key: any): any {
62
+ return null
63
+ }
64
+ }
65
+
66
+ // Value context wraps a parent and adds a key-value pair
67
+ class valueContext extends baseContext {
68
+ constructor(
69
+ private parent: Context,
70
+ private key: any,
71
+ private val: any,
72
+ ) {
73
+ super()
74
+ }
75
+
76
+ getParent(): Context {
77
+ return this.parent
78
+ }
79
+
80
+ Deadline(): [Date | null, boolean] {
81
+ return this.parent.Deadline()
82
+ }
83
+
84
+ Done(): $.Channel<{}> {
85
+ return this.parent.Done()
86
+ }
87
+
88
+ Err(): Error | null {
89
+ return this.parent.Err()
90
+ }
91
+
92
+ Value(key: any): any {
93
+ if (this.key === key) {
94
+ return this.val
95
+ }
96
+ return this.parent.Value(key)
97
+ }
98
+ }
99
+
100
+ // Cancel context that can be canceled
101
+ class cancelContext extends baseContext {
102
+ protected doneChannel: $.Channel<{}>
103
+ protected err: Error | null = null
104
+ protected cause: Error | null = null
105
+ protected children: Set<cancelContext> = new Set()
106
+ protected parent: Context
107
+ protected parentCancelCtx: cancelContext | null = null
108
+ protected removeFromParent: (() => void) | null = null
109
+
110
+ constructor(parent: Context) {
111
+ super()
112
+ this.parent = parent
113
+ this.doneChannel = $.makeChannel<{}>(0, {}, 'both')
114
+ }
115
+
116
+ Deadline(): [Date | null, boolean] {
117
+ return this.parent.Deadline()
118
+ }
119
+
120
+ Done(): $.Channel<{}> {
121
+ return this.doneChannel
122
+ }
123
+
124
+ Err(): Error | null {
125
+ return this.err
126
+ }
127
+
128
+ Value(key: any): any {
129
+ return this.parent.Value(key)
130
+ }
131
+
132
+ getCause(): Error | null {
133
+ if (this.cause !== null) {
134
+ return this.cause
135
+ }
136
+ return this.err
137
+ }
138
+
139
+ cancel(removeFromParent: boolean, err: Error, cause: Error | null): void {
140
+ if (this.err !== null) {
141
+ return // Already canceled
142
+ }
143
+
144
+ this.err = err
145
+ this.cause = cause
146
+ this.doneChannel.close()
147
+
148
+ // Cancel all children
149
+ for (const child of this.children) {
150
+ child.cancel(false, err, cause)
151
+ }
152
+ this.children.clear()
153
+
154
+ // Remove from parent's children if requested
155
+ if (removeFromParent && this.removeFromParent) {
156
+ this.removeFromParent()
157
+ this.removeFromParent = null
158
+ }
159
+ }
160
+
161
+ propagateCancel(): void {
162
+ // Find parent cancelContext if any
163
+ let parent = this.parent
164
+ while (parent instanceof valueContext) {
165
+ parent = (parent as valueContext).getParent()
166
+ }
167
+
168
+ if (parent instanceof cancelContext) {
169
+ // Parent is a cancel context, register as child
170
+ this.parentCancelCtx = parent
171
+ if (parent.err !== null) {
172
+ // Parent already canceled
173
+ this.cancel(false, parent.err, parent.cause)
174
+ } else {
175
+ parent.children.add(this)
176
+ this.removeFromParent = () => {
177
+ parent.children.delete(this)
178
+ }
179
+ }
180
+ } else {
181
+ // Watch parent's Done channel
182
+ this.watchParentDone()
183
+ }
184
+ }
185
+
186
+ private watchParentDone(): void {
187
+ const parentDone = this.parent.Done()
188
+ ;(async () => {
189
+ try {
190
+ await parentDone.receive()
191
+ } catch {
192
+ // Channel closed
193
+ }
194
+ // Parent is done, cancel this context
195
+ const parentErr = this.parent.Err()
196
+ if (parentErr && this.err === null) {
197
+ this.cancel(false, parentErr, null)
198
+ }
199
+ })()
200
+ }
201
+ }
202
+
203
+ // Timer context with deadline
204
+ class timerContext extends cancelContext {
205
+ private deadline: Date
206
+ private timer: any
207
+
208
+ constructor(parent: Context, deadline: Date) {
209
+ super(parent)
210
+ this.deadline = deadline
211
+ }
212
+
213
+ Deadline(): [Date | null, boolean] {
214
+ return [this.deadline, true]
215
+ }
216
+
217
+ startTimer(): void {
218
+ const now = Date.now()
219
+ const duration = this.deadline.getTime() - now
220
+
221
+ if (duration <= 0) {
222
+ // Already expired
223
+ this.cancel(true, DeadlineExceeded, null)
224
+ return
225
+ }
226
+
227
+ this.timer = setTimeout(() => {
228
+ this.cancel(true, DeadlineExceeded, null)
229
+ }, duration)
230
+ }
231
+
232
+ cancel(removeFromParent: boolean, err: Error, cause: Error | null): void {
233
+ super.cancel(removeFromParent, err, cause)
234
+ if (this.timer) {
235
+ clearTimeout(this.timer)
236
+ this.timer = null
237
+ }
238
+ }
239
+ }
240
+
241
+ // Without cancel context - inherits values but not cancellation
242
+ class withoutCancelContext extends baseContext {
243
+ constructor(private parent: Context) {
244
+ super()
245
+ }
246
+
247
+ Deadline(): [Date | null, boolean] {
248
+ return [null, false]
249
+ }
250
+
251
+ Done(): $.Channel<{}> {
252
+ return backgroundContext.getNeverClosedChannel()
253
+ }
254
+
255
+ Err(): Error | null {
256
+ return null
257
+ }
258
+
259
+ Value(key: any): any {
260
+ return this.parent.Value(key)
261
+ }
262
+ }
263
+
264
+ // Singleton contexts
265
+ const background = new backgroundContext()
266
+ const todo = new backgroundContext()
267
+
268
+ // Background returns a non-nil, empty Context that is never canceled
269
+ export function Background(): Context {
270
+ return background
271
+ }
272
+
273
+ // TODO returns a non-nil, empty Context
274
+ export function TODO(): Context {
275
+ return todo
276
+ }
277
+
278
+ // WithCancel returns a copy of parent with a new Done channel
279
+ export function WithCancel(parent: Context): [Context, CancelFunc] {
280
+ const ctx = new cancelContext(parent)
281
+ ctx.propagateCancel()
282
+
283
+ return [
284
+ ctx,
285
+ () => {
286
+ ctx.cancel(true, Canceled, null)
287
+ },
288
+ ]
289
+ }
290
+
291
+ // WithCancelCause returns a copy of parent with a new Done channel and cause recording
292
+ export function WithCancelCause(parent: Context): [Context, CancelCauseFunc] {
293
+ const ctx = new cancelContext(parent)
294
+ ctx.propagateCancel()
295
+
296
+ return [
297
+ ctx,
298
+ (cause: Error | null) => {
299
+ ctx.cancel(true, Canceled, cause)
300
+ },
301
+ ]
302
+ }
303
+
304
+ // WithDeadline returns a copy of parent with the deadline adjusted to be no later than d
305
+ export function WithDeadline(parent: Context, d: Date): [Context, CancelFunc] {
306
+ return WithDeadlineCause(parent, d, null)
307
+ }
308
+
309
+ // WithDeadlineCause is like WithDeadline but also sets the cause
310
+ export function WithDeadlineCause(
311
+ parent: Context,
312
+ d: Date,
313
+ cause: Error | null,
314
+ ): [Context, CancelFunc] {
315
+ // Check if parent deadline is already earlier
316
+ const [parentDeadline, ok] = parent.Deadline()
317
+ if (ok && parentDeadline && parentDeadline <= d) {
318
+ // Parent deadline is already sooner
319
+ return WithCancel(parent)
320
+ }
321
+
322
+ const ctx = new timerContext(parent, d)
323
+ ctx.propagateCancel()
324
+ ctx.startTimer()
325
+
326
+ return [
327
+ ctx,
328
+ () => {
329
+ ctx.cancel(true, Canceled, cause)
330
+ },
331
+ ]
332
+ }
333
+
334
+ // WithTimeout returns WithDeadline(parent, Date.now() + timeout)
335
+ export function WithTimeout(
336
+ parent: Context,
337
+ timeout: number,
338
+ ): [Context, CancelFunc] {
339
+ return WithDeadline(parent, new Date(Date.now() + timeout))
340
+ }
341
+
342
+ // WithTimeoutCause is like WithTimeout but also sets the cause
343
+ export function WithTimeoutCause(
344
+ parent: Context,
345
+ timeout: number,
346
+ cause: Error | null,
347
+ ): [Context, CancelFunc] {
348
+ return WithDeadlineCause(parent, new Date(Date.now() + timeout), cause)
349
+ }
350
+
351
+ // WithValue returns a copy of parent with the value associated with key
352
+ export function WithValue(parent: Context, key: any, val: any): Context {
353
+ return new valueContext(parent, key, val)
354
+ }
355
+
356
+ // WithoutCancel returns a context that inherits values but not cancellation
357
+ export function WithoutCancel(parent: Context): Context {
358
+ return new withoutCancelContext(parent)
359
+ }
360
+
361
+ // Cause returns the underlying cause of the context's cancellation
362
+ export function Cause(ctx: Context): Error | null {
363
+ let c = ctx
364
+ // Unwrap value contexts
365
+ while (c instanceof valueContext) {
366
+ c = (c as valueContext).getParent()
367
+ }
368
+
369
+ if (c instanceof cancelContext) {
370
+ return c.getCause()
371
+ }
372
+
373
+ return c.Err()
374
+ }
375
+
376
+ // AfterFunc runs f in a separate goroutine after ctx is done
377
+ export function AfterFunc(ctx: Context, f: () => void): () => boolean {
378
+ let stopped = false
379
+ let done = false
380
+
381
+ const promise = (async () => {
382
+ try {
383
+ await ctx.Done().receive()
384
+ } catch {
385
+ // Channel closed
386
+ }
387
+ if (!stopped) {
388
+ done = true
389
+ // Run in next tick to simulate goroutine
390
+ setImmediate(f)
391
+ }
392
+ })()
393
+
394
+ return () => {
395
+ if (!done) {
396
+ stopped = true
397
+ return true
398
+ }
399
+ return false
400
+ }
401
+ }
@@ -0,0 +1,69 @@
1
+ package context // import "context"
2
+
3
+ Package context defines the Context type, which carries deadlines, cancellation
4
+ signals, and other request-scoped values across API boundaries and between
5
+ processes.
6
+
7
+ Incoming requests to a server should create a Context, and outgoing calls to
8
+ servers should accept a Context. The chain of function calls between them must
9
+ propagate the Context, optionally replacing it with a derived Context created
10
+ using WithCancel, WithDeadline, WithTimeout, or WithValue.
11
+
12
+ A Context may be canceled to indicate that work done on its behalf should stop.
13
+ A Context with a deadline is canceled after the deadline passes. When a Context
14
+ is canceled, all Contexts derived from it are also canceled.
15
+
16
+ The WithCancel, WithDeadline, and WithTimeout functions take a Context (the
17
+ parent) and return a derived Context (the child) and a CancelFunc. Calling the
18
+ CancelFunc directly cancels the child and its children, removes the parent's
19
+ reference to the child, and stops any associated timers. Failing to call the
20
+ CancelFunc leaks the child and its children until the parent is canceled.
21
+ The go vet tool checks that CancelFuncs are used on all control-flow paths.
22
+
23
+ The WithCancelCause, WithDeadlineCause, and WithTimeoutCause functions return a
24
+ CancelCauseFunc, which takes an error and records it as the cancellation cause.
25
+ Calling Cause on the canceled context or any of its children retrieves the
26
+ cause. If no cause is specified, Cause(ctx) returns the same value as ctx.Err().
27
+
28
+ Programs that use Contexts should follow these rules to keep interfaces
29
+ consistent across packages and enable static analysis tools to check context
30
+ propagation:
31
+
32
+ Do not store Contexts inside a struct type; instead, pass a Context
33
+ explicitly to each function that needs it. This is discussed further in
34
+ https://go.dev/blog/context-and-structs. The Context should be the first
35
+ parameter, typically named ctx:
36
+
37
+ func DoSomething(ctx context.Context, arg Arg) error {
38
+ // ... use ctx ...
39
+ }
40
+
41
+ Do not pass a nil Context, even if a function permits it. Pass context.TODO if
42
+ you are unsure about which Context to use.
43
+
44
+ Use context Values only for request-scoped data that transits processes and
45
+ APIs, not for passing optional parameters to functions.
46
+
47
+ The same Context may be passed to functions running in different goroutines;
48
+ Contexts are safe for simultaneous use by multiple goroutines.
49
+
50
+ See https://go.dev/blog/context for example code for a server that uses
51
+ Contexts.
52
+
53
+ var Canceled = errors.New("context canceled")
54
+ var DeadlineExceeded error = deadlineExceededError{}
55
+ func AfterFunc(ctx Context, f func()) (stop func() bool)
56
+ func Cause(c Context) error
57
+ func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
58
+ func WithCancelCause(parent Context) (ctx Context, cancel CancelCauseFunc)
59
+ func WithDeadline(parent Context, d time.Time) (Context, CancelFunc)
60
+ func WithDeadlineCause(parent Context, d time.Time, cause error) (Context, CancelFunc)
61
+ func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
62
+ func WithTimeoutCause(parent Context, timeout time.Duration, cause error) (Context, CancelFunc)
63
+ type CancelCauseFunc func(cause error)
64
+ type CancelFunc func()
65
+ type Context interface{ ... }
66
+ func Background() Context
67
+ func TODO() Context
68
+ func WithValue(parent Context, key, val any) Context
69
+ func WithoutCancel(parent Context) Context
@@ -0,0 +1 @@
1
+ export * from './context.js'