go-go-scope 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +195 -0
- package/dist/index.cjs +1670 -0
- package/dist/index.d.cts +608 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +608 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +1658 -0
- package/package.json +71 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# go-go-scope
|
|
2
|
+
|
|
3
|
+
> Structured concurrency for TypeScript using Explicit Resource Management
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/go-go-scope)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## What is this?
|
|
9
|
+
|
|
10
|
+
`go-go-scope` helps you write async code that:
|
|
11
|
+
- ✅ Automatically cleans up resources
|
|
12
|
+
- ✅ Cancels operations when they're no longer needed
|
|
13
|
+
- ✅ Handles timeouts gracefully
|
|
14
|
+
- ✅ Prevents memory leaks
|
|
15
|
+
|
|
16
|
+
All using familiar `async/await` syntax.
|
|
17
|
+
|
|
18
|
+
## Quick Example
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { scope } from 'go-go-scope'
|
|
22
|
+
|
|
23
|
+
// Fetch data with automatic timeout and cleanup
|
|
24
|
+
async function fetchData() {
|
|
25
|
+
await using s = scope({ timeout: 5000 })
|
|
26
|
+
|
|
27
|
+
const [err, data] = await s.task(async ({ signal }) => {
|
|
28
|
+
const response = await fetch('/api/data', { signal })
|
|
29
|
+
return response.json()
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
if (err) {
|
|
33
|
+
console.log('Failed:', err.message)
|
|
34
|
+
return null
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return data
|
|
38
|
+
// Tasks are auto-cancelled if timeout is reached
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Key concepts:**
|
|
43
|
+
- `scope()` creates a container for async operations
|
|
44
|
+
- `s.task()` creates cancellable work units
|
|
45
|
+
- `{ signal }` is an `AbortSignal` for cancellation
|
|
46
|
+
- `[err, data]` is a Result tuple (never throws!)
|
|
47
|
+
- `await using` automatically cleans up
|
|
48
|
+
|
|
49
|
+
## Installation
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm install go-go-scope
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Requirements:**
|
|
56
|
+
- TypeScript 5.2+ (for `using` syntax)
|
|
57
|
+
- Node.js 18+ or modern browsers
|
|
58
|
+
|
|
59
|
+
**tsconfig.json:**
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"compilerOptions": {
|
|
63
|
+
"lib": ["ES2022", "ESNext.Disposable"]
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Documentation
|
|
69
|
+
|
|
70
|
+
**New to go-go-scope?** Start here:
|
|
71
|
+
1. [📖 Quick Start](./docs/01-quick-start.md) - Get started in 5 minutes
|
|
72
|
+
2. [🧠 Core Concepts](./docs/02-concepts.md) - Learn structured concurrency, Scope, and Task
|
|
73
|
+
|
|
74
|
+
**Reference:**
|
|
75
|
+
- [📚 API Reference](./docs/03-api-reference.md) - Complete API documentation
|
|
76
|
+
- [🚀 Advanced Features](./docs/04-advanced-features.md) - Channels, circuit breakers, retries, polling
|
|
77
|
+
- [⚖️ Comparisons](./docs/05-comparisons.md) - vs Vanilla JS, vs Effect
|
|
78
|
+
- [🔌 Integrations](./docs/06-integrations.md) - OpenTelemetry, go-go-try
|
|
79
|
+
|
|
80
|
+
## Features
|
|
81
|
+
|
|
82
|
+
- 🎯 **Native Resource Management** - Uses `using`/`await using` syntax
|
|
83
|
+
- 🔄 **Structured Concurrency** - Parent scopes auto-cancel children
|
|
84
|
+
- ⏱️ **Timeouts Built-in** - First-class timeout support
|
|
85
|
+
- 🏁 **Race Support** - Structured racing with loser cancellation
|
|
86
|
+
- 📊 **OpenTelemetry** - Optional tracing integration
|
|
87
|
+
- 🐛 **Debug Logging** - Built-in debug output
|
|
88
|
+
- 📦 **Minimal Dependencies** - Only `debug` utility
|
|
89
|
+
- 🔷 **Type-Safe** - Full TypeScript support
|
|
90
|
+
|
|
91
|
+
## Common Patterns
|
|
92
|
+
|
|
93
|
+
### Parallel Operations
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
await using s = scope()
|
|
97
|
+
|
|
98
|
+
const [[userErr, user], [postsErr, posts]] = await Promise.all([
|
|
99
|
+
s.task(() => fetchUser(1)),
|
|
100
|
+
s.task(() => fetchPosts(1))
|
|
101
|
+
])
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Race Operations
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
await using s = scope()
|
|
108
|
+
|
|
109
|
+
const [err, fastest] = await s.race([
|
|
110
|
+
() => fetch('https://fast.com'),
|
|
111
|
+
() => fetch('https://slow.com'),
|
|
112
|
+
])
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Retry on Failure
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
await using s = scope()
|
|
119
|
+
|
|
120
|
+
const [err, result] = await s.task(
|
|
121
|
+
() => fetchData(),
|
|
122
|
+
{ retry: { maxRetries: 3, delay: 1000 } }
|
|
123
|
+
)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Dependency Injection
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
await using s = scope()
|
|
130
|
+
.provide('db', () => openDatabase(), (db) => db.close())
|
|
131
|
+
|
|
132
|
+
const [err, result] = await s.task(({ services }) => {
|
|
133
|
+
return services.db.query('SELECT 1')
|
|
134
|
+
})
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Why go-go-scope?
|
|
138
|
+
|
|
139
|
+
### Before (Vanilla JS)
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
// Manual cleanup, easy to forget!
|
|
143
|
+
const controller = new AbortController()
|
|
144
|
+
const timeoutId = setTimeout(() => controller.abort(), 5000)
|
|
145
|
+
|
|
146
|
+
try {
|
|
147
|
+
const response = await fetch('/api/data', { signal: controller.signal })
|
|
148
|
+
clearTimeout(timeoutId) // Don't forget!
|
|
149
|
+
return response.json()
|
|
150
|
+
} catch (err) {
|
|
151
|
+
clearTimeout(timeoutId) // And here!
|
|
152
|
+
throw err
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### After (go-go-scope)
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
// Automatic cleanup, impossible to leak
|
|
160
|
+
await using s = scope({ timeout: 5000 })
|
|
161
|
+
const response = await fetch('/api/data', { signal: s.signal })
|
|
162
|
+
return response.json()
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Comparison
|
|
166
|
+
|
|
167
|
+
| Aspect | Vanilla JS | go-go-scope | Effect |
|
|
168
|
+
|--------|------------|-------------|--------|
|
|
169
|
+
| Learning curve | None | Low | Steep |
|
|
170
|
+
| Bundle size | 0 KB | ~3 KB | ~50KB+ |
|
|
171
|
+
| Timeout cleanup | Manual | ✅ Automatic | ✅ Automatic |
|
|
172
|
+
| Race cancellation | Manual | ✅ Automatic | ✅ Automatic |
|
|
173
|
+
| Error handling | try/catch | Result tuples | Error channel |
|
|
174
|
+
| Paradigm | Callbacks | async/await | Functional |
|
|
175
|
+
|
|
176
|
+
- **Choose go-go-scope** for structured concurrency with minimal learning curve
|
|
177
|
+
- **Choose Effect** for full functional programming ecosystem
|
|
178
|
+
|
|
179
|
+
See [full comparison](./docs/05-comparisons.md) for details.
|
|
180
|
+
|
|
181
|
+
## Performance
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
Vanilla JS (simple promise) 0.70ms (0.0007ms/op)
|
|
185
|
+
Effect (simple) 10.00ms (0.0100ms/op)
|
|
186
|
+
go-go-scope (simple task) 12.72ms (0.0127ms/op)
|
|
187
|
+
go-go-scope (with retry) 8.22ms (0.0082ms/op)
|
|
188
|
+
go-go-scope (with timeout) 16.99ms (0.0170ms/op)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
See [benchmark details](./benchmark/README.md).
|
|
192
|
+
|
|
193
|
+
## License
|
|
194
|
+
|
|
195
|
+
MIT © [thelinuxlich](https://github.com/thelinuxlich)
|